@rtsdk/topia 0.18.3 → 0.19.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 CHANGED
@@ -317,8 +317,6 @@ Once complete be sure to also call `await keyAsset.updateDataObject({ turnCount:
317
317
 
318
318
  You can leverage the data object methods for all types to track analytics unique to your Public Key by passing `analytics` as an optional array along with `profileId`, `urlSlug`, and/or `uniqueKey` to all calls that set, update, or increment data objects!
319
319
 
320
- **World** and **Dropped Asset** classes will automatically include `urlSlug`. In addition to `analytics` you can also pass `profileId` if you want to track event per user and/or a `uniqueKey` to additionally track uniqueness of the event for all time, per user (if `profileId` is included), and per world.
321
-
322
320
  Examples leveraging World data objects calls:
323
321
 
324
322
  ```ts
@@ -329,8 +327,6 @@ await world.updateDataObject({}, { analytics: [ {analyticName: "matches", unique
329
327
  await world.incrementDataObjectValue(`keyAssets.${assetId}.completions`, 1, { analytics: [{ analyticName:"completions", incrementBy: 2, profileId, uniqueKey: profileId, urlSlug }] });
330
328
  ```
331
329
 
332
- **Visitor** and **User** classes will automatically include `profileId`. In addition to `analytics` you can also pass `urlSlug` if you want to track event per world and/or a `uniqueKey` to additionally track uniqueness of the event for all time, per user, and per world (if `urlSlug` is included).
333
-
334
330
  Examples leveraging Visitor data objects calls:
335
331
 
336
332
  ```ts
@@ -349,7 +345,7 @@ await visitor.incrementDataObjectValue(`completions`, 1, {
349
345
  });
350
346
  ```
351
347
 
352
- Note: This does NOT impact the data objects themselves but rather allows you to track custom analytics (incremented by 1) across all instances of your application with a given Public Key.
348
+ Note: passing an empty object does NOT impact the data objects themselves but rather allows you to track custom analytics (incremented by 1) across all instances of your application with a given Public Key.
353
349
 
354
350
  <br>
355
351
 
package/dist/index.cjs CHANGED
@@ -40683,6 +40683,32 @@ class DroppedAsset extends Asset {
40683
40683
  }
40684
40684
  });
40685
40685
  }
40686
+ /**
40687
+ * Checks if this dropped asset exists with the current app's public key installed.
40688
+ *
40689
+ * @keywords check, exists, verify, validate, lookup
40690
+ *
40691
+ * @example
40692
+ * ```ts
40693
+ * const { exists } = await droppedAsset.checkExists();
40694
+ * ```
40695
+ *
40696
+ * @returns {Promise<{ exists: boolean }>} Returns whether the asset exists with the app's public key.
40697
+ */
40698
+ checkExists() {
40699
+ return __awaiter(this, void 0, void 0, function* () {
40700
+ try {
40701
+ const response = yield this.topiaPublicApi().get(`/world/${this.urlSlug}/dropped-asset/${this.id}/exists`, this.requestOptions);
40702
+ return response.data;
40703
+ }
40704
+ catch (error) {
40705
+ throw this.errorHandler({
40706
+ error,
40707
+ sdkMethod: "DroppedAsset.checkExists",
40708
+ });
40709
+ }
40710
+ });
40711
+ }
40686
40712
  /**
40687
40713
  * Retrieve analytics for a dropped asset by day, week, month, quarter, or year
40688
40714
  *
@@ -41013,7 +41039,7 @@ class UserInventoryItem extends InventoryItem {
41013
41039
  super(topia, item_id, { attributes: options.attributes, credentials: options.credentials });
41014
41040
  Object.assign(this, options.attributes);
41015
41041
  this.userItemId = id;
41016
- const { user_id = "", quantity = 0, grant_source = "unknown", type = "unknown", metadata = {}, created_at = new Date(), updated_at = new Date(), } = options.attributes;
41042
+ const { user_id = "", quantity = 0, grant_source = "unknown", type = "unknown", metadata = {}, created_at = new Date(), updated_at = new Date(), profile_id = null, } = options.attributes;
41017
41043
  this.item_id = item_id;
41018
41044
  this.quantity = quantity;
41019
41045
  this.grant_source = grant_source;
@@ -41022,6 +41048,7 @@ class UserInventoryItem extends InventoryItem {
41022
41048
  this.metadata = metadata;
41023
41049
  this.created_at = created_at;
41024
41050
  this.updated_at = updated_at;
41051
+ this.profile_id = profile_id;
41025
41052
  }
41026
41053
  /**
41027
41054
  * Fetches the user inventory item details from the platform and assigns them to this instance.
@@ -42701,7 +42728,7 @@ class User extends SDKController {
42701
42728
  * await user.modifyInventoryItemQuantity("item-id-123", 5);
42702
42729
  * ```
42703
42730
  *
42704
- * @returns {Promise<UserInventoryItem>} Returns the updated inventory or a response object.
42731
+ * @returns {Promise<UserInventoryItem>} Returns the updated inventory item or a response object.
42705
42732
  */
42706
42733
  modifyInventoryItemQuantity(item, quantity) {
42707
42734
  return __awaiter(this, void 0, void 0, function* () {
@@ -43287,7 +43314,7 @@ class Visitor extends User {
43287
43314
  * const items = await visitor.fetchInventoryItems();
43288
43315
  * ```
43289
43316
  *
43290
- * @returns {Promise<void>} Returns an array of InventoryItem objects.
43317
+ * @returns {Promise<void>} Returns a new instance of InventoryItem.
43291
43318
  */
43292
43319
  fetchInventoryItem(item) {
43293
43320
  return __awaiter(this, void 0, void 0, function* () {
@@ -43303,6 +43330,88 @@ class Visitor extends User {
43303
43330
  }
43304
43331
  });
43305
43332
  }
43333
+ /**
43334
+ * Gets an NPC for this visitor, if one exists.
43335
+ *
43336
+ * @example
43337
+ * ```ts
43338
+ * await visitor.getNpc();
43339
+ * ```
43340
+ *
43341
+ * @returns {Promise<Visitor | null>} Returns a Visitor object representing the NPC.
43342
+ */
43343
+ getNpc() {
43344
+ return __awaiter(this, void 0, void 0, function* () {
43345
+ try {
43346
+ const visitorResponse = yield this.topiaPublicApi().get(`/world/${this.urlSlug}/visitors/${this.id}/get-npc`, this.requestOptions);
43347
+ if (visitorResponse.data)
43348
+ return new Visitor(this.topia, visitorResponse.data.playerId, this.urlSlug, {
43349
+ attributes: visitorResponse.data,
43350
+ credentials: this.credentials,
43351
+ });
43352
+ return null;
43353
+ }
43354
+ catch (error) {
43355
+ throw this.errorHandler({ error, sdkMethod: "Visitor.getNpc" });
43356
+ }
43357
+ });
43358
+ }
43359
+ /**
43360
+ * Creates an NPC that follows this visitor using an inventory item the visitor owns.
43361
+ * One NPC is allowed per visitor, per application public key.
43362
+ *
43363
+ * @param userInventoryItemId The ID of the user's inventory item (must be an NPC type item owned by this visitor).
43364
+ * @param options Optional configuration for the NPC.
43365
+ * @param options.showNameplate Whether to display a nameplate above the NPC (default: true).
43366
+ *
43367
+ * @example
43368
+ * ```ts
43369
+ * // First, grant the NPC item to the visitor
43370
+ * const userItem = await visitor.grantInventoryItem(npcInventoryItem, 1);
43371
+ *
43372
+ * // Then create the NPC using the granted item
43373
+ * const npc = await visitor.createNpc(userItem.id);
43374
+ *
43375
+ * // Or create without a nameplate
43376
+ * const npc = await visitor.createNpc(userItem.id, { showNameplate: false });
43377
+ * ```
43378
+ *
43379
+ * @returns {Promise<Visitor>} Returns a Visitor object representing the created NPC.
43380
+ */
43381
+ createNpc(userInventoryItemId, options) {
43382
+ return __awaiter(this, void 0, void 0, function* () {
43383
+ try {
43384
+ const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, { userInventoryItemId, showNameplate: options === null || options === void 0 ? void 0 : options.showNameplate }, this.requestOptions);
43385
+ return new Visitor(this.topia, response.data.player.playerId, this.urlSlug, {
43386
+ attributes: response.data,
43387
+ credentials: this.credentials,
43388
+ });
43389
+ }
43390
+ catch (error) {
43391
+ throw this.errorHandler({ error, sdkMethod: "Visitor.createNpc" });
43392
+ }
43393
+ });
43394
+ }
43395
+ /**
43396
+ * Deletes the NPC this app has assigned to this visitor.
43397
+ *
43398
+ * @example
43399
+ * ```ts
43400
+ * await visitor.deleteNpc();
43401
+ * ```
43402
+ *
43403
+ * @returns {Promise<void>} Returns nothing if successful.
43404
+ */
43405
+ deleteNpc() {
43406
+ return __awaiter(this, void 0, void 0, function* () {
43407
+ try {
43408
+ yield this.topiaPublicApi().delete(`/world/${this.urlSlug}/visitors/${this.id}/delete-npc`, this.requestOptions);
43409
+ }
43410
+ catch (error) {
43411
+ throw this.errorHandler({ error, sdkMethod: "Visitor.deleteNpc" });
43412
+ }
43413
+ });
43414
+ }
43306
43415
  /**
43307
43416
  * Retrieves all inventory items owned by this visitor and app's key.
43308
43417
  *
@@ -43348,7 +43457,7 @@ class Visitor extends User {
43348
43457
  * await visitor.grantInventoryItem("item-id-123", 2);
43349
43458
  * ```
43350
43459
  *
43351
- * @returns {Promise<UserInventoryItem>} Returns the updated inventory or a response object.
43460
+ * @returns {Promise<UserInventoryItem>} Returns the updated inventory item or a response object.
43352
43461
  */
43353
43462
  grantInventoryItem(item, quantity = 1) {
43354
43463
  var _a;
@@ -43374,27 +43483,31 @@ class Visitor extends User {
43374
43483
  }
43375
43484
  /**
43376
43485
  * Modifies the quantity of an inventory item in this visitor's inventory.
43486
+ * Supports upsert behavior - if the visitor doesn't own the item yet, it will be granted first.
43377
43487
  *
43378
- * @param item The UserInventoryItem to modify.
43379
- * @param quantity The new quantity to set.
43488
+ * @param item Either a UserInventoryItem (for owned items) or an InventoryItem (for upsert).
43489
+ * @param quantity The quantity delta to apply (positive to add, negative to subtract).
43380
43490
  *
43381
43491
  * @example
43382
43492
  * ```ts
43383
- * await visitor.modifyInventoryItemQuantity("item-id-123", 5);
43493
+ * // Modify an existing user inventory item
43494
+ * await visitor.modifyInventoryItemQuantity(userItem, 5);
43495
+ *
43496
+ * // Upsert: grant if not owned, or modify if already owned
43497
+ * await visitor.modifyInventoryItemQuantity(inventoryItem, 1);
43384
43498
  * ```
43385
43499
  *
43386
- * @returns {Promise<UserInventoryItem>} Returns the updated inventory or a response object.
43500
+ * @returns {Promise<UserInventoryItem>} Returns the updated inventory item or a response object.
43387
43501
  */
43388
43502
  modifyInventoryItemQuantity(item, quantity) {
43389
- var _a;
43390
43503
  return __awaiter(this, void 0, void 0, function* () {
43391
- // Check for existence in #visitorInventoryItems
43392
- const found = (_a = __classPrivateFieldGet(this, _Visitor_visitorInventoryItems, "f")) === null || _a === void 0 ? void 0 : _a.some((visitorItem) => visitorItem.id === item.userItemId);
43393
- if (!found) {
43394
- throw new Error(`Inventory item with id '${item.userItemId}' does not exist in visitorInventoryItems.`);
43395
- }
43396
43504
  try {
43397
- const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/update-visitor-inventory-item-quantity`, { userItemId: item.id, itemId: item.item_id, quantity }, this.requestOptions);
43505
+ // Determine if item is a UserInventoryItem (has userItemId) or InventoryItem (only has id)
43506
+ const isUserItem = "userItemId" in item && item.userItemId;
43507
+ const body = isUserItem
43508
+ ? { userItemId: item.userItemId, itemId: item.item_id, quantity }
43509
+ : { itemId: item.id, quantity };
43510
+ const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/update-visitor-inventory-item-quantity`, body, this.requestOptions);
43398
43511
  const userInventoryItemFactory = new UserInventoryItemFactory(this.topia);
43399
43512
  const { inventoryItem, user_id, quantity: newQuantity } = response.data;
43400
43513
  return userInventoryItemFactory.create(inventoryItem, user_id, newQuantity, {
@@ -44811,7 +44924,7 @@ class WorldFactory extends SDKController {
44811
44924
  headers,
44812
44925
  }));
44813
44926
  }
44814
- yield Promise.all(promiseArray);
44927
+ yield Promise.allSettled(promiseArray);
44815
44928
  return { success: true };
44816
44929
  }
44817
44930
  catch (error) {
package/dist/index.d.ts CHANGED
@@ -74,7 +74,7 @@ type DroppedAssetLinkType = {
74
74
  linkSamlQueryParams?: string;
75
75
  };
76
76
 
77
- type InteractiveCredentials = {
77
+ type InteractiveCredentials$1 = {
78
78
  apiKey?: string;
79
79
  assetId?: string;
80
80
  interactiveNonce?: string;
@@ -88,22 +88,22 @@ type InteractiveCredentials = {
88
88
 
89
89
  type AssetOptions = {
90
90
  attributes?: AssetInterface | undefined;
91
- credentials?: InteractiveCredentials | undefined;
91
+ credentials?: InteractiveCredentials$1 | undefined;
92
92
  };
93
93
  type DroppedAssetOptions = {
94
94
  attributes?: DroppedAssetInterface | undefined;
95
- credentials?: InteractiveCredentials | undefined;
95
+ credentials?: InteractiveCredentials$1 | undefined;
96
96
  };
97
97
  type UserOptions = {
98
- credentials?: InteractiveCredentials | undefined;
98
+ credentials?: InteractiveCredentials$1 | undefined;
99
99
  };
100
100
  type VisitorOptions = {
101
101
  attributes?: VisitorInterface | undefined;
102
- credentials?: InteractiveCredentials | undefined;
102
+ credentials?: InteractiveCredentials$1 | undefined;
103
103
  };
104
104
  type WorldOptions = {
105
105
  attributes?: WorldDetailsInterface | undefined;
106
- credentials?: InteractiveCredentials | undefined;
106
+ credentials?: InteractiveCredentials$1 | undefined;
107
107
  };
108
108
 
109
109
  type ResponseType$1 = {
@@ -651,6 +651,21 @@ declare class DroppedAsset extends Asset implements DroppedAssetInterface {
651
651
  isInteractive?: boolean;
652
652
  interactivePublicKey: string;
653
653
  }): Promise<void | ResponseType$1>;
654
+ /**
655
+ * Checks if this dropped asset exists with the current app's public key installed.
656
+ *
657
+ * @keywords check, exists, verify, validate, lookup
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * const { exists } = await droppedAsset.checkExists();
662
+ * ```
663
+ *
664
+ * @returns {Promise<{ exists: boolean }>} Returns whether the asset exists with the app's public key.
665
+ */
666
+ checkExists(): Promise<{
667
+ exists: boolean;
668
+ }>;
654
669
  /**
655
670
  * Retrieve analytics for a dropped asset by day, week, month, quarter, or year
656
671
  *
@@ -1190,6 +1205,7 @@ declare class UserInventoryItem extends InventoryItem implements UserInventoryIt
1190
1205
  metadata?: object | null;
1191
1206
  grant_source: string;
1192
1207
  type: string;
1208
+ profile_id?: string | null;
1193
1209
  constructor(topia: Topia, id: string, options?: UserInventoryItemOptionalInterface);
1194
1210
  /**
1195
1211
  * Fetches the user inventory item details from the platform and assigns them to this instance.
@@ -1719,7 +1735,7 @@ declare class User extends SDKController implements UserInterface {
1719
1735
  * await user.modifyInventoryItemQuantity("item-id-123", 5);
1720
1736
  * ```
1721
1737
  *
1722
- * @returns {Promise<UserInventoryItem>} Returns the updated inventory or a response object.
1738
+ * @returns {Promise<UserInventoryItem>} Returns the updated inventory item or a response object.
1723
1739
  */
1724
1740
  modifyInventoryItemQuantity(item: UserInventoryItem, quantity: number): Promise<UserInventoryItem>;
1725
1741
  }
@@ -2063,9 +2079,56 @@ declare class Visitor extends User implements VisitorInterface {
2063
2079
  * const items = await visitor.fetchInventoryItems();
2064
2080
  * ```
2065
2081
  *
2066
- * @returns {Promise<void>} Returns an array of InventoryItem objects.
2082
+ * @returns {Promise<void>} Returns a new instance of InventoryItem.
2067
2083
  */
2068
2084
  fetchInventoryItem(item: InventoryItem): Promise<UserInventoryItem>;
2085
+ /**
2086
+ * Gets an NPC for this visitor, if one exists.
2087
+ *
2088
+ * @example
2089
+ * ```ts
2090
+ * await visitor.getNpc();
2091
+ * ```
2092
+ *
2093
+ * @returns {Promise<Visitor | null>} Returns a Visitor object representing the NPC.
2094
+ */
2095
+ getNpc(): Promise<Visitor | null>;
2096
+ /**
2097
+ * Creates an NPC that follows this visitor using an inventory item the visitor owns.
2098
+ * One NPC is allowed per visitor, per application public key.
2099
+ *
2100
+ * @param userInventoryItemId The ID of the user's inventory item (must be an NPC type item owned by this visitor).
2101
+ * @param options Optional configuration for the NPC.
2102
+ * @param options.showNameplate Whether to display a nameplate above the NPC (default: true).
2103
+ *
2104
+ * @example
2105
+ * ```ts
2106
+ * // First, grant the NPC item to the visitor
2107
+ * const userItem = await visitor.grantInventoryItem(npcInventoryItem, 1);
2108
+ *
2109
+ * // Then create the NPC using the granted item
2110
+ * const npc = await visitor.createNpc(userItem.id);
2111
+ *
2112
+ * // Or create without a nameplate
2113
+ * const npc = await visitor.createNpc(userItem.id, { showNameplate: false });
2114
+ * ```
2115
+ *
2116
+ * @returns {Promise<Visitor>} Returns a Visitor object representing the created NPC.
2117
+ */
2118
+ createNpc(userInventoryItemId: string, options?: {
2119
+ showNameplate?: boolean;
2120
+ }): Promise<Visitor>;
2121
+ /**
2122
+ * Deletes the NPC this app has assigned to this visitor.
2123
+ *
2124
+ * @example
2125
+ * ```ts
2126
+ * await visitor.deleteNpc();
2127
+ * ```
2128
+ *
2129
+ * @returns {Promise<void>} Returns nothing if successful.
2130
+ */
2131
+ deleteNpc(): Promise<void>;
2069
2132
  /**
2070
2133
  * Retrieves all inventory items owned by this visitor and app's key.
2071
2134
  *
@@ -2091,23 +2154,28 @@ declare class Visitor extends User implements VisitorInterface {
2091
2154
  * await visitor.grantInventoryItem("item-id-123", 2);
2092
2155
  * ```
2093
2156
  *
2094
- * @returns {Promise<UserInventoryItem>} Returns the updated inventory or a response object.
2157
+ * @returns {Promise<UserInventoryItem>} Returns the updated inventory item or a response object.
2095
2158
  */
2096
2159
  grantInventoryItem(item: InventoryItem, quantity?: number): Promise<UserInventoryItem>;
2097
2160
  /**
2098
2161
  * Modifies the quantity of an inventory item in this visitor's inventory.
2162
+ * Supports upsert behavior - if the visitor doesn't own the item yet, it will be granted first.
2099
2163
  *
2100
- * @param item The UserInventoryItem to modify.
2101
- * @param quantity The new quantity to set.
2164
+ * @param item Either a UserInventoryItem (for owned items) or an InventoryItem (for upsert).
2165
+ * @param quantity The quantity delta to apply (positive to add, negative to subtract).
2102
2166
  *
2103
2167
  * @example
2104
2168
  * ```ts
2105
- * await visitor.modifyInventoryItemQuantity("item-id-123", 5);
2169
+ * // Modify an existing user inventory item
2170
+ * await visitor.modifyInventoryItemQuantity(userItem, 5);
2171
+ *
2172
+ * // Upsert: grant if not owned, or modify if already owned
2173
+ * await visitor.modifyInventoryItemQuantity(inventoryItem, 1);
2106
2174
  * ```
2107
2175
  *
2108
- * @returns {Promise<UserInventoryItem>} Returns the updated inventory or a response object.
2176
+ * @returns {Promise<UserInventoryItem>} Returns the updated inventory item or a response object.
2109
2177
  */
2110
- modifyInventoryItemQuantity(item: UserInventoryItem, quantity: number): Promise<UserInventoryItem>;
2178
+ modifyInventoryItemQuantity(item: UserInventoryItem | InventoryItem, quantity: number): Promise<UserInventoryItem>;
2111
2179
  }
2112
2180
 
2113
2181
  type VisitorType = {
@@ -2150,7 +2218,7 @@ declare enum WorldActivityType {
2150
2218
  }
2151
2219
 
2152
2220
  interface SDKInterface {
2153
- credentials?: InteractiveCredentials;
2221
+ credentials?: InteractiveCredentials$1;
2154
2222
  jwt?: string;
2155
2223
  requestOptions: object;
2156
2224
  topia: Topia;
@@ -2187,7 +2255,7 @@ interface AssetInterface extends SDKInterface {
2187
2255
  }
2188
2256
  type AssetOptionalInterface = {
2189
2257
  attributes?: AssetInterface | object;
2190
- credentials?: InteractiveCredentials;
2258
+ credentials?: InteractiveCredentials$1;
2191
2259
  };
2192
2260
 
2193
2261
  interface DroppedAssetInterface extends AssetInterface {
@@ -2309,7 +2377,7 @@ interface DroppedAssetOptionalInterface {
2309
2377
  text?: string;
2310
2378
  urlSlug?: string;
2311
2379
  };
2312
- credentials?: InteractiveCredentials | object;
2380
+ credentials?: InteractiveCredentials$1 | object;
2313
2381
  }
2314
2382
  interface UpdateBroadcastInterface {
2315
2383
  assetBroadcast?: boolean;
@@ -2401,7 +2469,7 @@ interface EcosystemInterface {
2401
2469
  incrementDataObjectValue(path: string, amount: number, options: object): Promise<void | ResponseType$1>;
2402
2470
  }
2403
2471
  interface EcosystemOptionalInterface {
2404
- credentials?: InteractiveCredentials;
2472
+ credentials?: InteractiveCredentials$1;
2405
2473
  }
2406
2474
 
2407
2475
  interface SceneInterface {
@@ -2429,7 +2497,7 @@ interface SceneInterface {
2429
2497
  }
2430
2498
  type SceneOptionalInterface = {
2431
2499
  attributes?: SceneInterface | object;
2432
- credentials?: InteractiveCredentials;
2500
+ credentials?: InteractiveCredentials$1;
2433
2501
  };
2434
2502
 
2435
2503
  interface FireToastInterface {
@@ -2468,6 +2536,7 @@ interface UserInterface {
2468
2536
  }): Promise<ResponseType$1>;
2469
2537
  fetchDataObject(appPublicKey?: string, appJWT?: string): Promise<void | ResponseType$1>;
2470
2538
  setDataObject(dataObject: object | null | undefined, options: object): Promise<void | ResponseType$1>;
2539
+ updateDataObject(dataObject: object, options: object): Promise<void | ResponseType$1>;
2471
2540
  incrementDataObjectValue(path: string, amount: number, options: object): Promise<void | ResponseType$1>;
2472
2541
  fetchInventoryItems(): Promise<void>;
2473
2542
  inventoryItems: UserInventoryItem[];
@@ -2476,7 +2545,7 @@ interface UserInterface {
2476
2545
  dataObject?: object | null;
2477
2546
  }
2478
2547
  interface UserOptionalInterface {
2479
- credentials?: InteractiveCredentials;
2548
+ credentials?: InteractiveCredentials$1;
2480
2549
  profileId?: string | null;
2481
2550
  visitorId?: number | null;
2482
2551
  urlSlug?: string;
@@ -2504,6 +2573,11 @@ interface VisitorInterface extends SDKInterface {
2504
2573
  grantInventoryItem(item: InventoryItem, quantity: number): Promise<UserInventoryItem>;
2505
2574
  modifyInventoryItemQuantity(item: UserInventoryItem, quantity: number): Promise<UserInventoryItem>;
2506
2575
  fetchInventoryItem(item: InventoryItem): Promise<UserInventoryItem>;
2576
+ createNpc(userInventoryItemId: string, options?: {
2577
+ showNameplate?: boolean;
2578
+ }): Promise<Visitor>;
2579
+ deleteNpc(): Promise<void>;
2580
+ getNpc(): Promise<Visitor | null>;
2507
2581
  triggerParticle({ id, name, duration, }: {
2508
2582
  id?: string;
2509
2583
  name?: string;
@@ -2547,7 +2621,7 @@ interface VisitorInterface extends SDKInterface {
2547
2621
  }
2548
2622
  interface VisitorOptionalInterface {
2549
2623
  attributes?: VisitorInterface | object;
2550
- credentials?: InteractiveCredentials;
2624
+ credentials?: InteractiveCredentials$1;
2551
2625
  }
2552
2626
  interface MoveVisitorInterface {
2553
2627
  shouldTeleportVisitor: boolean;
@@ -2580,12 +2654,12 @@ interface WebRTCConnectorInterface {
2580
2654
  getTwilioConfig(): Promise<void | ResponseType$1>;
2581
2655
  }
2582
2656
  interface WebRTCConnectorOptionalInterface {
2583
- credentials?: InteractiveCredentials;
2657
+ credentials?: InteractiveCredentials$1;
2584
2658
  twilioConfig?: object;
2585
2659
  }
2586
2660
 
2587
2661
  interface WorldActivityOptionalInterface {
2588
- credentials?: InteractiveCredentials;
2662
+ credentials?: InteractiveCredentials$1;
2589
2663
  }
2590
2664
  interface MoveAllVisitorsInterface {
2591
2665
  shouldFetchVisitors?: boolean;
@@ -2675,13 +2749,13 @@ interface WorldInterface extends SDKInterface, WorldDetailsInterface {
2675
2749
  }
2676
2750
  interface WorldOptionalInterface {
2677
2751
  attributes?: WorldDetailsInterface | object;
2678
- credentials?: InteractiveCredentials;
2752
+ credentials?: InteractiveCredentials$1;
2679
2753
  }
2680
2754
  interface WorldWebhooksInterface {
2681
2755
  webhooks: Array<WebhookInterface>;
2682
2756
  }
2683
2757
 
2684
- type InteractiveCredentials$1 = {
2758
+ type InteractiveCredentials = {
2685
2759
  apiKey?: string;
2686
2760
  assetId?: string;
2687
2761
  interactiveNonce?: string;
@@ -2710,7 +2784,7 @@ interface InventoryItemInterface extends SDKInterface {
2710
2784
  }
2711
2785
  type InventoryItemOptionalInterface = {
2712
2786
  attributes?: InventoryItemInterface | object;
2713
- credentials?: InteractiveCredentials$1;
2787
+ credentials?: InteractiveCredentials;
2714
2788
  };
2715
2789
 
2716
2790
  /**
@@ -2725,10 +2799,11 @@ interface UserInventoryItemInterface extends InventoryItemInterface {
2725
2799
  updated_at?: Date;
2726
2800
  metadata?: object | null;
2727
2801
  grant_source: string;
2802
+ profile_id?: string | null;
2728
2803
  }
2729
2804
  type UserInventoryItemOptionalInterface = {
2730
2805
  attributes?: UserInventoryItemInterface | object;
2731
- credentials?: InteractiveCredentials$1;
2806
+ credentials?: InteractiveCredentials;
2732
2807
  };
2733
2808
 
2734
2809
  /**
@@ -2784,11 +2859,11 @@ declare class Topia implements TopiaInterface {
2784
2859
  * ```
2785
2860
  */
2786
2861
  declare abstract class SDKController implements SDKInterface {
2787
- credentials: InteractiveCredentials | undefined;
2862
+ credentials: InteractiveCredentials$1 | undefined;
2788
2863
  jwt?: string;
2789
2864
  requestOptions: object;
2790
2865
  topia: Topia;
2791
- constructor(topia: Topia, credentials?: InteractiveCredentials);
2866
+ constructor(topia: Topia, credentials?: InteractiveCredentials$1);
2792
2867
  topiaPublicApi(): axios.AxiosInstance;
2793
2868
  errorHandler({ error, message, params, sdkMethod, }: {
2794
2869
  error?: Error | AxiosError | unknown;
@@ -3368,7 +3443,7 @@ declare class DroppedAssetFactory extends SDKController {
3368
3443
  *
3369
3444
  * @returns {Promise<DroppedAsset>} Returns a new DroppedAsset object with all properties already fetched.
3370
3445
  */
3371
- getWithUniqueName(uniqueName: string, urlSlug: string, interactiveSecret: string, credentials: InteractiveCredentials): Promise<DroppedAsset>;
3446
+ getWithUniqueName(uniqueName: string, urlSlug: string, interactiveSecret: string, credentials: InteractiveCredentials$1): Promise<DroppedAsset>;
3372
3447
  /**
3373
3448
  * Drops an asset in a world and returns a new instance of DroppedAsset class with all properties.
3374
3449
  *
@@ -3950,4 +4025,4 @@ declare class WorldFactory extends SDKController {
3950
4025
  }>;
3951
4026
  }
3952
4027
 
3953
- export { AnalyticType, AnimationMetaType, Asset, AssetFactory, AssetInterface, AssetOptionalInterface, AssetOptions, AssetType, DroppedAsset, DroppedAssetClickType, DroppedAssetFactory, DroppedAssetInterface, DroppedAssetLinkType, DroppedAssetMediaType, DroppedAssetMediaVolumeRadius, DroppedAssetOptionalInterface, DroppedAssetOptions, Ecosystem, EcosystemFactory, EcosystemInterface, EcosystemOptionalInterface, FireToastInterface, FrameType, InteractiveCredentials, InventoryItemInterface, InventoryItemOptionalInterface, MoveAllVisitorsInterface, MoveVisitorInterface, OpenIframeInterface, RemoveClickableLinkInterface, ResponseType$1 as ResponseType, SDKController, SDKInterface, Scene, SceneFactory, SceneInterface, SceneOptionalInterface, SetClickableLinkMultiInterface, Topia, TopiaInterface, UpdateBroadcastInterface, UpdateClickTypeInterface, UpdateClickableLinkMultiInterface, UpdateDroppedAssetInterface, UpdateMediaTypeInterface, UpdatePrivateZoneInterface, User, UserFactory, UserInterface, UserInventoryItemInterface, UserInventoryItemOptionalInterface, UserOptionalInterface, UserOptions, Visitor, VisitorFactory, VisitorInterface, VisitorOptionalInterface, VisitorOptions, VisitorType, VisitorsToMoveArrayType, VisitorsToMoveType, WebRTCConnector, WebRTCConnectorFactory, WebRTCConnectorInterface, WebRTCConnectorOptionalInterface, WebhookInterface, World, WorldActivity, WorldActivityFactory, WorldActivityOptionalInterface, WorldActivityType, WorldDetailsInterface, WorldFactory, WorldInterface, WorldOptionalInterface, WorldOptions, WorldWebhooksInterface };
4028
+ export { AnalyticType, AnimationMetaType, Asset, AssetFactory, AssetInterface, AssetOptionalInterface, AssetOptions, AssetType, DroppedAsset, DroppedAssetClickType, DroppedAssetFactory, DroppedAssetInterface, DroppedAssetLinkType, DroppedAssetMediaType, DroppedAssetMediaVolumeRadius, DroppedAssetOptionalInterface, DroppedAssetOptions, Ecosystem, EcosystemFactory, EcosystemInterface, EcosystemOptionalInterface, FireToastInterface, FrameType, InteractiveCredentials$1 as InteractiveCredentials, InventoryItemInterface, InventoryItemOptionalInterface, MoveAllVisitorsInterface, MoveVisitorInterface, OpenIframeInterface, RemoveClickableLinkInterface, ResponseType$1 as ResponseType, SDKController, SDKInterface, Scene, SceneFactory, SceneInterface, SceneOptionalInterface, SetClickableLinkMultiInterface, Topia, TopiaInterface, UpdateBroadcastInterface, UpdateClickTypeInterface, UpdateClickableLinkMultiInterface, UpdateDroppedAssetInterface, UpdateMediaTypeInterface, UpdatePrivateZoneInterface, User, UserFactory, UserInterface, UserInventoryItemInterface, UserInventoryItemOptionalInterface, UserOptionalInterface, UserOptions, Visitor, VisitorFactory, VisitorInterface, VisitorOptionalInterface, VisitorOptions, VisitorType, VisitorsToMoveArrayType, VisitorsToMoveType, WebRTCConnector, WebRTCConnectorFactory, WebRTCConnectorInterface, WebRTCConnectorOptionalInterface, WebhookInterface, World, WorldActivity, WorldActivityFactory, WorldActivityOptionalInterface, WorldActivityType, WorldDetailsInterface, WorldFactory, WorldInterface, WorldOptionalInterface, WorldOptions, WorldWebhooksInterface };
package/dist/index.js CHANGED
@@ -40681,6 +40681,32 @@ class DroppedAsset extends Asset {
40681
40681
  }
40682
40682
  });
40683
40683
  }
40684
+ /**
40685
+ * Checks if this dropped asset exists with the current app's public key installed.
40686
+ *
40687
+ * @keywords check, exists, verify, validate, lookup
40688
+ *
40689
+ * @example
40690
+ * ```ts
40691
+ * const { exists } = await droppedAsset.checkExists();
40692
+ * ```
40693
+ *
40694
+ * @returns {Promise<{ exists: boolean }>} Returns whether the asset exists with the app's public key.
40695
+ */
40696
+ checkExists() {
40697
+ return __awaiter(this, void 0, void 0, function* () {
40698
+ try {
40699
+ const response = yield this.topiaPublicApi().get(`/world/${this.urlSlug}/dropped-asset/${this.id}/exists`, this.requestOptions);
40700
+ return response.data;
40701
+ }
40702
+ catch (error) {
40703
+ throw this.errorHandler({
40704
+ error,
40705
+ sdkMethod: "DroppedAsset.checkExists",
40706
+ });
40707
+ }
40708
+ });
40709
+ }
40684
40710
  /**
40685
40711
  * Retrieve analytics for a dropped asset by day, week, month, quarter, or year
40686
40712
  *
@@ -41011,7 +41037,7 @@ class UserInventoryItem extends InventoryItem {
41011
41037
  super(topia, item_id, { attributes: options.attributes, credentials: options.credentials });
41012
41038
  Object.assign(this, options.attributes);
41013
41039
  this.userItemId = id;
41014
- const { user_id = "", quantity = 0, grant_source = "unknown", type = "unknown", metadata = {}, created_at = new Date(), updated_at = new Date(), } = options.attributes;
41040
+ const { user_id = "", quantity = 0, grant_source = "unknown", type = "unknown", metadata = {}, created_at = new Date(), updated_at = new Date(), profile_id = null, } = options.attributes;
41015
41041
  this.item_id = item_id;
41016
41042
  this.quantity = quantity;
41017
41043
  this.grant_source = grant_source;
@@ -41020,6 +41046,7 @@ class UserInventoryItem extends InventoryItem {
41020
41046
  this.metadata = metadata;
41021
41047
  this.created_at = created_at;
41022
41048
  this.updated_at = updated_at;
41049
+ this.profile_id = profile_id;
41023
41050
  }
41024
41051
  /**
41025
41052
  * Fetches the user inventory item details from the platform and assigns them to this instance.
@@ -42699,7 +42726,7 @@ class User extends SDKController {
42699
42726
  * await user.modifyInventoryItemQuantity("item-id-123", 5);
42700
42727
  * ```
42701
42728
  *
42702
- * @returns {Promise<UserInventoryItem>} Returns the updated inventory or a response object.
42729
+ * @returns {Promise<UserInventoryItem>} Returns the updated inventory item or a response object.
42703
42730
  */
42704
42731
  modifyInventoryItemQuantity(item, quantity) {
42705
42732
  return __awaiter(this, void 0, void 0, function* () {
@@ -43285,7 +43312,7 @@ class Visitor extends User {
43285
43312
  * const items = await visitor.fetchInventoryItems();
43286
43313
  * ```
43287
43314
  *
43288
- * @returns {Promise<void>} Returns an array of InventoryItem objects.
43315
+ * @returns {Promise<void>} Returns a new instance of InventoryItem.
43289
43316
  */
43290
43317
  fetchInventoryItem(item) {
43291
43318
  return __awaiter(this, void 0, void 0, function* () {
@@ -43301,6 +43328,88 @@ class Visitor extends User {
43301
43328
  }
43302
43329
  });
43303
43330
  }
43331
+ /**
43332
+ * Gets an NPC for this visitor, if one exists.
43333
+ *
43334
+ * @example
43335
+ * ```ts
43336
+ * await visitor.getNpc();
43337
+ * ```
43338
+ *
43339
+ * @returns {Promise<Visitor | null>} Returns a Visitor object representing the NPC.
43340
+ */
43341
+ getNpc() {
43342
+ return __awaiter(this, void 0, void 0, function* () {
43343
+ try {
43344
+ const visitorResponse = yield this.topiaPublicApi().get(`/world/${this.urlSlug}/visitors/${this.id}/get-npc`, this.requestOptions);
43345
+ if (visitorResponse.data)
43346
+ return new Visitor(this.topia, visitorResponse.data.playerId, this.urlSlug, {
43347
+ attributes: visitorResponse.data,
43348
+ credentials: this.credentials,
43349
+ });
43350
+ return null;
43351
+ }
43352
+ catch (error) {
43353
+ throw this.errorHandler({ error, sdkMethod: "Visitor.getNpc" });
43354
+ }
43355
+ });
43356
+ }
43357
+ /**
43358
+ * Creates an NPC that follows this visitor using an inventory item the visitor owns.
43359
+ * One NPC is allowed per visitor, per application public key.
43360
+ *
43361
+ * @param userInventoryItemId The ID of the user's inventory item (must be an NPC type item owned by this visitor).
43362
+ * @param options Optional configuration for the NPC.
43363
+ * @param options.showNameplate Whether to display a nameplate above the NPC (default: true).
43364
+ *
43365
+ * @example
43366
+ * ```ts
43367
+ * // First, grant the NPC item to the visitor
43368
+ * const userItem = await visitor.grantInventoryItem(npcInventoryItem, 1);
43369
+ *
43370
+ * // Then create the NPC using the granted item
43371
+ * const npc = await visitor.createNpc(userItem.id);
43372
+ *
43373
+ * // Or create without a nameplate
43374
+ * const npc = await visitor.createNpc(userItem.id, { showNameplate: false });
43375
+ * ```
43376
+ *
43377
+ * @returns {Promise<Visitor>} Returns a Visitor object representing the created NPC.
43378
+ */
43379
+ createNpc(userInventoryItemId, options) {
43380
+ return __awaiter(this, void 0, void 0, function* () {
43381
+ try {
43382
+ const response = yield this.topiaPublicApi().post(`/world/${this.urlSlug}/visitors/${this.id}/create-npc`, { userInventoryItemId, showNameplate: options === null || options === void 0 ? void 0 : options.showNameplate }, this.requestOptions);
43383
+ return new Visitor(this.topia, response.data.player.playerId, this.urlSlug, {
43384
+ attributes: response.data,
43385
+ credentials: this.credentials,
43386
+ });
43387
+ }
43388
+ catch (error) {
43389
+ throw this.errorHandler({ error, sdkMethod: "Visitor.createNpc" });
43390
+ }
43391
+ });
43392
+ }
43393
+ /**
43394
+ * Deletes the NPC this app has assigned to this visitor.
43395
+ *
43396
+ * @example
43397
+ * ```ts
43398
+ * await visitor.deleteNpc();
43399
+ * ```
43400
+ *
43401
+ * @returns {Promise<void>} Returns nothing if successful.
43402
+ */
43403
+ deleteNpc() {
43404
+ return __awaiter(this, void 0, void 0, function* () {
43405
+ try {
43406
+ yield this.topiaPublicApi().delete(`/world/${this.urlSlug}/visitors/${this.id}/delete-npc`, this.requestOptions);
43407
+ }
43408
+ catch (error) {
43409
+ throw this.errorHandler({ error, sdkMethod: "Visitor.deleteNpc" });
43410
+ }
43411
+ });
43412
+ }
43304
43413
  /**
43305
43414
  * Retrieves all inventory items owned by this visitor and app's key.
43306
43415
  *
@@ -43346,7 +43455,7 @@ class Visitor extends User {
43346
43455
  * await visitor.grantInventoryItem("item-id-123", 2);
43347
43456
  * ```
43348
43457
  *
43349
- * @returns {Promise<UserInventoryItem>} Returns the updated inventory or a response object.
43458
+ * @returns {Promise<UserInventoryItem>} Returns the updated inventory item or a response object.
43350
43459
  */
43351
43460
  grantInventoryItem(item, quantity = 1) {
43352
43461
  var _a;
@@ -43372,27 +43481,31 @@ class Visitor extends User {
43372
43481
  }
43373
43482
  /**
43374
43483
  * Modifies the quantity of an inventory item in this visitor's inventory.
43484
+ * Supports upsert behavior - if the visitor doesn't own the item yet, it will be granted first.
43375
43485
  *
43376
- * @param item The UserInventoryItem to modify.
43377
- * @param quantity The new quantity to set.
43486
+ * @param item Either a UserInventoryItem (for owned items) or an InventoryItem (for upsert).
43487
+ * @param quantity The quantity delta to apply (positive to add, negative to subtract).
43378
43488
  *
43379
43489
  * @example
43380
43490
  * ```ts
43381
- * await visitor.modifyInventoryItemQuantity("item-id-123", 5);
43491
+ * // Modify an existing user inventory item
43492
+ * await visitor.modifyInventoryItemQuantity(userItem, 5);
43493
+ *
43494
+ * // Upsert: grant if not owned, or modify if already owned
43495
+ * await visitor.modifyInventoryItemQuantity(inventoryItem, 1);
43382
43496
  * ```
43383
43497
  *
43384
- * @returns {Promise<UserInventoryItem>} Returns the updated inventory or a response object.
43498
+ * @returns {Promise<UserInventoryItem>} Returns the updated inventory item or a response object.
43385
43499
  */
43386
43500
  modifyInventoryItemQuantity(item, quantity) {
43387
- var _a;
43388
43501
  return __awaiter(this, void 0, void 0, function* () {
43389
- // Check for existence in #visitorInventoryItems
43390
- const found = (_a = __classPrivateFieldGet(this, _Visitor_visitorInventoryItems, "f")) === null || _a === void 0 ? void 0 : _a.some((visitorItem) => visitorItem.id === item.userItemId);
43391
- if (!found) {
43392
- throw new Error(`Inventory item with id '${item.userItemId}' does not exist in visitorInventoryItems.`);
43393
- }
43394
43502
  try {
43395
- const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/update-visitor-inventory-item-quantity`, { userItemId: item.id, itemId: item.item_id, quantity }, this.requestOptions);
43503
+ // Determine if item is a UserInventoryItem (has userItemId) or InventoryItem (only has id)
43504
+ const isUserItem = "userItemId" in item && item.userItemId;
43505
+ const body = isUserItem
43506
+ ? { userItemId: item.userItemId, itemId: item.item_id, quantity }
43507
+ : { itemId: item.id, quantity };
43508
+ const response = yield this.topiaPublicApi().put(`/world/${this.urlSlug}/visitors/${this.id}/update-visitor-inventory-item-quantity`, body, this.requestOptions);
43396
43509
  const userInventoryItemFactory = new UserInventoryItemFactory(this.topia);
43397
43510
  const { inventoryItem, user_id, quantity: newQuantity } = response.data;
43398
43511
  return userInventoryItemFactory.create(inventoryItem, user_id, newQuantity, {
@@ -44809,7 +44922,7 @@ class WorldFactory extends SDKController {
44809
44922
  headers,
44810
44923
  }));
44811
44924
  }
44812
- yield Promise.all(promiseArray);
44925
+ yield Promise.allSettled(promiseArray);
44813
44926
  return { success: true };
44814
44927
  }
44815
44928
  catch (error) {
package/package.json CHANGED
@@ -61,5 +61,5 @@
61
61
  "yalc-push": "yarn build && yalc publish --push --dev --no-scripts"
62
62
  },
63
63
  "type": "module",
64
- "version": "0.18.03"
65
- }
64
+ "version": "0.19.01"
65
+ }