@playcademy/sandbox 0.3.4 → 0.3.5
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 +11 -11
- package/dist/cli.js +32 -8
- package/dist/config.d.ts +9 -1
- package/dist/config.js +3 -0
- package/dist/mocks/timeback.d.ts +1 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.js +12 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -199,17 +199,17 @@ bunx @playcademy/sandbox \
|
|
|
199
199
|
--timeback-student-id your-student-sourcedId
|
|
200
200
|
```
|
|
201
201
|
|
|
202
|
-
| Option | Description
|
|
203
|
-
| :------------------------------- |
|
|
204
|
-
| `--timeback-local` | Enable local TimeBack mode (Docker)
|
|
205
|
-
| `--timeback-oneroster-url <url>` | OneRoster API URL
|
|
206
|
-
| `--timeback-caliper-url <url>` | Caliper API URL
|
|
207
|
-
| `--timeback-course-id <id>` | Course ID for enrollments
|
|
208
|
-
| `--timeback-student-id <id>` | Student ID to link to demo user
|
|
209
|
-
| `--timeback-role <role>` | User role (student, parent, teacher, administrator)
|
|
210
|
-
| `--timeback-org-id <id>` | Organization ID
|
|
211
|
-
| `--timeback-org-name <name>` | Organization display name
|
|
212
|
-
| `--timeback-org-type <type>` | Organization type (school, district, department, etc.)
|
|
202
|
+
| Option | Description |
|
|
203
|
+
| :------------------------------- | :----------------------------------------------------- |
|
|
204
|
+
| `--timeback-local` | Enable local TimeBack mode (Docker) |
|
|
205
|
+
| `--timeback-oneroster-url <url>` | OneRoster API URL |
|
|
206
|
+
| `--timeback-caliper-url <url>` | Caliper API URL |
|
|
207
|
+
| `--timeback-course-id <id>` | Course ID for enrollments |
|
|
208
|
+
| `--timeback-student-id <id>` | Student ID to link to demo user |
|
|
209
|
+
| `--timeback-role <role>` | User role (student, parent, teacher, administrator) |
|
|
210
|
+
| `--timeback-org-id <id>` | Organization ID |
|
|
211
|
+
| `--timeback-org-name <name>` | Organization display name |
|
|
212
|
+
| `--timeback-org-type <type>` | Organization type (school, district, department, etc.) |
|
|
213
213
|
|
|
214
214
|
### Environment Variables
|
|
215
215
|
|
package/dist/cli.js
CHANGED
|
@@ -120609,6 +120609,9 @@ function configureTimeback(options) {
|
|
|
120609
120609
|
config.timeback.role = options.role;
|
|
120610
120610
|
process.env.SANDBOX_TIMEBACK_ROLE = options.role;
|
|
120611
120611
|
}
|
|
120612
|
+
if (options.courseOverrides) {
|
|
120613
|
+
config.timeback.courseOverrides = options.courseOverrides;
|
|
120614
|
+
}
|
|
120612
120615
|
}
|
|
120613
120616
|
function getTimebackDisplayMode() {
|
|
120614
120617
|
const { timebackId, mode } = config.timeback;
|
|
@@ -121478,7 +121481,7 @@ async function requirePortAvailable(port, timeoutMs = 100) {
|
|
|
121478
121481
|
// package.json
|
|
121479
121482
|
var package_default = {
|
|
121480
121483
|
name: "@playcademy/sandbox",
|
|
121481
|
-
version: "0.3.
|
|
121484
|
+
version: "0.3.5",
|
|
121482
121485
|
description: "Local development server for Playcademy game development",
|
|
121483
121486
|
type: "module",
|
|
121484
121487
|
exports: {
|
|
@@ -152337,7 +152340,14 @@ function getMockStudentProfile() {
|
|
|
152337
152340
|
}
|
|
152338
152341
|
async function getMockEnrollments(db) {
|
|
152339
152342
|
const allIntegrations = await db.query.gameTimebackIntegrations.findMany();
|
|
152340
|
-
|
|
152343
|
+
const overrides = config.timeback.courseOverrides;
|
|
152344
|
+
return allIntegrations.filter((i4) => {
|
|
152345
|
+
if (!overrides)
|
|
152346
|
+
return true;
|
|
152347
|
+
const key = `${i4.subject}:${i4.grade}`;
|
|
152348
|
+
const override = overrides[key];
|
|
152349
|
+
return override !== null && override !== false;
|
|
152350
|
+
}).map((i4) => ({
|
|
152341
152351
|
gameId: i4.gameId,
|
|
152342
152352
|
grade: i4.grade,
|
|
152343
152353
|
subject: i4.subject,
|
|
@@ -158318,7 +158328,7 @@ function printBanner(options) {
|
|
|
158318
158328
|
console.log("");
|
|
158319
158329
|
console.log(` ${import_picocolors.default.green(import_picocolors.default.bold("PLAYCADEMY SANDBOX"))} ${import_picocolors.default.green(`v${version4}`)} ${import_picocolors.default.dim("ready in")} ${import_picocolors.default.bold(startupTimeMs.toString())} ms`);
|
|
158320
158330
|
console.log("");
|
|
158321
|
-
console.log(` ${import_picocolors.default.green("➜")} ${import_picocolors.default.bold("Local:")}
|
|
158331
|
+
console.log(` ${import_picocolors.default.green("➜")} ${import_picocolors.default.bold("Local:")} ${import_picocolors.default.cyan(`http://localhost:${import_picocolors.default.bold(port.toString())}/api`)}`);
|
|
158322
158332
|
if (timebackCourseCount && timebackCourseCount > 0) {
|
|
158323
158333
|
const courseText = timebackCourseCount === 1 ? "course" : "courses";
|
|
158324
158334
|
console.log(` ${import_picocolors.default.green("➜")} ${import_picocolors.default.bold("Timeback:")} ${import_picocolors.default.cyan(`${timebackCourseCount} ${courseText}`)}`);
|
|
@@ -158530,9 +158540,20 @@ function parseOrganization(options) {
|
|
|
158530
158540
|
type: options.timebackOrgType
|
|
158531
158541
|
};
|
|
158532
158542
|
}
|
|
158543
|
+
function parseExcludedCourses(excludedCourses) {
|
|
158544
|
+
if (!excludedCourses)
|
|
158545
|
+
return;
|
|
158546
|
+
const overrides = {};
|
|
158547
|
+
const courses = excludedCourses.split(",").map((c3) => c3.trim()).filter(Boolean);
|
|
158548
|
+
for (const course of courses) {
|
|
158549
|
+
overrides[course] = false;
|
|
158550
|
+
}
|
|
158551
|
+
return Object.keys(overrides).length > 0 ? overrides : undefined;
|
|
158552
|
+
}
|
|
158533
158553
|
function parseTimebackOptions(options) {
|
|
158534
158554
|
const organization = parseOrganization(options);
|
|
158535
158555
|
const role = options.timebackRole;
|
|
158556
|
+
const courseOverrides = parseExcludedCourses(options.timebackExcludedCourses);
|
|
158536
158557
|
if (options.timebackLocal) {
|
|
158537
158558
|
return {
|
|
158538
158559
|
mode: "local",
|
|
@@ -158541,7 +158562,8 @@ function parseTimebackOptions(options) {
|
|
|
158541
158562
|
courseId: options.timebackCourseId,
|
|
158542
158563
|
timebackId: options.timebackStudentId,
|
|
158543
158564
|
role,
|
|
158544
|
-
organization
|
|
158565
|
+
organization,
|
|
158566
|
+
courseOverrides
|
|
158545
158567
|
};
|
|
158546
158568
|
}
|
|
158547
158569
|
if (options.timebackOnerosterUrl) {
|
|
@@ -158552,14 +158574,16 @@ function parseTimebackOptions(options) {
|
|
|
158552
158574
|
courseId: options.timebackCourseId,
|
|
158553
158575
|
timebackId: options.timebackStudentId,
|
|
158554
158576
|
role,
|
|
158555
|
-
organization
|
|
158577
|
+
organization,
|
|
158578
|
+
courseOverrides
|
|
158556
158579
|
};
|
|
158557
158580
|
}
|
|
158558
|
-
if (role || organization || options.timebackStudentId) {
|
|
158581
|
+
if (role || organization || options.timebackStudentId || courseOverrides) {
|
|
158559
158582
|
return {
|
|
158560
158583
|
timebackId: options.timebackStudentId,
|
|
158561
158584
|
role,
|
|
158562
|
-
organization
|
|
158585
|
+
organization,
|
|
158586
|
+
courseOverrides
|
|
158563
158587
|
};
|
|
158564
158588
|
}
|
|
158565
158589
|
return;
|
|
@@ -158567,7 +158591,7 @@ function parseTimebackOptions(options) {
|
|
|
158567
158591
|
|
|
158568
158592
|
// src/cli/index.ts
|
|
158569
158593
|
var program2 = new Command;
|
|
158570
|
-
program2.name("playcademy-sandbox").description("Local development server for Playcademy game development").version(version3).option("-p, --port <number>", "Port to run the server on", "4321").option("-v, --verbose", "Enable verbose logging", false).option("--project-name <name>", "Name of the current project").option("--project-slug <slug>", "Slug of the current project").option("--no-seed", "Do not seed the database with demo data").option("--recreate-db", "Recreate the on-disk database on start", false).option("--memory", "Use in-memory database (no persistence)", false).option("--db-path <path>", "Custom path for the database file (relative to cwd or absolute)").option("--config-path <path>", "Path to playcademy.config.json (defaults to cwd)").option("--timeback-local", "Use local TimeBack instance").option("--timeback-oneroster-url <url>", "TimeBack OneRoster API URL").option("--timeback-caliper-url <url>", "TimeBack Caliper API URL").option("--timeback-course-id <id>", "TimeBack course ID for seeding").option("--timeback-student-id <id>", "TimeBack student ID for demo user").option("--timeback-role <role>", "TimeBack user role (student, parent, teacher, administrator)").option("--timeback-org-id <id>", "TimeBack organization ID").option("--timeback-org-name <name>", "TimeBack organization name").option("--timeback-org-type <type>", "TimeBack organization type (school, district, department)").option("-q, --quiet", "Quiet mode (suppress interactive messages)", false).action(async (options) => {
|
|
158594
|
+
program2.name("playcademy-sandbox").description("Local development server for Playcademy game development").version(version3).option("-p, --port <number>", "Port to run the server on", "4321").option("-v, --verbose", "Enable verbose logging", false).option("--project-name <name>", "Name of the current project").option("--project-slug <slug>", "Slug of the current project").option("--no-seed", "Do not seed the database with demo data").option("--recreate-db", "Recreate the on-disk database on start", false).option("--memory", "Use in-memory database (no persistence)", false).option("--db-path <path>", "Custom path for the database file (relative to cwd or absolute)").option("--config-path <path>", "Path to playcademy.config.json (defaults to cwd)").option("--timeback-local", "Use local TimeBack instance").option("--timeback-oneroster-url <url>", "TimeBack OneRoster API URL").option("--timeback-caliper-url <url>", "TimeBack Caliper API URL").option("--timeback-course-id <id>", "TimeBack course ID for seeding").option("--timeback-student-id <id>", "TimeBack student ID for demo user").option("--timeback-role <role>", "TimeBack user role (student, parent, teacher, administrator)").option("--timeback-org-id <id>", "TimeBack organization ID").option("--timeback-org-name <name>", "TimeBack organization name").option("--timeback-org-type <type>", "TimeBack organization type (school, district, department)").option("--timeback-excluded-courses <courses>", 'Comma-separated courses to exclude from enrollment (e.g. "FastMath:3,FastMath:4")').option("-q, --quiet", "Quiet mode (suppress interactive messages)", false).action(async (options) => {
|
|
158571
158595
|
try {
|
|
158572
158596
|
const startTime = Date.now();
|
|
158573
158597
|
const port = parseInt(options.port);
|
package/dist/config.d.ts
CHANGED
|
@@ -14,6 +14,13 @@ interface TimebackOrganizationInput {
|
|
|
14
14
|
name?: string;
|
|
15
15
|
type?: TimebackOrgType;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Course enrollment overrides.
|
|
19
|
+
* - `'mock'` or omit: Use mock ID
|
|
20
|
+
* - Real string: Use that course ID
|
|
21
|
+
* - `null` or `false`: Exclude from enrollment
|
|
22
|
+
*/
|
|
23
|
+
type CourseEnrollmentOverrides = Record<string, 'mock' | string | null | false>;
|
|
17
24
|
/**
|
|
18
25
|
* Timeback configuration input for sandbox.
|
|
19
26
|
* All fields optional since they can be derived from defaults.
|
|
@@ -29,6 +36,7 @@ interface TimebackConfig {
|
|
|
29
36
|
timebackId?: string;
|
|
30
37
|
organization?: TimebackOrganizationInput;
|
|
31
38
|
role?: TimebackUserRole;
|
|
39
|
+
courseOverrides?: CourseEnrollmentOverrides;
|
|
32
40
|
}
|
|
33
41
|
/**
|
|
34
42
|
* Authentication configuration input for sandbox.
|
|
@@ -76,4 +84,4 @@ declare function getTimebackDisplayMode(): 'mock' | 'remote' | 'local' | null;
|
|
|
76
84
|
declare const config: SandboxConfig;
|
|
77
85
|
|
|
78
86
|
export { config, configureTimeback, getTimebackDisplayMode, hasTimebackCredentials, hasTimebackFullConfig, isTimebackEnabled, requireTimebackCredentials, setEmbeddedMode };
|
|
79
|
-
export type { AuthConfig, SandboxConfig, TimebackConfig, TimebackMode };
|
|
87
|
+
export type { AuthConfig, CourseEnrollmentOverrides, SandboxConfig, TimebackConfig, TimebackMode };
|
package/dist/config.js
CHANGED
|
@@ -127,6 +127,9 @@ function configureTimeback(options) {
|
|
|
127
127
|
config.timeback.role = options.role;
|
|
128
128
|
process.env.SANDBOX_TIMEBACK_ROLE = options.role;
|
|
129
129
|
}
|
|
130
|
+
if (options.courseOverrides) {
|
|
131
|
+
config.timeback.courseOverrides = options.courseOverrides;
|
|
132
|
+
}
|
|
130
133
|
}
|
|
131
134
|
function getTimebackDisplayMode() {
|
|
132
135
|
const { timebackId, mode } = config.timeback;
|
package/dist/mocks/timeback.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare function shouldMockTimeback(): boolean;
|
|
|
17
17
|
export declare function getMockStudentProfile(): TimebackStudentProfile;
|
|
18
18
|
/**
|
|
19
19
|
* Generate mock enrollments from seeded game integrations.
|
|
20
|
+
* Respects courseOverrides from config - null/false excludes the course.
|
|
20
21
|
*/
|
|
21
22
|
export declare function getMockEnrollments(db: DatabaseInstance): Promise<UserEnrollment[]>;
|
|
22
23
|
/**
|
package/dist/server.d.ts
CHANGED
|
@@ -15,6 +15,13 @@ interface TimebackOrganizationInput {
|
|
|
15
15
|
name?: string;
|
|
16
16
|
type?: TimebackOrgType;
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Course enrollment overrides.
|
|
20
|
+
* - `'mock'` or omit: Use mock ID
|
|
21
|
+
* - Real string: Use that course ID
|
|
22
|
+
* - `null` or `false`: Exclude from enrollment
|
|
23
|
+
*/
|
|
24
|
+
type CourseEnrollmentOverrides = Record<string, 'mock' | string | null | false>;
|
|
18
25
|
/**
|
|
19
26
|
* Timeback configuration input for sandbox.
|
|
20
27
|
* All fields optional since they can be derived from defaults.
|
|
@@ -30,6 +37,7 @@ interface TimebackConfig {
|
|
|
30
37
|
timebackId?: string;
|
|
31
38
|
organization?: TimebackOrganizationInput;
|
|
32
39
|
role?: TimebackUserRole;
|
|
40
|
+
courseOverrides?: CourseEnrollmentOverrides;
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
/**
|
package/dist/server.js
CHANGED
|
@@ -118699,6 +118699,9 @@ function configureTimeback(options) {
|
|
|
118699
118699
|
config.timeback.role = options.role;
|
|
118700
118700
|
process.env.SANDBOX_TIMEBACK_ROLE = options.role;
|
|
118701
118701
|
}
|
|
118702
|
+
if (options.courseOverrides) {
|
|
118703
|
+
config.timeback.courseOverrides = options.courseOverrides;
|
|
118704
|
+
}
|
|
118702
118705
|
}
|
|
118703
118706
|
function getTimebackDisplayMode() {
|
|
118704
118707
|
const { timebackId, mode } = config.timeback;
|
|
@@ -119568,7 +119571,7 @@ async function requirePortAvailable(port, timeoutMs = 100) {
|
|
|
119568
119571
|
// package.json
|
|
119569
119572
|
var package_default = {
|
|
119570
119573
|
name: "@playcademy/sandbox",
|
|
119571
|
-
version: "0.3.
|
|
119574
|
+
version: "0.3.5",
|
|
119572
119575
|
description: "Local development server for Playcademy game development",
|
|
119573
119576
|
type: "module",
|
|
119574
119577
|
exports: {
|
|
@@ -150427,7 +150430,14 @@ function getMockStudentProfile() {
|
|
|
150427
150430
|
}
|
|
150428
150431
|
async function getMockEnrollments(db) {
|
|
150429
150432
|
const allIntegrations = await db.query.gameTimebackIntegrations.findMany();
|
|
150430
|
-
|
|
150433
|
+
const overrides = config.timeback.courseOverrides;
|
|
150434
|
+
return allIntegrations.filter((i4) => {
|
|
150435
|
+
if (!overrides)
|
|
150436
|
+
return true;
|
|
150437
|
+
const key = `${i4.subject}:${i4.grade}`;
|
|
150438
|
+
const override = overrides[key];
|
|
150439
|
+
return override !== null && override !== false;
|
|
150440
|
+
}).map((i4) => ({
|
|
150431
150441
|
gameId: i4.gameId,
|
|
150432
150442
|
grade: i4.grade,
|
|
150433
150443
|
subject: i4.subject,
|