playcademy 0.3.0 → 0.5.0

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.
Files changed (3) hide show
  1. package/dist/index.js +162 -11
  2. package/dist/utils.js +11663 -0
  3. package/package.json +11 -7
package/dist/index.js CHANGED
@@ -19867,6 +19867,11 @@ function getBaseUrl() {
19867
19867
  }
19868
19868
  return "https://hub.playcademy.com";
19869
19869
  }
19870
+ function getApiUrl(path3) {
19871
+ const baseUrl = getBaseUrl();
19872
+ const normalizedPath = path3.startsWith("/") ? path3 : `/${path3}`;
19873
+ return `${baseUrl}${normalizedPath}`;
19874
+ }
19870
19875
  function getProfileName() {
19871
19876
  const context2 = getCliContext();
19872
19877
  return context2.profile || process.env.PLAYCADEMY_PROFILE || "default";
@@ -20585,6 +20590,17 @@ async function deriveTimebackConfig(config) {
20585
20590
  componentResource
20586
20591
  };
20587
20592
  }
20593
+ function deriveSourcedIds(courseId) {
20594
+ return {
20595
+ organization: PLAYCADEMY_DEFAULTS.organization,
20596
+ course: courseId,
20597
+ component: `${courseId}-component`,
20598
+ resource: `${courseId}-resource`,
20599
+ componentResource: `${courseId}-cr`,
20600
+ classCore: `${courseId}-class-core`,
20601
+ classAfterHours: `${courseId}-class-after`
20602
+ };
20603
+ }
20588
20604
 
20589
20605
  // src/lib/templates/loader.ts
20590
20606
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
@@ -26044,6 +26060,15 @@ var init_achievements = () => {
26044
26060
  };
26045
26061
  function createTimebackNamespace(client) {
26046
26062
  return {
26063
+ recordProgress: (progressData) => {
26064
+ return client["request"]("/api/integrations/timeback/progress", "POST", { progressData }, void 0, true);
26065
+ },
26066
+ recordSessionEnd: (sessionData) => {
26067
+ return client["request"]("/api/integrations/timeback/session-end", "POST", { sessionData }, void 0, true);
26068
+ },
26069
+ awardXP: (xpAmount, metadata) => {
26070
+ return client["request"]("/api/integrations/timeback/award-xp", "POST", { xpAmount, metadata }, void 0, true);
26071
+ },
26047
26072
  management: {
26048
26073
  setup: (request2) => {
26049
26074
  return client["request"]("/timeback/setup", "POST", request2);
@@ -26252,7 +26277,8 @@ async function waitForPlaycademyInit(allowedParentOrigins) {
26252
26277
  function createStandaloneConfig() {
26253
26278
  console.warn("[Playcademy SDK] Standalone mode detected, creating mock context for local development");
26254
26279
  const mockConfig = {
26255
- baseUrl: "/api",
26280
+ baseUrl: "http://localhost:4321",
26281
+ gameUrl: "http://localhost:8788",
26256
26282
  token: "mock-game-token-for-local-dev",
26257
26283
  gameId: "mock-game-id-from-template",
26258
26284
  realtimeUrl: void 0
@@ -26271,6 +26297,7 @@ async function init(options) {
26271
26297
  }
26272
26298
  const client = new PlaycademyClient2({
26273
26299
  baseUrl: config.baseUrl,
26300
+ gameUrl: config.gameUrl,
26274
26301
  token: config.token,
26275
26302
  gameId: config.gameId,
26276
26303
  autoStartSession: window.self !== window.top
@@ -26340,6 +26367,7 @@ var init_client = __esm2(() => {
26340
26367
  init_static();
26341
26368
  PlaycademyClient = class PlaycademyClient {
26342
26369
  baseUrl;
26370
+ gameUrl;
26343
26371
  authStrategy;
26344
26372
  gameId;
26345
26373
  config;
@@ -26348,7 +26376,8 @@ var init_client = __esm2(() => {
26348
26376
  authContext;
26349
26377
  initPayload;
26350
26378
  constructor(config) {
26351
- this.baseUrl = config?.baseUrl || "/api";
26379
+ this.baseUrl = config?.baseUrl || "";
26380
+ this.gameUrl = config?.gameUrl;
26352
26381
  this.gameId = config?.gameId;
26353
26382
  this.config = config || {};
26354
26383
  this.authStrategy = createAuthStrategy(config?.token ?? null, config?.tokenType);
@@ -26359,7 +26388,16 @@ var init_client = __esm2(() => {
26359
26388
  getBaseUrl() {
26360
26389
  const isRelative = this.baseUrl.startsWith("/");
26361
26390
  const isBrowser2 = typeof window !== "undefined";
26362
- return isRelative && isBrowser2 ? `${window.location.origin}${this.baseUrl}` : this.baseUrl;
26391
+ const effectiveBaseUrl = isRelative && isBrowser2 ? `${window.location.origin}${this.baseUrl}` : this.baseUrl;
26392
+ return `${effectiveBaseUrl}/api`;
26393
+ }
26394
+ getGameBackendUrl() {
26395
+ if (!this.gameUrl)
26396
+ return this.getBaseUrl();
26397
+ const isRelative = this.gameUrl.startsWith("/");
26398
+ const isBrowser2 = typeof window !== "undefined";
26399
+ const effectiveGameUrl = isRelative && isBrowser2 ? `${window.location.origin}${this.gameUrl}` : this.gameUrl;
26400
+ return `${effectiveGameUrl}/api`;
26363
26401
  }
26364
26402
  ping() {
26365
26403
  return "pong";
@@ -26392,16 +26430,17 @@ var init_client = __esm2(() => {
26392
26430
  listener(payload);
26393
26431
  });
26394
26432
  }
26395
- async request(path3, method, body, headers) {
26433
+ async request(path3, method, body, headers, useGameBackend = false) {
26396
26434
  const effectiveHeaders = {
26397
26435
  ...headers,
26398
26436
  ...this.authStrategy.getHeaders()
26399
26437
  };
26438
+ const targetBaseUrl = useGameBackend ? this.getGameBackendUrl() : this.baseUrl;
26400
26439
  return request({
26401
26440
  path: path3,
26402
26441
  method,
26403
26442
  body,
26404
- baseUrl: this.baseUrl,
26443
+ baseUrl: targetBaseUrl,
26405
26444
  extraHeaders: effectiveHeaders
26406
26445
  });
26407
26446
  }
@@ -27299,6 +27338,13 @@ async function getBackendSize(config) {
27299
27338
  return null;
27300
27339
  }
27301
27340
  }
27341
+ async function getDeployedBackend(_client, _gameId) {
27342
+ try {
27343
+ return null;
27344
+ } catch {
27345
+ return null;
27346
+ }
27347
+ }
27302
27348
  async function deployGameBackend(client, slug, config, projectPath, previousBackendHash, fullConfig) {
27303
27349
  try {
27304
27350
  const hasCustomRoutes2 = hasLocalBackend(projectPath);
@@ -27512,6 +27558,8 @@ import { stat } from "node:fs/promises";
27512
27558
  import { join as join5 } from "node:path";
27513
27559
 
27514
27560
  // src/lib/deploy/prompts.ts
27561
+ var REQUIRED_FIELDS = ["displayName", "gameType", "buildPath", "externalUrl"];
27562
+ var OPTIONAL_FIELDS = ["description", "emoji"];
27515
27563
  function getMissingFields(config) {
27516
27564
  const missingDisplayName = !config.displayName;
27517
27565
  const missingGameType = !config.gameType && !config.buildPath && !config.externalUrl;
@@ -27531,6 +27579,9 @@ function getMissingFields(config) {
27531
27579
  function hasMandatoryFieldsMissing(missing) {
27532
27580
  return missing.displayName || missing.gameType || missing.buildPath || missing.externalUrl;
27533
27581
  }
27582
+ function hasOptionalFieldsMissing(missing) {
27583
+ return missing.description || missing.emoji;
27584
+ }
27534
27585
 
27535
27586
  // src/lib/deploy/validate.ts
27536
27587
  import { existsSync as existsSync4 } from "fs";
@@ -27938,8 +27989,8 @@ async function analyzeChanges(context2) {
27938
27989
  async function calculateDeploymentPlan(context2, changes) {
27939
27990
  const { config, isNewDeployment, projectPath, deployBackend } = context2;
27940
27991
  if (isNewDeployment) {
27941
- const needsBackend2 = hasLocalBackend(projectPath) || !!context2.fullConfig?.integrations;
27942
- const shouldDeployBackend2 = deployBackend && needsBackend2;
27992
+ const needsBackend3 = hasLocalBackend(projectPath) || !!context2.fullConfig?.integrations;
27993
+ const shouldDeployBackend2 = deployBackend && needsBackend3;
27943
27994
  return {
27944
27995
  action: "deploy-new",
27945
27996
  gameType: config.gameType ?? "hosted",
@@ -27968,8 +28019,8 @@ async function calculateDeploymentPlan(context2, changes) {
27968
28019
  }
27969
28020
  }
27970
28021
  const shouldDeployFrontend = changes.build !== false || changes.config;
27971
- const needsBackend = hasLocalBackend(projectPath) || !!context2.fullConfig?.integrations;
27972
- const shouldDeployBackend = deployBackend && (changes.backend === true || needsBackend);
28022
+ const needsBackend2 = hasLocalBackend(projectPath) || !!context2.fullConfig?.integrations;
28023
+ const shouldDeployBackend = deployBackend && (changes.backend === true || needsBackend2);
27973
28024
  return {
27974
28025
  action: "update-existing",
27975
28026
  gameType: config.gameType ?? "hosted",
@@ -28138,6 +28189,9 @@ import { join as join8 } from "path";
28138
28189
  function hasCustomRoutes() {
28139
28190
  return existsSync7(join8(getWorkspace(), "api"));
28140
28191
  }
28192
+ function needsBackend(config) {
28193
+ return !!config.integrations || hasCustomRoutes();
28194
+ }
28141
28195
 
28142
28196
  // src/lib/dev/display.ts
28143
28197
  function displayRegisteredRoutes(integrations, customRoutes = []) {
@@ -32137,9 +32191,9 @@ async function registerBuiltinRoutes(app, integrations) {
32137
32191
 
32138
32192
  // src/lib/dev/server.ts
32139
32193
  async function startDevServer(port, config, options = {}) {
32140
- const { logger: enableLogger = true } = options;
32194
+ const { logger: enableLogger = true, quiet = false } = options;
32141
32195
  const app = new Hono2();
32142
- if (enableLogger) {
32196
+ if (enableLogger && !quiet) {
32143
32197
  app.use("*", logger2());
32144
32198
  }
32145
32199
  app.use("*", cors());
@@ -34325,6 +34379,103 @@ program.parse();
34325
34379
  if (!process.argv.slice(2).length) {
34326
34380
  program.outputHelp();
34327
34381
  }
34382
+ export {
34383
+ ConfigError,
34384
+ OPTIONAL_FIELDS,
34385
+ REQUIRED_FIELDS,
34386
+ analyzeChanges,
34387
+ bundleBackend,
34388
+ calculateConfigDiff,
34389
+ calculateDeploymentPlan,
34390
+ confirmDeploymentPlan,
34391
+ createClient,
34392
+ deployBackendIfNeeded,
34393
+ deployExternalGame,
34394
+ deployGameBackend,
34395
+ deployHostedGameFrontend,
34396
+ deriveSourcedIds,
34397
+ deriveTimebackConfig,
34398
+ detectConfigChanges,
34399
+ discoverRoutes,
34400
+ displayCleanupWarning,
34401
+ displayConfigPreview,
34402
+ displayConfigSuccess,
34403
+ displayCurrentConfiguration,
34404
+ displayDeploymentDiff,
34405
+ displayIntegrationDetails,
34406
+ displayRegisteredRoutes,
34407
+ displayResourcesStatus,
34408
+ displaySuccessMessage,
34409
+ ensureGameExists,
34410
+ findConfigPath,
34411
+ generateEntryCode,
34412
+ generateJsConfig,
34413
+ generateJsonConfig,
34414
+ getApiUrl,
34415
+ getAuthPath,
34416
+ getBackendHash,
34417
+ getBackendSize,
34418
+ getBaseUrl,
34419
+ getCallbackUrl,
34420
+ getCliContext,
34421
+ getCurrentProfile,
34422
+ getDeployedBackend,
34423
+ getDeployedGame,
34424
+ getEnvironment,
34425
+ getGameFromConfig,
34426
+ getGamesStorePath,
34427
+ getIntegrationsHash,
34428
+ getMissingFields,
34429
+ getProfile,
34430
+ getProfileName,
34431
+ getWebBaseUrl,
34432
+ getWorkspace,
34433
+ hasBackendChanged,
34434
+ hasCustomRoutes,
34435
+ hasLocalBackend,
34436
+ hasMandatoryFieldsMissing,
34437
+ hasOptionalFieldsMissing,
34438
+ hashDirectory,
34439
+ hashFile,
34440
+ listProfiles,
34441
+ loadAuthStore,
34442
+ loadConfig,
34443
+ loadDeployConfig,
34444
+ loadGameStore,
34445
+ logger,
34446
+ needsBackend,
34447
+ prepareDeploymentContext,
34448
+ processConfigVariables,
34449
+ promptForApiRoutes,
34450
+ promptForGameInfo,
34451
+ promptForMissingConfig,
34452
+ promptForTimeBackIntegration,
34453
+ registerCustomRoutes,
34454
+ removeDeployedGame,
34455
+ removeProfile,
34456
+ reportCancellation,
34457
+ reportDeploymentSuccess,
34458
+ reportDryRun,
34459
+ reportNoChanges,
34460
+ requireAuthenticatedClient,
34461
+ saveAuthStore,
34462
+ saveDeployedGame,
34463
+ saveDeploymentState,
34464
+ saveGameStore,
34465
+ saveProfile,
34466
+ scaffoldApiDirectory,
34467
+ selectConfigFormat,
34468
+ selectEnvironment,
34469
+ setCliContext,
34470
+ startCallbackServer,
34471
+ startDevServer,
34472
+ startHotReload,
34473
+ validateApiDirectoryDoesNotExist,
34474
+ validateBuildPath,
34475
+ validateConfig,
34476
+ validateDeployConfig,
34477
+ validateExternalUrl
34478
+ };
34328
34479
  /*! Bundled license information:
34329
34480
 
34330
34481
  chokidar/esm/index.js: