characterforge-js 1.0.0 β 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -339
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,53 +1,59 @@
|
|
|
1
|
-
# CharacterForge
|
|
1
|
+
# CharacterForge JS
|
|
2
2
|
|
|
3
|
-
AI-powered 3D character generation
|
|
3
|
+
TypeScript SDK for [CharacterForge](https://characterforge.app)βAI-powered stylized 3D character image generation for browsers, Node.js, and React Native.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/characterforge)
|
|
5
|
+
[](https://www.npmjs.com/package/characterforge-js)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
- **Character generation** β Configure appearance (gender, skin, hair, clothing, eyes, accessories) and receive a PNG image URL from the CharacterForge API.
|
|
11
|
+
- **No runtime dependencies** β The package itself ships without npm dependencies; it uses `fetch` and platform APIs.
|
|
12
|
+
- **Client-side caching** β IndexedDB on web; file system + metadata storage on React Native (optional peer-style installs).
|
|
13
|
+
- **Retries** β Exponential backoff with jitter for transient failures.
|
|
14
|
+
- **Typed** β Written in TypeScript with exported types for configuration and errors.
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
- **Node.js** β `>=16` per `package.json`. The client uses the global `fetch` API; use **Node 18+** (or provide a `fetch` polyfill) in Node environments.
|
|
19
|
+
- **Browser** β Modern browsers with `fetch` and IndexedDB for the default web cache.
|
|
20
|
+
- **React Native** β For native caching, install a file-system package and AsyncStorage (see below).
|
|
17
21
|
|
|
18
22
|
## Installation
|
|
19
23
|
|
|
20
24
|
```bash
|
|
21
|
-
npm install characterforge
|
|
25
|
+
npm install characterforge-js
|
|
22
26
|
```
|
|
23
27
|
|
|
24
|
-
### React Native
|
|
28
|
+
### React Native (caching)
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
Caching on React Native uses `expo-file-system` *or* `react-native-fs`, plus AsyncStorage for metadata. Install what matches your app:
|
|
27
31
|
|
|
28
32
|
**Expo:**
|
|
33
|
+
|
|
29
34
|
```bash
|
|
30
35
|
npx expo install expo-file-system @react-native-async-storage/async-storage
|
|
31
36
|
```
|
|
32
37
|
|
|
33
38
|
**Bare React Native:**
|
|
39
|
+
|
|
34
40
|
```bash
|
|
35
41
|
npm install react-native-fs @react-native-async-storage/async-storage
|
|
36
42
|
```
|
|
37
43
|
|
|
38
|
-
|
|
44
|
+
If these are not installed, the SDK falls back to a no-op cache on unsupported environments.
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
39
47
|
|
|
40
|
-
### Web
|
|
48
|
+
### Web or Node
|
|
41
49
|
|
|
42
50
|
```typescript
|
|
43
|
-
import { createCharacterForgeClient } from 'characterforge';
|
|
51
|
+
import { createCharacterForgeClient } from 'characterforge-js';
|
|
44
52
|
|
|
45
|
-
// Create a client instance
|
|
46
53
|
const client = createCharacterForgeClient({
|
|
47
|
-
apiKey:
|
|
54
|
+
apiKey: process.env.CHARACTERFORGE_API_KEY!,
|
|
48
55
|
});
|
|
49
56
|
|
|
50
|
-
// Generate a character
|
|
51
57
|
const imageUrl = await client.generate({
|
|
52
58
|
gender: 'female',
|
|
53
59
|
skinTone: 'medium',
|
|
@@ -60,24 +66,22 @@ const imageUrl = await client.generate({
|
|
|
60
66
|
transparent: true,
|
|
61
67
|
});
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
console.log('Generated image:', imageUrl);
|
|
69
|
+
console.log(imageUrl);
|
|
65
70
|
```
|
|
66
71
|
|
|
67
72
|
### React Native
|
|
68
73
|
|
|
69
74
|
```typescript
|
|
70
|
-
import { createCharacterForgeClient } from 'characterforge';
|
|
71
|
-
import { Image } from 'react-native';
|
|
75
|
+
import { createCharacterForgeClient } from 'characterforge-js';
|
|
76
|
+
import { Image, Button } from 'react-native';
|
|
77
|
+
import React from 'react';
|
|
72
78
|
|
|
73
|
-
// Create a client instance
|
|
74
79
|
const client = createCharacterForgeClient({
|
|
75
|
-
apiKey: 'your-api-key
|
|
80
|
+
apiKey: 'your-api-key',
|
|
76
81
|
});
|
|
77
82
|
|
|
78
|
-
// In your component
|
|
79
83
|
function MyComponent() {
|
|
80
|
-
const [imageUrl, setImageUrl] = React.useState(null);
|
|
84
|
+
const [imageUrl, setImageUrl] = React.useState<string | null>(null);
|
|
81
85
|
|
|
82
86
|
const generateCharacter = async () => {
|
|
83
87
|
const url = await client.generate({
|
|
@@ -97,370 +101,147 @@ function MyComponent() {
|
|
|
97
101
|
return (
|
|
98
102
|
<>
|
|
99
103
|
<Button title="Generate Character" onPress={generateCharacter} />
|
|
100
|
-
{imageUrl
|
|
104
|
+
{imageUrl ? <Image source={{ uri: imageUrl }} style={{ width: 300, height: 300 }} /> : null}
|
|
101
105
|
</>
|
|
102
106
|
);
|
|
103
107
|
}
|
|
104
108
|
```
|
|
105
109
|
|
|
106
|
-
## API
|
|
110
|
+
## API
|
|
107
111
|
|
|
108
112
|
### `createCharacterForgeClient(config)`
|
|
109
113
|
|
|
110
|
-
|
|
114
|
+
Returns a `CharacterForgeClient` instance.
|
|
111
115
|
|
|
112
|
-
|
|
116
|
+
**`CharacterForgeClientConfig`:**
|
|
113
117
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
/** Base URL for the API (optional, defaults to production) */
|
|
124
|
-
baseUrl?: string;
|
|
125
|
-
|
|
126
|
-
/** Enable/disable client-side caching (default: true) */
|
|
127
|
-
cache?: boolean;
|
|
128
|
-
|
|
129
|
-
/** Custom cache manager implementation (optional) */
|
|
130
|
-
cacheManager?: CacheManager;
|
|
131
|
-
|
|
132
|
-
/** Request timeout in milliseconds (default: 60000) */
|
|
133
|
-
timeout?: number;
|
|
134
|
-
|
|
135
|
-
/** Retry configuration (optional) */
|
|
136
|
-
retry?: {
|
|
137
|
-
maxRetries: number; // default: 3
|
|
138
|
-
baseDelayMs: number; // default: 1000
|
|
139
|
-
maxDelayMs: number; // default: 10000
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
**Returns:** `CharacterForgeClient` instance
|
|
118
|
+
| Option | Description |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| `apiKey` | **Required.** API key from CharacterForge. |
|
|
121
|
+
| `baseUrl` | Optional. API base URL (must expose `POST .../generate-character`). Defaults to the production CharacterForge backend. |
|
|
122
|
+
| `cache` | Enable client cache (default: `true`). |
|
|
123
|
+
| `cacheManager` | Optional custom `CacheManager` implementation. |
|
|
124
|
+
| `timeout` | Request timeout in ms (default: `60000`). |
|
|
125
|
+
| `retry` | `{ maxRetries, baseDelayMs, maxDelayMs }` β defaults: `3`, `1000`, `10000`. |
|
|
145
126
|
|
|
146
127
|
### `client.generate(config, onStatusUpdate?)`
|
|
147
128
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
**Parameters:**
|
|
151
|
-
|
|
152
|
-
- `config` - Character configuration object
|
|
153
|
-
- `onStatusUpdate` (optional) - Callback function for status updates
|
|
129
|
+
- **`config`** β `CharacterConfig` (see types in the package or below).
|
|
130
|
+
- **`onStatusUpdate`** β Optional `(status: string) => void` for messages such as `"Calling AI Cloud..."`, `"Caching result..."`, `"Retrieved from Client Cache!"`.
|
|
154
131
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
```typescript
|
|
158
|
-
interface CharacterConfig {
|
|
159
|
-
/** Gender: 'male' | 'female' */
|
|
160
|
-
gender: Gender;
|
|
161
|
-
|
|
162
|
-
/** Age group (optional): 'kid' | 'preteen' | 'teen' | 'young_adult' | 'adult' */
|
|
163
|
-
ageGroup?: AgeGroupId;
|
|
164
|
-
|
|
165
|
-
/** Skin tone: 'porcelain' | 'fair' | 'light' | 'medium' | 'olive' | 'brown' | 'dark' | 'deep' */
|
|
166
|
-
skinTone: SkinToneId;
|
|
167
|
-
|
|
168
|
-
/** Hair style: 'bob' | 'ponytail' | 'buns' | 'long' | 'pixie' | 'undercut' | 'quiff' | 'sidepart' | 'buzz' | 'combover' | 'messy' | 'afro' | 'curly' */
|
|
169
|
-
hairStyle: HairStyleId;
|
|
170
|
-
|
|
171
|
-
/** Hair color: 'black' | 'dark_brown' | 'brown' | 'auburn' | 'ginger' | 'dark_blonde' | 'blonde' | 'platinum' | 'grey' | 'white' | 'blue' | 'purple' */
|
|
172
|
-
hairColor: HairColorId;
|
|
173
|
-
|
|
174
|
-
/** Clothing: 'tshirt' | 'hoodie' | 'sweater' | 'jacket' | 'tank' | 'dress' | 'blouse' | 'polo' | 'buttonup' | 'henley' */
|
|
175
|
-
clothing: ClothingItemId;
|
|
176
|
-
|
|
177
|
-
/** Clothing color: 'white' | 'black' | 'navy' | 'red' | 'blue' | 'green' | 'yellow' | 'purple' | 'pink' | 'orange' | 'teal' */
|
|
178
|
-
clothingColor: ClothingColorId;
|
|
179
|
-
|
|
180
|
-
/** Eye color: 'dark' | 'brown' | 'blue' | 'green' | 'hazel' | 'grey' */
|
|
181
|
-
eyeColor: EyeColorId;
|
|
182
|
-
|
|
183
|
-
/** Accessories: array of 'none' | 'glasses' | 'sunglasses' | 'headphones' | 'cap' | 'beanie' */
|
|
184
|
-
accessories: AccessoryId[];
|
|
185
|
-
|
|
186
|
-
/** Generate with transparent background (default: true) */
|
|
187
|
-
transparent: boolean;
|
|
188
|
-
|
|
189
|
-
/** Use caching for this generation (default: true) */
|
|
190
|
-
cache?: boolean;
|
|
191
|
-
}
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
**Returns:** `Promise<string>` - URL to the generated image
|
|
195
|
-
|
|
196
|
-
**Example with status updates:**
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
const imageUrl = await client.generate(
|
|
200
|
-
{
|
|
201
|
-
gender: 'female',
|
|
202
|
-
skinTone: 'medium',
|
|
203
|
-
hairStyle: 'bob',
|
|
204
|
-
hairColor: 'brown',
|
|
205
|
-
clothing: 'hoodie',
|
|
206
|
-
clothingColor: 'blue',
|
|
207
|
-
eyeColor: 'brown',
|
|
208
|
-
accessories: ['glasses'],
|
|
209
|
-
transparent: true,
|
|
210
|
-
},
|
|
211
|
-
(status) => {
|
|
212
|
-
console.log('Status:', status);
|
|
213
|
-
// "Calling AI Cloud..."
|
|
214
|
-
// "Caching result..."
|
|
215
|
-
// "Retrieved from Client Cache!"
|
|
216
|
-
}
|
|
217
|
-
);
|
|
218
|
-
```
|
|
132
|
+
Returns `Promise<string>` β URL of the generated image (often a blob URL when cached on web).
|
|
219
133
|
|
|
220
134
|
### `client.clearCache()`
|
|
221
135
|
|
|
222
|
-
Clears
|
|
223
|
-
|
|
224
|
-
**Returns:** `Promise<void>`
|
|
225
|
-
|
|
226
|
-
```typescript
|
|
227
|
-
await client.clearCache();
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
## Error Handling
|
|
136
|
+
Clears the client-side cache. Returns `Promise<void>`.
|
|
231
137
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
import {
|
|
236
|
-
AuthenticationError,
|
|
237
|
-
InsufficientCreditsError,
|
|
238
|
-
NetworkError,
|
|
239
|
-
RateLimitError,
|
|
240
|
-
GenerationError,
|
|
241
|
-
} from 'characterforge';
|
|
242
|
-
|
|
243
|
-
try {
|
|
244
|
-
const imageUrl = await client.generate(config);
|
|
245
|
-
} catch (error) {
|
|
246
|
-
if (error instanceof AuthenticationError) {
|
|
247
|
-
console.error('Invalid API key');
|
|
248
|
-
} else if (error instanceof InsufficientCreditsError) {
|
|
249
|
-
console.error('Not enough credits. Please purchase more.');
|
|
250
|
-
} else if (error instanceof NetworkError) {
|
|
251
|
-
console.error('Network error. Please check your connection.');
|
|
252
|
-
} else if (error instanceof RateLimitError) {
|
|
253
|
-
console.error('Rate limited. Please slow down.');
|
|
254
|
-
} else if (error instanceof GenerationError) {
|
|
255
|
-
console.error('Generation failed:', error.message);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
## Caching
|
|
138
|
+
### `client.destroy()`
|
|
261
139
|
|
|
262
|
-
|
|
140
|
+
Releases resources (e.g. cache manager cleanup). Call when the client is no longer needed.
|
|
263
141
|
|
|
264
|
-
###
|
|
142
|
+
### `VERSION`
|
|
265
143
|
|
|
266
|
-
|
|
267
|
-
- Automatically manages object URLs to prevent memory leaks
|
|
268
|
-
- Configurable cache size (default: 100 images)
|
|
269
|
-
- Auto-expires after 7 days
|
|
270
|
-
- Automatically cleans up old entries
|
|
144
|
+
The package exports `VERSION` (string) matching the published SDK version.
|
|
271
145
|
|
|
272
|
-
|
|
146
|
+
## `CharacterConfig` (summary)
|
|
273
147
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
148
|
+
| Field | Notes |
|
|
149
|
+
| --- | --- |
|
|
150
|
+
| `gender` | `'male' \| 'female'` |
|
|
151
|
+
| `ageGroup` | Optional: `'kid' \| 'preteen' \| 'teen' \| 'young_adult' \| 'adult'` |
|
|
152
|
+
| `skinTone` | e.g. `'porcelain'` β¦ `'deep'` (see `SkinToneId` in types) |
|
|
153
|
+
| `hairStyle` | e.g. `'bob'`, `'quiff'`, `'afro'`, β¦ (`HairStyleId`) |
|
|
154
|
+
| `hairColor` | (`HairColorId`) |
|
|
155
|
+
| `clothing` | (`ClothingItemId`) |
|
|
156
|
+
| `clothingColor` | (`ClothingColorId`) |
|
|
157
|
+
| `eyeColor` | (`EyeColorId`) |
|
|
158
|
+
| `accessories` | `AccessoryId[]` β e.g. `'none'`, `'glasses'`, `'cap'` |
|
|
159
|
+
| `transparent` | Whether the image uses a transparent background |
|
|
160
|
+
| `cache` | Optional per-request override for caching |
|
|
278
161
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
You can disable caching globally or per-request:
|
|
162
|
+
Import the full unions from `characterforge-js`:
|
|
282
163
|
|
|
283
164
|
```typescript
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const imageUrl = await client.generate({
|
|
292
|
-
...config,
|
|
293
|
-
cache: false,
|
|
294
|
-
});
|
|
165
|
+
import type {
|
|
166
|
+
CharacterConfig,
|
|
167
|
+
CharacterForgeClientConfig,
|
|
168
|
+
Gender,
|
|
169
|
+
SkinToneId,
|
|
170
|
+
HairStyleId,
|
|
171
|
+
} from 'characterforge-js';
|
|
295
172
|
```
|
|
296
173
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
For advanced use cases, you can provide a custom cache implementation:
|
|
300
|
-
|
|
301
|
-
```typescript
|
|
302
|
-
import { CacheManager } from 'characterforge';
|
|
303
|
-
|
|
304
|
-
class MyCustomCache implements CacheManager {
|
|
305
|
-
async get(key: string): Promise<string | null> {
|
|
306
|
-
// Your implementation
|
|
307
|
-
}
|
|
174
|
+
## Errors
|
|
308
175
|
|
|
309
|
-
|
|
310
|
-
// Your implementation
|
|
311
|
-
}
|
|
176
|
+
The SDK throws typed errors. Common API-related classes (also re-exported from the main entry):
|
|
312
177
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
apiKey: 'your-api-key',
|
|
320
|
-
cacheManager: new MyCustomCache(),
|
|
321
|
-
});
|
|
322
|
-
```
|
|
178
|
+
- `AuthenticationError` β Invalid or missing API key.
|
|
179
|
+
- `InsufficientCreditsError` β Not enough credits.
|
|
180
|
+
- `RateLimitError` β HTTP 429 / too many requests.
|
|
181
|
+
- `NetworkError` β Timeouts and network failures.
|
|
182
|
+
- `ApiError` β Other API HTTP errors that participate in retries.
|
|
183
|
+
- `GenerationError` β Generation or response parsing failures.
|
|
323
184
|
|
|
324
|
-
|
|
185
|
+
`CharacterForgeError` is an **alias** for `GenerationError` (exported from the client module for backward compatibility).
|
|
325
186
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
If you're self-hosting or using a custom endpoint:
|
|
187
|
+
Additional utilities and types live under the same package:
|
|
329
188
|
|
|
330
189
|
```typescript
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
190
|
+
import {
|
|
191
|
+
AppError,
|
|
192
|
+
AuthorizationError,
|
|
193
|
+
ImageProcessingError,
|
|
194
|
+
ValidationError,
|
|
195
|
+
ConfigValidationError,
|
|
196
|
+
CacheError,
|
|
197
|
+
PaymentError,
|
|
198
|
+
isAppError,
|
|
199
|
+
isAuthenticationError,
|
|
200
|
+
isInsufficientCreditsError,
|
|
201
|
+
isNetworkError,
|
|
202
|
+
isRateLimitError,
|
|
203
|
+
parseError,
|
|
204
|
+
getUserFriendlyMessage,
|
|
205
|
+
} from 'characterforge-js';
|
|
335
206
|
```
|
|
336
207
|
|
|
337
|
-
|
|
208
|
+
## Caching
|
|
338
209
|
|
|
339
|
-
|
|
210
|
+
- **Web** β `WebCacheManager` uses IndexedDB, caps entries (e.g. 100), and expires old data (e.g. 7 days). Object URLs are managed to reduce leaks.
|
|
211
|
+
- **React Native** β `NativeCacheManager` stores files under a cache directory and keeps metadata in AsyncStorage.
|
|
212
|
+
- **Override** β Pass `cache: false` in client config or per `generate()` call. Implement `CacheManager` for custom storage.
|
|
340
213
|
|
|
341
|
-
|
|
342
|
-
const client = createCharacterForgeClient({
|
|
343
|
-
apiKey: 'your-api-key',
|
|
344
|
-
timeout: 30000, // 30 seconds
|
|
345
|
-
});
|
|
346
|
-
```
|
|
214
|
+
Advanced exports: `createCacheManager`, `WebCacheManager`, `NativeCacheManager`, `isBrowser`, `isReactNative`.
|
|
347
215
|
|
|
348
|
-
|
|
216
|
+
## Advanced configuration
|
|
349
217
|
|
|
350
|
-
|
|
218
|
+
**Custom base URL** (self-hosted or staging):
|
|
351
219
|
|
|
352
220
|
```typescript
|
|
353
221
|
const client = createCharacterForgeClient({
|
|
354
222
|
apiKey: 'your-api-key',
|
|
355
|
-
|
|
356
|
-
maxRetries: 5,
|
|
357
|
-
baseDelayMs: 2000,
|
|
358
|
-
maxDelayMs: 20000,
|
|
359
|
-
},
|
|
223
|
+
baseUrl: 'https://your-deployment.example.com/functions/v1',
|
|
360
224
|
});
|
|
361
225
|
```
|
|
362
226
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
The SDK is written in TypeScript and provides full type definitions:
|
|
366
|
-
|
|
367
|
-
```typescript
|
|
368
|
-
import type {
|
|
369
|
-
CharacterConfig,
|
|
370
|
-
CharacterForgeClientConfig,
|
|
371
|
-
Gender,
|
|
372
|
-
SkinToneId,
|
|
373
|
-
HairStyleId,
|
|
374
|
-
// ... and more
|
|
375
|
-
} from 'characterforge';
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
All types are exported for your convenience, enabling excellent IDE autocomplete and type checking.
|
|
227
|
+
The client calls `POST ${baseUrl}/generate-character`.
|
|
379
228
|
|
|
380
|
-
|
|
229
|
+
**Timeout and retries** β Set `timeout` and `retry` on the client config as needed.
|
|
381
230
|
|
|
382
|
-
|
|
231
|
+
## Logging
|
|
383
232
|
|
|
384
|
-
|
|
385
|
-
import React, { useState } from 'react';
|
|
386
|
-
import { createCharacterForgeClient } from 'characterforge';
|
|
233
|
+
For debugging integrations, the package exports `Logger`, `logger`, `sdkLogger`, and types `LogLevel`, `LogEntry`, `LoggerConfig`.
|
|
387
234
|
|
|
388
|
-
|
|
389
|
-
apiKey: process.env.REACT_APP_CHARACTER_FORGE_KEY!,
|
|
390
|
-
});
|
|
235
|
+
## API key
|
|
391
236
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
const [status, setStatus] = useState('');
|
|
396
|
-
const [error, setError] = useState<string | null>(null);
|
|
397
|
-
|
|
398
|
-
const handleGenerate = async () => {
|
|
399
|
-
setLoading(true);
|
|
400
|
-
setError(null);
|
|
401
|
-
|
|
402
|
-
try {
|
|
403
|
-
const url = await client.generate(
|
|
404
|
-
{
|
|
405
|
-
gender: 'female',
|
|
406
|
-
skinTone: 'medium',
|
|
407
|
-
hairStyle: 'bob',
|
|
408
|
-
hairColor: 'brown',
|
|
409
|
-
clothing: 'hoodie',
|
|
410
|
-
clothingColor: 'blue',
|
|
411
|
-
eyeColor: 'brown',
|
|
412
|
-
accessories: ['glasses'],
|
|
413
|
-
transparent: true,
|
|
414
|
-
},
|
|
415
|
-
(status) => setStatus(status)
|
|
416
|
-
);
|
|
417
|
-
|
|
418
|
-
setImageUrl(url);
|
|
419
|
-
} catch (err) {
|
|
420
|
-
setError(err instanceof Error ? err.message : 'Generation failed');
|
|
421
|
-
} finally {
|
|
422
|
-
setLoading(false);
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
|
|
426
|
-
return (
|
|
427
|
-
<div>
|
|
428
|
-
<button onClick={handleGenerate} disabled={loading}>
|
|
429
|
-
{loading ? 'Generating...' : 'Generate Character'}
|
|
430
|
-
</button>
|
|
431
|
-
|
|
432
|
-
{status && <p>Status: {status}</p>}
|
|
433
|
-
{error && <p style={{ color: 'red' }}>Error: {error}</p>}
|
|
434
|
-
|
|
435
|
-
{imageUrl && (
|
|
436
|
-
<img
|
|
437
|
-
src={imageUrl}
|
|
438
|
-
alt="Generated character"
|
|
439
|
-
style={{ width: 300, height: 300 }}
|
|
440
|
-
/>
|
|
441
|
-
)}
|
|
442
|
-
</div>
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
```
|
|
237
|
+
1. Open [characterforge.app](https://characterforge.app) and sign in.
|
|
238
|
+
2. Use the developer/dashboard area to create an API key.
|
|
239
|
+
3. Keep keys out of source control; use environment variables or your hostβs secret storage.
|
|
446
240
|
|
|
447
|
-
##
|
|
241
|
+
## Repository and issues
|
|
448
242
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
3. Navigate to the Developer Dashboard
|
|
452
|
-
4. Create a new API key
|
|
453
|
-
5. Copy your API key and use it in your application
|
|
454
|
-
|
|
455
|
-
**Important:** Keep your API key secret and never commit it to version control. Use environment variables or secure key management systems.
|
|
456
|
-
|
|
457
|
-
## Support
|
|
458
|
-
|
|
459
|
-
- π§ Email: support@characterforge.app
|
|
460
|
-
- π Issues: [GitHub Issues](https://github.com/characterforge/sdk/issues)
|
|
461
|
-
- π Documentation: [characterforge.app/docs](https://characterforge.app/docs)
|
|
462
|
-
|
|
463
|
-
**Note:** This package is published as `characterforge` on npm.
|
|
243
|
+
- **Repository:** [github.com/inceptivco/ToyForge](https://github.com/inceptivco/ToyForge) (this SDK lives under the `sdk` directory in that monorepo).
|
|
244
|
+
- **Issues:** [github.com/inceptivco/ToyForge/issues](https://github.com/inceptivco/ToyForge/issues)
|
|
464
245
|
|
|
465
246
|
## License
|
|
466
247
|
|
|
@@ -468,5 +249,4 @@ MIT Β© CharacterForge
|
|
|
468
249
|
|
|
469
250
|
## Contributing
|
|
470
251
|
|
|
471
|
-
Contributions are welcome
|
|
472
|
-
|
|
252
|
+
Contributions are welcome via pull requests against the repository above.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "characterforge-js",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "AI-powered 3D character generation SDK for web and React Native",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -39,13 +39,15 @@
|
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"repository": {
|
|
41
41
|
"type": "git",
|
|
42
|
-
"url": "https://github.com/
|
|
42
|
+
"url": "git+https://github.com/inceptivco/ToyForge.git",
|
|
43
|
+
"directory": "sdk"
|
|
43
44
|
},
|
|
44
45
|
"bugs": {
|
|
45
|
-
"url": "https://github.com/
|
|
46
|
+
"url": "https://github.com/inceptivco/ToyForge/issues"
|
|
46
47
|
},
|
|
47
48
|
"homepage": "https://characterforge.app",
|
|
48
49
|
"devDependencies": {
|
|
50
|
+
"@types/node": "^25.5.2",
|
|
49
51
|
"tsup": "^8.0.0",
|
|
50
52
|
"typescript": "^5.3.0"
|
|
51
53
|
},
|
|
@@ -56,4 +58,3 @@
|
|
|
56
58
|
"access": "public"
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
|
-
|