@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/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
- return this.client.request("GET", `/${this.elementType}/`, { params: options });
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
- return this.client.request("POST", `/${this.elementType}/`, { body: data });
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
- return this.client.request("PATCH", `/${this.elementType}/${id}/`, { body: data });
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 Resource(this, "world");
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
- errorMessage += `: ${errorJson.detail || errorJson.error || errorText}`;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlyworlds/sdk",
3
- "version": "2.0.2",
3
+ "version": "2.1.1",
4
4
  "description": "TypeScript SDK for the OnlyWorlds API - build world-building applications with type safety",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",