playcademy 0.1.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.
@@ -0,0 +1,6 @@
1
+
2
+
3
+ // Custom API routes directory
4
+ backend: {
5
+ directory: '{{API_DIRECTORY}}', // defaults to 'api'
6
+ },
@@ -0,0 +1,7 @@
1
+
2
+
3
+ // External integrations
4
+ // See https://docs.playcademy.com/integrations for more details
5
+ integrations: {
6
+ {{INTEGRATIONS_CONTENT}}
7
+ },
@@ -0,0 +1,4 @@
1
+ /** @type {import('playcademy/types').PlaycademyConfig} */
2
+ export default {
3
+ name: '{{GAME_NAME}}',{{GAME_DESCRIPTION}}{{GAME_EMOJI}}{{BACKEND_CONFIG}}{{INTEGRATIONS_CONFIG}}
4
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "name": "{{GAME_NAME}}"{{GAME_DESCRIPTION}}{{GAME_EMOJI}}{{BACKEND_CONFIG}}{{INTEGRATIONS_CONFIG}}
3
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Sample API route
3
+ *
4
+ * This route will be available at: https://<your-game-slug>.playcademy.gg/api/hello
5
+ */
6
+ import type { Context } from 'hono'
7
+
8
+ /**
9
+ * GET /api/hello
10
+ */
11
+ export async function GET(c: Context): Promise<Response> {
12
+ return c.json({
13
+ message: 'Hello from your game backend!',
14
+ timestamp: new Date().toISOString(),
15
+ })
16
+ }
17
+
18
+ /**
19
+ * POST /api/hello
20
+ */
21
+ export async function POST(c: Context): Promise<Response> {
22
+ const body = await c.req.json()
23
+
24
+ return c.json({
25
+ message: 'Received your data!',
26
+ received: body,
27
+ })
28
+ }
29
+
30
+ /**
31
+ * Environment variables available via c.env:
32
+ * - c.env.PLAYCADEMY_API_KEY - Game-scoped API key for calling Playcademy APIs
33
+ * - c.env.GAME_ID - Your game's unique ID
34
+ * - c.env.PLAYCADEMY_BASE_URL - Playcademy platform URL
35
+ *
36
+ * Access the SDK client:
37
+ * - const sdk = c.get('sdk') - Pre-initialized PlaycademyClient
38
+ */
@@ -0,0 +1,17 @@
1
+ // TimeBack integration configuration
2
+ // See https://docs.playcademy.com/timeback for more details
3
+ timeback: {
4
+ // Optional: customize organization
5
+ // organization: {
6
+ // name: 'My School',
7
+ // type: 'school',
8
+ // },
9
+ course: {
10
+ subjects: {{SUBJECTS}},
11
+ grades: {{GRADES}},
12
+ // Optional: customize course details
13
+ // title: 'Custom Course Title',
14
+ // courseCode: 'COURSE-101',
15
+ // level: 'Elementary',
16
+ },
17
+ },
@@ -0,0 +1,628 @@
1
+ import { UserInfo, ApiKey, BackendDeploymentResponse } from '@playcademy/data/types';
2
+ import { OrganizationConfig, CourseConfig, ComponentConfig, ResourceConfig, ComponentResourceConfig } from '@playcademy/timeback/types';
3
+ export { ComponentConfig, ComponentResourceConfig, CourseConfig, DerivedComponentConfig, DerivedComponentResourceConfig, DerivedCourseConfig, DerivedOrganizationConfig, DerivedResourceConfig, DerivedTimebackConfig, OrganizationConfig, ResourceConfig, TimebackGrade, TimebackSourcedIds, TimebackSubject } from '@playcademy/timeback/types';
4
+ import { PlaycademyClient } from '@playcademy/sdk';
5
+ import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
6
+
7
+ /**
8
+ * Type of authentication token
9
+ * Duplicated from SDK to avoid circular dependency
10
+ */
11
+ type TokenType = 'session' | 'apiKey' | 'gameJwt';
12
+ /**
13
+ * Authentication profile stored for a user
14
+ * CLI-specific type for managing stored credentials
15
+ */
16
+ interface AuthProfile {
17
+ token: string;
18
+ /** Type of token to determine how to use it in API calls */
19
+ tokenType: TokenType;
20
+ /** User ID associated with the token (may not be present for API keys) */
21
+ userId?: string;
22
+ email?: string;
23
+ /** ISO 8601 date string - when the token expires (if applicable) */
24
+ expiresAt?: string;
25
+ }
26
+ /**
27
+ * The complete auth store structure
28
+ * CLI-specific type for ~/.playcademy/auth.json
29
+ */
30
+ interface AuthStore {
31
+ /** Default authentication profile used when no profile is specified */
32
+ default: AuthProfile | null;
33
+ /** Named authentication profiles for different environments/contexts */
34
+ profiles: Record<string, AuthProfile>;
35
+ }
36
+ /**
37
+ * Login credentials for email/password authentication
38
+ */
39
+ interface LoginCredentials {
40
+ email: string;
41
+ password: string;
42
+ }
43
+ /**
44
+ * Login response from email/password authentication
45
+ */
46
+ interface LoginResponse {
47
+ /** Session token received from login */
48
+ token: string;
49
+ /** Always 'session' for email/password login */
50
+ tokenType: 'session';
51
+ /** User information associated with the token */
52
+ user: UserInfo;
53
+ /** ISO 8601 date string - when the session expires */
54
+ expiresAt: string;
55
+ }
56
+ /**
57
+ * API key creation response
58
+ * Extends ApiKey with the actual key on creation
59
+ */
60
+ interface ApiKeyWithSecret extends ApiKey {
61
+ /** The actual API key - only present when creating a new key */
62
+ apiKey: string;
63
+ }
64
+
65
+ /**
66
+ * API configuration derived from environment
67
+ */
68
+ interface ApiConfig {
69
+ /** Base URL for API requests (e.g., https://hub.playcademy.com) */
70
+ baseUrl: string;
71
+ /** Current environment being targeted */
72
+ environment: 'staging' | 'production';
73
+ }
74
+ /**
75
+ * Options for API requests
76
+ */
77
+ interface ApiRequestOptions {
78
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
79
+ /** Request body data - will be JSON stringified */
80
+ body?: unknown;
81
+ /** Additional headers to include in the request */
82
+ headers?: Record<string, string>;
83
+ /** Auth profile to use for this request (defaults to 'default') */
84
+ profile?: string;
85
+ }
86
+ /**
87
+ * Standard API error response
88
+ */
89
+ interface ApiErrorResponse {
90
+ /** Error code/type for programmatic handling */
91
+ error: string;
92
+ /** Human-readable error message */
93
+ message: string;
94
+ statusCode: number;
95
+ }
96
+ /**
97
+ * Better-auth sign-in response
98
+ */
99
+ interface SignInResponse {
100
+ /** Session token */
101
+ token: string;
102
+ /** User information */
103
+ user: {
104
+ id: string;
105
+ email: string;
106
+ };
107
+ /** ISO 8601 date string - when the session expires */
108
+ expiresAt: string;
109
+ }
110
+ /**
111
+ * Better-auth API key creation response
112
+ */
113
+ interface CreateApiKeyResponse {
114
+ /** The actual API key - only shown once */
115
+ apiKey: string;
116
+ /** Key metadata */
117
+ key: {
118
+ id: string;
119
+ name: string | null;
120
+ expiresAt: string | null;
121
+ createdAt: string;
122
+ };
123
+ }
124
+ /**
125
+ * Better-auth API key list item
126
+ */
127
+ interface ApiKeyListItem {
128
+ id: string;
129
+ name: string | null;
130
+ start: string;
131
+ enabled: boolean;
132
+ expiresAt: string | null;
133
+ createdAt: string;
134
+ updatedAt: string;
135
+ lastRequest: string | null;
136
+ requestCount: number;
137
+ }
138
+
139
+ /**
140
+ * @fileoverview Server SDK Type Definitions
141
+ *
142
+ * TypeScript type definitions for the server-side Playcademy SDK.
143
+ * Includes configuration types, client state, and re-exported TimeBack types.
144
+ */
145
+
146
+ /**
147
+ * TimeBack integration configuration for Playcademy config file
148
+ */
149
+ interface TimebackIntegrationConfig {
150
+ /** Organization overrides */
151
+ organization?: Partial<OrganizationConfig>;
152
+ /** Course configuration (subjects and grades REQUIRED) */
153
+ course: CourseConfig;
154
+ /** Component overrides */
155
+ component?: Partial<ComponentConfig>;
156
+ /** Resource overrides */
157
+ resource?: Partial<ResourceConfig>;
158
+ /** Component-Resource link overrides */
159
+ componentResource?: Partial<ComponentResourceConfig>;
160
+ }
161
+ /**
162
+ * Integrations configuration
163
+ */
164
+ interface IntegrationsConfig {
165
+ /** TimeBack integration (optional) */
166
+ timeback?: TimebackIntegrationConfig;
167
+ }
168
+ /**
169
+ * Unified Playcademy configuration
170
+ * Used for playcademy.config.{js,json}
171
+ */
172
+ interface PlaycademyConfig {
173
+ /** Game name */
174
+ name: string;
175
+ /** Game description */
176
+ description?: string;
177
+ /** Game emoji icon */
178
+ emoji?: string;
179
+ /** Build command to run before deployment */
180
+ buildCommand?: string[];
181
+ /** Path to build output */
182
+ buildPath?: string;
183
+ /** Game type */
184
+ gameType?: 'hosted' | 'external';
185
+ /** External URL (for external games) */
186
+ externalUrl?: string;
187
+ /** Game platform */
188
+ platform?: 'web' | 'unity' | 'godot';
189
+ /** Backend configuration */
190
+ backend?: {
191
+ /** Custom API routes directory (defaults to 'api') */
192
+ directory?: string;
193
+ };
194
+ /** External integrations */
195
+ integrations?: IntegrationsConfig;
196
+ }
197
+
198
+ type GameMetadata = {
199
+ description?: string;
200
+ emoji?: string;
201
+ [key: string]: unknown;
202
+ };
203
+ declare const games: drizzle_orm_pg_core.PgTableWithColumns<{
204
+ name: "games";
205
+ schema: undefined;
206
+ columns: {
207
+ id: drizzle_orm_pg_core.PgColumn<{
208
+ name: "id";
209
+ tableName: "games";
210
+ dataType: "string";
211
+ columnType: "PgUUID";
212
+ data: string;
213
+ driverParam: string;
214
+ notNull: true;
215
+ hasDefault: true;
216
+ isPrimaryKey: true;
217
+ isAutoincrement: false;
218
+ hasRuntimeDefault: false;
219
+ enumValues: undefined;
220
+ baseColumn: never;
221
+ identity: undefined;
222
+ generated: undefined;
223
+ }, {}, {}>;
224
+ developerId: drizzle_orm_pg_core.PgColumn<{
225
+ name: "developer_id";
226
+ tableName: "games";
227
+ dataType: "string";
228
+ columnType: "PgText";
229
+ data: string;
230
+ driverParam: string;
231
+ notNull: false;
232
+ hasDefault: false;
233
+ isPrimaryKey: false;
234
+ isAutoincrement: false;
235
+ hasRuntimeDefault: false;
236
+ enumValues: [string, ...string[]];
237
+ baseColumn: never;
238
+ identity: undefined;
239
+ generated: undefined;
240
+ }, {}, {}>;
241
+ slug: drizzle_orm_pg_core.PgColumn<{
242
+ name: "slug";
243
+ tableName: "games";
244
+ dataType: "string";
245
+ columnType: "PgVarchar";
246
+ data: string;
247
+ driverParam: string;
248
+ notNull: true;
249
+ hasDefault: false;
250
+ isPrimaryKey: false;
251
+ isAutoincrement: false;
252
+ hasRuntimeDefault: false;
253
+ enumValues: [string, ...string[]];
254
+ baseColumn: never;
255
+ identity: undefined;
256
+ generated: undefined;
257
+ }, {}, {
258
+ length: 255;
259
+ }>;
260
+ displayName: drizzle_orm_pg_core.PgColumn<{
261
+ name: "display_name";
262
+ tableName: "games";
263
+ dataType: "string";
264
+ columnType: "PgVarchar";
265
+ data: string;
266
+ driverParam: string;
267
+ notNull: true;
268
+ hasDefault: false;
269
+ isPrimaryKey: false;
270
+ isAutoincrement: false;
271
+ hasRuntimeDefault: false;
272
+ enumValues: [string, ...string[]];
273
+ baseColumn: never;
274
+ identity: undefined;
275
+ generated: undefined;
276
+ }, {}, {
277
+ length: 255;
278
+ }>;
279
+ version: drizzle_orm_pg_core.PgColumn<{
280
+ name: "version";
281
+ tableName: "games";
282
+ dataType: "string";
283
+ columnType: "PgVarchar";
284
+ data: string;
285
+ driverParam: string;
286
+ notNull: true;
287
+ hasDefault: false;
288
+ isPrimaryKey: false;
289
+ isAutoincrement: false;
290
+ hasRuntimeDefault: false;
291
+ enumValues: [string, ...string[]];
292
+ baseColumn: never;
293
+ identity: undefined;
294
+ generated: undefined;
295
+ }, {}, {
296
+ length: 50;
297
+ }>;
298
+ gameType: drizzle_orm_pg_core.PgColumn<{
299
+ name: "game_type";
300
+ tableName: "games";
301
+ dataType: "string";
302
+ columnType: "PgEnumColumn";
303
+ data: "hosted" | "external";
304
+ driverParam: string;
305
+ notNull: true;
306
+ hasDefault: true;
307
+ isPrimaryKey: false;
308
+ isAutoincrement: false;
309
+ hasRuntimeDefault: false;
310
+ enumValues: ["hosted", "external"];
311
+ baseColumn: never;
312
+ identity: undefined;
313
+ generated: undefined;
314
+ }, {}, {}>;
315
+ assetBundleBase: drizzle_orm_pg_core.PgColumn<{
316
+ name: "asset_bundle_base";
317
+ tableName: "games";
318
+ dataType: "string";
319
+ columnType: "PgText";
320
+ data: string;
321
+ driverParam: string;
322
+ notNull: false;
323
+ hasDefault: false;
324
+ isPrimaryKey: false;
325
+ isAutoincrement: false;
326
+ hasRuntimeDefault: false;
327
+ enumValues: [string, ...string[]];
328
+ baseColumn: never;
329
+ identity: undefined;
330
+ generated: undefined;
331
+ }, {}, {}>;
332
+ externalUrl: drizzle_orm_pg_core.PgColumn<{
333
+ name: "external_url";
334
+ tableName: "games";
335
+ dataType: "string";
336
+ columnType: "PgText";
337
+ data: string;
338
+ driverParam: string;
339
+ notNull: false;
340
+ hasDefault: false;
341
+ isPrimaryKey: false;
342
+ isAutoincrement: false;
343
+ hasRuntimeDefault: false;
344
+ enumValues: [string, ...string[]];
345
+ baseColumn: never;
346
+ identity: undefined;
347
+ generated: undefined;
348
+ }, {}, {}>;
349
+ platform: drizzle_orm_pg_core.PgColumn<{
350
+ name: "platform";
351
+ tableName: "games";
352
+ dataType: "string";
353
+ columnType: "PgEnumColumn";
354
+ data: "web" | "godot" | "unity";
355
+ driverParam: string;
356
+ notNull: true;
357
+ hasDefault: true;
358
+ isPrimaryKey: false;
359
+ isAutoincrement: false;
360
+ hasRuntimeDefault: false;
361
+ enumValues: ["web", "godot", "unity"];
362
+ baseColumn: never;
363
+ identity: undefined;
364
+ generated: undefined;
365
+ }, {}, {}>;
366
+ mapElementId: drizzle_orm_pg_core.PgColumn<{
367
+ name: "map_element_id";
368
+ tableName: "games";
369
+ dataType: "string";
370
+ columnType: "PgUUID";
371
+ data: string;
372
+ driverParam: string;
373
+ notNull: false;
374
+ hasDefault: false;
375
+ isPrimaryKey: false;
376
+ isAutoincrement: false;
377
+ hasRuntimeDefault: false;
378
+ enumValues: undefined;
379
+ baseColumn: never;
380
+ identity: undefined;
381
+ generated: undefined;
382
+ }, {}, {}>;
383
+ metadata: drizzle_orm_pg_core.PgColumn<{
384
+ name: "metadata";
385
+ tableName: "games";
386
+ dataType: "json";
387
+ columnType: "PgJsonb";
388
+ data: GameMetadata;
389
+ driverParam: unknown;
390
+ notNull: true;
391
+ hasDefault: true;
392
+ isPrimaryKey: false;
393
+ isAutoincrement: false;
394
+ hasRuntimeDefault: false;
395
+ enumValues: undefined;
396
+ baseColumn: never;
397
+ identity: undefined;
398
+ generated: undefined;
399
+ }, {}, {
400
+ $type: GameMetadata;
401
+ }>;
402
+ createdAt: drizzle_orm_pg_core.PgColumn<{
403
+ name: "created_at";
404
+ tableName: "games";
405
+ dataType: "date";
406
+ columnType: "PgTimestamp";
407
+ data: Date;
408
+ driverParam: string;
409
+ notNull: false;
410
+ hasDefault: true;
411
+ isPrimaryKey: false;
412
+ isAutoincrement: false;
413
+ hasRuntimeDefault: false;
414
+ enumValues: undefined;
415
+ baseColumn: never;
416
+ identity: undefined;
417
+ generated: undefined;
418
+ }, {}, {}>;
419
+ updatedAt: drizzle_orm_pg_core.PgColumn<{
420
+ name: "updated_at";
421
+ tableName: "games";
422
+ dataType: "date";
423
+ columnType: "PgTimestamp";
424
+ data: Date;
425
+ driverParam: string;
426
+ notNull: false;
427
+ hasDefault: true;
428
+ isPrimaryKey: false;
429
+ isAutoincrement: false;
430
+ hasRuntimeDefault: false;
431
+ enumValues: undefined;
432
+ baseColumn: never;
433
+ identity: undefined;
434
+ generated: undefined;
435
+ }, {}, {}>;
436
+ };
437
+ dialect: "pg";
438
+ }>;
439
+ type GameRow = typeof games.$inferSelect;
440
+ type BaseGame = Omit<GameRow, 'gameType' | 'assetBundleBase' | 'externalUrl'>;
441
+ type HostedGame = BaseGame & {
442
+ gameType: 'hosted';
443
+ assetBundleBase: string;
444
+ externalUrl: null;
445
+ };
446
+ type ExternalGame = BaseGame & {
447
+ gameType: 'external';
448
+ assetBundleBase: null;
449
+ externalUrl: string;
450
+ };
451
+ type Game = HostedGame | ExternalGame;
452
+
453
+ /**
454
+ * Deployed game tracking - maps project directories to game IDs
455
+ */
456
+ interface DeployedGameInfo {
457
+ gameId: string;
458
+ lastDeployedAt: string;
459
+ buildPath?: string;
460
+ buildHash?: string;
461
+ buildSize?: number;
462
+ backendHash?: string;
463
+ backendSize?: number;
464
+ backendDeployedAt?: string;
465
+ }
466
+ interface GameStore {
467
+ [projectPath: string]: DeployedGameInfo;
468
+ }
469
+ /**
470
+ * Backend deployment response with code hash for change detection
471
+ */
472
+ interface BackendDeploymentWithHash extends BackendDeploymentResponse {
473
+ /** SHA-256 hash of the deployed backend code */
474
+ backendHash: string;
475
+ /** Size of the deployed backend code in bytes */
476
+ backendSize: number;
477
+ }
478
+ /**
479
+ * Deployment context containing all information needed for deployment
480
+ */
481
+ interface DeploymentContext {
482
+ config: DeployConfig;
483
+ fullConfig: PlaycademyConfig | null;
484
+ configFileName: string | null;
485
+ client: PlaycademyClient;
486
+ projectPath: string;
487
+ existingGame?: Game;
488
+ deployedGameInfo?: DeployedGameInfo;
489
+ isNewDeployment: boolean;
490
+ buildHash?: string;
491
+ buildSize?: number;
492
+ previousBuildHash?: string;
493
+ previousBuildSize?: number;
494
+ previousBackendHash?: string;
495
+ previousBackendSize?: number;
496
+ isDryRun: boolean;
497
+ deployBackend: boolean;
498
+ verbose: boolean;
499
+ }
500
+ /**
501
+ * Analysis of what changed in an update
502
+ */
503
+ interface DeploymentChanges {
504
+ config: boolean;
505
+ build: boolean | undefined;
506
+ backend: boolean | undefined;
507
+ }
508
+ /**
509
+ * Plan for what needs to be deployed
510
+ */
511
+ interface DeploymentPlan {
512
+ action: 'deploy-new' | 'update-existing' | 'no-changes';
513
+ gameType: 'hosted' | 'external';
514
+ shouldDeployFrontend: boolean;
515
+ shouldDeployBackend: boolean;
516
+ changes?: DeploymentChanges;
517
+ currentBackendSize?: number;
518
+ }
519
+ /**
520
+ * Result of a deployment
521
+ */
522
+ interface DeploymentResult {
523
+ game: Game;
524
+ backendDeployment?: BackendDeploymentWithHash | null;
525
+ }
526
+ /**
527
+ * Deployment configuration
528
+ *
529
+ * Configuration for deploying a game to Playcademy.
530
+ * Can be provided via CLI options, playcademy.json file, or package.json.
531
+ */
532
+ interface DeployConfig {
533
+ /** Game slug (URL-friendly identifier) */
534
+ slug?: string;
535
+ /** Display name for the game */
536
+ displayName?: string;
537
+ /** Game description */
538
+ description?: string;
539
+ /** Emoji icon for the game */
540
+ emoji?: string;
541
+ /** Path to the build directory or zip file */
542
+ buildPath?: string;
543
+ /** Game platform (defaults to 'web') */
544
+ platform?: 'web' | 'unity' | 'godot';
545
+ /** Game type */
546
+ gameType?: 'hosted' | 'external';
547
+ /** External URL for external games */
548
+ externalUrl?: string;
549
+ }
550
+ interface DeployNewGameOptions {
551
+ client: PlaycademyClient;
552
+ config: DeployConfig;
553
+ isDryRun: boolean;
554
+ projectPath: string;
555
+ buildHash?: string;
556
+ backend?: boolean;
557
+ }
558
+ interface UpdateExistingGameOptions {
559
+ configFileName?: string | null;
560
+ client: PlaycademyClient;
561
+ config: DeployConfig;
562
+ backend?: boolean;
563
+ existingGame: Game;
564
+ isDryRun: boolean;
565
+ projectPath: string;
566
+ previousBuildHash?: string;
567
+ currentBuildHash?: string;
568
+ previousBuildSize?: number;
569
+ currentBuildSize?: number;
570
+ previousBackendHash?: string;
571
+ previousBackendSize?: number;
572
+ verbose?: boolean;
573
+ }
574
+
575
+ /**
576
+ * Types for the CLI local HTTP server that handles OAuth callbacks
577
+ */
578
+ /**
579
+ * Callback data received from the Playcademy server after SSO authentication
580
+ */
581
+ interface SsoCallbackData {
582
+ /** The session token from SSO authentication */
583
+ sessionToken: string;
584
+ /** User's email address */
585
+ email: string;
586
+ /** User's ID */
587
+ userId: string;
588
+ }
589
+ /**
590
+ * Result from starting and running the callback server
591
+ */
592
+ interface CallbackServerResult {
593
+ /** Whether the callback was successful */
594
+ success: boolean;
595
+ /** The callback data if successful */
596
+ data?: SsoCallbackData;
597
+ /** Error message if unsuccessful */
598
+ error?: string;
599
+ }
600
+
601
+ /**
602
+ * Preview options
603
+ */
604
+ interface PreviewOptions {
605
+ /** Path to project directory (defaults to current directory) */
606
+ project?: string;
607
+ /** Preview duration in hours (defaults to 24, max 168) */
608
+ duration?: number;
609
+ /** Optional password protection for the preview */
610
+ password?: string;
611
+ /** Description or message for the preview */
612
+ message?: string;
613
+ }
614
+ /**
615
+ * Preview response
616
+ */
617
+ interface PreviewResponse {
618
+ /** Unique preview identifier */
619
+ id: string;
620
+ /** URL where the preview is accessible */
621
+ url: string;
622
+ /** ISO 8601 date string - when the preview expires */
623
+ expiresAt: string;
624
+ /** Base64 encoded QR code image for easy mobile access */
625
+ qrCode?: string;
626
+ }
627
+
628
+ export type { ApiConfig, ApiErrorResponse, ApiKeyListItem, ApiKeyWithSecret, ApiRequestOptions, AuthProfile, AuthStore, BackendDeploymentWithHash, CallbackServerResult, CreateApiKeyResponse, DeployConfig, DeployNewGameOptions, DeployedGameInfo, DeploymentChanges, DeploymentContext, DeploymentPlan, DeploymentResult, GameStore, IntegrationsConfig, LoginCredentials, LoginResponse, PlaycademyConfig, PreviewOptions, PreviewResponse, SignInResponse, SsoCallbackData, TimebackIntegrationConfig, TokenType, UpdateExistingGameOptions };