diff --git a/README.md b/README.md index 9ff7049..c900aaf 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,68 @@ A library for working with character cards. +## Installation + +To install the library, use npm: + +```sh +npm install @openrouter/character +``` + +## Usage + +Here's a simple example of how to use the library: + +```javascript +import { Character } from '@openrouter/character'; + +const file = new File(['{"name": "John Doe"}'], 'character.json', { type: 'application/json' }); + +Character.fromFile(file).then((character) => { + console.log(character.name); // Output: John Doe +}); +``` + +## API Documentation + +### `Character` + +#### Properties + +- `metadata`: The metadata of the character. +- `fallbackAvatar`: The fallback avatar of the character. + +#### Methods + +- `static fromFile(file: File): Promise`: Creates a `Character` instance from a file. +- `avatar`: Returns the avatar of the character. +- `description`: Returns the description of the character. +- `name`: Returns the name of the character. + +## Comprehensive Example + +Here's a comprehensive example demonstrating the `Character` class: + +```javascript +import { Character } from '@openrouter/character'; + +const jsonFile = new File(['{"name": "John Doe", "description": "A brave warrior"}'], 'character.json', { type: 'application/json' }); +const pngFile = new File([/* PNG file data */], 'character.png', { type: 'image/png' }); +const webpFile = new File([/* WEBP file data */], 'character.webp', { type: 'image/webp' }); + +Promise.all([ + Character.fromFile(jsonFile), + Character.fromFile(pngFile), + Character.fromFile(webpFile) +]).then(([jsonCharacter, pngCharacter, webpCharacter]) => { + console.log(jsonCharacter.name); // Output: John Doe + console.log(jsonCharacter.description); // Output: A brave warrior + + console.log(pngCharacter.avatar); // Output: Base64 encoded PNG avatar + console.log(webpCharacter.avatar); // Output: Base64 encoded WEBP avatar +}); +``` + ## Acknowledgements - https://github.com/SillyTavern/SillyTavern diff --git a/tests/character.test.js b/tests/character.test.js new file mode 100644 index 0000000..fcc5b9f --- /dev/null +++ b/tests/character.test.js @@ -0,0 +1,55 @@ +import { Character } from '../src/index.js'; +import { test, describe } from 'node:test'; +import assert from 'node:assert'; + +describe('Character', () => { + test('Character.fromFile with JSON file', async () => { + const file = new File(['{"name": "John Doe"}'], 'character.json', { type: 'application/json' }); + const character = await Character.fromFile(file); + assert.strictEqual(character.name, 'John Doe'); + }); + + test('Character.fromFile with PNG file', async () => { + const pngData = new Uint8Array([ + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xDE, 0x00, 0x00, 0x00, + 0x0A, 0x74, 0x45, 0x58, 0x74, 0x63, 0x68, 0x61, 0x72, 0x61, 0x00, 0x7B, + 0x22, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3A, 0x22, 0x4A, 0x6F, 0x68, 0x6E, + 0x20, 0x44, 0x6F, 0x65, 0x22, 0x7D, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44, + 0x41, 0x54, 0x78, 0x9C, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, + 0xE2, 0x21, 0xBC, 0x33, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, + 0xAE, 0x42, 0x60, 0x82 + ]); + const file = new File([pngData], 'character.png', { type: 'image/png' }); + const character = await Character.fromFile(file); + assert.strictEqual(character.name, 'John Doe'); + }); + + test('Character.fromFile with WEBP file', async () => { + const webpData = new Uint8Array([ + 0x52, 0x49, 0x46, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50, + 0x56, 0x50, 0x38, 0x20, 0x0A, 0x00, 0x00, 0x00, 0x30, 0x2E, 0x30, 0x30, + 0x2E, 0x30, 0x30, 0x2E, 0x30, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, + 0x4C, 0x49, 0x53, 0x54, 0x3A, 0x00, 0x00, 0x00, 0x4A, 0x53, 0x4F, 0x4E, + 0x3A, 0x7B, 0x22, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3A, 0x22, 0x4A, 0x6F, + 0x68, 0x6E, 0x20, 0x44, 0x6F, 0x65, 0x22, 0x7D, 0x00, 0x00, 0x00, 0x00 + ]); + const file = new File([webpData], 'character.webp', { type: 'image/webp' }); + const character = await Character.fromFile(file); + assert.strictEqual(character.name, 'John Doe'); + }); + + test('Character properties and methods', async () => { + const metadata = { + name: 'John Doe', + description: 'A brave warrior', + avatar: 'none', + system_prompt: 'A warrior in a fantasy world' + }; + const character = new Character(metadata); + assert.strictEqual(character.name, 'John Doe'); + assert.strictEqual(character.description, 'A warrior in a fantasy world'); + assert.strictEqual(character.avatar, ''); + }); +});