@playcademy/sdk 0.6.1-beta.4 → 0.6.1-beta.6

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/types.d.ts CHANGED
@@ -355,96 +355,194 @@ interface AdvanceCourseResponse {
355
355
  }
356
356
 
357
357
  /**
358
- * Achievement Types
358
+ * @fileoverview Server SDK Type Definitions
359
359
  *
360
- * @module types/achievement
360
+ * TypeScript type definitions for the server-side Playcademy SDK.
361
+ * Includes configuration types, client state, and re-exported TimeBack types.
361
362
  */
362
- type AchievementScopeType = 'daily' | 'weekly' | 'monthly' | 'yearly' | 'game' | 'global' | 'map' | 'level' | 'event';
363
- declare enum AchievementCompletionType {
364
- TIME_PLAYED_SESSION = "time_played_session",
365
- INTERACTION = "interaction",
366
- LEADERBOARD_RANK = "leaderboard_rank",
367
- FIRST_SCORE = "first_score",
368
- PERSONAL_BEST = "personal_best"
363
+
364
+ /**
365
+ * Base configuration for TimeBack integration (shared across all courses).
366
+ * References upstream TimeBack types from @playcademy/timeback.
367
+ *
368
+ * All fields are optional and support template variables: {grade}, {subject}, {gameSlug}
369
+ */
370
+ interface TimebackBaseConfig {
371
+ /** Organization configuration (shared across all courses) */
372
+ organization?: Partial<OrganizationConfig>;
373
+ /** Course defaults (can be overridden per-course) */
374
+ course?: Partial<CourseConfig>;
375
+ /** Component defaults */
376
+ component?: Partial<ComponentConfig>;
377
+ /** Resource defaults */
378
+ resource?: Partial<ResourceConfig>;
379
+ /** ComponentResource defaults */
380
+ componentResource?: Partial<ComponentResourceConfig>;
369
381
  }
370
- interface AchievementCurrent {
371
- id: string;
372
- title: string;
373
- description?: string | null;
374
- scope: AchievementScopeType;
375
- rewardCredits: number;
376
- limit: number;
377
- completionType: string;
378
- completionConfig: unknown;
379
- target: unknown;
380
- active: boolean;
381
- createdAt?: Date | null;
382
- updatedAt?: Date | null;
383
- status: 'available' | 'completed';
384
- scopeKey: string;
385
- windowStart: string;
386
- windowEnd: string;
382
+ /**
383
+ * Extended course configuration that merges TimebackCourseConfig with per-course overrides.
384
+ * Used in playcademy.config.* to allow per-course customization.
385
+ */
386
+ interface TimebackCourseConfigWithOverrides extends TimebackCourseConfig {
387
+ title?: string;
388
+ courseCode?: string;
389
+ level?: string;
390
+ metadata?: CourseConfig['metadata'];
391
+ totalXp?: number | null;
392
+ masterableUnits?: number | null;
387
393
  }
388
- interface AchievementWithStatus {
389
- id: string;
390
- title: string;
391
- description: string | null;
392
- scope: AchievementScopeType;
393
- rewardCredits: number;
394
- limit: number;
395
- completionType: string;
396
- completionConfig: unknown;
397
- target: unknown;
398
- active: boolean;
399
- createdAt: Date | null;
400
- updatedAt: Date | null;
401
- status: 'available' | 'completed';
402
- scopeKey: string;
403
- windowStart?: string;
404
- windowEnd?: string;
394
+ /**
395
+ * TimeBack integration configuration for Playcademy config file.
396
+ *
397
+ * Supports two levels of customization:
398
+ * 1. `base`: Shared defaults for all courses (organization, course, component, resource, componentResource)
399
+ * 2. Per-course overrides in the `courses` array (title, courseCode, level, gradingScheme, metadata)
400
+ *
401
+ * Template variables ({grade}, {subject}, {gameSlug}) can be used in string fields.
402
+ */
403
+ interface TimebackIntegrationConfig {
404
+ /** Multi-grade course configuration (array of grade/subject/totalXp with optional per-course overrides) */
405
+ courses: TimebackCourseConfigWithOverrides[];
406
+ /** Optional base configuration (shared across all courses, can be overridden per-course) */
407
+ base?: TimebackBaseConfig;
405
408
  }
406
- interface AchievementHistoryEntry {
407
- achievementId: string;
408
- title: string;
409
- rewardCredits: number;
410
- createdAt: Date;
411
- scopeKey: string;
409
+ /**
410
+ * Custom API routes integration
411
+ */
412
+ interface CustomRoutesIntegration {
413
+ /** Directory for custom API routes (defaults to 'server/api') */
414
+ directory?: string;
412
415
  }
413
- interface AchievementProgressResponse {
414
- achievementId: string;
415
- status: 'completed' | 'already_completed';
416
- rewardCredits: number;
417
- scopeKey: string;
418
- createdAt: Date;
416
+ /**
417
+ * Database integration
418
+ */
419
+ interface DatabaseIntegration {
420
+ /** Database directory (defaults to 'db') */
421
+ directory?: string;
422
+ /** Schema strategy: 'push' uses drizzle-kit push-style diffing, 'migrate' uses migration files.
423
+ * When omitted, auto-detects based on presence of a migrations directory with _journal.json. */
424
+ strategy?: 'push' | 'migrate';
425
+ }
426
+ interface QueueConfig {
427
+ maxBatchSize?: number;
428
+ maxRetries?: number;
429
+ maxBatchTimeout?: number;
430
+ maxConcurrency?: number;
431
+ retryDelay?: number;
432
+ deadLetterQueue?: string;
433
+ }
434
+ /**
435
+ * Integrations configuration
436
+ * All backend features (database, custom routes, external services) are configured here
437
+ */
438
+ interface IntegrationsConfig {
439
+ /** TimeBack integration (optional) */
440
+ timeback?: TimebackIntegrationConfig | null;
441
+ /** Custom API routes (optional) */
442
+ customRoutes?: CustomRoutesIntegration | boolean;
443
+ /** Database (optional) */
444
+ database?: DatabaseIntegration | boolean;
445
+ /** Key-Value storage (optional) */
446
+ kv?: boolean;
447
+ /** Bucket storage (optional) */
448
+ bucket?: boolean;
449
+ /** Authentication (optional) */
450
+ auth?: boolean;
451
+ /** Queues (optional) */
452
+ queues?: Record<string, QueueConfig | boolean>;
453
+ }
454
+ /**
455
+ * Unified Playcademy configuration
456
+ * Used for playcademy.config.{js,json}
457
+ */
458
+ interface PlaycademyConfig {
459
+ /** Game name */
460
+ name: string;
461
+ /** Game description */
462
+ description?: string;
463
+ /** Game emoji icon */
464
+ emoji?: string;
465
+ /** Build command to run before deployment */
466
+ buildCommand?: string[];
467
+ /** Path to build output */
468
+ buildPath?: string;
469
+ /** Game type */
470
+ gameType?: 'hosted' | 'external';
471
+ /** External URL (for external games) */
472
+ externalUrl?: string;
473
+ /** Game platform */
474
+ platform?: 'web' | 'unity' | 'godot';
475
+ /** Integrations (database, custom routes, external services) */
476
+ integrations?: IntegrationsConfig;
419
477
  }
420
478
 
421
479
  /**
422
- * Notification Types
480
+ * Configuration options for initializing a PlaycademyClient instance.
423
481
  *
424
- * @module types/notification
482
+ * @example
483
+ * ```typescript
484
+ * const config: PlaycademyServerClientConfig = {
485
+ * apiKey: process.env.PLAYCADEMY_API_KEY!,
486
+ * gameId: 'my-math-game',
487
+ * configPath: './playcademy.config.js'
488
+ * }
489
+ * ```
425
490
  */
426
-
427
- declare enum NotificationType {
428
- ACHIEVEMENT = "achievement",
429
- SYSTEM = "system",
430
- PROMO = "promo"
431
- }
432
- declare enum NotificationStatus {
433
- PENDING = "pending",
434
- DELIVERED = "delivered",
435
- SEEN = "seen",
436
- CLICKED = "clicked",
437
- DISMISSED = "dismissed",
438
- EXPIRED = "expired"
491
+ interface PlaycademyServerClientConfig {
492
+ /**
493
+ * Playcademy API key for server-to-server authentication.
494
+ * Obtain from the Playcademy developer dashboard.
495
+ */
496
+ apiKey: string;
497
+ /**
498
+ * Optional path to playcademy.config.js file.
499
+ * If not provided, searches current directory and up to 3 parent directories.
500
+ * Ignored if `config` is provided directly.
501
+ *
502
+ * @example './config/playcademy.config.js'
503
+ */
504
+ configPath?: string;
505
+ /**
506
+ * Optional config object (for edge environments without filesystem).
507
+ * If provided, skips filesystem-based config loading.
508
+ *
509
+ * @example { name: 'My Game', integrations: { timeback: {...} } }
510
+ */
511
+ config?: PlaycademyConfig;
512
+ /**
513
+ * Optional base URL for Playcademy API.
514
+ * Defaults to environment variables or 'https://hub.playcademy.net'.
515
+ *
516
+ * @example 'http://localhost:3000' for local development
517
+ */
518
+ baseUrl?: string;
519
+ /**
520
+ * Optional game ID.
521
+ * If not provided, will attempt to fetch from API using the API token.
522
+ *
523
+ * @example 'my-math-game'
524
+ */
525
+ gameId?: string;
439
526
  }
440
- interface NotificationStats {
441
- total: number;
442
- delivered: number;
443
- seen: number;
444
- clicked: number;
445
- dismissed: number;
446
- expired: number;
447
- clickThroughRate: number;
527
+ /**
528
+ * Internal state maintained by the PlaycademyClient instance.
529
+ *
530
+ * @internal
531
+ */
532
+ interface PlaycademyServerClientState {
533
+ /** API key for authentication */
534
+ apiKey: string;
535
+ /** Base URL for API requests */
536
+ baseUrl: string;
537
+ /** Game identifier */
538
+ gameId: string;
539
+ /** Loaded game configuration from playcademy.config.js */
540
+ config: PlaycademyConfig;
541
+ /**
542
+ * TimeBack course ID fetched from the Playcademy API.
543
+ * Used for all TimeBack event recording.
544
+ */
545
+ courseId?: string;
448
546
  }
449
547
 
450
548
  /**
@@ -609,30 +707,94 @@ interface UserRankResponse {
609
707
  score: number;
610
708
  userId: string;
611
709
  }
612
- interface UserScore {
613
- id: string;
614
- score: number;
615
- achievedAt: Date;
616
- metadata?: Record<string, unknown>;
617
- gameId: string;
618
- gameTitle: string;
619
- gameSlug: string;
710
+ interface UserScore {
711
+ id: string;
712
+ score: number;
713
+ achievedAt: Date;
714
+ metadata?: Record<string, unknown>;
715
+ gameId: string;
716
+ gameTitle: string;
717
+ gameSlug: string;
718
+ }
719
+ /**
720
+ * Leaderboard entry with required game context.
721
+ * Used when fetching leaderboards for a specific game.
722
+ */
723
+ interface GameLeaderboardEntry {
724
+ rank: number;
725
+ userId: string;
726
+ username: string;
727
+ userImage?: string | null;
728
+ score: number;
729
+ achievedAt: Date;
730
+ metadata?: Record<string, unknown>;
731
+ gameId: string;
732
+ gameTitle: string;
733
+ gameSlug: string;
734
+ }
735
+
736
+ /**
737
+ * Achievement Types
738
+ *
739
+ * @module types/achievement
740
+ */
741
+ type AchievementScopeType = 'daily' | 'weekly' | 'monthly' | 'yearly' | 'game' | 'global' | 'map' | 'level' | 'event';
742
+ declare enum AchievementCompletionType {
743
+ TIME_PLAYED_SESSION = "time_played_session",
744
+ INTERACTION = "interaction",
745
+ LEADERBOARD_RANK = "leaderboard_rank",
746
+ FIRST_SCORE = "first_score",
747
+ PERSONAL_BEST = "personal_best"
748
+ }
749
+ interface AchievementCurrent {
750
+ id: string;
751
+ title: string;
752
+ description?: string | null;
753
+ scope: AchievementScopeType;
754
+ rewardCredits: number;
755
+ limit: number;
756
+ completionType: string;
757
+ completionConfig: unknown;
758
+ target: unknown;
759
+ active: boolean;
760
+ createdAt?: Date | null;
761
+ updatedAt?: Date | null;
762
+ status: 'available' | 'completed';
763
+ scopeKey: string;
764
+ windowStart: string;
765
+ windowEnd: string;
766
+ }
767
+ interface AchievementWithStatus {
768
+ id: string;
769
+ title: string;
770
+ description: string | null;
771
+ scope: AchievementScopeType;
772
+ rewardCredits: number;
773
+ limit: number;
774
+ completionType: string;
775
+ completionConfig: unknown;
776
+ target: unknown;
777
+ active: boolean;
778
+ createdAt: Date | null;
779
+ updatedAt: Date | null;
780
+ status: 'available' | 'completed';
781
+ scopeKey: string;
782
+ windowStart?: string;
783
+ windowEnd?: string;
784
+ }
785
+ interface AchievementHistoryEntry {
786
+ achievementId: string;
787
+ title: string;
788
+ rewardCredits: number;
789
+ createdAt: Date;
790
+ scopeKey: string;
620
791
  }
621
- /**
622
- * Leaderboard entry with required game context.
623
- * Used when fetching leaderboards for a specific game.
624
- */
625
- interface GameLeaderboardEntry {
626
- rank: number;
627
- userId: string;
628
- username: string;
629
- userImage?: string | null;
630
- score: number;
631
- achievedAt: Date;
632
- metadata?: Record<string, unknown>;
633
- gameId: string;
634
- gameTitle: string;
635
- gameSlug: string;
792
+ interface AchievementProgressResponse {
793
+ achievementId: string;
794
+ status: 'completed' | 'already_completed';
795
+ rewardCredits: number;
796
+ scopeKey: string;
797
+ createdAt: Date;
636
798
  }
637
799
 
638
800
  /**
@@ -752,6 +914,35 @@ interface LevelProgressResponse {
752
914
  totalXP: number;
753
915
  }
754
916
 
917
+ /**
918
+ * Notification Types
919
+ *
920
+ * @module types/notification
921
+ */
922
+
923
+ declare enum NotificationType {
924
+ ACHIEVEMENT = "achievement",
925
+ SYSTEM = "system",
926
+ PROMO = "promo"
927
+ }
928
+ declare enum NotificationStatus {
929
+ PENDING = "pending",
930
+ DELIVERED = "delivered",
931
+ SEEN = "seen",
932
+ CLICKED = "clicked",
933
+ DISMISSED = "dismissed",
934
+ EXPIRED = "expired"
935
+ }
936
+ interface NotificationStats {
937
+ total: number;
938
+ delivered: number;
939
+ seen: number;
940
+ clicked: number;
941
+ dismissed: number;
942
+ expired: number;
943
+ clickThroughRate: number;
944
+ }
945
+
755
946
  /**
756
947
  * Shop Types
757
948
  *
@@ -1076,7 +1267,7 @@ declare const users: drizzle_orm_pg_core.PgTableWithColumns<{
1076
1267
  generated: undefined;
1077
1268
  }, {}, {}>;
1078
1269
  };
1079
- dialect: "pg";
1270
+ dialect: 'pg';
1080
1271
  }>;
1081
1272
 
1082
1273
  interface GameMetadata {
@@ -1352,7 +1543,7 @@ declare const games: drizzle_orm_pg_core.PgTableWithColumns<{
1352
1543
  generated: undefined;
1353
1544
  }, {}, {}>;
1354
1545
  };
1355
- dialect: "pg";
1546
+ dialect: 'pg';
1356
1547
  }>;
1357
1548
  declare const gameSessions: drizzle_orm_pg_core.PgTableWithColumns<{
1358
1549
  name: "game_sessions";
@@ -1444,7 +1635,7 @@ declare const gameSessions: drizzle_orm_pg_core.PgTableWithColumns<{
1444
1635
  generated: undefined;
1445
1636
  }, {}, {}>;
1446
1637
  };
1447
- dialect: "pg";
1638
+ dialect: 'pg';
1448
1639
  }>;
1449
1640
  /**
1450
1641
  * Custom hostnames table
@@ -1645,7 +1836,7 @@ declare const gameCustomHostnames: drizzle_orm_pg_core.PgTableWithColumns<{
1645
1836
  generated: undefined;
1646
1837
  }, {}, {}>;
1647
1838
  };
1648
- dialect: "pg";
1839
+ dialect: 'pg';
1649
1840
  }>;
1650
1841
  declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
1651
1842
  name: "items";
@@ -1822,7 +2013,7 @@ declare const items: drizzle_orm_pg_core.PgTableWithColumns<{
1822
2013
  generated: undefined;
1823
2014
  }, {}, {}>;
1824
2015
  };
1825
- dialect: "pg";
2016
+ dialect: 'pg';
1826
2017
  }>;
1827
2018
  declare const inventoryItems: drizzle_orm_pg_core.PgTableWithColumns<{
1828
2019
  name: "inventory_items";
@@ -1914,7 +2105,7 @@ declare const inventoryItems: drizzle_orm_pg_core.PgTableWithColumns<{
1914
2105
  generated: undefined;
1915
2106
  }, {}, {}>;
1916
2107
  };
1917
- dialect: "pg";
2108
+ dialect: 'pg';
1918
2109
  }>;
1919
2110
  declare const currencies: drizzle_orm_pg_core.PgTableWithColumns<{
1920
2111
  name: "currencies";
@@ -2023,7 +2214,7 @@ declare const currencies: drizzle_orm_pg_core.PgTableWithColumns<{
2023
2214
  generated: undefined;
2024
2215
  }, {}, {}>;
2025
2216
  };
2026
- dialect: "pg";
2217
+ dialect: 'pg';
2027
2218
  }>;
2028
2219
  declare const shopListings: drizzle_orm_pg_core.PgTableWithColumns<{
2029
2220
  name: "shop_listings";
@@ -2217,7 +2408,7 @@ declare const shopListings: drizzle_orm_pg_core.PgTableWithColumns<{
2217
2408
  generated: undefined;
2218
2409
  }, {}, {}>;
2219
2410
  };
2220
- dialect: "pg";
2411
+ dialect: 'pg';
2221
2412
  }>;
2222
2413
  declare const maps: drizzle_orm_pg_core.PgTableWithColumns<{
2223
2414
  name: "maps";
@@ -2368,7 +2559,7 @@ declare const maps: drizzle_orm_pg_core.PgTableWithColumns<{
2368
2559
  generated: undefined;
2369
2560
  }, {}, {}>;
2370
2561
  };
2371
- dialect: "pg";
2562
+ dialect: 'pg';
2372
2563
  }>;
2373
2564
  declare const mapElements: drizzle_orm_pg_core.PgTableWithColumns<{
2374
2565
  name: "map_elements";
@@ -2481,7 +2672,7 @@ declare const mapElements: drizzle_orm_pg_core.PgTableWithColumns<{
2481
2672
  $type: Record<string, unknown>;
2482
2673
  }>;
2483
2674
  };
2484
- dialect: "pg";
2675
+ dialect: 'pg';
2485
2676
  }>;
2486
2677
  declare const mapObjects: drizzle_orm_pg_core.PgTableWithColumns<{
2487
2678
  name: "map_objects";
@@ -2641,7 +2832,7 @@ declare const mapObjects: drizzle_orm_pg_core.PgTableWithColumns<{
2641
2832
  generated: undefined;
2642
2833
  }, {}, {}>;
2643
2834
  };
2644
- dialect: "pg";
2835
+ dialect: 'pg';
2645
2836
  }>;
2646
2837
 
2647
2838
  declare const userLevels: drizzle_orm_pg_core.PgTableWithColumns<{
@@ -2768,7 +2959,7 @@ declare const userLevels: drizzle_orm_pg_core.PgTableWithColumns<{
2768
2959
  generated: undefined;
2769
2960
  }, {}, {}>;
2770
2961
  };
2771
- dialect: "pg";
2962
+ dialect: 'pg';
2772
2963
  }>;
2773
2964
  declare const levelConfigs: drizzle_orm_pg_core.PgTableWithColumns<{
2774
2965
  name: "level_configs";
@@ -2860,7 +3051,7 @@ declare const levelConfigs: drizzle_orm_pg_core.PgTableWithColumns<{
2860
3051
  generated: undefined;
2861
3052
  }, {}, {}>;
2862
3053
  };
2863
- dialect: "pg";
3054
+ dialect: 'pg';
2864
3055
  }>;
2865
3056
 
2866
3057
  declare const spriteTemplates: drizzle_orm_pg_core.PgTableWithColumns<{
@@ -2957,7 +3148,7 @@ declare const spriteTemplates: drizzle_orm_pg_core.PgTableWithColumns<{
2957
3148
  generated: undefined;
2958
3149
  }, {}, {}>;
2959
3150
  };
2960
- dialect: "pg";
3151
+ dialect: 'pg';
2961
3152
  }>;
2962
3153
  declare const characterComponents: drizzle_orm_pg_core.PgTableWithColumns<{
2963
3154
  name: "character_components";
@@ -3140,7 +3331,7 @@ declare const characterComponents: drizzle_orm_pg_core.PgTableWithColumns<{
3140
3331
  generated: undefined;
3141
3332
  }, {}, {}>;
3142
3333
  };
3143
- dialect: "pg";
3334
+ dialect: 'pg';
3144
3335
  }>;
3145
3336
  declare const playerCharacters: drizzle_orm_pg_core.PgTableWithColumns<{
3146
3337
  name: "player_characters";
@@ -3283,7 +3474,7 @@ declare const playerCharacters: drizzle_orm_pg_core.PgTableWithColumns<{
3283
3474
  generated: undefined;
3284
3475
  }, {}, {}>;
3285
3476
  };
3286
- dialect: "pg";
3477
+ dialect: 'pg';
3287
3478
  }>;
3288
3479
  declare const playerCharacterAccessories: drizzle_orm_pg_core.PgTableWithColumns<{
3289
3480
  name: "player_character_accessories";
@@ -3394,7 +3585,7 @@ declare const playerCharacterAccessories: drizzle_orm_pg_core.PgTableWithColumns
3394
3585
  generated: undefined;
3395
3586
  }, {}, {}>;
3396
3587
  };
3397
- dialect: "pg";
3588
+ dialect: 'pg';
3398
3589
  }>;
3399
3590
  declare const notifications: drizzle_orm_pg_core.PgTableWithColumns<{
3400
3591
  name: "notifications";
@@ -3679,7 +3870,7 @@ declare const notifications: drizzle_orm_pg_core.PgTableWithColumns<{
3679
3870
  generated: undefined;
3680
3871
  }, {}, {}>;
3681
3872
  };
3682
- dialect: "pg";
3873
+ dialect: 'pg';
3683
3874
  }>;
3684
3875
  declare const UpsertGameMetadataSchema: z.ZodEffects<z.ZodObject<{
3685
3876
  displayName: z.ZodString;
@@ -4422,197 +4613,6 @@ type SpriteTemplateRow = typeof spriteTemplates.$inferSelect;
4422
4613
 
4423
4614
  type NotificationRow = InferSelectModel<typeof notifications>;
4424
4615
 
4425
- /**
4426
- * @fileoverview Server SDK Type Definitions
4427
- *
4428
- * TypeScript type definitions for the server-side Playcademy SDK.
4429
- * Includes configuration types, client state, and re-exported TimeBack types.
4430
- */
4431
-
4432
- /**
4433
- * Base configuration for TimeBack integration (shared across all courses).
4434
- * References upstream TimeBack types from @playcademy/timeback.
4435
- *
4436
- * All fields are optional and support template variables: {grade}, {subject}, {gameSlug}
4437
- */
4438
- interface TimebackBaseConfig {
4439
- /** Organization configuration (shared across all courses) */
4440
- organization?: Partial<OrganizationConfig>;
4441
- /** Course defaults (can be overridden per-course) */
4442
- course?: Partial<CourseConfig>;
4443
- /** Component defaults */
4444
- component?: Partial<ComponentConfig>;
4445
- /** Resource defaults */
4446
- resource?: Partial<ResourceConfig>;
4447
- /** ComponentResource defaults */
4448
- componentResource?: Partial<ComponentResourceConfig>;
4449
- }
4450
- /**
4451
- * Extended course configuration that merges TimebackCourseConfig with per-course overrides.
4452
- * Used in playcademy.config.* to allow per-course customization.
4453
- */
4454
- interface TimebackCourseConfigWithOverrides extends TimebackCourseConfig {
4455
- title?: string;
4456
- courseCode?: string;
4457
- level?: string;
4458
- metadata?: CourseConfig['metadata'];
4459
- totalXp?: number | null;
4460
- masterableUnits?: number | null;
4461
- }
4462
- /**
4463
- * TimeBack integration configuration for Playcademy config file.
4464
- *
4465
- * Supports two levels of customization:
4466
- * 1. `base`: Shared defaults for all courses (organization, course, component, resource, componentResource)
4467
- * 2. Per-course overrides in the `courses` array (title, courseCode, level, gradingScheme, metadata)
4468
- *
4469
- * Template variables ({grade}, {subject}, {gameSlug}) can be used in string fields.
4470
- */
4471
- interface TimebackIntegrationConfig {
4472
- /** Multi-grade course configuration (array of grade/subject/totalXp with optional per-course overrides) */
4473
- courses: TimebackCourseConfigWithOverrides[];
4474
- /** Optional base configuration (shared across all courses, can be overridden per-course) */
4475
- base?: TimebackBaseConfig;
4476
- }
4477
- /**
4478
- * Custom API routes integration
4479
- */
4480
- interface CustomRoutesIntegration {
4481
- /** Directory for custom API routes (defaults to 'server/api') */
4482
- directory?: string;
4483
- }
4484
- /**
4485
- * Database integration
4486
- */
4487
- interface DatabaseIntegration {
4488
- /** Database directory (defaults to 'db') */
4489
- directory?: string;
4490
- /** Schema strategy: 'push' uses drizzle-kit push-style diffing, 'migrate' uses migration files.
4491
- * When omitted, auto-detects based on presence of a migrations directory with _journal.json. */
4492
- strategy?: 'push' | 'migrate';
4493
- }
4494
- interface QueueConfig {
4495
- maxBatchSize?: number;
4496
- maxRetries?: number;
4497
- maxBatchTimeout?: number;
4498
- maxConcurrency?: number;
4499
- retryDelay?: number;
4500
- deadLetterQueue?: string;
4501
- }
4502
- /**
4503
- * Integrations configuration
4504
- * All backend features (database, custom routes, external services) are configured here
4505
- */
4506
- interface IntegrationsConfig {
4507
- /** TimeBack integration (optional) */
4508
- timeback?: TimebackIntegrationConfig | null;
4509
- /** Custom API routes (optional) */
4510
- customRoutes?: CustomRoutesIntegration | boolean;
4511
- /** Database (optional) */
4512
- database?: DatabaseIntegration | boolean;
4513
- /** Key-Value storage (optional) */
4514
- kv?: boolean;
4515
- /** Bucket storage (optional) */
4516
- bucket?: boolean;
4517
- /** Authentication (optional) */
4518
- auth?: boolean;
4519
- /** Queues (optional) */
4520
- queues?: Record<string, QueueConfig | boolean>;
4521
- }
4522
- /**
4523
- * Unified Playcademy configuration
4524
- * Used for playcademy.config.{js,json}
4525
- */
4526
- interface PlaycademyConfig {
4527
- /** Game name */
4528
- name: string;
4529
- /** Game description */
4530
- description?: string;
4531
- /** Game emoji icon */
4532
- emoji?: string;
4533
- /** Build command to run before deployment */
4534
- buildCommand?: string[];
4535
- /** Path to build output */
4536
- buildPath?: string;
4537
- /** Game type */
4538
- gameType?: 'hosted' | 'external';
4539
- /** External URL (for external games) */
4540
- externalUrl?: string;
4541
- /** Game platform */
4542
- platform?: 'web' | 'unity' | 'godot';
4543
- /** Integrations (database, custom routes, external services) */
4544
- integrations?: IntegrationsConfig;
4545
- }
4546
-
4547
- /**
4548
- * Configuration options for initializing a PlaycademyClient instance.
4549
- *
4550
- * @example
4551
- * ```typescript
4552
- * const config: PlaycademyServerClientConfig = {
4553
- * apiKey: process.env.PLAYCADEMY_API_KEY!,
4554
- * gameId: 'my-math-game',
4555
- * configPath: './playcademy.config.js'
4556
- * }
4557
- * ```
4558
- */
4559
- interface PlaycademyServerClientConfig {
4560
- /**
4561
- * Playcademy API key for server-to-server authentication.
4562
- * Obtain from the Playcademy developer dashboard.
4563
- */
4564
- apiKey: string;
4565
- /**
4566
- * Optional path to playcademy.config.js file.
4567
- * If not provided, searches current directory and up to 3 parent directories.
4568
- * Ignored if `config` is provided directly.
4569
- *
4570
- * @example './config/playcademy.config.js'
4571
- */
4572
- configPath?: string;
4573
- /**
4574
- * Optional config object (for edge environments without filesystem).
4575
- * If provided, skips filesystem-based config loading.
4576
- *
4577
- * @example { name: 'My Game', integrations: { timeback: {...} } }
4578
- */
4579
- config?: PlaycademyConfig;
4580
- /**
4581
- * Optional base URL for Playcademy API.
4582
- * Defaults to environment variables or 'https://hub.playcademy.net'.
4583
- *
4584
- * @example 'http://localhost:3000' for local development
4585
- */
4586
- baseUrl?: string;
4587
- /**
4588
- * Optional game ID.
4589
- * If not provided, will attempt to fetch from API using the API token.
4590
- *
4591
- * @example 'my-math-game'
4592
- */
4593
- gameId?: string;
4594
- }
4595
- /**
4596
- * Internal state maintained by the PlaycademyClient instance.
4597
- *
4598
- * @internal
4599
- */
4600
- interface PlaycademyServerClientState {
4601
- /** API key for authentication */
4602
- apiKey: string;
4603
- /** Base URL for API requests */
4604
- baseUrl: string;
4605
- /** Game identifier */
4606
- gameId: string;
4607
- /** Loaded game configuration from playcademy.config.js */
4608
- config: PlaycademyConfig;
4609
- /**
4610
- * TimeBack course ID fetched from the Playcademy API.
4611
- * Used for all TimeBack event recording.
4612
- */
4613
- courseId?: string;
4614
- }
4615
-
4616
4616
  /**
4617
4617
  * Connection monitoring types
4618
4618
  *
@@ -5253,8 +5253,8 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
5253
5253
  */
5254
5254
  runtime: {
5255
5255
  getGameToken: (gameId: string, options?: {
5256
- apply?: boolean | undefined;
5257
- } | undefined) => Promise<GameTokenResponse>;
5256
+ apply?: boolean;
5257
+ }) => Promise<GameTokenResponse>;
5258
5258
  exit: () => Promise<void>;
5259
5259
  onInit: (handler: (context: GameContextPayload) => void) => void;
5260
5260
  onTokenRefresh: (handler: (data: {
@@ -5278,7 +5278,7 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
5278
5278
  getListenerCounts: () => Record<string, number>;
5279
5279
  assets: {
5280
5280
  url(pathOrStrings: string | TemplateStringsArray, ...values: unknown[]): string;
5281
- fetch: (path: string, options?: RequestInit | undefined) => Promise<Response>;
5281
+ fetch: (path: string, options?: RequestInit) => Promise<Response>;
5282
5282
  json: <T = unknown>(path: string) => Promise<T>;
5283
5283
  blob: (path: string) => Promise<Blob>;
5284
5284
  text: (path: string) => Promise<string>;
@@ -5303,13 +5303,13 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
5303
5303
  */
5304
5304
  timeback: {
5305
5305
  readonly user: TimebackUser;
5306
- startActivity: (metadata: ActivityData, options?: StartActivityOptions | undefined) => void;
5306
+ startActivity: (metadata: ActivityData, options?: StartActivityOptions) => void;
5307
5307
  pauseActivity: () => void;
5308
5308
  resumeActivity: () => void;
5309
5309
  endActivity: (data: EndActivityScoreData) => Promise<EndActivityResponse>;
5310
5310
  advanceCourse: (options?: {
5311
- subject?: TimebackSubject | undefined;
5312
- } | undefined) => Promise<AdvanceCourseResponse>;
5311
+ subject?: TimebackSubject;
5312
+ }) => Promise<AdvanceCourseResponse>;
5313
5313
  };
5314
5314
  /**
5315
5315
  * Playcademy Credits (platform currency) management.
@@ -5326,14 +5326,14 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
5326
5326
  * - `submit(score, metadata?)` - Record a game score
5327
5327
  */
5328
5328
  scores: {
5329
- submit: (score: number, metadata?: Record<string, unknown> | undefined) => Promise<ScoreSubmission>;
5329
+ submit: (score: number, metadata?: Record<string, unknown>) => Promise<ScoreSubmission>;
5330
5330
  };
5331
5331
  /**
5332
5332
  * Read-only leaderboard access for the current game scope.
5333
5333
  * - `fetch(options?)` - Fetch leaderboard entries
5334
5334
  */
5335
5335
  leaderboard: {
5336
- fetch: (options?: LeaderboardOptions | undefined) => Promise<GameLeaderboardEntry[]>;
5336
+ fetch: (options?: LeaderboardOptions) => Promise<GameLeaderboardEntry[]>;
5337
5337
  };
5338
5338
  /**
5339
5339
  * Demo-mode helpers. Methods throw when called outside `client.mode === 'demo'`,
@@ -5347,7 +5347,7 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
5347
5347
  get: () => Promise<DemoProfile>;
5348
5348
  update: (updates: DemoProfileUpdate) => Promise<DemoProfile>;
5349
5349
  };
5350
- end: (score: number, options?: DemoEndOptions | undefined) => void;
5350
+ end: (score: number, options?: DemoEndOptions) => void;
5351
5351
  };
5352
5352
  /**
5353
5353
  * Realtime multiplayer authentication.
@@ -5364,13 +5364,13 @@ declare class PlaycademyClient extends PlaycademyBaseClient {
5364
5364
  * - Routes are relative to your game's deployment (e.g., '/hello' → your-game.playcademy.gg/api/hello)
5365
5365
  */
5366
5366
  backend: {
5367
- get<T = unknown>(path: string, headers?: Record<string, string> | undefined): Promise<T>;
5368
- post<T = unknown>(path: string, body?: unknown, headers?: Record<string, string> | undefined): Promise<T>;
5369
- put<T = unknown>(path: string, body?: unknown, headers?: Record<string, string> | undefined): Promise<T>;
5370
- patch<T = unknown>(path: string, body?: unknown, headers?: Record<string, string> | undefined): Promise<T>;
5371
- delete<T = unknown>(path: string, headers?: Record<string, string> | undefined): Promise<T>;
5372
- request<T = unknown>(path: string, method: Method, body?: unknown, headers?: Record<string, string> | undefined): Promise<T>;
5373
- download(path: string, method?: Method, body?: unknown, headers?: Record<string, string> | undefined): Promise<Response>;
5367
+ get<T = unknown>(path: string, headers?: Record<string, string>): Promise<T>;
5368
+ post<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
5369
+ put<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
5370
+ patch<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
5371
+ delete<T = unknown>(path: string, headers?: Record<string, string>): Promise<T>;
5372
+ request<T = unknown>(path: string, method: Method, body?: unknown, headers?: Record<string, string>): Promise<T>;
5373
+ download(path: string, method?: Method, body?: unknown, headers?: Record<string, string>): Promise<Response>;
5374
5374
  url(pathOrStrings: string | TemplateStringsArray, ...values: unknown[]): string;
5375
5375
  };
5376
5376
  /** Auto-initializes a PlaycademyClient with context from the environment */