@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.d.ts CHANGED
@@ -553,8 +553,22 @@ interface Pin extends BaseElement {
553
553
  map?: ElementId<ElementType.Map>;
554
554
  element_type?: ElementType;
555
555
  element_id?: AnyElementId;
556
+ /**
557
+ * X coordinate on map (must be integer)
558
+ * The API requires integer values. Float coordinates from mouse events
559
+ * or calculations should be rounded: Math.round(x)
560
+ */
556
561
  x?: number;
562
+ /**
563
+ * Y coordinate on map (must be integer)
564
+ * The API requires integer values. Float coordinates from mouse events
565
+ * or calculations should be rounded: Math.round(y)
566
+ */
557
567
  y?: number;
568
+ /**
569
+ * Z coordinate for 3D positioning (must be integer)
570
+ * The API requires integer values. Float coordinates should be rounded: Math.round(z)
571
+ */
558
572
  z?: number;
559
573
  }
560
574
  /**
@@ -2711,6 +2725,272 @@ declare function createElementIds<T extends ElementType>(ids: string[]): Element
2711
2725
  */
2712
2726
  declare function createAnyElementId(id: string): AnyElementId;
2713
2727
 
2728
+ /**
2729
+ * OnlyWorlds Token Management API Types
2730
+ *
2731
+ * Types for the token rating system that provides daily token allowances
2732
+ * for API usage and AI integration features.
2733
+ */
2734
+ /**
2735
+ * Current token status for the authenticated user
2736
+ */
2737
+ interface TokenStatus {
2738
+ /** Remaining tokens available for today */
2739
+ tokens_available_today: number;
2740
+ /** User's daily token allowance (default: 10000) */
2741
+ token_rating: number;
2742
+ /** Tokens consumed so far today */
2743
+ tokens_used_today: number;
2744
+ /** Date of last reset (ISO format) */
2745
+ last_reset: string;
2746
+ /** Number of active token sessions */
2747
+ sessions_active: number;
2748
+ }
2749
+ /**
2750
+ * Response from token consumption endpoint
2751
+ */
2752
+ interface TokenConsumeResponse {
2753
+ /** Whether the consumption was successful */
2754
+ success: boolean;
2755
+ /** Actual tokens consumed */
2756
+ tokens_consumed: number;
2757
+ /** Updated token balance */
2758
+ tokens_remaining: number;
2759
+ /** User's daily allowance */
2760
+ token_rating: number;
2761
+ /** Warning message if insufficient tokens (consumption still succeeds but tracks debt) */
2762
+ error?: string | null;
2763
+ }
2764
+ /**
2765
+ * Parameters for consuming tokens
2766
+ */
2767
+ interface TokenConsumeParams {
2768
+ /** Number of tokens to consume (required) */
2769
+ amount: number;
2770
+ /** Service identifier (default: "sdk_client") */
2771
+ service?: string;
2772
+ /** Session ID from access key response (optional) */
2773
+ sessionId?: string | null;
2774
+ /** Additional metadata for analytics (optional) */
2775
+ metadata?: Record<string, any> | null;
2776
+ }
2777
+ /**
2778
+ * Response from getting encrypted access key (advanced use case)
2779
+ */
2780
+ interface AccessKeyResponse {
2781
+ /** Base64 encoded encrypted OpenAI key */
2782
+ encrypted_key: string;
2783
+ /** Key expiration timestamp (ISO format) */
2784
+ expires_at: string;
2785
+ /** Session ID for tracking usage */
2786
+ session_id: string;
2787
+ /** Current token balance */
2788
+ tokens_available: number;
2789
+ /** User's token allowance */
2790
+ token_rating: number;
2791
+ /** Encryption algorithm used */
2792
+ encryption_method: string;
2793
+ }
2794
+ /**
2795
+ * Public encryption information for client-side decryption
2796
+ */
2797
+ interface EncryptionInfo {
2798
+ /** Encryption algorithm (e.g., "Fernet") */
2799
+ algorithm: string;
2800
+ /** Key derivation method (e.g., "SHA256") */
2801
+ key_derivation: string;
2802
+ /** Public salt used in key derivation */
2803
+ salt: string;
2804
+ /** Format description */
2805
+ format: string;
2806
+ /** Human-readable description */
2807
+ description: string;
2808
+ /** Example JavaScript implementation */
2809
+ javascript_example: string;
2810
+ }
2811
+ /**
2812
+ * Response from session revocation
2813
+ */
2814
+ interface RevokeSessionResponse {
2815
+ /** Whether revocation was successful */
2816
+ success: boolean;
2817
+ /** Status message */
2818
+ message: string;
2819
+ }
2820
+ /**
2821
+ * Response from revoking all sessions
2822
+ */
2823
+ interface RevokeAllSessionsResponse {
2824
+ /** Whether revocation was successful */
2825
+ success: boolean;
2826
+ /** Number of sessions revoked */
2827
+ sessions_revoked: number;
2828
+ }
2829
+ /**
2830
+ * Game tier / subscription level
2831
+ * (affects future features, currently all tiers get same token rating)
2832
+ */
2833
+ declare enum GameTier {
2834
+ FREE = "free",
2835
+ SILVER = "silver",
2836
+ GOLD = "gold",
2837
+ PLATINUM = "platinum",
2838
+ DIAMOND = "diamond",
2839
+ DELUXE = "deluxe"
2840
+ }
2841
+
2842
+ /**
2843
+ * Token Management Resource
2844
+ *
2845
+ * Provides access to the OnlyWorlds token rating system API.
2846
+ * Based on the working implementation in base-tool/src/llm/token-service.ts
2847
+ */
2848
+
2849
+ /**
2850
+ * Token Management Resource
2851
+ *
2852
+ * Handles token status checking, consumption tracking, and encrypted key access
2853
+ * for AI integration features.
2854
+ *
2855
+ * All endpoints require authentication (API-Key + API-Pin headers).
2856
+ *
2857
+ * Example usage:
2858
+ * ```typescript
2859
+ * const client = new OnlyWorldsClient({ apiKey, apiPin });
2860
+ *
2861
+ * // Check token status
2862
+ * const status = await client.tokens.getStatus();
2863
+ * console.log(`${status.tokens_available_today}/${status.token_rating} tokens available`);
2864
+ *
2865
+ * // Consume tokens
2866
+ * await client.tokens.consume({
2867
+ * amount: 500,
2868
+ * service: 'my_tool',
2869
+ * metadata: { feature: 'chat', model: 'gpt-4' }
2870
+ * });
2871
+ * ```
2872
+ */
2873
+ declare class TokenResource {
2874
+ private client;
2875
+ constructor(client: OnlyWorldsClient);
2876
+ /**
2877
+ * Get current token status for authenticated user
2878
+ *
2879
+ * Returns daily token allowance, usage, and availability.
2880
+ * Matches base-tool's checkStatus() pattern.
2881
+ *
2882
+ * @returns Current token status
2883
+ * @example
2884
+ * ```typescript
2885
+ * const status = await client.tokens.getStatus();
2886
+ * console.log(`Available: ${status.tokens_available_today}/${status.token_rating}`);
2887
+ * console.log(`Used today: ${status.tokens_used_today}`);
2888
+ * console.log(`Active sessions: ${status.sessions_active}`);
2889
+ * ```
2890
+ */
2891
+ getStatus(): Promise<TokenStatus>;
2892
+ /**
2893
+ * Consume tokens for service usage
2894
+ *
2895
+ * Reports token consumption to track daily usage. Allows consumption even if
2896
+ * exceeds available tokens (tracks as debt), but warns via error field.
2897
+ * Matches base-tool's reportUsage() pattern.
2898
+ *
2899
+ * @param params - Token consumption parameters
2900
+ * @returns Consumption result with updated balance
2901
+ * @example
2902
+ * ```typescript
2903
+ * const result = await client.tokens.consume({
2904
+ * amount: 500,
2905
+ * service: 'worldbuilding_tool',
2906
+ * metadata: {
2907
+ * feature: 'character_generation',
2908
+ * model: 'gpt-4',
2909
+ * prompt_tokens: 300,
2910
+ * completion_tokens: 200
2911
+ * }
2912
+ * });
2913
+ *
2914
+ * if (result.error) {
2915
+ * console.warn('Token warning:', result.error);
2916
+ * }
2917
+ * console.log(`${result.tokens_remaining} tokens remaining`);
2918
+ * ```
2919
+ */
2920
+ consume(params: TokenConsumeParams): Promise<TokenConsumeResponse>;
2921
+ /**
2922
+ * Get encrypted OpenAI API key (advanced use case)
2923
+ *
2924
+ * Requires minimum 100 tokens available. Creates a 1-hour session for tracking.
2925
+ * Returns encrypted key that must be decrypted client-side using Fernet.
2926
+ *
2927
+ * See base-tool/src/llm/token-service.ts:99-155 for full implementation example
2928
+ * including client-side decryption with the 'fernet' npm package.
2929
+ *
2930
+ * @returns Encrypted access key and session info
2931
+ * @throws Error if insufficient tokens (< 100)
2932
+ * @example
2933
+ * ```typescript
2934
+ * // Get encrypted key
2935
+ * const access = await client.tokens.getAccessKey();
2936
+ *
2937
+ * // Decrypt using fernet library (see base-tool for full example)
2938
+ * // 1. Derive key from world ID using SHA-256
2939
+ * // 2. Use 'fernet' npm package to decrypt
2940
+ * // 3. Use decrypted OpenAI key for direct API calls
2941
+ * // 4. Report usage with access.session_id
2942
+ *
2943
+ * console.log('Session:', access.session_id);
2944
+ * console.log('Expires:', access.expires_at);
2945
+ * ```
2946
+ */
2947
+ getAccessKey(): Promise<AccessKeyResponse>;
2948
+ /**
2949
+ * Revoke a specific token session
2950
+ *
2951
+ * Invalidates the session ID obtained from getAccessKey().
2952
+ * Use when cleaning up or on logout.
2953
+ *
2954
+ * @param sessionId - Session ID to revoke
2955
+ * @returns Revocation result
2956
+ * @example
2957
+ * ```typescript
2958
+ * await client.tokens.revokeSession('session-id-here');
2959
+ * ```
2960
+ */
2961
+ revokeSession(sessionId: string): Promise<RevokeSessionResponse>;
2962
+ /**
2963
+ * Revoke all active sessions (emergency use)
2964
+ *
2965
+ * Invalidates all token sessions for the authenticated user.
2966
+ * Use for security cleanup or when sessions are stuck.
2967
+ *
2968
+ * @returns Revocation result with count of revoked sessions
2969
+ * @example
2970
+ * ```typescript
2971
+ * const result = await client.tokens.revokeAllSessions();
2972
+ * console.log(`Revoked ${result.sessions_revoked} sessions`);
2973
+ * ```
2974
+ */
2975
+ revokeAllSessions(): Promise<RevokeAllSessionsResponse>;
2976
+ /**
2977
+ * Get public encryption info (no auth required)
2978
+ *
2979
+ * Returns algorithm details and example code for client-side decryption.
2980
+ * Public endpoint - can be called without authentication.
2981
+ *
2982
+ * @returns Encryption algorithm and implementation details
2983
+ * @example
2984
+ * ```typescript
2985
+ * const info = await client.tokens.getEncryptionInfo();
2986
+ * console.log('Algorithm:', info.algorithm);
2987
+ * console.log('Key derivation:', info.key_derivation);
2988
+ * console.log(info.javascript_example);
2989
+ * ```
2990
+ */
2991
+ getEncryptionInfo(): Promise<EncryptionInfo>;
2992
+ }
2993
+
2714
2994
  interface OnlyWorldsConfig {
2715
2995
  apiKey: string;
2716
2996
  apiPin: string;
@@ -2741,6 +3021,29 @@ declare class Resource<T, TInput> {
2741
3021
  create(data: TInput): Promise<T>;
2742
3022
  update(id: string, data: Partial<TInput>): Promise<T>;
2743
3023
  delete(id: string): Promise<void>;
3024
+ /**
3025
+ * Round Pin coordinates to integers (API requirement)
3026
+ * @private
3027
+ */
3028
+ private roundPinCoordinates;
3029
+ }
3030
+ /**
3031
+ * Special resource class for World endpoint
3032
+ * The /world/ endpoint returns a single World object directly (not paginated)
3033
+ * because API keys are world-scoped (one key = one world)
3034
+ */
3035
+ declare class WorldResource {
3036
+ private client;
3037
+ constructor(client: OnlyWorldsClient);
3038
+ /**
3039
+ * Get the world associated with the current API key
3040
+ * Returns the world directly (not wrapped in pagination)
3041
+ */
3042
+ get(): Promise<World>;
3043
+ /**
3044
+ * Update the current world
3045
+ */
3046
+ update(data: Partial<WorldInput>): Promise<World>;
2744
3047
  }
2745
3048
  /**
2746
3049
  * Main OnlyWorlds API client
@@ -2748,7 +3051,8 @@ declare class Resource<T, TInput> {
2748
3051
  declare class OnlyWorldsClient {
2749
3052
  private baseUrl;
2750
3053
  private headers;
2751
- worlds: Resource<World, WorldInput>;
3054
+ worlds: WorldResource;
3055
+ tokens: TokenResource;
2752
3056
  abilities: Resource<Ability, AbilityInput>;
2753
3057
  characters: Resource<Character, CharacterInput>;
2754
3058
  collectives: Resource<Collective, CollectiveInput>;
@@ -2779,15 +3083,10 @@ declare class OnlyWorldsClient {
2779
3083
  params?: Record<string, any>;
2780
3084
  body?: any;
2781
3085
  }): Promise<T>;
2782
- /**
2783
- * Get all worlds accessible with current credentials
2784
- * @deprecated Use client.worlds.list() instead for consistent API
2785
- */
2786
- getWorlds(): Promise<ApiResponse<World>>;
2787
3086
  /**
2788
3087
  * Helper to convert nested objects to _id/_ids format
2789
3088
  */
2790
3089
  static prepareInput<T extends Record<string, any>>(data: T): any;
2791
3090
  }
2792
3091
 
2793
- export { type Ability, type AbilityInput, type AnyElementId, type ApiResponse, type BaseElement, type Character, type CharacterInput, type Collective, type CollectiveInput, type Construct, type ConstructInput, type Creature, type CreatureInput, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_UNICODE_ICONS, type ElementId, type ElementIds, ElementType, type Event, type EventInput, FIELD_SCHEMA, type Family, type FamilyInput, type FieldInfo, type FieldType, type Institution, type InstitutionInput, type Language, type LanguageInput, type Law, type LawInput, type ListOptions, type Location, type LocationInput, type Map, type MapInput, type Marker, type MarkerInput, type Narrative, type NarrativeInput, ONLYWORLDS_VERSION, type Object$1 as Object, type ObjectInput, OnlyWorldsClient, type OnlyWorldsConfig, type Phenomenon, type PhenomenonInput, type Pin, type PinInput, type Relation, type RelationInput, type SectionInfo, type Species, type SpeciesInput, type Title, type TitleInput, type Trait, type TraitInput, type World, type WorldInput, type Zone, type ZoneInput, createAnyElementId, createElementId, createElementIds, getElementIcon, getElementLabel, getElementSections, getElementUnicodeIcon };
3092
+ export { type Ability, type AbilityInput, type AccessKeyResponse, type AnyElementId, type ApiResponse, type BaseElement, type Character, type CharacterInput, type Collective, type CollectiveInput, type Construct, type ConstructInput, type Creature, type CreatureInput, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_UNICODE_ICONS, type ElementId, type ElementIds, ElementType, type EncryptionInfo, type Event, type EventInput, FIELD_SCHEMA, type Family, type FamilyInput, type FieldInfo, type FieldType, GameTier, type Institution, type InstitutionInput, type Language, type LanguageInput, type Law, type LawInput, type ListOptions, type Location, type LocationInput, type Map, type MapInput, type Marker, type MarkerInput, type Narrative, type NarrativeInput, ONLYWORLDS_VERSION, type Object$1 as Object, type ObjectInput, OnlyWorldsClient, type OnlyWorldsConfig, type Phenomenon, type PhenomenonInput, type Pin, type PinInput, type Relation, type RelationInput, type RevokeAllSessionsResponse, type RevokeSessionResponse, type SectionInfo, type Species, type SpeciesInput, type Title, type TitleInput, type TokenConsumeParams, type TokenConsumeResponse, type TokenStatus, type Trait, type TraitInput, type World, type WorldInput, type Zone, type ZoneInput, createAnyElementId, createElementId, createElementIds, getElementIcon, getElementLabel, getElementSections, getElementUnicodeIcon };
package/dist/index.js CHANGED
@@ -26,6 +26,7 @@ __export(index_exports, {
26
26
  ELEMENT_UNICODE_ICONS: () => ELEMENT_UNICODE_ICONS,
27
27
  ElementType: () => ElementType,
28
28
  FIELD_SCHEMA: () => FIELD_SCHEMA,
29
+ GameTier: () => GameTier,
29
30
  ONLYWORLDS_VERSION: () => ONLYWORLDS_VERSION,
30
31
  OnlyWorldsClient: () => OnlyWorldsClient,
31
32
  createAnyElementId: () => createAnyElementId,
@@ -38,6 +39,151 @@ __export(index_exports, {
38
39
  });
39
40
  module.exports = __toCommonJS(index_exports);
40
41
 
42
+ // src/token-resource.ts
43
+ var TokenResource = class {
44
+ constructor(client) {
45
+ this.client = client;
46
+ }
47
+ /**
48
+ * Get current token status for authenticated user
49
+ *
50
+ * Returns daily token allowance, usage, and availability.
51
+ * Matches base-tool's checkStatus() pattern.
52
+ *
53
+ * @returns Current token status
54
+ * @example
55
+ * ```typescript
56
+ * const status = await client.tokens.getStatus();
57
+ * console.log(`Available: ${status.tokens_available_today}/${status.token_rating}`);
58
+ * console.log(`Used today: ${status.tokens_used_today}`);
59
+ * console.log(`Active sessions: ${status.sessions_active}`);
60
+ * ```
61
+ */
62
+ async getStatus() {
63
+ return this.client.request("GET", "/tokens/status/");
64
+ }
65
+ /**
66
+ * Consume tokens for service usage
67
+ *
68
+ * Reports token consumption to track daily usage. Allows consumption even if
69
+ * exceeds available tokens (tracks as debt), but warns via error field.
70
+ * Matches base-tool's reportUsage() pattern.
71
+ *
72
+ * @param params - Token consumption parameters
73
+ * @returns Consumption result with updated balance
74
+ * @example
75
+ * ```typescript
76
+ * const result = await client.tokens.consume({
77
+ * amount: 500,
78
+ * service: 'worldbuilding_tool',
79
+ * metadata: {
80
+ * feature: 'character_generation',
81
+ * model: 'gpt-4',
82
+ * prompt_tokens: 300,
83
+ * completion_tokens: 200
84
+ * }
85
+ * });
86
+ *
87
+ * if (result.error) {
88
+ * console.warn('Token warning:', result.error);
89
+ * }
90
+ * console.log(`${result.tokens_remaining} tokens remaining`);
91
+ * ```
92
+ */
93
+ async consume(params) {
94
+ return this.client.request("POST", "/tokens/consume/", {
95
+ body: {
96
+ amount: params.amount,
97
+ service: params.service || "sdk_client",
98
+ session_id: params.sessionId ?? null,
99
+ metadata: params.metadata ?? null
100
+ }
101
+ });
102
+ }
103
+ /**
104
+ * Get encrypted OpenAI API key (advanced use case)
105
+ *
106
+ * Requires minimum 100 tokens available. Creates a 1-hour session for tracking.
107
+ * Returns encrypted key that must be decrypted client-side using Fernet.
108
+ *
109
+ * See base-tool/src/llm/token-service.ts:99-155 for full implementation example
110
+ * including client-side decryption with the 'fernet' npm package.
111
+ *
112
+ * @returns Encrypted access key and session info
113
+ * @throws Error if insufficient tokens (< 100)
114
+ * @example
115
+ * ```typescript
116
+ * // Get encrypted key
117
+ * const access = await client.tokens.getAccessKey();
118
+ *
119
+ * // Decrypt using fernet library (see base-tool for full example)
120
+ * // 1. Derive key from world ID using SHA-256
121
+ * // 2. Use 'fernet' npm package to decrypt
122
+ * // 3. Use decrypted OpenAI key for direct API calls
123
+ * // 4. Report usage with access.session_id
124
+ *
125
+ * console.log('Session:', access.session_id);
126
+ * console.log('Expires:', access.expires_at);
127
+ * ```
128
+ */
129
+ async getAccessKey() {
130
+ return this.client.request("GET", "/tokens/access-key/");
131
+ }
132
+ /**
133
+ * Revoke a specific token session
134
+ *
135
+ * Invalidates the session ID obtained from getAccessKey().
136
+ * Use when cleaning up or on logout.
137
+ *
138
+ * @param sessionId - Session ID to revoke
139
+ * @returns Revocation result
140
+ * @example
141
+ * ```typescript
142
+ * await client.tokens.revokeSession('session-id-here');
143
+ * ```
144
+ */
145
+ async revokeSession(sessionId) {
146
+ return this.client.request(
147
+ "POST",
148
+ `/tokens/revoke-session/?session_id=${encodeURIComponent(sessionId)}`
149
+ );
150
+ }
151
+ /**
152
+ * Revoke all active sessions (emergency use)
153
+ *
154
+ * Invalidates all token sessions for the authenticated user.
155
+ * Use for security cleanup or when sessions are stuck.
156
+ *
157
+ * @returns Revocation result with count of revoked sessions
158
+ * @example
159
+ * ```typescript
160
+ * const result = await client.tokens.revokeAllSessions();
161
+ * console.log(`Revoked ${result.sessions_revoked} sessions`);
162
+ * ```
163
+ */
164
+ async revokeAllSessions() {
165
+ return this.client.request("POST", "/tokens/revoke-all-sessions/");
166
+ }
167
+ /**
168
+ * Get public encryption info (no auth required)
169
+ *
170
+ * Returns algorithm details and example code for client-side decryption.
171
+ * Public endpoint - can be called without authentication.
172
+ *
173
+ * @returns Encryption algorithm and implementation details
174
+ * @example
175
+ * ```typescript
176
+ * const info = await client.tokens.getEncryptionInfo();
177
+ * console.log('Algorithm:', info.algorithm);
178
+ * console.log('Key derivation:', info.key_derivation);
179
+ * console.log(info.javascript_example);
180
+ * ```
181
+ */
182
+ async getEncryptionInfo() {
183
+ return this.client.request("GET", "/tokens/encryption-info/");
184
+ }
185
+ };
186
+
41
187
  // src/client.ts
42
188
  var Resource = class {
43
189
  constructor(client, elementType) {
@@ -45,20 +191,60 @@ var Resource = class {
45
191
  this.elementType = elementType;
46
192
  }
47
193
  async list(options) {
48
- return this.client.request("GET", `/${this.elementType}/`, { params: options });
194
+ const response = await this.client.request("GET", `/${this.elementType}/`, { params: options });
195
+ if (Array.isArray(response)) {
196
+ return {
197
+ count: response.length,
198
+ next: null,
199
+ previous: null,
200
+ results: response
201
+ };
202
+ }
203
+ return response;
49
204
  }
50
205
  async get(id) {
51
206
  return this.client.request("GET", `/${this.elementType}/${id}/`);
52
207
  }
53
208
  async create(data) {
54
- return this.client.request("POST", `/${this.elementType}/`, { body: data });
209
+ const body = this.elementType === "pin" ? this.roundPinCoordinates(data) : data;
210
+ return this.client.request("POST", `/${this.elementType}/`, { body });
55
211
  }
56
212
  async update(id, data) {
57
- return this.client.request("PATCH", `/${this.elementType}/${id}/`, { body: data });
213
+ const body = this.elementType === "pin" ? this.roundPinCoordinates(data) : data;
214
+ return this.client.request("PATCH", `/${this.elementType}/${id}/`, { body });
58
215
  }
59
216
  async delete(id) {
60
217
  return this.client.request("DELETE", `/${this.elementType}/${id}/`);
61
218
  }
219
+ /**
220
+ * Round Pin coordinates to integers (API requirement)
221
+ * @private
222
+ */
223
+ roundPinCoordinates(data) {
224
+ const rounded = { ...data };
225
+ if (typeof rounded.x === "number") rounded.x = Math.round(rounded.x);
226
+ if (typeof rounded.y === "number") rounded.y = Math.round(rounded.y);
227
+ if (typeof rounded.z === "number") rounded.z = Math.round(rounded.z);
228
+ return rounded;
229
+ }
230
+ };
231
+ var WorldResource = class {
232
+ constructor(client) {
233
+ this.client = client;
234
+ }
235
+ /**
236
+ * Get the world associated with the current API key
237
+ * Returns the world directly (not wrapped in pagination)
238
+ */
239
+ async get() {
240
+ return this.client.request("GET", "/world/");
241
+ }
242
+ /**
243
+ * Update the current world
244
+ */
245
+ async update(data) {
246
+ return this.client.request("PATCH", "/world/", { body: data });
247
+ }
62
248
  };
63
249
  var OnlyWorldsClient = class {
64
250
  constructor(config) {
@@ -68,7 +254,8 @@ var OnlyWorldsClient = class {
68
254
  "API-Key": config.apiKey,
69
255
  "API-Pin": config.apiPin
70
256
  };
71
- this.worlds = new Resource(this, "world");
257
+ this.worlds = new WorldResource(this);
258
+ this.tokens = new TokenResource(this);
72
259
  this.abilities = new Resource(this, "ability");
73
260
  this.characters = new Resource(this, "character");
74
261
  this.collectives = new Resource(this, "collective");
@@ -119,7 +306,15 @@ var OnlyWorldsClient = class {
119
306
  if (errorText) {
120
307
  try {
121
308
  const errorJson = JSON.parse(errorText);
122
- errorMessage += `: ${errorJson.detail || errorJson.error || errorText}`;
309
+ if (Array.isArray(errorJson.detail)) {
310
+ const validationErrors = errorJson.detail.map((err) => {
311
+ const location = err.loc ? err.loc.join(".") : "unknown";
312
+ return `${location}: ${err.msg}`;
313
+ }).join("; ");
314
+ errorMessage += `: ${validationErrors}`;
315
+ } else {
316
+ errorMessage += `: ${errorJson.detail || errorJson.error || errorText}`;
317
+ }
123
318
  } catch {
124
319
  errorMessage += `: ${errorText}`;
125
320
  }
@@ -133,13 +328,6 @@ var OnlyWorldsClient = class {
133
328
  }
134
329
  return response.json();
135
330
  }
136
- /**
137
- * Get all worlds accessible with current credentials
138
- * @deprecated Use client.worlds.list() instead for consistent API
139
- */
140
- async getWorlds() {
141
- return this.request("GET", "/world/");
142
- }
143
331
  /**
144
332
  * Helper to convert nested objects to _id/_ids format
145
333
  */
@@ -974,6 +1162,17 @@ function createElementIds(ids) {
974
1162
  function createAnyElementId(id) {
975
1163
  return id;
976
1164
  }
1165
+
1166
+ // src/token-types.ts
1167
+ var GameTier = /* @__PURE__ */ ((GameTier2) => {
1168
+ GameTier2["FREE"] = "free";
1169
+ GameTier2["SILVER"] = "silver";
1170
+ GameTier2["GOLD"] = "gold";
1171
+ GameTier2["PLATINUM"] = "platinum";
1172
+ GameTier2["DIAMOND"] = "diamond";
1173
+ GameTier2["DELUXE"] = "deluxe";
1174
+ return GameTier2;
1175
+ })(GameTier || {});
977
1176
  // Annotate the CommonJS export names for ESM import in node:
978
1177
  0 && (module.exports = {
979
1178
  ELEMENT_ICONS,
@@ -982,6 +1181,7 @@ function createAnyElementId(id) {
982
1181
  ELEMENT_UNICODE_ICONS,
983
1182
  ElementType,
984
1183
  FIELD_SCHEMA,
1184
+ GameTier,
985
1185
  ONLYWORLDS_VERSION,
986
1186
  OnlyWorldsClient,
987
1187
  createAnyElementId,