@series-inc/rundot-game-sdk 5.23.0-beta.0 → 5.23.0-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.
Files changed (106) hide show
  1. package/README.md +11 -0
  2. package/dist/{AdsApi-25-HRS5D.d.ts → AdsApi-rdaTFMYZ.d.ts} +60 -11
  3. package/dist/{callRemoteFunction-D-Ah7AxA.d.ts → callRemoteFunction-NBIrdLoa.d.ts} +2 -2
  4. package/dist/{chunk-BJGV6WIK.js → chunk-57DREBKB.js} +2 -2
  5. package/dist/chunk-57DREBKB.js.map +1 -0
  6. package/dist/{chunk-NTONRZFO.js → chunk-7VLTROLB.js} +146 -9
  7. package/dist/chunk-7VLTROLB.js.map +1 -0
  8. package/dist/{chunk-TNBSGNJ2.js → chunk-LKE6IJ4M.js} +3 -3
  9. package/dist/chunk-LKE6IJ4M.js.map +1 -0
  10. package/dist/{chunk-APR46OZQ.js → chunk-V4I4PKDK.js} +277 -55
  11. package/dist/chunk-V4I4PKDK.js.map +1 -0
  12. package/dist/host-http.d.ts +4 -4
  13. package/dist/host-http.js +1 -1
  14. package/dist/index.d.ts +35 -17
  15. package/dist/index.js +2 -2
  16. package/dist/{sandbox → playground}/index.js +104 -102
  17. package/dist/playground/index.js.map +1 -0
  18. package/dist/rundot-game-api/index.d.ts +2 -2
  19. package/dist/rundot-game-api/index.js +3 -3
  20. package/dist/rundot-game-api/index.js.map +1 -1
  21. package/dist/tabCoordinator-2BPJNWVV.js +3 -0
  22. package/dist/{tabCoordinator-SPKWPZDQ.js.map → tabCoordinator-2BPJNWVV.js.map} +1 -1
  23. package/dist/vite/index.css +1 -1
  24. package/dist/vite/index.css.map +1 -1
  25. package/dist/vite/index.d.ts +151 -86
  26. package/dist/vite/index.js +4319 -4298
  27. package/dist/vite/index.js.map +1 -1
  28. package/docs/README.md +97 -0
  29. package/docs/SUMMARY.md +67 -0
  30. package/docs/agents-index.txt +1 -0
  31. package/docs/rundot-developer-platform/api/ACCESS_GATE.md +218 -0
  32. package/docs/rundot-developer-platform/api/ADS.md +167 -0
  33. package/docs/rundot-developer-platform/api/ADVANCED-MULTIPLAYER.md +386 -0
  34. package/docs/rundot-developer-platform/api/AI.md +434 -0
  35. package/docs/rundot-developer-platform/api/ANALYTICS.md +98 -0
  36. package/docs/rundot-developer-platform/api/APP.md +610 -0
  37. package/docs/rundot-developer-platform/api/ASSETS.md +441 -0
  38. package/docs/rundot-developer-platform/api/ATTRIBUTION.md +93 -0
  39. package/docs/rundot-developer-platform/api/AUDIO_GEN.md +283 -0
  40. package/docs/rundot-developer-platform/api/AVATAR_3D.md +210 -0
  41. package/docs/rundot-developer-platform/api/BIGNUMBERS.md +161 -0
  42. package/docs/rundot-developer-platform/api/BUILDING_TIMERS.md +591 -0
  43. package/docs/rundot-developer-platform/api/CLIPS.md +466 -0
  44. package/docs/rundot-developer-platform/api/COLLECTIBLES.md +89 -0
  45. package/docs/rundot-developer-platform/api/CONTEXT.md +99 -0
  46. package/docs/rundot-developer-platform/api/CREDITS.md +137 -0
  47. package/docs/rundot-developer-platform/api/EMBEDDED_LIBRARIES.md +152 -0
  48. package/docs/rundot-developer-platform/api/ENERGY_SYSTEM.md +508 -0
  49. package/docs/rundot-developer-platform/api/ENTITLEMENTS.md +267 -0
  50. package/docs/rundot-developer-platform/api/ENVIRONMENT.md +375 -0
  51. package/docs/rundot-developer-platform/api/EXPERIMENTS.md +118 -0
  52. package/docs/rundot-developer-platform/api/FILES.md +677 -0
  53. package/docs/rundot-developer-platform/api/GACHA_SYSTEM.md +695 -0
  54. package/docs/rundot-developer-platform/api/GAMEPAD.md +155 -0
  55. package/docs/rundot-developer-platform/api/HAPTICS.md +65 -0
  56. package/docs/rundot-developer-platform/api/IMAGE_GEN.md +308 -0
  57. package/docs/rundot-developer-platform/api/IN_APP_MESSAGING.md +162 -0
  58. package/docs/rundot-developer-platform/api/LEADERBOARD.md +673 -0
  59. package/docs/rundot-developer-platform/api/LIFECYCLES.md +159 -0
  60. package/docs/rundot-developer-platform/api/LOGGING.md +107 -0
  61. package/docs/rundot-developer-platform/api/MULTIPLAYER.md +985 -0
  62. package/docs/rundot-developer-platform/api/NAVIGATION.md +217 -0
  63. package/docs/rundot-developer-platform/api/NOTIFICATIONS.md +310 -0
  64. package/docs/rundot-developer-platform/api/PRELOADER.md +93 -0
  65. package/docs/rundot-developer-platform/api/PROFILE.md +74 -0
  66. package/docs/rundot-developer-platform/api/PURCHASES.md +349 -0
  67. package/docs/rundot-developer-platform/api/PVP_SYSTEM.md +376 -0
  68. package/docs/rundot-developer-platform/api/RATE_LIMITS.md +65 -0
  69. package/docs/rundot-developer-platform/api/RELEASE_NOTES.md +131 -0
  70. package/docs/rundot-developer-platform/api/SAFE_AREA.md +90 -0
  71. package/docs/rundot-developer-platform/api/SERVER_AUTHORITATIVE.md +617 -0
  72. package/docs/rundot-developer-platform/api/SHARED_ASSETS.md +109 -0
  73. package/docs/rundot-developer-platform/api/SHARING.md +308 -0
  74. package/docs/rundot-developer-platform/api/SHOP.md +533 -0
  75. package/docs/rundot-developer-platform/api/SIMULATION_CONFIG.md +1147 -0
  76. package/docs/rundot-developer-platform/api/SPRITE_GEN.md +308 -0
  77. package/docs/rundot-developer-platform/api/STATS.md +162 -0
  78. package/docs/rundot-developer-platform/api/STORAGE.md +268 -0
  79. package/docs/rundot-developer-platform/api/SYSTEM.md +128 -0
  80. package/docs/rundot-developer-platform/api/THREE_D_GEN.md +507 -0
  81. package/docs/rundot-developer-platform/api/TIME.md +164 -0
  82. package/docs/rundot-developer-platform/api/UGC.md +1435 -0
  83. package/docs/rundot-developer-platform/api/VIDEO.md +155 -0
  84. package/docs/rundot-developer-platform/api/VIDEO_GEN.md +327 -0
  85. package/docs/rundot-developer-platform/cli-reference.md +525 -0
  86. package/docs/rundot-developer-platform/deploying-your-game.md +342 -0
  87. package/docs/rundot-developer-platform/error-handling.md +94 -0
  88. package/docs/rundot-developer-platform/getting-started.md +150 -0
  89. package/docs/rundot-developer-platform/initializing-your-game.md +41 -0
  90. package/docs/rundot-developer-platform/marketing-your-game.md +455 -0
  91. package/docs/rundot-developer-platform/playground.md +302 -0
  92. package/docs/rundot-developer-platform/runtime-environment.md +76 -0
  93. package/docs/rundot-developer-platform/setting-your-game-thumbnail.md +37 -0
  94. package/docs/rundot-developer-platform/troubleshooting.md +124 -0
  95. package/package.json +18 -7
  96. package/scripts/copy-docs.mjs +52 -0
  97. package/scripts/install-hint.mjs +10 -0
  98. package/scripts/setup.mjs +378 -0
  99. package/dist/chunk-APR46OZQ.js.map +0 -1
  100. package/dist/chunk-BJGV6WIK.js.map +0 -1
  101. package/dist/chunk-NTONRZFO.js.map +0 -1
  102. package/dist/chunk-TNBSGNJ2.js.map +0 -1
  103. package/dist/sandbox/index.js.map +0 -1
  104. package/dist/tabCoordinator-SPKWPZDQ.js +0 -3
  105. package/scripts/postinstall.mjs +0 -463
  106. /package/dist/{sandbox → playground}/index.d.ts +0 -0
package/README.md CHANGED
@@ -15,6 +15,17 @@ Build connected HTML5 games that integrate deeply with the RUN.game platform. Th
15
15
  npm install @series-inc/rundot-game-sdk@latest
16
16
  ```
17
17
 
18
+ Installing the package only prints a hint — it makes no changes to your project.
19
+ To copy the SDK docs into your project and configure your AI agent files
20
+ (`AGENTS.md`/`CLAUDE.md`/`GEMINI.md`, `.gitignore`, and CLI hooks), run the
21
+ explicit, consent-gated setup command:
22
+
23
+ ```bash
24
+ npx rundot-sdk-setup
25
+ ```
26
+
27
+ It prompts before each change (pass `-y` to accept all, `--no` to skip all).
28
+
18
29
  ### Initialize
19
30
 
20
31
  ```typescript
@@ -407,8 +407,14 @@ interface DeviceApi {
407
407
  interface PlatformCapabilities {
408
408
  /** Rewarded/interstitial ads can be shown on this platform. */
409
409
  readonly ads: boolean;
410
- /** In-app purchases can be initiated on this platform. */
410
+ /** One-time/consumable in-app purchases can be initiated (e.g. currency
411
+ * top-up). Does NOT cover recurring subscriptions — see `subscriptions`. */
411
412
  readonly purchases: boolean;
413
+ /** Recurring subscription purchases can be initiated on this platform.
414
+ * `false` where third-party billing is banned (e.g. Steam); games hide
415
+ * subscription upsell/paywalls up front. Reading an existing subscriber's
416
+ * status is unaffected. */
417
+ readonly subscriptions: boolean;
412
418
  }
413
419
  interface EnvironmentInfo {
414
420
  readonly isDevelopment: boolean;
@@ -427,18 +433,41 @@ interface EnvironmentInfo {
427
433
  * `HostEnvironmentApi` then defaults each capability to `true`.
428
434
  */
429
435
  readonly capabilities: PlatformCapabilities;
436
+ /**
437
+ * Whether the game is running on the Steam channel on a desktop/laptop PC
438
+ * (the Steam client, NOT Steam Deck hardware). Channel-static for the
439
+ * session — branch UX on it (Steam-specific copy, hiding app-store prompts,
440
+ * etc.). Mutually exclusive with `isSteamDeck`: both are `false` off Steam,
441
+ * and exactly one is `true` on Steam. To ask "am I on Steam at all?", check
442
+ * `isSteamDesktop || isSteamDeck`. Also exposed as `system.isSteamDesktop()`. A host
443
+ * that predates this field omits it on the wire; `HostEnvironmentApi` then
444
+ * defaults it to `false`.
445
+ */
446
+ readonly isSteamDesktop: boolean;
447
+ /**
448
+ * Whether the game is running on Steam Deck hardware. Device-static for the
449
+ * session — branch UX on it (gamepad-first navigation, handheld layout,
450
+ * larger touch targets). Mutually exclusive with `isSteamDesktop` (see above).
451
+ * Also exposed as `system.isSteamDeck()`. A host that predates this field
452
+ * omits it on the wire; `HostEnvironmentApi` then defaults it to `false`.
453
+ */
454
+ readonly isSteamDeck: boolean;
430
455
  }
431
456
  /**
432
457
  * The INIT_SDK environment payload as it arrives over the wire / is stored on
433
- * `_environmentData`. Identical to `EnvironmentInfo` except `capabilities` is
434
- * optional (and partial), because a host older than the capabilities field
435
- * omits it. `HostEnvironmentApi` upgrades this into a full `EnvironmentInfo`.
458
+ * `_environmentData`. Identical to `EnvironmentInfo` except `capabilities`,
459
+ * `isSteamDesktop`, and `isSteamDeck` are optional, because a host older than those
460
+ * fields omits them. `HostEnvironmentApi` upgrades this into a full
461
+ * `EnvironmentInfo`.
436
462
  */
437
- interface RawEnvironmentInfo extends Omit<EnvironmentInfo, 'capabilities'> {
463
+ interface RawEnvironmentInfo extends Omit<EnvironmentInfo, 'capabilities' | 'isSteamDesktop' | 'isSteamDeck'> {
438
464
  readonly capabilities?: {
439
465
  readonly ads?: boolean;
440
466
  readonly purchases?: boolean;
467
+ readonly subscriptions?: boolean;
441
468
  };
469
+ readonly isSteamDesktop?: boolean;
470
+ readonly isSteamDeck?: boolean;
442
471
  }
443
472
  interface EnvironmentApi {
444
473
  getEnvironment(): EnvironmentInfo;
@@ -490,6 +519,20 @@ interface SystemApi {
490
519
  * @returns true if on web platform
491
520
  */
492
521
  isWeb(): boolean;
522
+ /**
523
+ * Check if running on the Steam channel on a desktop/laptop PC (the Steam
524
+ * client, NOT Steam Deck hardware). Mutually exclusive with `isSteamDeck()`;
525
+ * to ask "am I on Steam at all?", check `isSteamDesktop() || isSteamDeck()`.
526
+ * @returns true on Steam desktop/laptop (non-Deck)
527
+ */
528
+ isSteamDesktop(): boolean;
529
+ /**
530
+ * Check if running on Steam Deck hardware. Mutually exclusive with
531
+ * `isSteamDesktop()`. Use to branch UX for the handheld (gamepad-first
532
+ * navigation, handheld layout, larger touch targets).
533
+ * @returns true on Steam Deck
534
+ */
535
+ isSteamDeck(): boolean;
493
536
  /**
494
537
  * Check whether the current platform can present an "Add to Home Screen"
495
538
  * prompt for the running game right now.
@@ -1880,8 +1923,8 @@ interface LoadEmbeddedAssetsResponse {
1880
1923
  base64Data: string;
1881
1924
  }
1882
1925
 
1883
- /** the different subscription tiers RUN offers. CORE is lowest, ULTIMATE is highest */
1884
- type SubscriptionTier = 'CORE' | 'PLUS' | 'PRIME' | 'ULTIMATE';
1926
+ /** the different subscription tiers RUN offers. LITE is lowest, ULTIMATE is highest */
1927
+ type SubscriptionTier = 'LITE' | 'CORE' | 'PLUS' | 'PRIME' | 'ULTIMATE';
1885
1928
  /** the different billing intervals RUN offers for subscriptions */
1886
1929
  type SubscriptionInterval = 'weekly' | 'monthly' | 'annual';
1887
1930
  interface IsPlayerSubscribedRequest {
@@ -2671,11 +2714,14 @@ interface SocialApi {
2671
2714
  *
2672
2715
  * @param options.shareParams Arbitrary share parameters for your game.
2673
2716
  * @param options.metadata Optional OpenGraph metadata for rich previews.
2717
+ * @param options.slug Optional cosmetic slug appended to the share URL (e.g.
2718
+ * "boss-level"). Sanitized server-side; non-unique; does not affect resolution.
2674
2719
  * @returns The generated share URL.
2675
2720
  */
2676
2721
  shareLinkAsync(options: {
2677
2722
  shareParams: Record<string, string>;
2678
2723
  metadata?: ShareMetadata;
2724
+ slug?: string;
2679
2725
  }): Promise<ShareLinkResult>;
2680
2726
  /**
2681
2727
  * Create a share document and return both the URL and a QR code image.
@@ -2685,12 +2731,15 @@ interface SocialApi {
2685
2731
  * @param options.shareParams Arbitrary share parameters for your game.
2686
2732
  * @param options.metadata Optional OpenGraph metadata for the share.
2687
2733
  * @param options.qrOptions Customisation for the generated QR code.
2734
+ * @param options.slug Optional cosmetic slug appended to the share URL (e.g.
2735
+ * "boss-level"). Sanitized server-side; non-unique; does not affect resolution.
2688
2736
  * @returns The generated share URL, QR code (as a data URL), and shareLinkId.
2689
2737
  */
2690
2738
  createQRCodeAsync(options: {
2691
2739
  shareParams: Record<string, string>;
2692
2740
  metadata?: ShareMetadata;
2693
2741
  qrOptions?: SocialQRCodeOptions;
2742
+ slug?: string;
2694
2743
  }): Promise<QRCodeResult>;
2695
2744
  /**
2696
2745
  * Write click metadata to a share as the current user (clicker).
@@ -4015,7 +4064,7 @@ interface Host {
4015
4064
  * registers the `onNotificationParamsUpdate` subscription. Lets the host
4016
4065
  * tell "SDK booted past READY" apart from "SDK has a live notification
4017
4066
  * subscriber" — the latter is the precise signal for "a live push WILL be
4018
- * received". Optional: Mock / Sandbox hosts have no remote peer and so
4067
+ * received". Optional: Mock / Playground hosts have no remote peer and so
4019
4068
  * don't implement it.
4020
4069
  */
4021
4070
  notifyNotificationParamsSubscribeReady?(): void;
@@ -4024,9 +4073,9 @@ interface Host {
4024
4073
  /**
4025
4074
  * Create a Host instance based on the runtime environment.
4026
4075
  *
4027
- * SandboxHost is loaded via a separate entry point (`@series-inc/rundot-game-sdk/sandbox`)
4028
- * which registers a factory on `globalThis.__RUNDOT_SANDBOX_HOST_FACTORY__`.
4029
- * The Vite sandbox plugin injects this import automatically, keeping Firebase
4076
+ * PlaygroundHost is loaded via a separate entry point (`@series-inc/rundot-game-sdk/playground`)
4077
+ * which registers a factory on `globalThis.__RUNDOT_PLAYGROUND_HOST_FACTORY__`.
4078
+ * The Vite playground plugin injects this import automatically, keeping Firebase
4030
4079
  * completely out of the main bundle's dependency graph.
4031
4080
  */
4032
4081
  declare function createHost(rundotGameApi: RundotGameAPI, isMock: boolean): Promise<Host>;
@@ -11,8 +11,8 @@
11
11
  * })
12
12
  * ```
13
13
  *
14
- * ⚠️ SANDBOX-ONLY: This file depends on Firebase and should ONLY be imported by SandboxHost
15
- * and other sandbox-only modules. Do NOT import from barrel exports (http/index.ts).
14
+ * ⚠️ PLAYGROUND-ONLY: This file depends on Firebase and should ONLY be imported by PlaygroundHost
15
+ * and other playground-only modules. Do NOT import from barrel exports (http/index.ts).
16
16
  * This ensures Firebase is not bundled in production builds.
17
17
  */
18
18
  /**
@@ -403,5 +403,5 @@ var HttpLeaderboardApi = class {
403
403
  };
404
404
 
405
405
  export { HttpAudioGenApi, HttpImageGenApi, HttpLeaderboardApi, HttpSpriteGenApi, HttpThreeDGenApi, HttpVideoGenApi };
406
- //# sourceMappingURL=chunk-BJGV6WIK.js.map
407
- //# sourceMappingURL=chunk-BJGV6WIK.js.map
406
+ //# sourceMappingURL=chunk-57DREBKB.js.map
407
+ //# sourceMappingURL=chunk-57DREBKB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/imageGen/HttpImageGenApi.ts","../src/audioGen/HttpAudioGenApi.ts","../src/videoGen/HttpVideoGenApi.ts","../src/spriteGen/HttpSpriteGenApi.ts","../src/threeDGen/HttpThreeDGenApi.ts","../src/leaderboard/normalizeScores.ts","../src/leaderboard/HttpLeaderboardApi.ts"],"names":[],"mappings":"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","file":"chunk-57DREBKB.js","sourcesContent":["// Host-facing HTTP implementation of ImageGenApi. Firebase-free: auth + base URL\n// come from the injected BackendHttpDeps, so any host (PlaygroundHost, Telegram/Steam\n// shells) can construct it. Do NOT import from barrel exports (imageGen/index.ts).\n\nimport { ImageGenApi, ImageGenParams, ImageGenResult, ImageGenJobEvent, DepthEstimationParams, DepthEstimationResult, RemoveBackgroundParams, RemoveBackgroundResult, UpscaleImageParams, UpscaleImageResult } from './ImageGenApi';\nimport type { BackendHttpDeps } from '../http/backendHttpDeps';\n\nexport class HttpImageGenApi implements ImageGenApi {\n private readonly appId: string;\n private readonly deps: BackendHttpDeps;\n\n constructor(appId: string, deps: BackendHttpDeps) {\n this.appId = appId;\n this.deps = deps;\n }\n\n private async authedPost<T>(path: string, body: Record<string, unknown>): Promise<T> {\n const idToken = await this.deps.getIdToken();\n const baseUrl = this.deps.getCloudRunUrl();\n const url = `${baseUrl}/v1/imagegen/${this.appId}/${path}`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${idToken}`,\n 'x-consumer': 'sdk',\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = `Request failed (${response.status})`;\n try {\n const errorJson = JSON.parse(errorText);\n errorMessage = errorJson.error || errorJson.message || errorMessage;\n } catch {\n if (errorText) errorMessage = errorText;\n }\n throw new Error(errorMessage);\n }\n\n return response.json();\n }\n\n async generate(params: ImageGenParams): Promise<ImageGenResult> {\n return this.authedPost<ImageGenResult>('generate', params as unknown as Record<string, unknown>);\n }\n\n async estimateDepth(params: DepthEstimationParams): Promise<DepthEstimationResult> {\n return this.authedPost<DepthEstimationResult>('estimate-depth', params as unknown as Record<string, unknown>);\n }\n\n async removeBackground(params: RemoveBackgroundParams): Promise<RemoveBackgroundResult> {\n return this.authedPost<RemoveBackgroundResult>('remove-background', params as unknown as Record<string, unknown>);\n }\n\n async upscaleImage(params: UpscaleImageParams): Promise<UpscaleImageResult> {\n return this.authedPost<UpscaleImageResult>('upscale-image', params as unknown as Record<string, unknown>);\n }\n\n async getCompletedJobs(): Promise<ImageGenJobEvent[]> {\n return [];\n }\n}\n","// Host-facing HTTP implementation of AudioGenApi. Firebase-free: auth + base URL\n// come from the injected BackendHttpDeps. Do NOT import from barrel exports\n// (audioGen/index.ts).\n\nimport {\n AudioGenApi,\n AudioGenParams,\n AudioGenResult,\n AudioGenJobEvent,\n ListVoicesResult,\n DesignVoicesParams,\n DesignVoicesResult,\n SaveDesignedVoiceParams,\n SaveDesignedVoiceResult,\n} from './AudioGenApi';\nimport { RundotApiError, RateLimitedError } from '../errors';\nimport type { BackendHttpDeps } from '../http/backendHttpDeps';\n\nexport class HttpAudioGenApi implements AudioGenApi {\n private readonly appId: string;\n private readonly deps: BackendHttpDeps;\n\n constructor(appId: string, deps: BackendHttpDeps) {\n this.appId = appId;\n this.deps = deps;\n }\n\n private async authedFetch(path: string, method: string, body?: unknown): Promise<Response> {\n const idToken = await this.deps.getIdToken();\n const baseUrl = this.deps.getCloudRunUrl();\n const url = `${baseUrl}/v1/audiogen/${this.appId}/${path}`;\n\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${idToken}`,\n },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!response.ok) {\n if (response.status === 429) {\n const retryAfterSec = parseInt(response.headers.get('Retry-After') ?? '60', 10);\n throw new RateLimitedError(retryAfterSec * 1000);\n }\n const errorText = await response.text();\n let errorMessage = `Audio generation failed (${response.status})`;\n let errorCode = 'UNKNOWN';\n try {\n const errorJson = JSON.parse(errorText) as Record<string, unknown>;\n errorMessage = (errorJson.error ?? errorJson.message ?? errorMessage) as string;\n if (typeof errorJson.code === 'string') errorCode = errorJson.code;\n } catch {\n if (errorText) errorMessage = errorText;\n }\n throw new RundotApiError(errorCode, errorMessage, response.status);\n }\n\n return response;\n }\n\n async generate(params: AudioGenParams): Promise<AudioGenResult> {\n const response = await this.authedFetch('generate', 'POST', params);\n return response.json();\n }\n\n async getCompletedJobs(): Promise<AudioGenJobEvent[]> {\n return [];\n }\n\n async listVoices(): Promise<ListVoicesResult> {\n const response = await this.authedFetch('voices', 'GET');\n return response.json();\n }\n\n async designVoices(params: DesignVoicesParams): Promise<DesignVoicesResult> {\n const response = await this.authedFetch('voices/design', 'POST', params);\n return response.json();\n }\n\n async saveDesignedVoice(params: SaveDesignedVoiceParams): Promise<SaveDesignedVoiceResult> {\n const response = await this.authedFetch('voices/save', 'POST', params);\n return response.json();\n }\n}\n","// Host-facing HTTP implementation of VideoGenApi. Firebase-free: auth + base URL\n// come from the injected BackendHttpDeps. Do NOT import from barrel exports\n// (videoGen/index.ts).\n\nimport { VideoGenApi, VideoGenParams, VideoGenResult, VideoGenJobEvent, VideoGenJobStartedEvent } from './VideoGenApi'\nimport type { BackendHttpDeps } from '../http/backendHttpDeps'\n\nexport class HttpVideoGenApi implements VideoGenApi {\n private readonly appId: string\n private readonly deps: BackendHttpDeps\n\n constructor(appId: string, deps: BackendHttpDeps) {\n this.appId = appId\n this.deps = deps\n }\n\n async generate(params: VideoGenParams): Promise<VideoGenResult> {\n const idToken = await this.deps.getIdToken()\n const baseUrl = this.deps.getCloudRunUrl()\n const url = `${baseUrl}/v1/videogen/${this.appId}/sync-generate`\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${idToken}`,\n },\n body: JSON.stringify(params),\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n let errorMessage = `Video generation failed (${response.status})`\n try {\n const errorJson = JSON.parse(errorText)\n errorMessage = errorJson.error || errorJson.message || errorMessage\n } catch {\n if (errorText) errorMessage = errorText\n }\n throw new Error(errorMessage)\n }\n\n return response.json()\n }\n\n async getCompletedJobs(): Promise<VideoGenJobEvent[]> {\n return []\n }\n\n async cancel(jobId: string): Promise<void> {\n const idToken = await this.deps.getIdToken()\n const baseUrl = this.deps.getCloudRunUrl()\n const url = `${baseUrl}/v1/jobs/${this.appId}/${jobId}/cancel`\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${idToken}`,\n },\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n let errorMessage = `Job cancellation failed (${response.status})`\n try {\n const errorJson = JSON.parse(errorText)\n errorMessage = errorJson.error || errorJson.message || errorMessage\n } catch {\n if (errorText) errorMessage = errorText\n }\n throw new Error(errorMessage)\n }\n }\n\n onJobStarted(_callback: (event: VideoGenJobStartedEvent) => void): { unsubscribe: () => void } {\n return { unsubscribe: () => {} }\n }\n}\n","// Host-facing HTTP implementation of SpriteGenApi. Firebase-free: auth + base URL\n// come from the injected BackendHttpDeps.\n\nimport { SpriteGenApi, SpriteGenParams, SpriteGenResult, AnimateSpriteParams, AnimateSpriteResult, SpriteGenJobEvent } from './SpriteGenApi';\nimport type { BackendHttpDeps } from '../http/backendHttpDeps';\n\nexport class HttpSpriteGenApi implements SpriteGenApi {\n private readonly appId: string;\n private readonly deps: BackendHttpDeps;\n\n constructor(appId: string, deps: BackendHttpDeps) {\n this.appId = appId;\n this.deps = deps;\n }\n\n async generate(params: SpriteGenParams): Promise<SpriteGenResult> {\n const idToken = await this.deps.getIdToken();\n const baseUrl = this.deps.getCloudRunUrl();\n const url = `${baseUrl}/v1/spritegen/${this.appId}/generate`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${idToken}`,\n },\n body: JSON.stringify(params),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = `Sprite generation failed (${response.status})`;\n try {\n const errorJson = JSON.parse(errorText);\n errorMessage = errorJson.error || errorJson.message || errorMessage;\n } catch {\n if (errorText) errorMessage = errorText;\n }\n throw new Error(errorMessage);\n }\n\n return response.json();\n }\n\n async animate(params: AnimateSpriteParams): Promise<AnimateSpriteResult> {\n const idToken = await this.deps.getIdToken();\n const baseUrl = this.deps.getCloudRunUrl();\n const url = `${baseUrl}/v1/spritegen/${this.appId}/animate`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${idToken}`,\n },\n body: JSON.stringify(params),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = `Sprite animation failed (${response.status})`;\n try {\n const errorJson = JSON.parse(errorText);\n errorMessage = errorJson.error || errorJson.message || errorMessage;\n } catch {\n if (errorText) errorMessage = errorText;\n }\n throw new Error(errorMessage);\n }\n\n return response.json();\n }\n\n async getCompletedJobs(): Promise<SpriteGenJobEvent[]> {\n return [];\n }\n}\n","// Host-facing HTTP implementation of ThreeDGenApi. Firebase-free: auth + base URL\n// come from the injected BackendHttpDeps. Do NOT import from barrel exports\n// (threeDGen/index.ts).\n\nimport {\n ThreeDGenApi,\n ThreeDGenParams,\n ThreeDGenResult,\n RemeshParams,\n RemeshResult,\n RigParams,\n RigResult,\n AnimateParams,\n AnimateResult,\n ThreeDGenJobEvent,\n} from './ThreeDGenApi'\nimport { RundotApiError } from '../errors'\nimport type { BackendHttpDeps } from '../http/backendHttpDeps'\n\nexport class HttpThreeDGenApi implements ThreeDGenApi {\n private readonly appId: string\n private readonly deps: BackendHttpDeps\n\n constructor(appId: string, deps: BackendHttpDeps) {\n this.appId = appId\n this.deps = deps\n }\n\n async generate(params: ThreeDGenParams): Promise<ThreeDGenResult> {\n return this.post<ThreeDGenResult>('sync-generate', params)\n }\n\n async remesh(params: RemeshParams): Promise<RemeshResult> {\n return this.post<RemeshResult>('sync-remesh', params)\n }\n\n async rig(params: RigParams): Promise<RigResult> {\n return this.post<RigResult>('sync-rig', params)\n }\n\n async animate(params: AnimateParams): Promise<AnimateResult> {\n return this.post<AnimateResult>('sync-animate', params)\n }\n\n async getCompletedJobs(): Promise<ThreeDGenJobEvent[]> {\n return []\n }\n\n private async post<T>(endpoint: string, body: unknown): Promise<T> {\n const idToken = await this.deps.getIdToken()\n const baseUrl = this.deps.getCloudRunUrl()\n const url = `${baseUrl}/v1/threedgen/${this.appId}/${endpoint}`\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${idToken}`,\n },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n let errorMessage = `3D generation failed (${response.status})`\n let errorCode = 'UNKNOWN'\n let detail: string | undefined\n try {\n const errorJson = JSON.parse(errorText) as Record<string, unknown>\n errorMessage = (errorJson.error ?? errorJson.message ?? errorMessage) as string\n if (typeof errorJson.code === 'string') errorCode = errorJson.code\n if (typeof errorJson.detail === 'string') detail = errorJson.detail\n } catch {\n if (errorText) errorMessage = errorText\n }\n throw new RundotApiError(errorCode, errorMessage, response.status, detail)\n }\n\n return response.json()\n }\n}\n","/**\n * Idempotently convert Firestore-serialized timestamps to epoch millis on\n * leaderboard score responses. Leaderboard endpoints serialize Firestore\n * Timestamps as `{ seconds, nanoseconds }` (or `{ _seconds, _nanoseconds }`),\n * but `LeaderboardEntry` declares `submittedAt`/`expiresAt` as epoch millis.\n * Already-millis values pass through unchanged.\n */\nfunction toMillis(value: unknown): unknown {\n if (value && typeof value === 'object') {\n const v = value as Record<string, unknown>\n // Firestore Timestamp instance (defensive — survives only in-process, not\n // over HTTP/JSON, but keeps parity with the RN host's normalizer so this can\n // be the single source of truth when that migrates).\n if (typeof v.toMillis === 'function') {\n try {\n return (v.toMillis as () => number)()\n } catch {\n return value\n }\n }\n const seconds = (v.seconds ?? v._seconds) as number | undefined\n const nanos = (v.nanoseconds ?? v._nanoseconds) as number | undefined\n if (typeof seconds === 'number' && typeof nanos === 'number') {\n return seconds * 1000 + Math.floor(nanos / 1_000_000)\n }\n }\n return value\n}\n\nfunction normalizeEntry(entry: unknown): unknown {\n if (!entry || typeof entry !== 'object') return entry\n const e = entry as Record<string, unknown>\n return { ...e, submittedAt: toMillis(e.submittedAt), expiresAt: toMillis(e.expiresAt) }\n}\n\nexport function normalizeScoresResponse<T>(payload: T): T {\n if (!payload || typeof payload !== 'object') return payload\n const p = payload as Record<string, unknown>\n const result: Record<string, unknown> = { ...p }\n if (Array.isArray(p.entries)) result.entries = p.entries.map(normalizeEntry)\n if (p.context && typeof p.context === 'object') {\n const c = p.context as Record<string, unknown>\n result.context = {\n ...c,\n topEntries: Array.isArray(c.topEntries) ? c.topEntries.map(normalizeEntry) : c.topEntries,\n beforePlayer: Array.isArray(c.beforePlayer) ? c.beforePlayer.map(normalizeEntry) : c.beforePlayer,\n playerEntry: c.playerEntry ? normalizeEntry(c.playerEntry) : c.playerEntry,\n afterPlayer: Array.isArray(c.afterPlayer) ? c.afterPlayer.map(normalizeEntry) : c.afterPlayer,\n }\n }\n return result as T\n}\n","/**\n * HTTP-backed {@link LeaderboardApi} implementation usable by any host.\n *\n * Firebase-free: the caller injects `callRemote` (PlaygroundHost passes\n * `callRemoteFunction`; platform shells pass their own authenticated invoker),\n * so importing this file does NOT pull firebase into a host bundle. Do NOT\n * import from barrel exports (leaderboard/index.ts).\n */\nimport {\n LeaderboardApi,\n ScoreToken,\n SubmitScoreParams,\n SubmitScoreResult,\n GetPagedScoresOptions,\n PagedScoresResponse,\n PlayerRankOptions,\n PlayerRankResult,\n GetPodiumScoresOptions,\n PodiumScoresResponse,\n} from './LeaderboardApi'\nimport type { RemoteFunctionInvoker } from '../http/callRemoteFunction'\nimport { normalizeScoresResponse } from './normalizeScores'\n\n/**\n * HTTP-based implementation of LeaderboardApi.\n */\nexport class HttpLeaderboardApi implements LeaderboardApi {\n private readonly appId: string\n private readonly callRemote: RemoteFunctionInvoker\n\n constructor(\n appId: string,\n options: {\n callRemote: RemoteFunctionInvoker\n },\n ) {\n this.appId = appId\n this.callRemote = options.callRemote\n }\n\n async createScoreToken(mode?: string): Promise<ScoreToken> {\n return this.callRemote<ScoreToken>('apiCreateScoreToken', {\n appId: this.appId,\n mode: mode || 'default',\n })\n }\n\n async submitScore(params: SubmitScoreParams): Promise<SubmitScoreResult> {\n return this.callRemote<SubmitScoreResult>('apiSubmitScore', {\n appId: this.appId,\n token: params.token,\n score: params.score,\n duration: params.duration,\n mode: params.mode || 'default',\n period: params.period,\n telemetry: params.telemetry,\n metadata: params.metadata,\n // Score-sealing hash auto-computed by RpcLeaderboardApi; without it sealed\n // leaderboards reject the score.\n hash: params.hash,\n })\n }\n\n async getPagedScores(options?: GetPagedScoresOptions): Promise<PagedScoresResponse> {\n const res = await this.callRemote<PagedScoresResponse>('apiGetPagedScores', {\n appId: this.appId,\n mode: options?.mode || 'default',\n period: options?.period || 'alltime',\n periodDate: options?.periodDate,\n cursor: options?.cursor,\n limit: options?.limit,\n variant: options?.variant || 'standard',\n topCount: options?.topCount,\n contextAhead: options?.contextAhead,\n contextBehind: options?.contextBehind,\n })\n return normalizeScoresResponse(res)\n }\n\n async getMyRank(options?: PlayerRankOptions): Promise<PlayerRankResult> {\n const res = await this.callRemote<PlayerRankResult>('apiGetMyRank', {\n appId: this.appId,\n mode: options?.mode || 'default',\n period: options?.period || 'alltime',\n periodDate: options?.periodDate,\n })\n return normalizeScoresResponse(res)\n }\n\n async getPodiumScores(options?: GetPodiumScoresOptions): Promise<PodiumScoresResponse> {\n const res = await this.callRemote<PodiumScoresResponse>('apiGetPodiumScores', {\n appId: this.appId,\n mode: options?.mode || 'default',\n period: options?.period || 'alltime',\n periodDate: options?.periodDate,\n topCount: options?.topCount,\n contextAhead: options?.contextAhead,\n contextBehind: options?.contextBehind,\n })\n return normalizeScoresResponse(res)\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { mapCreditsExhaustion, generateId, createRpcAdminGenApi, createMockAdminGenApi, SHARE_FILE_ALLOWED_MIME_TYPES, SHARE_FILE_MAX_SIZE_BYTES, RpcAdsApi, RpcAnalyticsApi, RpcStorageApi, RpcInboundStorageApi, DualEmitStorageApi, RpcAvatarApi, RpcNavigationApi, RpcNotificationsApi, RpcPopupsApi, HostProfileApi, HostDeviceApi, HostEnvironmentApi, HostSystemApi, HostCdnApi, HostTimeApi, RpcHapticsApi, RpcGamepadApi, RpcFeaturesApi, RpcLifecycleApi, RpcRoomsApi, RpcLoggingApi, RpcCreditsApi, RpcPreloaderApi, ClipsApiImpl, RpcEntitlementApi, RpcStatsApi, RpcCollectiblesApi, RpcShopApi, RpcVideoApi, RpcAttributionApi, RpcSharedAssetsApi, initializeRoomsApi, RpcAccessGateApi, WsMultiplayerApi, applyAccessGates, wireIdentityReplica, sanitizeProfile, MockAdsApi, MockLifecycleApi, MockAnalyticsApi, createMockStorageApi, MockAvatarApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, MockProfileApi, MockDeviceApi, MockEnvironmentApi, MockSystemApi, MockCdnApi, MockTimeApi, MockHapticsApi, MockGamepadApi, MockFeaturesApi, MockLoggingApi, MockIapApi, MockCreditsApi, MockEntitlementApi, MockStatsApi, MockCollectiblesApi, MockShopApi, MockVideoApi, MockAppApi, MockAttributionApi, MockPreloaderApi, MockSharedAssetsApi, MockAccessGateApi, MockMultiplayerApi, asCreditsExhaustedError } from './chunk-APR46OZQ.js';
1
+ import { mapCreditsExhaustion, generateId, createRpcAdminGenApi, createMockAdminGenApi, PlaygroundAppApi, warnRenamed, SHARE_FILE_ALLOWED_MIME_TYPES, SHARE_FILE_MAX_SIZE_BYTES, RpcAdsApi, RpcAnalyticsApi, RpcStorageApi, RpcInboundStorageApi, DualEmitStorageApi, RpcAvatarApi, RpcNavigationApi, RpcNotificationsApi, RpcPopupsApi, HostProfileApi, HostDeviceApi, HostEnvironmentApi, HostSystemApi, HostCdnApi, HostTimeApi, RpcHapticsApi, RpcGamepadApi, RpcFeaturesApi, RpcLifecycleApi, RpcRoomsApi, RpcLoggingApi, RpcCreditsApi, RpcPreloaderApi, ClipsApiImpl, RpcEntitlementApi, RpcStatsApi, RpcCollectiblesApi, RpcShopApi, RpcVideoApi, RpcAttributionApi, RpcSharedAssetsApi, initializeRoomsApi, RpcAccessGateApi, WsMultiplayerApi, applyAccessGates, wireIdentityReplica, sanitizeProfile, utf8ByteLength, MockAdsApi, MockLifecycleApi, MockAnalyticsApi, createMockStorageApi, MockAvatarApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, MockProfileApi, MockDeviceApi, MockEnvironmentApi, MockSystemApi, MockCdnApi, MockTimeApi, MockHapticsApi, MockGamepadApi, MockFeaturesApi, MockLoggingApi, MockIapApi, MockCreditsApi, MockEntitlementApi, MockStatsApi, MockCollectiblesApi, MockShopApi, MockVideoApi, MockAppApi, MockAttributionApi, MockPreloaderApi, MockSharedAssetsApi, MockAccessGateApi, MockMultiplayerApi, asCreditsExhaustedError } from './chunk-V4I4PKDK.js';
2
2
  import { RundotApiError } from './chunk-HVVCNDSV.js';
3
3
 
4
4
  // src/ai/RpcAiApi.ts
@@ -1023,7 +1023,7 @@ function initializeSimulation(rundotGameApi, host) {
1023
1023
  }
1024
1024
 
1025
1025
  // src/version.ts
1026
- var SDK_VERSION = "5.23.0-beta.0";
1026
+ var SDK_VERSION = "5.23.0-beta.2";
1027
1027
 
1028
1028
  // src/leaderboard/utils.ts
1029
1029
  var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
@@ -1139,6 +1139,46 @@ var RpcLeaderboardApi = class {
1139
1139
  }
1140
1140
  };
1141
1141
 
1142
+ // src/leaderboard/validateSubmitScore.ts
1143
+ var MIN_SCORE = 0;
1144
+ var MAX_SCORE = 999999999;
1145
+ var MIN_DURATION_SEC = 10;
1146
+ var MAX_DURATION_SEC = 3600;
1147
+ var MAX_METADATA_BYTES = 20 * 1024;
1148
+ function validateSubmitScore(params) {
1149
+ const { score, duration, metadata } = params;
1150
+ if (typeof score !== "number" || Number.isNaN(score)) {
1151
+ throw new RundotApiError("INVALID_ARGUMENT", "Score must be a valid number", 400);
1152
+ }
1153
+ if (score < MIN_SCORE || score > MAX_SCORE) {
1154
+ throw new RundotApiError("INVALID_ARGUMENT", "Score out of bounds", 400);
1155
+ }
1156
+ if (!Number.isFinite(duration) || duration < 0) {
1157
+ throw new RundotApiError("INVALID_ARGUMENT", "Duration must be a positive number", 400);
1158
+ }
1159
+ if (duration < MIN_DURATION_SEC || duration > MAX_DURATION_SEC) {
1160
+ throw new RundotApiError("INVALID_ARGUMENT", "Duration out of bounds", 400);
1161
+ }
1162
+ if (metadata !== void 0 && metadata !== null) {
1163
+ if (typeof metadata !== "object" || Array.isArray(metadata)) {
1164
+ throw new RundotApiError("INVALID_ARGUMENT", "Metadata must be a plain object", 400);
1165
+ }
1166
+ let serialized;
1167
+ try {
1168
+ serialized = JSON.stringify(metadata);
1169
+ } catch {
1170
+ throw new RundotApiError("INVALID_ARGUMENT", "Metadata must be JSON serializable", 400);
1171
+ }
1172
+ if (utf8ByteLength(serialized) > MAX_METADATA_BYTES) {
1173
+ throw new RundotApiError("INVALID_ARGUMENT", "Metadata exceeds 20KB limit", 400);
1174
+ }
1175
+ const reparsed = JSON.parse(serialized);
1176
+ if (typeof reparsed !== "object" || reparsed === null || Array.isArray(reparsed)) {
1177
+ throw new RundotApiError("INVALID_ARGUMENT", "Metadata must be an object", 400);
1178
+ }
1179
+ }
1180
+ }
1181
+
1142
1182
  // src/leaderboard/MockLeaderboardApi.ts
1143
1183
  var MockLeaderboardApi = class {
1144
1184
  tokens = /* @__PURE__ */ new Map();
@@ -1224,6 +1264,7 @@ var MockLeaderboardApi = class {
1224
1264
  * @throws Error if token not found in cache or validation fails
1225
1265
  */
1226
1266
  async submitScore(params) {
1267
+ validateSubmitScore(params);
1227
1268
  let hash;
1228
1269
  if (params.token) {
1229
1270
  const cachedToken = this.tokenCache.get(params.token);
@@ -1809,11 +1850,94 @@ function initializeUgc(rundotGameApiInstance, host) {
1809
1850
  rundotGameApiInstance.ugc = host.ugc;
1810
1851
  }
1811
1852
 
1853
+ // src/social/validateShare.ts
1854
+ var SHARE_PARAMS_MAX_KEYS = 20;
1855
+ var SHARE_PARAMS_MAX_VALUE_LENGTH = 100 * 1024;
1856
+ var SHARE_PARAMS_MAX_TOTAL_SIZE = 200 * 1024;
1857
+ var META_MAX_TITLE = 200;
1858
+ var META_MAX_DESCRIPTION = 1e3;
1859
+ var META_MAX_IMAGE_URL = 2048;
1860
+ var CLICK_MAX_KEYS = 20;
1861
+ var CLICK_MAX_KEY_LENGTH = 64;
1862
+ var CLICK_MAX_VALUE_LENGTH = 1024;
1863
+ var CLICK_MAX_TOTAL_SIZE = 4096;
1864
+ function invalid(message) {
1865
+ throw new RundotApiError("UNKNOWN", message, 0);
1866
+ }
1867
+ function validateShareParams(shareParams) {
1868
+ if (shareParams === void 0 || shareParams === null) return;
1869
+ if (typeof shareParams !== "object" || Array.isArray(shareParams)) {
1870
+ invalid("shareParams must be a plain object");
1871
+ }
1872
+ const entries = Object.entries(shareParams);
1873
+ if (entries.length > SHARE_PARAMS_MAX_KEYS) {
1874
+ invalid(`shareParams exceeds maximum of ${SHARE_PARAMS_MAX_KEYS} keys`);
1875
+ }
1876
+ for (const [key, value] of entries) {
1877
+ if (typeof value !== "string") invalid(`shareParams value for key "${key}" must be a string`);
1878
+ if (value.length > SHARE_PARAMS_MAX_VALUE_LENGTH) {
1879
+ invalid(`shareParams value for key "${key}" exceeds maximum length of 100KB`);
1880
+ }
1881
+ }
1882
+ if (JSON.stringify(shareParams).length > SHARE_PARAMS_MAX_TOTAL_SIZE) {
1883
+ invalid("shareParams exceeds maximum serialized size of 200KB");
1884
+ }
1885
+ }
1886
+ function validateShareMetadata(metadata) {
1887
+ if (metadata === void 0 || metadata === null) return;
1888
+ if (typeof metadata !== "object" || Array.isArray(metadata)) invalid("metadata must be a plain object");
1889
+ const m = metadata;
1890
+ if (m.title !== void 0 && typeof m.title !== "string") invalid("metadata.title must be a string");
1891
+ if (m.description !== void 0 && typeof m.description !== "string") invalid("metadata.description must be a string");
1892
+ if (m.imageUrl !== void 0 && typeof m.imageUrl !== "string") invalid("metadata.imageUrl must be a string");
1893
+ if (typeof m.title === "string" && m.title.length > META_MAX_TITLE) invalid(`metadata.title exceeds maximum length of ${META_MAX_TITLE}`);
1894
+ if (typeof m.description === "string" && m.description.length > META_MAX_DESCRIPTION) invalid(`metadata.description exceeds maximum length of ${META_MAX_DESCRIPTION}`);
1895
+ if (typeof m.imageUrl === "string" && m.imageUrl.length > META_MAX_IMAGE_URL) invalid(`metadata.imageUrl exceeds maximum length of ${META_MAX_IMAGE_URL}`);
1896
+ }
1897
+ function validateClickMetadata(metadata) {
1898
+ if (typeof metadata !== "object" || metadata === null) invalid("metadata must be a non-null object");
1899
+ const entries = Object.entries(metadata);
1900
+ if (entries.length > CLICK_MAX_KEYS) invalid(`metadata exceeds maximum of ${CLICK_MAX_KEYS} keys`);
1901
+ for (const [key, value] of entries) {
1902
+ if (typeof value !== "string") invalid(`metadata value for key "${key}" must be a string`);
1903
+ if (key.length > CLICK_MAX_KEY_LENGTH) invalid(`metadata key "${key}" exceeds maximum length of ${CLICK_MAX_KEY_LENGTH}`);
1904
+ if (value.length > CLICK_MAX_VALUE_LENGTH) invalid(`metadata value for key "${key}" exceeds maximum length of ${CLICK_MAX_VALUE_LENGTH}`);
1905
+ }
1906
+ if (JSON.stringify(metadata).length > CLICK_MAX_TOTAL_SIZE) {
1907
+ invalid(`metadata total size exceeds maximum of ${CLICK_MAX_TOTAL_SIZE} bytes`);
1908
+ }
1909
+ }
1910
+ function validateShareFile(options) {
1911
+ const { data, mimeType } = options;
1912
+ if (!SHARE_FILE_ALLOWED_MIME_TYPES.includes(mimeType)) {
1913
+ throw new Error(
1914
+ `unsupported MIME type "${mimeType}". Allowed: ${SHARE_FILE_ALLOWED_MIME_TYPES.join(", ")}`
1915
+ );
1916
+ }
1917
+ let sizeBytes;
1918
+ if (typeof Blob !== "undefined" && data instanceof Blob) {
1919
+ sizeBytes = data.size;
1920
+ } else if (data instanceof ArrayBuffer) {
1921
+ sizeBytes = data.byteLength;
1922
+ } else if (typeof data === "string") {
1923
+ const len = data.length;
1924
+ const paddingChars = (data[len - 1] === "=" ? 1 : 0) + (data[len - 2] === "=" ? 1 : 0);
1925
+ sizeBytes = Math.floor(len * 3 / 4) - paddingChars;
1926
+ } else {
1927
+ return;
1928
+ }
1929
+ if (sizeBytes > SHARE_FILE_MAX_SIZE_BYTES) {
1930
+ throw new Error(`file size (${sizeBytes} bytes) exceeds max allowed (${SHARE_FILE_MAX_SIZE_BYTES} bytes)`);
1931
+ }
1932
+ }
1933
+
1812
1934
  // src/social/MockSocialApi.ts
1813
1935
  var MOCK_QR_CODE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
1814
1936
  var MOCK_SHARE_LINK_ID = "mock-share-id";
1815
1937
  var MockSocialApi = class {
1816
1938
  async shareLinkAsync(options) {
1939
+ validateShareParams(options.shareParams);
1940
+ validateShareMetadata(options.metadata);
1817
1941
  const shareUrl = this.createMockUrl(options.shareParams);
1818
1942
  if (typeof navigator !== "undefined" && navigator.clipboard) {
1819
1943
  try {
@@ -1828,6 +1952,8 @@ var MockSocialApi = class {
1828
1952
  return { shareUrl, shareLinkId: MOCK_SHARE_LINK_ID };
1829
1953
  }
1830
1954
  async createQRCodeAsync(options) {
1955
+ validateShareParams(options.shareParams);
1956
+ validateShareMetadata(options.metadata);
1831
1957
  const shareUrl = this.createMockUrl(options.shareParams);
1832
1958
  return {
1833
1959
  shareUrl,
@@ -1836,6 +1962,7 @@ var MockSocialApi = class {
1836
1962
  };
1837
1963
  }
1838
1964
  async addShareClickDataAsync(options) {
1965
+ validateClickMetadata(options.metadata);
1839
1966
  }
1840
1967
  async getShareClicksAsync(options) {
1841
1968
  return { clicks: [], truncated: false };
@@ -1843,7 +1970,8 @@ var MockSocialApi = class {
1843
1970
  async getMyShareClickDataAsync(options) {
1844
1971
  return null;
1845
1972
  }
1846
- async shareFileAsync(_options) {
1973
+ async shareFileAsync(options) {
1974
+ validateShareFile(options);
1847
1975
  console.warn("[RUN:mock] shareFileAsync called \u2014 returning cancelled: false");
1848
1976
  return { cancelled: false };
1849
1977
  }
@@ -2497,6 +2625,13 @@ var MockAdminThreeDGenApi = class {
2497
2625
  };
2498
2626
 
2499
2627
  // src/app/index.ts
2628
+ var SandboxAppApi = class extends PlaygroundAppApi {
2629
+ // @deprecated-alias
2630
+ constructor(...args) {
2631
+ warnRenamed("SandboxAppApi", "PlaygroundAppApi");
2632
+ super(...args);
2633
+ }
2634
+ };
2500
2635
  function initializeApp(rundotGameApiInstance, host) {
2501
2636
  rundotGameApiInstance.app = host.app;
2502
2637
  }
@@ -2510,7 +2645,8 @@ var RpcSocialApi = class {
2510
2645
  async shareLinkAsync(options) {
2511
2646
  const result = await this.rpcClient.call("H5_SHARE_LINK" /* SHARE_LINK */, {
2512
2647
  shareParams: options.shareParams,
2513
- metadata: options.metadata ?? {}
2648
+ metadata: options.metadata ?? {},
2649
+ slug: options.slug
2514
2650
  });
2515
2651
  return {
2516
2652
  shareUrl: result.shareUrl,
@@ -2523,7 +2659,8 @@ var RpcSocialApi = class {
2523
2659
  {
2524
2660
  shareParams: options.shareParams,
2525
2661
  metadata: options.metadata ?? {},
2526
- qrOptions: options.qrOptions ?? {}
2662
+ qrOptions: options.qrOptions ?? {},
2663
+ slug: options.slug
2527
2664
  }
2528
2665
  );
2529
2666
  return {
@@ -3893,7 +4030,7 @@ var MockHost = class {
3893
4030
  // src/Host.ts
3894
4031
  async function createHost(rundotGameApi, isMock) {
3895
4032
  if (isMock) {
3896
- const factory = globalThis.__RUNDOT_SANDBOX_HOST_FACTORY__;
4033
+ const factory = globalThis.__RUNDOT_PLAYGROUND_HOST_FACTORY__;
3897
4034
  if (factory) {
3898
4035
  return factory(rundotGameApi);
3899
4036
  }
@@ -3931,6 +4068,6 @@ function initializeClips(rundotGameApi, host) {
3931
4068
  rundotGameApi.clips = host.clips;
3932
4069
  }
3933
4070
 
3934
- export { HASH_ALGORITHM_NODE, HASH_ALGORITHM_WEB_CRYPTO, MockAdminImageGenApi, MockAdminSpriteGenApi, MockAdminThreeDGenApi, MockAiApi, MockCaptureConsent, MockClipsApi, MockImageGenApi, MockLeaderboardApi, MockSocialApi, MockSpriteGenApi, RemoteHost, RpcAdminImageGenApi, RpcAdminSpriteGenApi, RpcAdminThreeDGenApi, RpcAdminUgcApi, RpcAiApi, RpcAppApi, RpcCaptureConsent, RpcClient, RpcIapApi, RpcImageGenApi, RpcLeaderboardApi, RpcSimulationApi, RpcSocialApi, RpcSpriteGenApi, SDK_VERSION, buildInitializationContext, computeScoreHash, createHost, initializeAi, initializeApp, initializeAudioGen, initializeClips, initializeFiles, initializeIap, initializeImageGen, initializeLeaderboard, initializeSimulation, initializeSocial, initializeSpriteGen, initializeTextGen, initializeThreeDGen, initializeUgc, initializeVideoGen };
3935
- //# sourceMappingURL=chunk-NTONRZFO.js.map
3936
- //# sourceMappingURL=chunk-NTONRZFO.js.map
4071
+ export { HASH_ALGORITHM_NODE, HASH_ALGORITHM_WEB_CRYPTO, MockAdminImageGenApi, MockAdminSpriteGenApi, MockAdminThreeDGenApi, MockAiApi, MockCaptureConsent, MockClipsApi, MockImageGenApi, MockLeaderboardApi, MockSocialApi, MockSpriteGenApi, RemoteHost, RpcAdminImageGenApi, RpcAdminSpriteGenApi, RpcAdminThreeDGenApi, RpcAdminUgcApi, RpcAiApi, RpcAppApi, RpcCaptureConsent, RpcClient, RpcIapApi, RpcImageGenApi, RpcLeaderboardApi, RpcSimulationApi, RpcSocialApi, RpcSpriteGenApi, SDK_VERSION, SandboxAppApi, buildInitializationContext, computeScoreHash, createHost, initializeAi, initializeApp, initializeAudioGen, initializeClips, initializeFiles, initializeIap, initializeImageGen, initializeLeaderboard, initializeSimulation, initializeSocial, initializeSpriteGen, initializeTextGen, initializeThreeDGen, initializeUgc, initializeVideoGen };
4072
+ //# sourceMappingURL=chunk-7VLTROLB.js.map
4073
+ //# sourceMappingURL=chunk-7VLTROLB.js.map