@playcademy/better-auth 0.0.4 → 0.0.5-beta.2
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/server.js +201 -178
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -15178,10 +15178,203 @@ var defuReplaceArrays = createDefu((obj, key, value) => {
|
|
|
15178
15178
|
}
|
|
15179
15179
|
});
|
|
15180
15180
|
// ../sdk/dist/server.js
|
|
15181
|
-
import { resolve as resolve2 } from "path";
|
|
15182
15181
|
import { existsSync, readdirSync, statSync } from "fs";
|
|
15183
15182
|
import { readFile } from "fs/promises";
|
|
15184
15183
|
import { dirname, parse as parse5, resolve } from "path";
|
|
15184
|
+
import { resolve as resolve2 } from "path";
|
|
15185
|
+
var __defProp4 = Object.defineProperty;
|
|
15186
|
+
var __export3 = (target, all) => {
|
|
15187
|
+
for (var name in all)
|
|
15188
|
+
__defProp4(target, name, {
|
|
15189
|
+
get: all[name],
|
|
15190
|
+
enumerable: true,
|
|
15191
|
+
configurable: true,
|
|
15192
|
+
set: (newValue) => all[name] = () => newValue
|
|
15193
|
+
});
|
|
15194
|
+
};
|
|
15195
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
15196
|
+
function findFilePath(filename, startDir, maxLevels = 3) {
|
|
15197
|
+
const filenames = Array.isArray(filename) ? filename : [filename];
|
|
15198
|
+
let currentDir = resolve(startDir);
|
|
15199
|
+
let levelsSearched = 0;
|
|
15200
|
+
while (levelsSearched <= maxLevels) {
|
|
15201
|
+
for (const fname of filenames) {
|
|
15202
|
+
const filePath = resolve(currentDir, fname);
|
|
15203
|
+
if (existsSync(filePath)) {
|
|
15204
|
+
return {
|
|
15205
|
+
path: filePath,
|
|
15206
|
+
dir: currentDir,
|
|
15207
|
+
filename: fname
|
|
15208
|
+
};
|
|
15209
|
+
}
|
|
15210
|
+
}
|
|
15211
|
+
if (levelsSearched >= maxLevels) {
|
|
15212
|
+
break;
|
|
15213
|
+
}
|
|
15214
|
+
const parentDir = dirname(currentDir);
|
|
15215
|
+
if (parentDir === currentDir) {
|
|
15216
|
+
break;
|
|
15217
|
+
}
|
|
15218
|
+
const parsed = parse5(currentDir);
|
|
15219
|
+
if (parsed.root === currentDir) {
|
|
15220
|
+
break;
|
|
15221
|
+
}
|
|
15222
|
+
currentDir = parentDir;
|
|
15223
|
+
levelsSearched++;
|
|
15224
|
+
}
|
|
15225
|
+
return null;
|
|
15226
|
+
}
|
|
15227
|
+
async function loadFile(filename, options = {}) {
|
|
15228
|
+
const {
|
|
15229
|
+
cwd = process.cwd(),
|
|
15230
|
+
required: required3 = false,
|
|
15231
|
+
searchUp = false,
|
|
15232
|
+
maxLevels = 3,
|
|
15233
|
+
parseJson = false,
|
|
15234
|
+
stripComments = false
|
|
15235
|
+
} = options;
|
|
15236
|
+
let fileResult;
|
|
15237
|
+
if (searchUp) {
|
|
15238
|
+
fileResult = findFilePath(filename, cwd, maxLevels);
|
|
15239
|
+
} else {
|
|
15240
|
+
const filenames = Array.isArray(filename) ? filename : [filename];
|
|
15241
|
+
fileResult = null;
|
|
15242
|
+
for (const fname of filenames) {
|
|
15243
|
+
const filePath = resolve(cwd, fname);
|
|
15244
|
+
if (existsSync(filePath)) {
|
|
15245
|
+
fileResult = {
|
|
15246
|
+
path: filePath,
|
|
15247
|
+
dir: cwd,
|
|
15248
|
+
filename: fname
|
|
15249
|
+
};
|
|
15250
|
+
break;
|
|
15251
|
+
}
|
|
15252
|
+
}
|
|
15253
|
+
}
|
|
15254
|
+
if (!fileResult) {
|
|
15255
|
+
if (required3) {
|
|
15256
|
+
const fileList = Array.isArray(filename) ? filename.join(" or ") : filename;
|
|
15257
|
+
const message2 = searchUp ? `${fileList} not found in ${cwd} or up to ${maxLevels} parent directories` : `${fileList} not found at ${cwd}`;
|
|
15258
|
+
throw new Error(message2);
|
|
15259
|
+
}
|
|
15260
|
+
return null;
|
|
15261
|
+
}
|
|
15262
|
+
try {
|
|
15263
|
+
let content = await readFile(fileResult.path, "utf8");
|
|
15264
|
+
if (parseJson) {
|
|
15265
|
+
if (stripComments) {
|
|
15266
|
+
content = stripJsonComments(content);
|
|
15267
|
+
}
|
|
15268
|
+
return JSON.parse(content);
|
|
15269
|
+
}
|
|
15270
|
+
return content;
|
|
15271
|
+
} catch (error3) {
|
|
15272
|
+
throw new Error(`Failed to load ${fileResult.filename} from ${fileResult.path}: ${error3 instanceof Error ? error3.message : String(error3)}`, { cause: error3 });
|
|
15273
|
+
}
|
|
15274
|
+
}
|
|
15275
|
+
async function findFile(filename, options = {}) {
|
|
15276
|
+
const { cwd = process.cwd(), searchUp = false, maxLevels = 3 } = options;
|
|
15277
|
+
if (searchUp) {
|
|
15278
|
+
return findFilePath(filename, cwd, maxLevels);
|
|
15279
|
+
}
|
|
15280
|
+
const filenames = Array.isArray(filename) ? filename : [filename];
|
|
15281
|
+
for (const fname of filenames) {
|
|
15282
|
+
const filePath = resolve(cwd, fname);
|
|
15283
|
+
if (existsSync(filePath)) {
|
|
15284
|
+
return {
|
|
15285
|
+
path: filePath,
|
|
15286
|
+
dir: cwd,
|
|
15287
|
+
filename: fname
|
|
15288
|
+
};
|
|
15289
|
+
}
|
|
15290
|
+
}
|
|
15291
|
+
return null;
|
|
15292
|
+
}
|
|
15293
|
+
function stripJsonComments(jsonc) {
|
|
15294
|
+
let result = jsonc.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
15295
|
+
result = result.replace(/\/\/.*/g, "");
|
|
15296
|
+
return result;
|
|
15297
|
+
}
|
|
15298
|
+
var init_file_loader = () => {};
|
|
15299
|
+
var exports_config_loader = {};
|
|
15300
|
+
__export3(exports_config_loader, {
|
|
15301
|
+
loadConfig: () => loadConfig,
|
|
15302
|
+
findConfigPath: () => findConfigPath
|
|
15303
|
+
});
|
|
15304
|
+
async function findConfigPath(configPath) {
|
|
15305
|
+
if (configPath) {
|
|
15306
|
+
return resolve2(configPath);
|
|
15307
|
+
}
|
|
15308
|
+
const result = await findFile(["playcademy.config.js", "playcademy.config.mjs", "playcademy.config.json"], {
|
|
15309
|
+
searchUp: true,
|
|
15310
|
+
maxLevels: 3
|
|
15311
|
+
});
|
|
15312
|
+
if (!result) {
|
|
15313
|
+
throw new Error("playcademy.config.js not found. Please create a playcademy.config.js file or specify the config path.");
|
|
15314
|
+
}
|
|
15315
|
+
return result.path;
|
|
15316
|
+
}
|
|
15317
|
+
async function loadConfig(configPath) {
|
|
15318
|
+
try {
|
|
15319
|
+
let config2;
|
|
15320
|
+
let actualPath;
|
|
15321
|
+
if (configPath) {
|
|
15322
|
+
actualPath = resolve2(configPath);
|
|
15323
|
+
if (actualPath.endsWith(".json")) {
|
|
15324
|
+
config2 = await loadFile(actualPath, { required: true, parseJson: true });
|
|
15325
|
+
} else {
|
|
15326
|
+
const module = await import(actualPath);
|
|
15327
|
+
config2 = module.default || module;
|
|
15328
|
+
}
|
|
15329
|
+
} else {
|
|
15330
|
+
actualPath = await findConfigPath();
|
|
15331
|
+
if (actualPath.endsWith(".json")) {
|
|
15332
|
+
config2 = await loadFile(actualPath, { required: true, parseJson: true });
|
|
15333
|
+
} else {
|
|
15334
|
+
const module = await import(actualPath);
|
|
15335
|
+
config2 = module.default || module;
|
|
15336
|
+
}
|
|
15337
|
+
}
|
|
15338
|
+
if (!config2 || typeof config2 !== "object") {
|
|
15339
|
+
throw new Error("Config file must export/contain an object");
|
|
15340
|
+
}
|
|
15341
|
+
validateConfig(config2);
|
|
15342
|
+
return config2;
|
|
15343
|
+
} catch (error3) {
|
|
15344
|
+
throw new Error(`Failed to load config file: ${error3 instanceof Error ? error3.message : String(error3)}`, { cause: error3 });
|
|
15345
|
+
}
|
|
15346
|
+
}
|
|
15347
|
+
function validateConfig(config2) {
|
|
15348
|
+
if (!config2 || typeof config2 !== "object") {
|
|
15349
|
+
throw new Error("Configuration must be an object");
|
|
15350
|
+
}
|
|
15351
|
+
const cfg = config2;
|
|
15352
|
+
if (!cfg.name || typeof cfg.name !== "string") {
|
|
15353
|
+
throw new Error("Missing required field: name");
|
|
15354
|
+
}
|
|
15355
|
+
if (cfg.timeback) {
|
|
15356
|
+
if (typeof cfg.timeback !== "object") {
|
|
15357
|
+
throw new Error("timeback must be an object if provided");
|
|
15358
|
+
}
|
|
15359
|
+
const tb = cfg.timeback;
|
|
15360
|
+
if (!tb.course) {
|
|
15361
|
+
throw new Error("timeback.course is required for TimeBack integration");
|
|
15362
|
+
}
|
|
15363
|
+
if (typeof tb.course !== "object") {
|
|
15364
|
+
throw new Error("timeback.course must be an object");
|
|
15365
|
+
}
|
|
15366
|
+
const course = tb.course;
|
|
15367
|
+
if (!course.subjects || !Array.isArray(course.subjects) || course.subjects.length === 0) {
|
|
15368
|
+
throw new Error("timeback.course.subjects is required (array of subjects)");
|
|
15369
|
+
}
|
|
15370
|
+
if (!course.grades || !Array.isArray(course.grades) || course.grades.length === 0) {
|
|
15371
|
+
throw new Error("timeback.course.grades is required (array of grade levels)");
|
|
15372
|
+
}
|
|
15373
|
+
}
|
|
15374
|
+
}
|
|
15375
|
+
var init_config_loader = __esm(() => {
|
|
15376
|
+
init_file_loader();
|
|
15377
|
+
});
|
|
15185
15378
|
var VALID_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
|
15186
15379
|
var VALID_SUBJECTS = [
|
|
15187
15380
|
"Reading",
|
|
@@ -15371,179 +15564,6 @@ async function makeApiRequest(baseUrl, apiToken, endpoint, method = "GET", body)
|
|
|
15371
15564
|
}
|
|
15372
15565
|
return await response.json();
|
|
15373
15566
|
}
|
|
15374
|
-
function findFilePath(filename, startDir, maxLevels = 3) {
|
|
15375
|
-
const filenames = Array.isArray(filename) ? filename : [filename];
|
|
15376
|
-
let currentDir = resolve(startDir);
|
|
15377
|
-
let levelsSearched = 0;
|
|
15378
|
-
while (levelsSearched <= maxLevels) {
|
|
15379
|
-
for (const fname of filenames) {
|
|
15380
|
-
const filePath = resolve(currentDir, fname);
|
|
15381
|
-
if (existsSync(filePath)) {
|
|
15382
|
-
return {
|
|
15383
|
-
path: filePath,
|
|
15384
|
-
dir: currentDir,
|
|
15385
|
-
filename: fname
|
|
15386
|
-
};
|
|
15387
|
-
}
|
|
15388
|
-
}
|
|
15389
|
-
if (levelsSearched >= maxLevels) {
|
|
15390
|
-
break;
|
|
15391
|
-
}
|
|
15392
|
-
const parentDir = dirname(currentDir);
|
|
15393
|
-
if (parentDir === currentDir) {
|
|
15394
|
-
break;
|
|
15395
|
-
}
|
|
15396
|
-
const parsed = parse5(currentDir);
|
|
15397
|
-
if (parsed.root === currentDir) {
|
|
15398
|
-
break;
|
|
15399
|
-
}
|
|
15400
|
-
currentDir = parentDir;
|
|
15401
|
-
levelsSearched++;
|
|
15402
|
-
}
|
|
15403
|
-
return null;
|
|
15404
|
-
}
|
|
15405
|
-
async function loadFile(filename, options = {}) {
|
|
15406
|
-
const {
|
|
15407
|
-
cwd = process.cwd(),
|
|
15408
|
-
required: required3 = false,
|
|
15409
|
-
searchUp = false,
|
|
15410
|
-
maxLevels = 3,
|
|
15411
|
-
parseJson = false,
|
|
15412
|
-
stripComments = false
|
|
15413
|
-
} = options;
|
|
15414
|
-
let fileResult;
|
|
15415
|
-
if (searchUp) {
|
|
15416
|
-
fileResult = findFilePath(filename, cwd, maxLevels);
|
|
15417
|
-
} else {
|
|
15418
|
-
const filenames = Array.isArray(filename) ? filename : [filename];
|
|
15419
|
-
fileResult = null;
|
|
15420
|
-
for (const fname of filenames) {
|
|
15421
|
-
const filePath = resolve(cwd, fname);
|
|
15422
|
-
if (existsSync(filePath)) {
|
|
15423
|
-
fileResult = {
|
|
15424
|
-
path: filePath,
|
|
15425
|
-
dir: cwd,
|
|
15426
|
-
filename: fname
|
|
15427
|
-
};
|
|
15428
|
-
break;
|
|
15429
|
-
}
|
|
15430
|
-
}
|
|
15431
|
-
}
|
|
15432
|
-
if (!fileResult) {
|
|
15433
|
-
if (required3) {
|
|
15434
|
-
const fileList = Array.isArray(filename) ? filename.join(" or ") : filename;
|
|
15435
|
-
const message2 = searchUp ? `${fileList} not found in ${cwd} or up to ${maxLevels} parent directories` : `${fileList} not found at ${cwd}`;
|
|
15436
|
-
throw new Error(message2);
|
|
15437
|
-
}
|
|
15438
|
-
return null;
|
|
15439
|
-
}
|
|
15440
|
-
try {
|
|
15441
|
-
let content = await readFile(fileResult.path, "utf8");
|
|
15442
|
-
if (parseJson) {
|
|
15443
|
-
if (stripComments) {
|
|
15444
|
-
content = stripJsonComments(content);
|
|
15445
|
-
}
|
|
15446
|
-
return JSON.parse(content);
|
|
15447
|
-
}
|
|
15448
|
-
return content;
|
|
15449
|
-
} catch (error3) {
|
|
15450
|
-
throw new Error(`Failed to load ${fileResult.filename} from ${fileResult.path}: ${error3 instanceof Error ? error3.message : String(error3)}`, { cause: error3 });
|
|
15451
|
-
}
|
|
15452
|
-
}
|
|
15453
|
-
async function findFile(filename, options = {}) {
|
|
15454
|
-
const { cwd = process.cwd(), searchUp = false, maxLevels = 3 } = options;
|
|
15455
|
-
if (searchUp) {
|
|
15456
|
-
return findFilePath(filename, cwd, maxLevels);
|
|
15457
|
-
}
|
|
15458
|
-
const filenames = Array.isArray(filename) ? filename : [filename];
|
|
15459
|
-
for (const fname of filenames) {
|
|
15460
|
-
const filePath = resolve(cwd, fname);
|
|
15461
|
-
if (existsSync(filePath)) {
|
|
15462
|
-
return {
|
|
15463
|
-
path: filePath,
|
|
15464
|
-
dir: cwd,
|
|
15465
|
-
filename: fname
|
|
15466
|
-
};
|
|
15467
|
-
}
|
|
15468
|
-
}
|
|
15469
|
-
return null;
|
|
15470
|
-
}
|
|
15471
|
-
function stripJsonComments(jsonc) {
|
|
15472
|
-
let result = jsonc.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
15473
|
-
result = result.replace(/\/\/.*/g, "");
|
|
15474
|
-
return result;
|
|
15475
|
-
}
|
|
15476
|
-
async function findConfigPath(configPath) {
|
|
15477
|
-
if (configPath) {
|
|
15478
|
-
return resolve2(configPath);
|
|
15479
|
-
}
|
|
15480
|
-
const result = await findFile(["playcademy.config.js", "playcademy.config.mjs", "playcademy.config.json"], {
|
|
15481
|
-
searchUp: true,
|
|
15482
|
-
maxLevels: 3
|
|
15483
|
-
});
|
|
15484
|
-
if (!result) {
|
|
15485
|
-
throw new Error("playcademy.config.js not found. Please create a playcademy.config.js file or specify the config path.");
|
|
15486
|
-
}
|
|
15487
|
-
return result.path;
|
|
15488
|
-
}
|
|
15489
|
-
async function loadConfig(configPath) {
|
|
15490
|
-
try {
|
|
15491
|
-
let config2;
|
|
15492
|
-
let actualPath;
|
|
15493
|
-
if (configPath) {
|
|
15494
|
-
actualPath = resolve2(configPath);
|
|
15495
|
-
if (actualPath.endsWith(".json")) {
|
|
15496
|
-
config2 = await loadFile(actualPath, { required: true, parseJson: true });
|
|
15497
|
-
} else {
|
|
15498
|
-
const module = await import(actualPath);
|
|
15499
|
-
config2 = module.default || module;
|
|
15500
|
-
}
|
|
15501
|
-
} else {
|
|
15502
|
-
actualPath = await findConfigPath();
|
|
15503
|
-
if (actualPath.endsWith(".json")) {
|
|
15504
|
-
config2 = await loadFile(actualPath, { required: true, parseJson: true });
|
|
15505
|
-
} else {
|
|
15506
|
-
const module = await import(actualPath);
|
|
15507
|
-
config2 = module.default || module;
|
|
15508
|
-
}
|
|
15509
|
-
}
|
|
15510
|
-
if (!config2 || typeof config2 !== "object") {
|
|
15511
|
-
throw new Error("Config file must export/contain an object");
|
|
15512
|
-
}
|
|
15513
|
-
validateConfig(config2);
|
|
15514
|
-
return config2;
|
|
15515
|
-
} catch (error3) {
|
|
15516
|
-
throw new Error(`Failed to load config file: ${error3 instanceof Error ? error3.message : String(error3)}`, { cause: error3 });
|
|
15517
|
-
}
|
|
15518
|
-
}
|
|
15519
|
-
function validateConfig(config2) {
|
|
15520
|
-
if (!config2 || typeof config2 !== "object") {
|
|
15521
|
-
throw new Error("Configuration must be an object");
|
|
15522
|
-
}
|
|
15523
|
-
const cfg = config2;
|
|
15524
|
-
if (!cfg.name || typeof cfg.name !== "string") {
|
|
15525
|
-
throw new Error("Missing required field: name");
|
|
15526
|
-
}
|
|
15527
|
-
if (cfg.timeback) {
|
|
15528
|
-
if (typeof cfg.timeback !== "object") {
|
|
15529
|
-
throw new Error("timeback must be an object if provided");
|
|
15530
|
-
}
|
|
15531
|
-
const tb = cfg.timeback;
|
|
15532
|
-
if (!tb.course) {
|
|
15533
|
-
throw new Error("timeback.course is required for TimeBack integration");
|
|
15534
|
-
}
|
|
15535
|
-
if (typeof tb.course !== "object") {
|
|
15536
|
-
throw new Error("timeback.course must be an object");
|
|
15537
|
-
}
|
|
15538
|
-
const course = tb.course;
|
|
15539
|
-
if (!course.subjects || !Array.isArray(course.subjects) || course.subjects.length === 0) {
|
|
15540
|
-
throw new Error("timeback.course.subjects is required (array of subjects)");
|
|
15541
|
-
}
|
|
15542
|
-
if (!course.grades || !Array.isArray(course.grades) || course.grades.length === 0) {
|
|
15543
|
-
throw new Error("timeback.course.grades is required (array of grade levels)");
|
|
15544
|
-
}
|
|
15545
|
-
}
|
|
15546
|
-
}
|
|
15547
15567
|
|
|
15548
15568
|
class PlaycademyClient {
|
|
15549
15569
|
state;
|
|
@@ -15551,17 +15571,20 @@ class PlaycademyClient {
|
|
|
15551
15571
|
this.state = state;
|
|
15552
15572
|
}
|
|
15553
15573
|
static async init(config2) {
|
|
15554
|
-
const { apiKey,
|
|
15574
|
+
const { apiKey, baseUrl, gameId } = config2;
|
|
15555
15575
|
if (!apiKey || typeof apiKey !== "string") {
|
|
15556
15576
|
throw new Error("[Playcademy SDK] apiKey is required");
|
|
15557
15577
|
}
|
|
15558
|
-
|
|
15559
|
-
|
|
15578
|
+
if (!config2.config) {
|
|
15579
|
+
throw new Error("[Playcademy SDK] config is required in edge environments. Pass config directly, or use PlaycademyClient from @playcademy/sdk/server for filesystem-based config loading.");
|
|
15580
|
+
}
|
|
15581
|
+
const envBaseUrl = typeof process !== "undefined" ? process.env?.PLAYCADEMY_BASE_URL : undefined;
|
|
15582
|
+
const finalBaseUrl = baseUrl || envBaseUrl || "https://hub.playcademy.net";
|
|
15560
15583
|
const state = {
|
|
15561
15584
|
apiKey,
|
|
15562
15585
|
baseUrl: finalBaseUrl,
|
|
15563
15586
|
gameId: gameId || "",
|
|
15564
|
-
config:
|
|
15587
|
+
config: config2.config
|
|
15565
15588
|
};
|
|
15566
15589
|
const client = new PlaycademyClient(state);
|
|
15567
15590
|
if (!gameId) {
|