@playcademy/sdk 0.0.1-beta.21 → 0.0.1-beta.23
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 +15 -2
- package/dist/core/client.d.ts +25 -2
- package/dist/core/namespaces/credits.d.ts +51 -0
- package/dist/core/namespaces/index.d.ts +2 -0
- package/dist/core/namespaces/levels.d.ts +93 -0
- package/dist/core/namespaces/users.d.ts +56 -9
- package/dist/index.js +151 -2
- package/dist/types.d.ts +13 -2
- package/dist/types.js +43 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -136,11 +136,17 @@ All methods returning data are strongly typed.
|
|
|
136
136
|
- `me()`: Fetch current user details.
|
|
137
137
|
- **`inventory`**:
|
|
138
138
|
- `get()`: Get player inventory.
|
|
139
|
-
- `add(
|
|
140
|
-
- `
|
|
139
|
+
- `add(identifier, qty)`: Add item to player inventory (accepts UUID or internal name).
|
|
140
|
+
- `remove(identifier, qty)`: Remove item from player inventory (accepts UUID or internal name).
|
|
141
|
+
- `quantity(identifier)`: Get current quantity of an item (accepts UUID or internal name).
|
|
142
|
+
- `has(identifier, minQuantity?)`: Check if user has enough of an item (accepts UUID or internal name).
|
|
141
143
|
- **`progress`**: Manages persistent progress data for a game (e.g., levels completed, scores, collectibles).
|
|
142
144
|
- `get(gameId?)`: Get the entire progress state for a game. `gameId` is optional and defaults to the client's current game context.
|
|
143
145
|
- `update(data, gameId?)`: Update the progress state for a game. `gameId` is optional. The `data` object can be structured to hold progress for various internal nodes or aspects of the game.
|
|
146
|
+
- **`credits`**: Convenient methods for working with Playcademy Credits (primary platform currency).
|
|
147
|
+
- `balance()`: Get current credits balance.
|
|
148
|
+
- `add(amount)`: Add credits to user.
|
|
149
|
+
- `spend(amount)`: Spend credits from user.
|
|
144
150
|
- **`games`**: Manages game sessions and transient game state.
|
|
145
151
|
- `fetch(gameIdOrSlug)`: Fetch game details with manifest.
|
|
146
152
|
- `list()`: List all games.
|
|
@@ -162,6 +168,13 @@ All methods returning data are strongly typed.
|
|
|
162
168
|
- **`admin.shopListings`**: CRUD operations for shop listings.
|
|
163
169
|
- **`shop`**: Player-facing shop operations.
|
|
164
170
|
- `view()`: Get shop items and currency information.
|
|
171
|
+
- **`levels`**: Player level and experience point management.
|
|
172
|
+
- `get()`: Get current user level information.
|
|
173
|
+
- `progress()`: Get level progress with XP to next level.
|
|
174
|
+
- `addXP(amount)`: Add XP to user.
|
|
175
|
+
- **`config`**:
|
|
176
|
+
- `list()`: Get all level configurations (full XP curve).
|
|
177
|
+
- `get(level)`: Get configuration for a specific level.
|
|
165
178
|
- **`telemetry`**: Push metrics.
|
|
166
179
|
|
|
167
180
|
## Contributing
|
package/dist/core/client.d.ts
CHANGED
|
@@ -118,8 +118,10 @@ export declare class PlaycademyClient {
|
|
|
118
118
|
}>;
|
|
119
119
|
inventory: {
|
|
120
120
|
get: () => Promise<import("@playcademy/types").InventoryItemWithItem[]>;
|
|
121
|
-
add: (
|
|
122
|
-
|
|
121
|
+
add: (identifier: string, qty: number) => Promise<import("..").InventoryMutationResponse>;
|
|
122
|
+
remove: (identifier: string, qty: number) => Promise<import("..").InventoryMutationResponse>;
|
|
123
|
+
quantity: (identifier: string) => Promise<number>;
|
|
124
|
+
has: (identifier: string, minQuantity?: number) => Promise<boolean>;
|
|
123
125
|
};
|
|
124
126
|
};
|
|
125
127
|
/** Developer tools (auth, games, keys management) */
|
|
@@ -311,10 +313,31 @@ export declare class PlaycademyClient {
|
|
|
311
313
|
shop: {
|
|
312
314
|
view: () => Promise<import("..").ShopViewResponse>;
|
|
313
315
|
};
|
|
316
|
+
/** Level methods (levels) */
|
|
317
|
+
levels: {
|
|
318
|
+
get: () => Promise<import("@playcademy/types").UserLevel>;
|
|
319
|
+
progress: () => Promise<{
|
|
320
|
+
level: number;
|
|
321
|
+
currentXp: number;
|
|
322
|
+
xpToNextLevel: number;
|
|
323
|
+
totalXP: number;
|
|
324
|
+
}>;
|
|
325
|
+
addXP: (amount: number) => Promise<import("@playcademy/types").XPAddResult>;
|
|
326
|
+
config: {
|
|
327
|
+
list: () => Promise<import("@playcademy/types").LevelConfig[]>;
|
|
328
|
+
get: (level: number) => Promise<import("@playcademy/types").LevelConfig | null>;
|
|
329
|
+
};
|
|
330
|
+
};
|
|
314
331
|
/** Telemetry methods (pushMetrics) */
|
|
315
332
|
telemetry: {
|
|
316
333
|
pushMetrics: (metrics: Record<string, number>) => Promise<void>;
|
|
317
334
|
};
|
|
335
|
+
/** Credits methods (credits management) */
|
|
336
|
+
credits: {
|
|
337
|
+
balance: () => Promise<number>;
|
|
338
|
+
add: (amount: number) => Promise<number>;
|
|
339
|
+
spend: (amount: number) => Promise<number>;
|
|
340
|
+
};
|
|
318
341
|
/** Auto-initializes a PlaycademyClient with context from the environment */
|
|
319
342
|
static init: typeof init;
|
|
320
343
|
/** Authenticates a user with email and password */
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { PlaycademyClient } from '../client';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the credits namespace for the PlaycademyClient.
|
|
4
|
+
* Provides convenient methods for working with Playcademy Credits (the primary platform currency).
|
|
5
|
+
*
|
|
6
|
+
* @param client - The PlaycademyClient instance
|
|
7
|
+
* @returns Credits namespace with balance and transaction methods
|
|
8
|
+
*/
|
|
9
|
+
export declare function createCreditsNamespace(client: PlaycademyClient): {
|
|
10
|
+
/**
|
|
11
|
+
* Gets the current balance of Playcademy Credits for the authenticated user.
|
|
12
|
+
* This is a convenience method that finds the primary currency in the user's inventory.
|
|
13
|
+
*
|
|
14
|
+
* @returns Promise resolving to the current credits balance
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const balance = await client.credits.balance()
|
|
19
|
+
* console.log('Current credits:', balance)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
balance: () => Promise<number>;
|
|
23
|
+
/**
|
|
24
|
+
* Adds Playcademy Credits to the user's inventory.
|
|
25
|
+
* This is a convenience method that automatically finds the credits item ID.
|
|
26
|
+
*
|
|
27
|
+
* @param amount - The amount of credits to add (must be positive)
|
|
28
|
+
* @returns Promise resolving to the new total balance
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const newBalance = await client.credits.add(100)
|
|
33
|
+
* console.log('New balance after adding 100 credits:', newBalance)
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
add: (amount: number) => Promise<number>;
|
|
37
|
+
/**
|
|
38
|
+
* Spends (removes) Playcademy Credits from the user's inventory.
|
|
39
|
+
* This is a convenience method that automatically finds the credits item ID.
|
|
40
|
+
*
|
|
41
|
+
* @param amount - The amount of credits to spend (must be positive)
|
|
42
|
+
* @returns Promise resolving to the new total balance
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const newBalance = await client.credits.spend(50)
|
|
47
|
+
* console.log('New balance after spending 50 credits:', newBalance)
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
spend: (amount: number) => Promise<number>;
|
|
51
|
+
};
|
|
@@ -7,3 +7,5 @@ export { createMapsNamespace } from './maps';
|
|
|
7
7
|
export { createAdminNamespace } from './admin';
|
|
8
8
|
export { createShopNamespace } from './shop';
|
|
9
9
|
export { createTelemetryNamespace } from './telemetry';
|
|
10
|
+
export { createLevelsNamespace } from './levels';
|
|
11
|
+
export { createCreditsNamespace } from './credits';
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { UserLevel, LevelConfig, XPAddResult } from '../../types';
|
|
2
|
+
import type { PlaycademyClient } from '../client';
|
|
3
|
+
/**
|
|
4
|
+
* Creates the levels namespace for the PlaycademyClient.
|
|
5
|
+
* Provides methods for managing user levels and experience points.
|
|
6
|
+
*
|
|
7
|
+
* @param client - The PlaycademyClient instance
|
|
8
|
+
* @returns Levels namespace with level and XP methods
|
|
9
|
+
*/
|
|
10
|
+
export declare function createLevelsNamespace(client: PlaycademyClient): {
|
|
11
|
+
/**
|
|
12
|
+
* Retrieves the current user's level information.
|
|
13
|
+
*
|
|
14
|
+
* @returns Promise resolving to user level data
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const userLevel = await client.levels.get()
|
|
19
|
+
* console.log('Current level:', userLevel.currentLevel)
|
|
20
|
+
* console.log('Current XP:', userLevel.currentXp)
|
|
21
|
+
* console.log('Total XP earned:', userLevel.totalXP)
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
get: () => Promise<UserLevel>;
|
|
25
|
+
/**
|
|
26
|
+
* Retrieves the current user's level progress information.
|
|
27
|
+
*
|
|
28
|
+
* @returns Promise resolving to level progress data
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const progress = await client.levels.progress()
|
|
33
|
+
* console.log('Level:', progress.level)
|
|
34
|
+
* console.log('XP to next level:', progress.xpToNextLevel)
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
progress: () => Promise<{
|
|
38
|
+
level: number;
|
|
39
|
+
currentXp: number;
|
|
40
|
+
xpToNextLevel: number;
|
|
41
|
+
totalXP: number;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Adds XP to the current user.
|
|
45
|
+
* Emits 'xpGained' and 'levelUp' events when successful.
|
|
46
|
+
*
|
|
47
|
+
* @param amount - The amount of XP to add (must be positive)
|
|
48
|
+
* @returns Promise resolving to XP addition result
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const result = await client.levels.addXP(100)
|
|
53
|
+
* console.log('New level:', result.newLevel)
|
|
54
|
+
* console.log('Leveled up:', result.leveledUp)
|
|
55
|
+
* console.log('Credits awarded:', result.creditsAwarded)
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
addXP: (amount: number) => Promise<XPAddResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Configuration methods for level system.
|
|
61
|
+
*/
|
|
62
|
+
config: {
|
|
63
|
+
/**
|
|
64
|
+
* Retrieves all level configurations (full XP curve).
|
|
65
|
+
*
|
|
66
|
+
* @returns Promise resolving to array of level configurations
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const configs = await client.levels.config.list()
|
|
71
|
+
* configs.forEach(config => {
|
|
72
|
+
* console.log(`Level ${config.level}: ${config.xpRequired} XP, ${config.creditsReward} credits`)
|
|
73
|
+
* })
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
list: () => Promise<LevelConfig[]>;
|
|
77
|
+
/**
|
|
78
|
+
* Retrieves configuration for a specific level.
|
|
79
|
+
*
|
|
80
|
+
* @param level - The level number to get configuration for
|
|
81
|
+
* @returns Promise resolving to level configuration or null if not found
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const config = await client.levels.config.get(10)
|
|
86
|
+
* if (config) {
|
|
87
|
+
* console.log(`Level 10 requires ${config.xpRequired} XP`)
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
get: (level: number) => Promise<LevelConfig | null>;
|
|
92
|
+
};
|
|
93
|
+
};
|
|
@@ -52,33 +52,80 @@ export declare function createUsersNamespace(client: PlaycademyClient): {
|
|
|
52
52
|
get: () => Promise<InventoryItemWithItem[]>;
|
|
53
53
|
/**
|
|
54
54
|
* Adds items to the user's inventory.
|
|
55
|
+
* Accepts either an item UUID or internal name.
|
|
55
56
|
* Emits an 'inventoryChange' event when successful.
|
|
56
57
|
*
|
|
57
|
-
* @param
|
|
58
|
+
* @param identifier - The item UUID or internal name
|
|
58
59
|
* @param qty - The quantity to add (must be positive)
|
|
59
60
|
* @returns Promise resolving to mutation response with new total
|
|
60
61
|
*
|
|
61
62
|
* @example
|
|
62
63
|
* ```typescript
|
|
63
|
-
*
|
|
64
|
+
* // Using internal name
|
|
65
|
+
* const result = await client.users.inventory.add('GOLD_COIN', 100)
|
|
66
|
+
*
|
|
67
|
+
* // Using UUID
|
|
68
|
+
* const result = await client.users.inventory.add('550e8400-e29b-41d4-a716-446655440000', 100)
|
|
69
|
+
*
|
|
64
70
|
* console.log('New total:', result.newTotal)
|
|
65
71
|
* ```
|
|
66
72
|
*/
|
|
67
|
-
add: (
|
|
73
|
+
add: (identifier: string, qty: number) => Promise<InventoryMutationResponse>;
|
|
68
74
|
/**
|
|
69
|
-
*
|
|
75
|
+
* Removes items from the user's inventory.
|
|
76
|
+
* Accepts either an item UUID or internal name.
|
|
70
77
|
* Emits an 'inventoryChange' event when successful.
|
|
71
78
|
*
|
|
72
|
-
* @param
|
|
73
|
-
* @param qty - The quantity to
|
|
79
|
+
* @param identifier - The item UUID or internal name
|
|
80
|
+
* @param qty - The quantity to remove (must be positive)
|
|
74
81
|
* @returns Promise resolving to mutation response with new total
|
|
75
82
|
*
|
|
76
83
|
* @example
|
|
77
84
|
* ```typescript
|
|
78
|
-
*
|
|
79
|
-
*
|
|
85
|
+
* // Using internal name
|
|
86
|
+
* const result = await client.users.inventory.remove('HEALTH_POTION', 1)
|
|
87
|
+
*
|
|
88
|
+
* // Using UUID
|
|
89
|
+
* const result = await client.users.inventory.remove('uuid-456-789', 1)
|
|
90
|
+
*
|
|
91
|
+
* console.log('Remaining:', result.newTotal)
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
remove: (identifier: string, qty: number) => Promise<InventoryMutationResponse>;
|
|
95
|
+
/**
|
|
96
|
+
* Gets the current quantity of an item.
|
|
97
|
+
* Accepts either an item UUID or internal name.
|
|
98
|
+
*
|
|
99
|
+
* @param identifier - The item UUID or internal name
|
|
100
|
+
* @returns Promise resolving to the current quantity (0 if not owned)
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* const qty = await client.users.inventory.quantity('HEALTH_POTION')
|
|
105
|
+
* const qty2 = await client.users.inventory.quantity('uuid-123-456')
|
|
106
|
+
* console.log('Health potions:', qty)
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
quantity: (identifier: string) => Promise<number>;
|
|
110
|
+
/**
|
|
111
|
+
* Checks if the user has at least the specified quantity of an item.
|
|
112
|
+
* Accepts either an item UUID or internal name.
|
|
113
|
+
*
|
|
114
|
+
* @param identifier - The item UUID or internal name
|
|
115
|
+
* @param minQuantity - Minimum quantity required (defaults to 1)
|
|
116
|
+
* @returns Promise resolving to true if user has enough of the item
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* const hasKey = await client.users.inventory.has('DUNGEON_KEY')
|
|
121
|
+
* const hasEnoughGold = await client.users.inventory.has('GOLD_COIN', 100)
|
|
122
|
+
* const hasPotion = await client.users.inventory.has('uuid-123-456', 5)
|
|
123
|
+
*
|
|
124
|
+
* if (hasKey && hasEnoughGold) {
|
|
125
|
+
* console.log('Can enter premium dungeon!')
|
|
126
|
+
* }
|
|
80
127
|
* ```
|
|
81
128
|
*/
|
|
82
|
-
|
|
129
|
+
has: (identifier: string, minQuantity?: number) => Promise<boolean>;
|
|
83
130
|
};
|
|
84
131
|
};
|
package/dist/index.js
CHANGED
|
@@ -258,13 +258,29 @@ var init_games = __esm(() => {
|
|
|
258
258
|
|
|
259
259
|
// src/core/namespaces/users.ts
|
|
260
260
|
function createUsersNamespace(client) {
|
|
261
|
+
const itemIdCache = new Map;
|
|
262
|
+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
263
|
+
const resolveItemId = async (identifier) => {
|
|
264
|
+
if (UUID_REGEX.test(identifier))
|
|
265
|
+
return identifier;
|
|
266
|
+
if (itemIdCache.has(identifier))
|
|
267
|
+
return itemIdCache.get(identifier);
|
|
268
|
+
const inventory = await client.users.inventory.get();
|
|
269
|
+
const item = inventory.find((inv) => inv.item?.internalName === identifier);
|
|
270
|
+
if (!item) {
|
|
271
|
+
throw new Error(`Item with internal name '${identifier}' not found in inventory`);
|
|
272
|
+
}
|
|
273
|
+
itemIdCache.set(identifier, item.item.id);
|
|
274
|
+
return item.item.id;
|
|
275
|
+
};
|
|
261
276
|
return {
|
|
262
277
|
me: async () => {
|
|
263
278
|
return client["request"]("/users/me", "GET");
|
|
264
279
|
},
|
|
265
280
|
inventory: {
|
|
266
281
|
get: async () => client["request"](`/inventory`, "GET"),
|
|
267
|
-
add: async (
|
|
282
|
+
add: async (identifier, qty) => {
|
|
283
|
+
const itemId = await resolveItemId(identifier);
|
|
268
284
|
const res = await client["request"](`/inventory/add`, "POST", { itemId, qty });
|
|
269
285
|
client["emit"]("inventoryChange", {
|
|
270
286
|
itemId,
|
|
@@ -273,7 +289,8 @@ function createUsersNamespace(client) {
|
|
|
273
289
|
});
|
|
274
290
|
return res;
|
|
275
291
|
},
|
|
276
|
-
|
|
292
|
+
remove: async (identifier, qty) => {
|
|
293
|
+
const itemId = await resolveItemId(identifier);
|
|
277
294
|
const res = await client["request"](`/inventory/spend`, "POST", { itemId, qty });
|
|
278
295
|
client["emit"]("inventoryChange", {
|
|
279
296
|
itemId,
|
|
@@ -281,6 +298,19 @@ function createUsersNamespace(client) {
|
|
|
281
298
|
newTotal: res.newTotal
|
|
282
299
|
});
|
|
283
300
|
return res;
|
|
301
|
+
},
|
|
302
|
+
quantity: async (identifier) => {
|
|
303
|
+
const inventory = await client.users.inventory.get();
|
|
304
|
+
if (UUID_REGEX.test(identifier)) {
|
|
305
|
+
const item2 = inventory.find((inv) => inv.item?.id === identifier);
|
|
306
|
+
return item2?.quantity ?? 0;
|
|
307
|
+
}
|
|
308
|
+
const item = inventory.find((inv) => inv.item?.internalName === identifier);
|
|
309
|
+
return item?.quantity ?? 0;
|
|
310
|
+
},
|
|
311
|
+
has: async (identifier, minQuantity = 1) => {
|
|
312
|
+
const qty = await client.users.inventory.quantity(identifier);
|
|
313
|
+
return qty >= minQuantity;
|
|
284
314
|
}
|
|
285
315
|
}
|
|
286
316
|
};
|
|
@@ -368,10 +398,127 @@ function createTelemetryNamespace(client) {
|
|
|
368
398
|
};
|
|
369
399
|
}
|
|
370
400
|
|
|
401
|
+
// src/core/namespaces/levels.ts
|
|
402
|
+
function createLevelsNamespace(client) {
|
|
403
|
+
return {
|
|
404
|
+
get: async () => {
|
|
405
|
+
return client["request"]("/users/level", "GET");
|
|
406
|
+
},
|
|
407
|
+
progress: async () => {
|
|
408
|
+
return client["request"]("/users/level/progress", "GET");
|
|
409
|
+
},
|
|
410
|
+
addXP: async (amount) => {
|
|
411
|
+
const currentUserLevel = await client["request"]("/users/level", "GET");
|
|
412
|
+
const oldLevel = currentUserLevel.currentLevel;
|
|
413
|
+
const payload = { amount };
|
|
414
|
+
const result = await client["request"]("/users/xp/add", "POST", payload);
|
|
415
|
+
client["emit"]("xpGained", {
|
|
416
|
+
amount,
|
|
417
|
+
totalXP: result.totalXP,
|
|
418
|
+
leveledUp: result.leveledUp
|
|
419
|
+
});
|
|
420
|
+
if (result.leveledUp) {
|
|
421
|
+
client["emit"]("levelUp", {
|
|
422
|
+
oldLevel,
|
|
423
|
+
newLevel: result.newLevel,
|
|
424
|
+
creditsAwarded: result.creditsAwarded
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
return result;
|
|
428
|
+
},
|
|
429
|
+
config: {
|
|
430
|
+
list: async () => {
|
|
431
|
+
return client["request"]("/levels/config", "GET");
|
|
432
|
+
},
|
|
433
|
+
get: async (level) => {
|
|
434
|
+
return client["request"](`/levels/config/${level}`, "GET");
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// ../data/src/constants.ts
|
|
441
|
+
var ITEM_INTERNAL_NAMES, CURRENCIES, BADGES;
|
|
442
|
+
var init_constants = __esm(() => {
|
|
443
|
+
ITEM_INTERNAL_NAMES = {
|
|
444
|
+
PLAYCADEMY_CREDITS: "PLAYCADEMY_CREDITS",
|
|
445
|
+
PLAYCADEMY_XP: "PLAYCADEMY_XP",
|
|
446
|
+
FOUNDING_MEMBER_BADGE: "FOUNDING_MEMBER_BADGE",
|
|
447
|
+
EARLY_ADOPTER_BADGE: "EARLY_ADOPTER_BADGE",
|
|
448
|
+
FIRST_GAME_BADGE: "FIRST_GAME_BADGE",
|
|
449
|
+
COMMON_SWORD: "COMMON_SWORD",
|
|
450
|
+
SMALL_HEALTH_POTION: "SMALL_HEALTH_POTION",
|
|
451
|
+
SMALL_BACKPACK: "SMALL_BACKPACK"
|
|
452
|
+
};
|
|
453
|
+
CURRENCIES = {
|
|
454
|
+
PRIMARY: ITEM_INTERNAL_NAMES.PLAYCADEMY_CREDITS,
|
|
455
|
+
XP: ITEM_INTERNAL_NAMES.PLAYCADEMY_XP
|
|
456
|
+
};
|
|
457
|
+
BADGES = {
|
|
458
|
+
FOUNDING_MEMBER: ITEM_INTERNAL_NAMES.FOUNDING_MEMBER_BADGE,
|
|
459
|
+
EARLY_ADOPTER: ITEM_INTERNAL_NAMES.EARLY_ADOPTER_BADGE,
|
|
460
|
+
FIRST_GAME: ITEM_INTERNAL_NAMES.FIRST_GAME_BADGE
|
|
461
|
+
};
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
// src/core/namespaces/credits.ts
|
|
465
|
+
function createCreditsNamespace(client) {
|
|
466
|
+
let cachedCreditsItemId = null;
|
|
467
|
+
const getCreditsItemId = async () => {
|
|
468
|
+
if (cachedCreditsItemId) {
|
|
469
|
+
return cachedCreditsItemId;
|
|
470
|
+
}
|
|
471
|
+
const items = await client.admin.items.list();
|
|
472
|
+
const creditsItem = items.find((item) => item.internalName === CURRENCIES.PRIMARY);
|
|
473
|
+
if (!creditsItem) {
|
|
474
|
+
throw new Error("Playcademy Credits item not found in catalog");
|
|
475
|
+
}
|
|
476
|
+
cachedCreditsItemId = creditsItem.id;
|
|
477
|
+
return creditsItem.id;
|
|
478
|
+
};
|
|
479
|
+
return {
|
|
480
|
+
balance: async () => {
|
|
481
|
+
const inventory = await client.users.inventory.get();
|
|
482
|
+
const creditsItem = inventory.find((item) => item.item?.internalName === CURRENCIES.PRIMARY);
|
|
483
|
+
return creditsItem?.quantity ?? 0;
|
|
484
|
+
},
|
|
485
|
+
add: async (amount) => {
|
|
486
|
+
if (amount <= 0) {
|
|
487
|
+
throw new Error("Amount must be positive");
|
|
488
|
+
}
|
|
489
|
+
const creditsItemId = await getCreditsItemId();
|
|
490
|
+
const result = await client.users.inventory.add(creditsItemId, amount);
|
|
491
|
+
client["emit"]("inventoryChange", {
|
|
492
|
+
itemId: creditsItemId,
|
|
493
|
+
delta: amount,
|
|
494
|
+
newTotal: result.newTotal
|
|
495
|
+
});
|
|
496
|
+
return result.newTotal;
|
|
497
|
+
},
|
|
498
|
+
spend: async (amount) => {
|
|
499
|
+
if (amount <= 0) {
|
|
500
|
+
throw new Error("Amount must be positive");
|
|
501
|
+
}
|
|
502
|
+
const creditsItemId = await getCreditsItemId();
|
|
503
|
+
const result = await client.users.inventory.remove(creditsItemId, amount);
|
|
504
|
+
client["emit"]("inventoryChange", {
|
|
505
|
+
itemId: creditsItemId,
|
|
506
|
+
delta: -amount,
|
|
507
|
+
newTotal: result.newTotal
|
|
508
|
+
});
|
|
509
|
+
return result.newTotal;
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
var init_credits = __esm(() => {
|
|
514
|
+
init_constants();
|
|
515
|
+
});
|
|
516
|
+
|
|
371
517
|
// src/core/namespaces/index.ts
|
|
372
518
|
var init_namespaces = __esm(() => {
|
|
373
519
|
init_runtime();
|
|
374
520
|
init_games();
|
|
521
|
+
init_credits();
|
|
375
522
|
});
|
|
376
523
|
|
|
377
524
|
// src/core/static/init.ts
|
|
@@ -568,7 +715,9 @@ var init_client = __esm(() => {
|
|
|
568
715
|
maps = createMapsNamespace(this);
|
|
569
716
|
admin = createAdminNamespace(this);
|
|
570
717
|
shop = createShopNamespace(this);
|
|
718
|
+
levels = createLevelsNamespace(this);
|
|
571
719
|
telemetry = createTelemetryNamespace(this);
|
|
720
|
+
credits = createCreditsNamespace(this);
|
|
572
721
|
static init = init;
|
|
573
722
|
static login = login;
|
|
574
723
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { User, InventoryItemWithItem, Game, DeveloperKey, DeveloperStatusResponse, MapElement, Item, InsertItem, ManifestV1, UpdateItem, Currency, InsertCurrency, UpdateCurrency, ShopListing, InsertShopListing, UpdateShopListing } from '@playcademy/types';
|
|
1
|
+
import type { User, InventoryItemWithItem, Game, DeveloperKey, DeveloperStatusResponse, MapElement, Item, InsertItem, ManifestV1, UpdateItem, Currency, InsertCurrency, UpdateCurrency, ShopListing, InsertShopListing, UpdateShopListing, UserLevel, LevelConfig, XPAddResult, UserLevelWithConfig, XPActionInput } from '@playcademy/types';
|
|
2
|
+
export { ITEM_INTERNAL_NAMES, CURRENCIES, BADGES, } from '@playcademy/data/constants';
|
|
2
3
|
export interface ClientConfig {
|
|
3
4
|
baseUrl: string;
|
|
4
5
|
token?: string;
|
|
@@ -13,6 +14,16 @@ export interface ClientEvents {
|
|
|
13
14
|
delta: number;
|
|
14
15
|
newTotal: number;
|
|
15
16
|
};
|
|
17
|
+
levelUp: {
|
|
18
|
+
oldLevel: number;
|
|
19
|
+
newLevel: number;
|
|
20
|
+
creditsAwarded: number;
|
|
21
|
+
};
|
|
22
|
+
xpGained: {
|
|
23
|
+
amount: number;
|
|
24
|
+
totalXP: number;
|
|
25
|
+
leveledUp: boolean;
|
|
26
|
+
};
|
|
16
27
|
}
|
|
17
28
|
export type GameContextPayload = {
|
|
18
29
|
token: string;
|
|
@@ -68,4 +79,4 @@ export interface ShopViewResponse {
|
|
|
68
79
|
shopItems: ShopDisplayItem[];
|
|
69
80
|
currencies: CurrencyInfo[];
|
|
70
81
|
}
|
|
71
|
-
export type { User, InventoryItemWithItem, Game, ManifestV1, DeveloperKey, DeveloperStatusResponse, MapElement, Item, InsertItem, UpdateItem, Currency, InsertCurrency, UpdateCurrency, ShopListing, InsertShopListing, UpdateShopListing, };
|
|
82
|
+
export type { User, InventoryItemWithItem, Game, ManifestV1, DeveloperKey, DeveloperStatusResponse, MapElement, Item, InsertItem, UpdateItem, Currency, InsertCurrency, UpdateCurrency, ShopListing, InsertShopListing, UpdateShopListing, UserLevel, LevelConfig, XPAddResult, UserLevelWithConfig, XPActionInput, };
|
package/dist/types.js
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, {
|
|
5
|
+
get: all[name],
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
set: (newValue) => all[name] = () => newValue
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
12
|
+
|
|
13
|
+
// ../data/src/constants.ts
|
|
14
|
+
var ITEM_INTERNAL_NAMES, CURRENCIES, BADGES;
|
|
15
|
+
var init_constants = __esm(() => {
|
|
16
|
+
ITEM_INTERNAL_NAMES = {
|
|
17
|
+
PLAYCADEMY_CREDITS: "PLAYCADEMY_CREDITS",
|
|
18
|
+
PLAYCADEMY_XP: "PLAYCADEMY_XP",
|
|
19
|
+
FOUNDING_MEMBER_BADGE: "FOUNDING_MEMBER_BADGE",
|
|
20
|
+
EARLY_ADOPTER_BADGE: "EARLY_ADOPTER_BADGE",
|
|
21
|
+
FIRST_GAME_BADGE: "FIRST_GAME_BADGE",
|
|
22
|
+
COMMON_SWORD: "COMMON_SWORD",
|
|
23
|
+
SMALL_HEALTH_POTION: "SMALL_HEALTH_POTION",
|
|
24
|
+
SMALL_BACKPACK: "SMALL_BACKPACK"
|
|
25
|
+
};
|
|
26
|
+
CURRENCIES = {
|
|
27
|
+
PRIMARY: ITEM_INTERNAL_NAMES.PLAYCADEMY_CREDITS,
|
|
28
|
+
XP: ITEM_INTERNAL_NAMES.PLAYCADEMY_XP
|
|
29
|
+
};
|
|
30
|
+
BADGES = {
|
|
31
|
+
FOUNDING_MEMBER: ITEM_INTERNAL_NAMES.FOUNDING_MEMBER_BADGE,
|
|
32
|
+
EARLY_ADOPTER: ITEM_INTERNAL_NAMES.EARLY_ADOPTER_BADGE,
|
|
33
|
+
FIRST_GAME: ITEM_INTERNAL_NAMES.FIRST_GAME_BADGE
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// src/types.ts
|
|
38
|
+
init_constants();
|
|
39
|
+
export {
|
|
40
|
+
ITEM_INTERNAL_NAMES,
|
|
41
|
+
CURRENCIES,
|
|
42
|
+
BADGES
|
|
43
|
+
};
|