@playcademy/sdk 0.2.2 → 0.2.3
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 +300 -339
- package/dist/index.js +186 -29
- package/dist/internal.d.ts +2989 -2224
- package/dist/internal.js +218 -64
- package/dist/server.d.ts +298 -39
- package/dist/server.js +104 -8
- package/dist/types.d.ts +2134 -563
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -241,6 +241,7 @@ var detectOutputFormat = () => {
|
|
|
241
241
|
};
|
|
242
242
|
var colors = {
|
|
243
243
|
reset: "\x1B[0m",
|
|
244
|
+
bold: "\x1B[1m",
|
|
244
245
|
dim: "\x1B[2m",
|
|
245
246
|
red: "\x1B[31m",
|
|
246
247
|
yellow: "\x1B[33m",
|
|
@@ -262,44 +263,48 @@ var getLevelColor = (level) => {
|
|
|
262
263
|
return colors.reset;
|
|
263
264
|
}
|
|
264
265
|
};
|
|
265
|
-
var formatBrowserOutput = (level, message, context) => {
|
|
266
|
+
var formatBrowserOutput = (level, message, context, scope) => {
|
|
266
267
|
const timestamp = new Date().toISOString();
|
|
267
268
|
const levelUpper = level.toUpperCase();
|
|
268
269
|
const consoleMethod = getConsoleMethod(level);
|
|
270
|
+
const scopePrefix = scope ? `[${scope}] ` : "";
|
|
269
271
|
if (context && Object.keys(context).length > 0) {
|
|
270
|
-
consoleMethod(`[${timestamp}] ${levelUpper}`, message
|
|
272
|
+
consoleMethod(`[${timestamp}] ${levelUpper}`, `${scopePrefix}${message}`, context);
|
|
271
273
|
} else {
|
|
272
|
-
consoleMethod(`[${timestamp}] ${levelUpper}`, message);
|
|
274
|
+
consoleMethod(`[${timestamp}] ${levelUpper}`, `${scopePrefix}${message}`);
|
|
273
275
|
}
|
|
274
276
|
};
|
|
275
|
-
var formatColorTTY = (level, message, context) => {
|
|
277
|
+
var formatColorTTY = (level, message, context, scope) => {
|
|
276
278
|
const timestamp = new Date().toISOString();
|
|
277
279
|
const levelColor = getLevelColor(level);
|
|
278
280
|
const levelUpper = level.toUpperCase().padEnd(5);
|
|
279
281
|
const consoleMethod = getConsoleMethod(level);
|
|
280
282
|
const coloredPrefix = `${colors.dim}[${timestamp}]${colors.reset} ${levelColor}${levelUpper}${colors.reset}`;
|
|
283
|
+
const scopePrefix = scope ? `${colors.bold}[${scope}]${colors.reset} ` : "";
|
|
281
284
|
if (context && Object.keys(context).length > 0) {
|
|
282
|
-
consoleMethod(`${coloredPrefix} ${message}`, context);
|
|
285
|
+
consoleMethod(`${coloredPrefix} ${scopePrefix}${message}`, context);
|
|
283
286
|
} else {
|
|
284
|
-
consoleMethod(`${coloredPrefix} ${message}`);
|
|
287
|
+
consoleMethod(`${coloredPrefix} ${scopePrefix}${message}`);
|
|
285
288
|
}
|
|
286
289
|
};
|
|
287
|
-
var formatJSONSingleLine = (level, message, context) => {
|
|
290
|
+
var formatJSONSingleLine = (level, message, context, scope) => {
|
|
288
291
|
const timestamp = new Date().toISOString();
|
|
289
292
|
const logEntry = {
|
|
290
293
|
timestamp,
|
|
291
294
|
level: level.toUpperCase(),
|
|
295
|
+
...scope && { scope },
|
|
292
296
|
message,
|
|
293
297
|
...context && Object.keys(context).length > 0 && { context }
|
|
294
298
|
};
|
|
295
299
|
const consoleMethod = getConsoleMethod(level);
|
|
296
300
|
consoleMethod(JSON.stringify(logEntry));
|
|
297
301
|
};
|
|
298
|
-
var formatJSONPretty = (level, message, context) => {
|
|
302
|
+
var formatJSONPretty = (level, message, context, scope) => {
|
|
299
303
|
const timestamp = new Date().toISOString();
|
|
300
304
|
const logEntry = {
|
|
301
305
|
timestamp,
|
|
302
306
|
level: level.toUpperCase(),
|
|
307
|
+
...scope && { scope },
|
|
303
308
|
message,
|
|
304
309
|
...context && Object.keys(context).length > 0 && { context }
|
|
305
310
|
};
|
|
@@ -340,36 +345,37 @@ var shouldLog = (level) => {
|
|
|
340
345
|
return levelPriority[level] >= levelPriority[minLevel];
|
|
341
346
|
};
|
|
342
347
|
var customHandler;
|
|
343
|
-
var performLog = (level, message, context) => {
|
|
348
|
+
var performLog = (level, message, context, scope) => {
|
|
344
349
|
if (!shouldLog(level))
|
|
345
350
|
return;
|
|
346
351
|
if (customHandler) {
|
|
347
|
-
customHandler(level, message, context);
|
|
352
|
+
customHandler(level, message, context, scope);
|
|
348
353
|
return;
|
|
349
354
|
}
|
|
350
355
|
const outputFormat = detectOutputFormat();
|
|
351
356
|
switch (outputFormat) {
|
|
352
357
|
case "browser":
|
|
353
|
-
formatBrowserOutput(level, message, context);
|
|
358
|
+
formatBrowserOutput(level, message, context, scope);
|
|
354
359
|
break;
|
|
355
360
|
case "color-tty":
|
|
356
|
-
formatColorTTY(level, message, context);
|
|
361
|
+
formatColorTTY(level, message, context, scope);
|
|
357
362
|
break;
|
|
358
363
|
case "json-single-line":
|
|
359
|
-
formatJSONSingleLine(level, message, context);
|
|
364
|
+
formatJSONSingleLine(level, message, context, scope);
|
|
360
365
|
break;
|
|
361
366
|
case "json-pretty":
|
|
362
|
-
formatJSONPretty(level, message, context);
|
|
367
|
+
formatJSONPretty(level, message, context, scope);
|
|
363
368
|
break;
|
|
364
369
|
}
|
|
365
370
|
};
|
|
366
|
-
var createLogger = () => {
|
|
371
|
+
var createLogger = (scopeName) => {
|
|
367
372
|
return {
|
|
368
|
-
debug: (message, context) => performLog("debug", message, context),
|
|
369
|
-
info: (message, context) => performLog("info", message, context),
|
|
370
|
-
warn: (message, context) => performLog("warn", message, context),
|
|
371
|
-
error: (message, context) => performLog("error", message, context),
|
|
372
|
-
log: performLog
|
|
373
|
+
debug: (message, context) => performLog("debug", message, context, scopeName),
|
|
374
|
+
info: (message, context) => performLog("info", message, context, scopeName),
|
|
375
|
+
warn: (message, context) => performLog("warn", message, context, scopeName),
|
|
376
|
+
error: (message, context) => performLog("error", message, context, scopeName),
|
|
377
|
+
log: (level, message, context) => performLog(level, message, context, scopeName),
|
|
378
|
+
scope: (name) => createLogger(scopeName ? `${scopeName}.${name}` : name)
|
|
373
379
|
};
|
|
374
380
|
};
|
|
375
381
|
var log = createLogger();
|
|
@@ -384,26 +390,87 @@ class PlaycademyError extends Error {
|
|
|
384
390
|
|
|
385
391
|
class ApiError extends Error {
|
|
386
392
|
status;
|
|
393
|
+
code;
|
|
387
394
|
details;
|
|
388
|
-
|
|
389
|
-
|
|
395
|
+
rawBody;
|
|
396
|
+
constructor(status, code, message, details, rawBody) {
|
|
397
|
+
super(message);
|
|
390
398
|
this.status = status;
|
|
399
|
+
this.name = "ApiError";
|
|
400
|
+
this.code = code;
|
|
391
401
|
this.details = details;
|
|
402
|
+
this.rawBody = rawBody;
|
|
392
403
|
Object.setPrototypeOf(this, ApiError.prototype);
|
|
393
404
|
}
|
|
405
|
+
static fromResponse(status, statusText, body) {
|
|
406
|
+
if (body && typeof body === "object" && "error" in body) {
|
|
407
|
+
const errorBody = body;
|
|
408
|
+
const err = errorBody.error;
|
|
409
|
+
if (err && typeof err === "object") {
|
|
410
|
+
return new ApiError(status, err.code ?? statusCodeToErrorCode(status), err.message ?? statusText, err.details, body);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return new ApiError(status, statusCodeToErrorCode(status), statusText, undefined, body);
|
|
414
|
+
}
|
|
415
|
+
is(code) {
|
|
416
|
+
return this.code === code;
|
|
417
|
+
}
|
|
418
|
+
isClientError() {
|
|
419
|
+
return this.status >= 400 && this.status < 500;
|
|
420
|
+
}
|
|
421
|
+
isServerError() {
|
|
422
|
+
return this.status >= 500;
|
|
423
|
+
}
|
|
424
|
+
isRetryable() {
|
|
425
|
+
return this.isServerError() || this.code === "TOO_MANY_REQUESTS" || this.code === "RATE_LIMITED" || this.code === "TIMEOUT";
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
function statusCodeToErrorCode(status) {
|
|
429
|
+
switch (status) {
|
|
430
|
+
case 400:
|
|
431
|
+
return "BAD_REQUEST";
|
|
432
|
+
case 401:
|
|
433
|
+
return "UNAUTHORIZED";
|
|
434
|
+
case 403:
|
|
435
|
+
return "FORBIDDEN";
|
|
436
|
+
case 404:
|
|
437
|
+
return "NOT_FOUND";
|
|
438
|
+
case 405:
|
|
439
|
+
return "METHOD_NOT_ALLOWED";
|
|
440
|
+
case 409:
|
|
441
|
+
return "CONFLICT";
|
|
442
|
+
case 410:
|
|
443
|
+
return "GONE";
|
|
444
|
+
case 412:
|
|
445
|
+
return "PRECONDITION_FAILED";
|
|
446
|
+
case 413:
|
|
447
|
+
return "PAYLOAD_TOO_LARGE";
|
|
448
|
+
case 422:
|
|
449
|
+
return "VALIDATION_FAILED";
|
|
450
|
+
case 429:
|
|
451
|
+
return "TOO_MANY_REQUESTS";
|
|
452
|
+
case 500:
|
|
453
|
+
return "INTERNAL_ERROR";
|
|
454
|
+
case 501:
|
|
455
|
+
return "NOT_IMPLEMENTED";
|
|
456
|
+
case 503:
|
|
457
|
+
return "SERVICE_UNAVAILABLE";
|
|
458
|
+
case 504:
|
|
459
|
+
return "TIMEOUT";
|
|
460
|
+
default:
|
|
461
|
+
return status >= 500 ? "INTERNAL_ERROR" : "BAD_REQUEST";
|
|
462
|
+
}
|
|
394
463
|
}
|
|
395
464
|
function extractApiErrorInfo(error) {
|
|
396
465
|
if (!(error instanceof ApiError)) {
|
|
397
466
|
return null;
|
|
398
467
|
}
|
|
399
|
-
|
|
468
|
+
return {
|
|
400
469
|
status: error.status,
|
|
401
|
-
|
|
470
|
+
code: error.code,
|
|
471
|
+
message: error.message,
|
|
472
|
+
...error.details !== undefined && { details: error.details }
|
|
402
473
|
};
|
|
403
|
-
if (error.details) {
|
|
404
|
-
info.details = error.details;
|
|
405
|
-
}
|
|
406
|
-
return info;
|
|
407
474
|
}
|
|
408
475
|
|
|
409
476
|
// src/core/static/login.ts
|
|
@@ -1030,6 +1097,96 @@ function createUsersNamespace(client) {
|
|
|
1030
1097
|
}
|
|
1031
1098
|
};
|
|
1032
1099
|
}
|
|
1100
|
+
// ../constants/src/achievements.ts
|
|
1101
|
+
var ACHIEVEMENT_IDS = {
|
|
1102
|
+
PLAY_ANY_GAME_DAILY: "play_any_game_daily",
|
|
1103
|
+
DAILY_CHEST_OPEN: "daily_chest_open",
|
|
1104
|
+
LEADERBOARD_TOP3_DAILY: "leaderboard_top3_daily",
|
|
1105
|
+
LEADERBOARD_TOP3_WEEKLY: "leaderboard_top3_weekly",
|
|
1106
|
+
FIRST_SCORE_ANY_GAME: "first_score_any_game",
|
|
1107
|
+
PERSONAL_BEST_ANY_GAME: "personal_best_any_game"
|
|
1108
|
+
};
|
|
1109
|
+
var ACHIEVEMENT_DEFINITIONS = [
|
|
1110
|
+
{
|
|
1111
|
+
id: ACHIEVEMENT_IDS.PLAY_ANY_GAME_DAILY,
|
|
1112
|
+
title: "Play any game",
|
|
1113
|
+
description: "Play any arcade game for at least 60 seconds in a single session.",
|
|
1114
|
+
scope: "daily",
|
|
1115
|
+
rewardCredits: 10,
|
|
1116
|
+
limit: 1,
|
|
1117
|
+
completionType: "time_played_session",
|
|
1118
|
+
completionConfig: { minSeconds: 60 },
|
|
1119
|
+
target: { anyArcadeGame: true },
|
|
1120
|
+
active: true
|
|
1121
|
+
},
|
|
1122
|
+
{
|
|
1123
|
+
id: ACHIEVEMENT_IDS.DAILY_CHEST_OPEN,
|
|
1124
|
+
title: "Opened the daily chest",
|
|
1125
|
+
description: "Find the chest on the map and open it to claim your reward.",
|
|
1126
|
+
scope: "daily",
|
|
1127
|
+
rewardCredits: 10,
|
|
1128
|
+
limit: 1,
|
|
1129
|
+
completionType: "interaction",
|
|
1130
|
+
completionConfig: { triggerId: "bunny_chest" },
|
|
1131
|
+
target: { map: "arcade" },
|
|
1132
|
+
active: true
|
|
1133
|
+
},
|
|
1134
|
+
{
|
|
1135
|
+
id: ACHIEVEMENT_IDS.LEADERBOARD_TOP3_DAILY,
|
|
1136
|
+
title: "Daily Champion",
|
|
1137
|
+
description: "Finish in the top 3 of any game leaderboard for the day.",
|
|
1138
|
+
scope: "daily",
|
|
1139
|
+
rewardCredits: 25,
|
|
1140
|
+
limit: 1,
|
|
1141
|
+
completionType: "leaderboard_rank",
|
|
1142
|
+
completionConfig: {
|
|
1143
|
+
rankRewards: [50, 30, 15]
|
|
1144
|
+
},
|
|
1145
|
+
target: { anyArcadeGame: true },
|
|
1146
|
+
active: true
|
|
1147
|
+
},
|
|
1148
|
+
{
|
|
1149
|
+
id: ACHIEVEMENT_IDS.LEADERBOARD_TOP3_WEEKLY,
|
|
1150
|
+
title: "Weekly Legend",
|
|
1151
|
+
description: "Finish in the top 3 of any game leaderboard for the week.",
|
|
1152
|
+
scope: "weekly",
|
|
1153
|
+
rewardCredits: 50,
|
|
1154
|
+
limit: 1,
|
|
1155
|
+
completionType: "leaderboard_rank",
|
|
1156
|
+
completionConfig: {
|
|
1157
|
+
rankRewards: [100, 60, 30]
|
|
1158
|
+
},
|
|
1159
|
+
target: { anyArcadeGame: true },
|
|
1160
|
+
active: true
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
id: ACHIEVEMENT_IDS.FIRST_SCORE_ANY_GAME,
|
|
1164
|
+
title: "First Score",
|
|
1165
|
+
description: "Submit your first score in any arcade game.",
|
|
1166
|
+
scope: "game",
|
|
1167
|
+
rewardCredits: 5,
|
|
1168
|
+
limit: 1,
|
|
1169
|
+
completionType: "first_score",
|
|
1170
|
+
completionConfig: {},
|
|
1171
|
+
target: { anyArcadeGame: true },
|
|
1172
|
+
active: true
|
|
1173
|
+
},
|
|
1174
|
+
{
|
|
1175
|
+
id: ACHIEVEMENT_IDS.PERSONAL_BEST_ANY_GAME,
|
|
1176
|
+
title: "Personal Best",
|
|
1177
|
+
description: "Beat your personal best score in any arcade game.",
|
|
1178
|
+
scope: "daily",
|
|
1179
|
+
rewardCredits: 5,
|
|
1180
|
+
limit: 3,
|
|
1181
|
+
completionType: "personal_best",
|
|
1182
|
+
completionConfig: {},
|
|
1183
|
+
target: { anyArcadeGame: true },
|
|
1184
|
+
active: true
|
|
1185
|
+
}
|
|
1186
|
+
];
|
|
1187
|
+
// ../constants/src/typescript.ts
|
|
1188
|
+
var TSC_PACKAGE = "@typescript/native-preview";
|
|
1189
|
+
var USE_NATIVE_TSC = TSC_PACKAGE.includes("native-preview");
|
|
1033
1190
|
// ../constants/src/overworld.ts
|
|
1034
1191
|
var ITEM_SLUGS = {
|
|
1035
1192
|
PLAYCADEMY_CREDITS: "PLAYCADEMY_CREDITS",
|
|
@@ -1702,7 +1859,7 @@ async function request({
|
|
|
1702
1859
|
const errorBody = await clonedRes.json().catch(() => clonedRes.text().catch(() => {
|
|
1703
1860
|
return;
|
|
1704
1861
|
})) ?? undefined;
|
|
1705
|
-
throw
|
|
1862
|
+
throw ApiError.fromResponse(res.status, res.statusText, errorBody);
|
|
1706
1863
|
}
|
|
1707
1864
|
if (res.status === 204)
|
|
1708
1865
|
return;
|