@onlyworlds/sdk 2.0.2 → 2.1.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 +174 -44
- package/dist/index.d.mts +306 -7
- package/dist/index.d.ts +306 -7
- package/dist/index.js +212 -12
- package/dist/index.mjs +211 -12
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,148 @@
|
|
|
1
|
+
// src/token-resource.ts
|
|
2
|
+
var TokenResource = class {
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Get current token status for authenticated user
|
|
8
|
+
*
|
|
9
|
+
* Returns daily token allowance, usage, and availability.
|
|
10
|
+
* Matches base-tool's checkStatus() pattern.
|
|
11
|
+
*
|
|
12
|
+
* @returns Current token status
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const status = await client.tokens.getStatus();
|
|
16
|
+
* console.log(`Available: ${status.tokens_available_today}/${status.token_rating}`);
|
|
17
|
+
* console.log(`Used today: ${status.tokens_used_today}`);
|
|
18
|
+
* console.log(`Active sessions: ${status.sessions_active}`);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
async getStatus() {
|
|
22
|
+
return this.client.request("GET", "/tokens/status/");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Consume tokens for service usage
|
|
26
|
+
*
|
|
27
|
+
* Reports token consumption to track daily usage. Allows consumption even if
|
|
28
|
+
* exceeds available tokens (tracks as debt), but warns via error field.
|
|
29
|
+
* Matches base-tool's reportUsage() pattern.
|
|
30
|
+
*
|
|
31
|
+
* @param params - Token consumption parameters
|
|
32
|
+
* @returns Consumption result with updated balance
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const result = await client.tokens.consume({
|
|
36
|
+
* amount: 500,
|
|
37
|
+
* service: 'worldbuilding_tool',
|
|
38
|
+
* metadata: {
|
|
39
|
+
* feature: 'character_generation',
|
|
40
|
+
* model: 'gpt-4',
|
|
41
|
+
* prompt_tokens: 300,
|
|
42
|
+
* completion_tokens: 200
|
|
43
|
+
* }
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* if (result.error) {
|
|
47
|
+
* console.warn('Token warning:', result.error);
|
|
48
|
+
* }
|
|
49
|
+
* console.log(`${result.tokens_remaining} tokens remaining`);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
async consume(params) {
|
|
53
|
+
return this.client.request("POST", "/tokens/consume/", {
|
|
54
|
+
body: {
|
|
55
|
+
amount: params.amount,
|
|
56
|
+
service: params.service || "sdk_client",
|
|
57
|
+
session_id: params.sessionId ?? null,
|
|
58
|
+
metadata: params.metadata ?? null
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get encrypted OpenAI API key (advanced use case)
|
|
64
|
+
*
|
|
65
|
+
* Requires minimum 100 tokens available. Creates a 1-hour session for tracking.
|
|
66
|
+
* Returns encrypted key that must be decrypted client-side using Fernet.
|
|
67
|
+
*
|
|
68
|
+
* See base-tool/src/llm/token-service.ts:99-155 for full implementation example
|
|
69
|
+
* including client-side decryption with the 'fernet' npm package.
|
|
70
|
+
*
|
|
71
|
+
* @returns Encrypted access key and session info
|
|
72
|
+
* @throws Error if insufficient tokens (< 100)
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* // Get encrypted key
|
|
76
|
+
* const access = await client.tokens.getAccessKey();
|
|
77
|
+
*
|
|
78
|
+
* // Decrypt using fernet library (see base-tool for full example)
|
|
79
|
+
* // 1. Derive key from world ID using SHA-256
|
|
80
|
+
* // 2. Use 'fernet' npm package to decrypt
|
|
81
|
+
* // 3. Use decrypted OpenAI key for direct API calls
|
|
82
|
+
* // 4. Report usage with access.session_id
|
|
83
|
+
*
|
|
84
|
+
* console.log('Session:', access.session_id);
|
|
85
|
+
* console.log('Expires:', access.expires_at);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
async getAccessKey() {
|
|
89
|
+
return this.client.request("GET", "/tokens/access-key/");
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Revoke a specific token session
|
|
93
|
+
*
|
|
94
|
+
* Invalidates the session ID obtained from getAccessKey().
|
|
95
|
+
* Use when cleaning up or on logout.
|
|
96
|
+
*
|
|
97
|
+
* @param sessionId - Session ID to revoke
|
|
98
|
+
* @returns Revocation result
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* await client.tokens.revokeSession('session-id-here');
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
async revokeSession(sessionId) {
|
|
105
|
+
return this.client.request(
|
|
106
|
+
"POST",
|
|
107
|
+
`/tokens/revoke-session/?session_id=${encodeURIComponent(sessionId)}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Revoke all active sessions (emergency use)
|
|
112
|
+
*
|
|
113
|
+
* Invalidates all token sessions for the authenticated user.
|
|
114
|
+
* Use for security cleanup or when sessions are stuck.
|
|
115
|
+
*
|
|
116
|
+
* @returns Revocation result with count of revoked sessions
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const result = await client.tokens.revokeAllSessions();
|
|
120
|
+
* console.log(`Revoked ${result.sessions_revoked} sessions`);
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
async revokeAllSessions() {
|
|
124
|
+
return this.client.request("POST", "/tokens/revoke-all-sessions/");
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get public encryption info (no auth required)
|
|
128
|
+
*
|
|
129
|
+
* Returns algorithm details and example code for client-side decryption.
|
|
130
|
+
* Public endpoint - can be called without authentication.
|
|
131
|
+
*
|
|
132
|
+
* @returns Encryption algorithm and implementation details
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const info = await client.tokens.getEncryptionInfo();
|
|
136
|
+
* console.log('Algorithm:', info.algorithm);
|
|
137
|
+
* console.log('Key derivation:', info.key_derivation);
|
|
138
|
+
* console.log(info.javascript_example);
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
async getEncryptionInfo() {
|
|
142
|
+
return this.client.request("GET", "/tokens/encryption-info/");
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
1
146
|
// src/client.ts
|
|
2
147
|
var Resource = class {
|
|
3
148
|
constructor(client, elementType) {
|
|
@@ -5,20 +150,60 @@ var Resource = class {
|
|
|
5
150
|
this.elementType = elementType;
|
|
6
151
|
}
|
|
7
152
|
async list(options) {
|
|
8
|
-
|
|
153
|
+
const response = await this.client.request("GET", `/${this.elementType}/`, { params: options });
|
|
154
|
+
if (Array.isArray(response)) {
|
|
155
|
+
return {
|
|
156
|
+
count: response.length,
|
|
157
|
+
next: null,
|
|
158
|
+
previous: null,
|
|
159
|
+
results: response
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
return response;
|
|
9
163
|
}
|
|
10
164
|
async get(id) {
|
|
11
165
|
return this.client.request("GET", `/${this.elementType}/${id}/`);
|
|
12
166
|
}
|
|
13
167
|
async create(data) {
|
|
14
|
-
|
|
168
|
+
const body = this.elementType === "pin" ? this.roundPinCoordinates(data) : data;
|
|
169
|
+
return this.client.request("POST", `/${this.elementType}/`, { body });
|
|
15
170
|
}
|
|
16
171
|
async update(id, data) {
|
|
17
|
-
|
|
172
|
+
const body = this.elementType === "pin" ? this.roundPinCoordinates(data) : data;
|
|
173
|
+
return this.client.request("PATCH", `/${this.elementType}/${id}/`, { body });
|
|
18
174
|
}
|
|
19
175
|
async delete(id) {
|
|
20
176
|
return this.client.request("DELETE", `/${this.elementType}/${id}/`);
|
|
21
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Round Pin coordinates to integers (API requirement)
|
|
180
|
+
* @private
|
|
181
|
+
*/
|
|
182
|
+
roundPinCoordinates(data) {
|
|
183
|
+
const rounded = { ...data };
|
|
184
|
+
if (typeof rounded.x === "number") rounded.x = Math.round(rounded.x);
|
|
185
|
+
if (typeof rounded.y === "number") rounded.y = Math.round(rounded.y);
|
|
186
|
+
if (typeof rounded.z === "number") rounded.z = Math.round(rounded.z);
|
|
187
|
+
return rounded;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
var WorldResource = class {
|
|
191
|
+
constructor(client) {
|
|
192
|
+
this.client = client;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Get the world associated with the current API key
|
|
196
|
+
* Returns the world directly (not wrapped in pagination)
|
|
197
|
+
*/
|
|
198
|
+
async get() {
|
|
199
|
+
return this.client.request("GET", "/world/");
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Update the current world
|
|
203
|
+
*/
|
|
204
|
+
async update(data) {
|
|
205
|
+
return this.client.request("PATCH", "/world/", { body: data });
|
|
206
|
+
}
|
|
22
207
|
};
|
|
23
208
|
var OnlyWorldsClient = class {
|
|
24
209
|
constructor(config) {
|
|
@@ -28,7 +213,8 @@ var OnlyWorldsClient = class {
|
|
|
28
213
|
"API-Key": config.apiKey,
|
|
29
214
|
"API-Pin": config.apiPin
|
|
30
215
|
};
|
|
31
|
-
this.worlds = new
|
|
216
|
+
this.worlds = new WorldResource(this);
|
|
217
|
+
this.tokens = new TokenResource(this);
|
|
32
218
|
this.abilities = new Resource(this, "ability");
|
|
33
219
|
this.characters = new Resource(this, "character");
|
|
34
220
|
this.collectives = new Resource(this, "collective");
|
|
@@ -79,7 +265,15 @@ var OnlyWorldsClient = class {
|
|
|
79
265
|
if (errorText) {
|
|
80
266
|
try {
|
|
81
267
|
const errorJson = JSON.parse(errorText);
|
|
82
|
-
|
|
268
|
+
if (Array.isArray(errorJson.detail)) {
|
|
269
|
+
const validationErrors = errorJson.detail.map((err) => {
|
|
270
|
+
const location = err.loc ? err.loc.join(".") : "unknown";
|
|
271
|
+
return `${location}: ${err.msg}`;
|
|
272
|
+
}).join("; ");
|
|
273
|
+
errorMessage += `: ${validationErrors}`;
|
|
274
|
+
} else {
|
|
275
|
+
errorMessage += `: ${errorJson.detail || errorJson.error || errorText}`;
|
|
276
|
+
}
|
|
83
277
|
} catch {
|
|
84
278
|
errorMessage += `: ${errorText}`;
|
|
85
279
|
}
|
|
@@ -93,13 +287,6 @@ var OnlyWorldsClient = class {
|
|
|
93
287
|
}
|
|
94
288
|
return response.json();
|
|
95
289
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Get all worlds accessible with current credentials
|
|
98
|
-
* @deprecated Use client.worlds.list() instead for consistent API
|
|
99
|
-
*/
|
|
100
|
-
async getWorlds() {
|
|
101
|
-
return this.request("GET", "/world/");
|
|
102
|
-
}
|
|
103
290
|
/**
|
|
104
291
|
* Helper to convert nested objects to _id/_ids format
|
|
105
292
|
*/
|
|
@@ -934,6 +1121,17 @@ function createElementIds(ids) {
|
|
|
934
1121
|
function createAnyElementId(id) {
|
|
935
1122
|
return id;
|
|
936
1123
|
}
|
|
1124
|
+
|
|
1125
|
+
// src/token-types.ts
|
|
1126
|
+
var GameTier = /* @__PURE__ */ ((GameTier2) => {
|
|
1127
|
+
GameTier2["FREE"] = "free";
|
|
1128
|
+
GameTier2["SILVER"] = "silver";
|
|
1129
|
+
GameTier2["GOLD"] = "gold";
|
|
1130
|
+
GameTier2["PLATINUM"] = "platinum";
|
|
1131
|
+
GameTier2["DIAMOND"] = "diamond";
|
|
1132
|
+
GameTier2["DELUXE"] = "deluxe";
|
|
1133
|
+
return GameTier2;
|
|
1134
|
+
})(GameTier || {});
|
|
937
1135
|
export {
|
|
938
1136
|
ELEMENT_ICONS,
|
|
939
1137
|
ELEMENT_LABELS,
|
|
@@ -941,6 +1139,7 @@ export {
|
|
|
941
1139
|
ELEMENT_UNICODE_ICONS,
|
|
942
1140
|
ElementType,
|
|
943
1141
|
FIELD_SCHEMA,
|
|
1142
|
+
GameTier,
|
|
944
1143
|
ONLYWORLDS_VERSION,
|
|
945
1144
|
OnlyWorldsClient,
|
|
946
1145
|
createAnyElementId,
|
package/package.json
CHANGED