@seriousgaming/sdk-tools 0.0.0-stage → 1.0.0-alpha.1
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/LICENSE +93 -0
- package/README.md +36 -2
- package/dist/bundling/logic-exports.d.ts +34 -0
- package/dist/bundling/node-builtins.d.ts +21 -0
- package/dist/bundling/transpiler.d.ts +7 -0
- package/dist/cli.js +27368 -0
- package/dist/client/dev-server.d.ts +59 -0
- package/dist/client/index.d.ts +28 -0
- package/dist/client/stub-services.d.ts +32 -0
- package/dist/client/test-session.d.ts +195 -0
- package/dist/client.js +16884 -0
- package/dist/core/asset-reference-translator.d.ts +46 -0
- package/dist/core/clock.d.ts +57 -0
- package/dist/core/faults.d.ts +65 -0
- package/dist/core/game-settings.d.ts +65 -0
- package/dist/core/history.d.ts +89 -0
- package/dist/core/listen-with-fallback.d.ts +30 -0
- package/dist/core/mutation-queue.d.ts +61 -0
- package/dist/core/package-scenario.d.ts +89 -0
- package/dist/core/participant-registry.d.ts +109 -0
- package/dist/core/pending-changes.d.ts +14 -0
- package/dist/core/protocol.d.ts +83 -0
- package/dist/core/scenario-drafts.d.ts +32 -0
- package/dist/core/session-endpoints.d.ts +108 -0
- package/dist/core/session-gates.d.ts +75 -0
- package/dist/core/session-host.d.ts +94 -0
- package/dist/core/session-refusals.d.ts +56 -0
- package/dist/core/session-rewind.d.ts +32 -0
- package/dist/core/session-roster.d.ts +128 -0
- package/dist/core/session-surfaces.d.ts +32 -0
- package/dist/core/session-ticks.d.ts +18 -0
- package/dist/core/session-timers.d.ts +84 -0
- package/dist/core/session-writes.d.ts +40 -0
- package/dist/core/session.d.ts +385 -0
- package/dist/core/settings-locks.d.ts +22 -0
- package/dist/core/team-names.d.ts +52 -0
- package/dist/core/team-state-store.d.ts +209 -0
- package/dist/core/tick-timer.d.ts +75 -0
- package/dist/dev/blob-links.d.ts +10 -0
- package/dist/dev/console/assets/index-DgFglsnA.js +204 -0
- package/dist/dev/console/index.html +12 -0
- package/dist/dev/console-path.d.ts +19 -0
- package/dist/dev/lockfile.d.ts +124 -0
- package/dist/dev/package-watcher.d.ts +21 -0
- package/dist/dev/routes.d.ts +67 -0
- package/dist/dev/shell.d.ts +260 -0
- package/dist/dev/surfaces.d.ts +41 -0
- package/dist/dev/tools-identity.d.ts +23 -0
- package/dist/dev/view/batch.d.ts +172 -0
- package/dist/dev/view/commands.d.ts +75 -0
- package/dist/dev/view/route.d.ts +58 -0
- package/dist/dev/view/view.d.ts +78 -0
- package/dist/dev/view/viewer.d.ts +32 -0
- package/dist/discovery/config.d.ts +9 -0
- package/dist/discovery/manifest-paths.d.ts +21 -0
- package/dist/discovery/removed-fields.d.ts +90 -0
- package/dist/docs/api/deck.md +386 -0
- package/dist/docs/api/index.md +67 -0
- package/dist/docs/api/sdk-commands.md +286 -0
- package/dist/docs/api/sdk-e2e.md +433 -0
- package/dist/docs/api/sdk-projection.md +207 -0
- package/dist/docs/api/sdk-testing.md +214 -0
- package/dist/docs/api/sdk-tools-client.md +560 -0
- package/dist/docs/api/sdk-ui-testing.md +231 -0
- package/dist/docs/api/sdk-ui.md +1269 -0
- package/dist/docs/api/sdk.md +2140 -0
- package/dist/docs/changelog-0.x.md +1156 -0
- package/dist/docs/changelog.md +236 -0
- package/dist/docs/cli-and-dev-server.md +217 -0
- package/dist/docs/cli-error-codes.md +154 -0
- package/dist/docs/cli-reference.md +2488 -0
- package/dist/docs/cli-simulation-testing.md +222 -0
- package/dist/docs/concepts/index.md +46 -0
- package/dist/docs/concepts/terminology.md +322 -0
- package/dist/docs/environment-variables.md +102 -0
- package/dist/docs/getting-started.md +145 -0
- package/dist/docs/guides/ai-facilitation.md +220 -0
- package/dist/docs/guides/capabilities.md +460 -0
- package/dist/docs/guides/endpoints.md +335 -0
- package/dist/docs/guides/engine-testing.md +477 -0
- package/dist/docs/guides/engine.md +527 -0
- package/dist/docs/guides/file-handling.md +405 -0
- package/dist/docs/guides/games.md +176 -0
- package/dist/docs/guides/global-settings.md +94 -0
- package/dist/docs/guides/guide.md +123 -0
- package/dist/docs/guides/hooks.md +183 -0
- package/dist/docs/guides/index.md +51 -0
- package/dist/docs/guides/internationalization.md +288 -0
- package/dist/docs/guides/llm-integration.md +635 -0
- package/dist/docs/guides/multi-team-games.md +586 -0
- package/dist/docs/guides/patterns.md +391 -0
- package/dist/docs/guides/presentation.md +196 -0
- package/dist/docs/guides/production-constraints.md +130 -0
- package/dist/docs/guides/scenario-editor.md +143 -0
- package/dist/docs/guides/scenarios.md +515 -0
- package/dist/docs/guides/session.md +972 -0
- package/dist/docs/guides/settings.md +458 -0
- package/dist/docs/guides/setup.md +193 -0
- package/dist/docs/guides/speech-generation.md +233 -0
- package/dist/docs/guides/starter-game.md +164 -0
- package/dist/docs/guides/testing.md +575 -0
- package/dist/docs/guides/tick-controller.md +569 -0
- package/dist/docs/guides/type-safety.md +516 -0
- package/dist/docs/guides/ui.md +1389 -0
- package/dist/docs/guides/upgrading.md +636 -0
- package/dist/docs/guides/validators.md +217 -0
- package/dist/docs/guides/waiting-room.md +244 -0
- package/dist/docs/index.md +41 -0
- package/dist/docs/recipes/act-on-the-session-from-an-endpoint.md +95 -0
- package/dist/docs/recipes/adapt-a-game-for-walkthroughs.md +133 -0
- package/dist/docs/recipes/adapt-ui-for-observers.md +74 -0
- package/dist/docs/recipes/call-endpoint-from-ui.md +109 -0
- package/dist/docs/recipes/check-a-package-from-a-script.md +117 -0
- package/dist/docs/recipes/create-capability.md +66 -0
- package/dist/docs/recipes/create-endpoint.md +127 -0
- package/dist/docs/recipes/create-engine.md +111 -0
- package/dist/docs/recipes/create-game.md +70 -0
- package/dist/docs/recipes/create-guide.md +75 -0
- package/dist/docs/recipes/create-hook.md +80 -0
- package/dist/docs/recipes/create-presentation.md +142 -0
- package/dist/docs/recipes/create-scenario-editor.md +102 -0
- package/dist/docs/recipes/create-scenario.md +98 -0
- package/dist/docs/recipes/create-session-ui.md +116 -0
- package/dist/docs/recipes/create-settings.md +88 -0
- package/dist/docs/recipes/create-setup.md +115 -0
- package/dist/docs/recipes/create-tick-controller.md +65 -0
- package/dist/docs/recipes/create-user-interface.md +96 -0
- package/dist/docs/recipes/create-validator.md +67 -0
- package/dist/docs/recipes/create-waiting-room-ui.md +109 -0
- package/dist/docs/recipes/declare-api-uses.md +67 -0
- package/dist/docs/recipes/design-state-for-concurrent-writes.md +96 -0
- package/dist/docs/recipes/distribute-package.md +80 -0
- package/dist/docs/recipes/e2e-testing.md +116 -0
- package/dist/docs/recipes/end-game-on-condition.md +154 -0
- package/dist/docs/recipes/fix-duplicate-packages.md +101 -0
- package/dist/docs/recipes/index.md +86 -0
- package/dist/docs/recipes/make-an-endpoint-external.md +101 -0
- package/dist/docs/recipes/negotiate-across-teams.md +164 -0
- package/dist/docs/recipes/observe-other-teams-state.md +119 -0
- package/dist/docs/recipes/publish-a-package.md +139 -0
- package/dist/docs/recipes/remember-a-viewers-choice.md +55 -0
- package/dist/docs/recipes/review-a-past-day.md +73 -0
- package/dist/docs/recipes/share-assets-across-scenarios.md +120 -0
- package/dist/docs/recipes/share-logic-between-engine-and-ui.md +130 -0
- package/dist/docs/recipes/show-all-teams-participants.md +109 -0
- package/dist/docs/recipes/start-from-an-empty-package.md +169 -0
- package/dist/docs/recipes/take-a-file-in-an-endpoint.md +82 -0
- package/dist/docs/recipes/test-a-multi-role-game.md +51 -0
- package/dist/docs/recipes/test-user-interface.md +95 -0
- package/dist/docs/recipes/test-with-engine.md +115 -0
- package/dist/docs/recipes/upload-and-display-files.md +148 -0
- package/dist/docs/recipes/use-request-play.md +65 -0
- package/dist/docs/recipes/use-request-tick.md +75 -0
- package/dist/docs/troubleshooting.md +816 -0
- package/dist/execution/blob-inputs.d.ts +57 -0
- package/dist/execution/bundle-reload.d.ts +42 -0
- package/dist/execution/config-resolver.d.ts +127 -0
- package/dist/execution/configuration-builder.d.ts +66 -0
- package/dist/execution/context-composition.d.ts +161 -0
- package/dist/execution/endpoint-actions.d.ts +9 -0
- package/dist/execution/endpoint-payloads.d.ts +32 -0
- package/dist/execution/endpoint-runner.d.ts +129 -0
- package/dist/execution/engine-state.d.ts +40 -0
- package/dist/execution/executor-callbacks.d.ts +56 -0
- package/dist/execution/executor.d.ts +436 -0
- package/dist/execution/gates.d.ts +45 -0
- package/dist/execution/hook-chain.d.ts +25 -0
- package/dist/execution/logic-calls.d.ts +190 -0
- package/dist/execution/logic-failure.d.ts +84 -0
- package/dist/execution/logic-loader.d.ts +54 -0
- package/dist/execution/logic-result.d.ts +76 -0
- package/dist/execution/tick-controller-call.d.ts +32 -0
- package/dist/execution/types.d.ts +48 -0
- package/dist/generation/ts-type.d.ts +39 -0
- package/dist/guide/locale.d.ts +12 -0
- package/dist/guide/video-registry.d.ts +42 -0
- package/dist/help-examples.d.ts +125 -0
- package/dist/host/adapter.d.ts +67 -0
- package/dist/host/host-channel.d.ts +222 -0
- package/dist/host/index.d.ts +20 -0
- package/dist/host/protocol.d.ts +783 -0
- package/dist/host/surfaces.d.ts +42 -0
- package/dist/host/theme.d.ts +55 -0
- package/dist/host.js +583 -0
- package/dist/prompts/index.d.ts +7 -0
- package/dist/prompts/schema-builder.d.ts +29 -0
- package/dist/prompts/types.d.ts +108 -0
- package/dist/prompts/validators.d.ts +32 -0
- package/dist/runtime/capability-scope.d.ts +6 -0
- package/dist/runtime/context-merge.d.ts +29 -0
- package/dist/runtime/context-projection.d.ts +41 -0
- package/dist/runtime/guarded-callbacks.d.ts +15 -0
- package/dist/runtime/index.d.ts +27 -0
- package/dist/runtime/manifest-version.d.ts +55 -0
- package/dist/runtime/tick-validation.d.ts +25 -0
- package/dist/runtime.js +346 -0
- package/dist/schema.json +1546 -0
- package/dist/server/vite-plugin.d.ts +46 -0
- package/dist/services/tts/client.d.ts +51 -0
- package/dist/services/tts/elevenlabs.d.ts +24 -0
- package/dist/services/tts/types.d.ts +44 -0
- package/dist/storage/asset-resolver.d.ts +49 -0
- package/dist/storage/blob-store.d.ts +41 -0
- package/dist/templates/endpoint/logic.test.ts.liquid +61 -0
- package/dist/templates/endpoint/logic.ts.liquid +25 -0
- package/dist/templates/engine/init.json.liquid +7 -0
- package/dist/templates/engine/logic-aggregate.test.ts.liquid +90 -0
- package/dist/templates/engine/logic-aggregate.ts.liquid +46 -0
- package/dist/templates/engine/logic.test.ts.liquid +61 -0
- package/dist/templates/engine/logic.ts.liquid +32 -0
- package/dist/templates/engine/run.json.liquid +7 -0
- package/dist/templates/guide/01-at-a-glance.md.liquid +19 -0
- package/dist/templates/guide/02-preparation.md.liquid +18 -0
- package/dist/templates/guide/03-running-the-session.md.liquid +37 -0
- package/dist/templates/hook/logic.test.ts.liquid +46 -0
- package/dist/templates/hook/logic.ts.liquid +12 -0
- package/dist/templates/package/CLAUDE.md.template +338 -0
- package/dist/templates/package/DESIGN.md.liquid +144 -0
- package/dist/templates/package/README.md.liquid +143 -0
- package/dist/templates/package/claude/rules/workflow-create-capability.md +26 -0
- package/dist/templates/package/claude/rules/workflow-create-endpoint.md +35 -0
- package/dist/templates/package/claude/rules/workflow-create-engine.md +35 -0
- package/dist/templates/package/claude/rules/workflow-create-guide.md +40 -0
- package/dist/templates/package/claude/rules/workflow-create-presentation.md +37 -0
- package/dist/templates/package/claude/rules/workflow-create-user-interface.md +31 -0
- package/dist/templates/package/claude/rules/workflow-publish-package.md +54 -0
- package/dist/templates/package/claude/rules/workflow-test-engine-or-ui.md +30 -0
- package/dist/templates/package/claude/rules/workflow-update-sdk-version.md +43 -0
- package/dist/templates/package/claude/settings.json.template +16 -0
- package/dist/templates/package/gitignore.template +15 -0
- package/dist/templates/package/global-setup.ts.template +21 -0
- package/dist/templates/package/globals.d.ts.template +2 -0
- package/dist/templates/package/oxfmtrc.json.template +14 -0
- package/dist/templates/package/oxlintrc.json.template +238 -0
- package/dist/templates/package/package.json.liquid +65 -0
- package/dist/templates/package/playwright.config.ts.liquid +19 -0
- package/dist/templates/package/pnpm-workspace.yaml.template +27 -0
- package/dist/templates/package/test-setup.ts.liquid +7 -0
- package/dist/templates/package/tsconfig.json.liquid +15 -0
- package/dist/templates/package/vite.config.ts.liquid +19 -0
- package/dist/templates/package/vitest.config.ts.liquid +25 -0
- package/dist/templates/package/vitest.engine.config.ts.liquid +12 -0
- package/dist/templates/presentation/index.html.liquid +20 -0
- package/dist/templates/presentation/src/App.tsx.liquid +49 -0
- package/dist/templates/presentation/src/Slides.tsx.liquid +81 -0
- package/dist/templates/presentation/src/i18n.ts.liquid +54 -0
- package/dist/templates/presentation/src/main.tsx.liquid +14 -0
- package/dist/templates/scenario_editor/src/App.test.tsx.liquid +30 -0
- package/dist/templates/scenario_editor/src/App.tsx.liquid +95 -0
- package/dist/templates/scenario_editor/src/i18n.ts.liquid +44 -0
- package/dist/templates/session/src/App.test.tsx.liquid +60 -0
- package/dist/templates/session/src/App.tsx.liquid +128 -0
- package/dist/templates/session/src/i18n.ts.liquid +53 -0
- package/dist/templates/session/src/main.tsx.liquid +48 -0
- package/dist/templates/session/src/theme.ts.liquid +46 -0
- package/dist/templates/settings-editor/index.html.liquid +12 -0
- package/dist/templates/settings-editor/src/main.tsx.liquid +48 -0
- package/dist/templates/settings-editor/src/theme.ts.liquid +24 -0
- package/dist/templates/setup/src/App.test.tsx.liquid +39 -0
- package/dist/templates/setup/src/App.tsx.liquid +102 -0
- package/dist/templates/setup/src/i18n.ts.liquid +47 -0
- package/dist/templates/starter-game/capabilities/briefing/capability.sdk.json +18 -0
- package/dist/templates/starter-game/capabilities/plan/capability.sdk.json +17 -0
- package/dist/templates/starter-game/capabilities/results/capability.sdk.json +61 -0
- package/dist/templates/starter-game/capabilities/roles/capability.sdk.json +17 -0
- package/dist/templates/starter-game/capabilities/weather/capability.sdk.json +23 -0
- package/dist/templates/starter-game/engine/defaults.ts +81 -0
- package/dist/templates/starter-game/engine/engine.sdk.json +12 -0
- package/dist/templates/starter-game/engine/logic.test.ts +221 -0
- package/dist/templates/starter-game/engine/logic.ts +149 -0
- package/dist/templates/starter-game/engine/test-helpers.ts +74 -0
- package/dist/templates/starter-game/engine/types.ts +139 -0
- package/dist/templates/starter-game/guide/content/en/01-at-a-glance.md +51 -0
- package/dist/templates/starter-game/guide/content/en/02-preparation.md +35 -0
- package/dist/templates/starter-game/guide/content/en/03-running-the-day.md +58 -0
- package/dist/templates/starter-game/guide/guide.sdk.json +10 -0
- package/dist/templates/starter-game/guide/guide.test.ts +108 -0
- package/dist/templates/starter-game/hooks/assignproducts/defaults.ts +37 -0
- package/dist/templates/starter-game/hooks/assignproducts/hook.sdk.json +13 -0
- package/dist/templates/starter-game/hooks/assignproducts/logic/logic.test.ts +77 -0
- package/dist/templates/starter-game/hooks/assignproducts/logic/logic.ts +47 -0
- package/dist/templates/starter-game/hooks/assignproducts/types.ts +55 -0
- package/dist/templates/starter-game/package.json +68 -0
- package/dist/templates/starter-game/playwright.config.ts +19 -0
- package/dist/templates/starter-game/scenarios/heatwave/scenario.sdk.json +20 -0
- package/dist/templates/starter-game/scenarios/ordinary_week/scenario.sdk.json +12 -0
- package/dist/templates/starter-game/seriousgaming.sdk.json +23 -0
- package/dist/templates/starter-game/session/defaults.ts +80 -0
- package/dist/templates/starter-game/session/index.html +12 -0
- package/dist/templates/starter-game/session/session.sdk.json +11 -0
- package/dist/templates/starter-game/session/src/App.test.tsx +307 -0
- package/dist/templates/starter-game/session/src/App.tsx +309 -0
- package/dist/templates/starter-game/session/src/Section.tsx +37 -0
- package/dist/templates/starter-game/session/src/TeamDoor.tsx +96 -0
- package/dist/templates/starter-game/session/src/format.ts +8 -0
- package/dist/templates/starter-game/session/src/i18n.ts +51 -0
- package/dist/templates/starter-game/session/src/main.tsx +48 -0
- package/dist/templates/starter-game/session/src/theme.ts +45 -0
- package/dist/templates/starter-game/session/types.ts +135 -0
- package/dist/templates/starter-game/settings/engine/settings.sdk.json +50 -0
- package/dist/templates/starter-game/settings/menu/settings.sdk.json +78 -0
- package/dist/templates/starter-game/settings/session/settings.sdk.json +23 -0
- package/dist/templates/starter-game/settings/ui/settings.sdk.json +25 -0
- package/dist/templates/starter-game/test-setup.ts +7 -0
- package/dist/templates/starter-game/testing/e2e/game.spec.ts +139 -0
- package/dist/templates/starter-game/testing/e2e/global-setup.ts +21 -0
- package/dist/templates/starter-game/testing/engine/game.engine.test.ts +171 -0
- package/dist/templates/starter-game/tsconfig.json +19 -0
- package/dist/templates/starter-game/ui/defaults.ts +60 -0
- package/dist/templates/starter-game/ui/index.html +12 -0
- package/dist/templates/starter-game/ui/src/App.test.tsx +138 -0
- package/dist/templates/starter-game/ui/src/App.tsx +175 -0
- package/dist/templates/starter-game/ui/src/DayBar.test.tsx +78 -0
- package/dist/templates/starter-game/ui/src/DayBar.tsx +72 -0
- package/dist/templates/starter-game/ui/src/HistoryPanel.test.tsx +74 -0
- package/dist/templates/starter-game/ui/src/HistoryPanel.tsx +120 -0
- package/dist/templates/starter-game/ui/src/MakeRow.tsx +129 -0
- package/dist/templates/starter-game/ui/src/Section.tsx +37 -0
- package/dist/templates/starter-game/ui/src/ThemeToggle.tsx +49 -0
- package/dist/templates/starter-game/ui/src/TodayPanel.test.tsx +179 -0
- package/dist/templates/starter-game/ui/src/TodayPanel.tsx +92 -0
- package/dist/templates/starter-game/ui/src/YesterdayPanel.tsx +142 -0
- package/dist/templates/starter-game/ui/src/format.ts +12 -0
- package/dist/templates/starter-game/ui/src/i18n.ts +95 -0
- package/dist/templates/starter-game/ui/src/main.tsx +48 -0
- package/dist/templates/starter-game/ui/src/menu.ts +18 -0
- package/dist/templates/starter-game/ui/src/test-helpers.ts +58 -0
- package/dist/templates/starter-game/ui/src/theme.ts +45 -0
- package/dist/templates/starter-game/ui/src/writes.ts +43 -0
- package/dist/templates/starter-game/ui/types.ts +137 -0
- package/dist/templates/starter-game/ui/ui.sdk.json +11 -0
- package/dist/templates/starter-game/validators/capacity/defaults.ts +37 -0
- package/dist/templates/starter-game/validators/capacity/logic/logic.test.ts +96 -0
- package/dist/templates/starter-game/validators/capacity/logic/logic.ts +45 -0
- package/dist/templates/starter-game/validators/capacity/types.ts +55 -0
- package/dist/templates/starter-game/validators/capacity/validator.sdk.json +11 -0
- package/dist/templates/starter-game/vite.config.ts +19 -0
- package/dist/templates/starter-game/vitest.config.ts +15 -0
- package/dist/templates/starter-game/vitest.engine.config.ts +19 -0
- package/dist/templates/starter-game/waiting_room/defaults.ts +40 -0
- package/dist/templates/starter-game/waiting_room/index.html +12 -0
- package/dist/templates/starter-game/waiting_room/src/App.test.tsx +102 -0
- package/dist/templates/starter-game/waiting_room/src/App.tsx +194 -0
- package/dist/templates/starter-game/waiting_room/src/i18n.ts +33 -0
- package/dist/templates/starter-game/waiting_room/src/main.tsx +48 -0
- package/dist/templates/starter-game/waiting_room/src/theme.ts +45 -0
- package/dist/templates/starter-game/waiting_room/types.ts +59 -0
- package/dist/templates/starter-game/waiting_room/waiting_room.sdk.json +10 -0
- package/dist/templates/tick-controller/logic.ts.liquid +8 -0
- package/dist/templates/ui/index.html.liquid +12 -0
- package/dist/templates/ui/src/App.test.tsx.liquid +41 -0
- package/dist/templates/ui/src/App.tsx.liquid +103 -0
- package/dist/templates/ui/src/i18n.ts.liquid +47 -0
- package/dist/templates/ui/src/main.tsx.liquid +48 -0
- package/dist/templates/ui/src/theme.ts.liquid +46 -0
- package/dist/templates/validator/logic.test.ts.liquid +42 -0
- package/dist/templates/validator/logic.ts.liquid +21 -0
- package/dist/templates/waiting-room/index.html.liquid +12 -0
- package/dist/templates/waiting-room/src/App.test.tsx.liquid +57 -0
- package/dist/templates/waiting-room/src/App.tsx.liquid +118 -0
- package/dist/templates/waiting-room/src/i18n.ts.liquid +44 -0
- package/dist/templates/waiting-room/src/main.tsx.liquid +48 -0
- package/dist/templates/waiting-room/src/theme.ts.liquid +46 -0
- package/dist/templating/resource-metadata.d.ts +131 -0
- package/dist/types.d.ts +14 -0
- package/dist/utils/atomic-write.d.ts +40 -0
- package/dist/utils/cli-error.d.ts +64 -0
- package/dist/utils/document-parser-client.d.ts +20 -0
- package/dist/utils/env-loader.d.ts +40 -0
- package/dist/utils/error-codes.d.ts +335 -0
- package/dist/utils/errors.d.ts +19 -0
- package/dist/utils/global-settings.d.ts +65 -0
- package/dist/utils/llm-client.d.ts +34 -0
- package/dist/utils/logger.d.ts +36 -0
- package/dist/utils/output.d.ts +109 -0
- package/dist/utils/platform.d.ts +14 -0
- package/dist/utils/prompt.d.ts +36 -0
- package/dist/utils/real-path.d.ts +6 -0
- package/dist/utils/schema-properties.d.ts +35 -0
- package/dist/validation/ajv.d.ts +17 -0
- package/dist/validation/facilitator-guide-validator.d.ts +27 -0
- package/dist/validation/findings.d.ts +40 -0
- package/dist/validation/game-constraints.d.ts +10 -0
- package/dist/validation/game-validator.d.ts +34 -0
- package/dist/validation/package-validation.d.ts +41 -0
- package/dist/validation/package-validator.d.ts +19 -0
- package/dist/validation/resource-validator.d.ts +79 -0
- package/dist/validation/schema-defaults-validator.d.ts +29 -0
- package/dist/validation/schema-validation.d.ts +115 -0
- package/dist/validation/semver.d.ts +9 -0
- package/package.json +122 -3
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Button, Stack, Tooltip, Typography } from '@mui/material';
|
|
2
|
+
import type { TeamLinks } from '@seriousgaming/sdk/ui';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
links: TeamLinks | undefined;
|
|
8
|
+
teamName: string;
|
|
9
|
+
show: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The two ways a facilitator gets into a stall: observing, and joining.
|
|
14
|
+
*
|
|
15
|
+
* Both are one click. Reading a URL out of a table and typing it into another
|
|
16
|
+
* tab is the thing a facilitator actually does half a dozen times a session,
|
|
17
|
+
* and it is the slowest part of running one.
|
|
18
|
+
*
|
|
19
|
+
* `target="_blank"` rather than navigating this frame: a session surface owns
|
|
20
|
+
* the whole canvas, and replacing it with a player's screen would leave the
|
|
21
|
+
* facilitator with no way back. The host grants `allow-popups` and
|
|
22
|
+
* `allow-popups-to-escape-sandbox` for exactly this.
|
|
23
|
+
*
|
|
24
|
+
* The two links are not the same kind of thing, and the labels say so.
|
|
25
|
+
* Observing admits nobody: an observer has no participant record and no
|
|
26
|
+
* presence, so the stall never sees a fourth person appear. Joining is a real
|
|
27
|
+
* seat at a real stall, which is what you want when you are showing somebody
|
|
28
|
+
* how it works and not what you want when you are checking on them.
|
|
29
|
+
*/
|
|
30
|
+
export default function TeamDoor({ links, teamName, show }: Props) {
|
|
31
|
+
const { t } = useTranslation();
|
|
32
|
+
const [copied, setCopied] = useState(false);
|
|
33
|
+
const [reveal, setReveal] = useState(false);
|
|
34
|
+
|
|
35
|
+
// Empty until the host delivers them, which is one frame rather than never.
|
|
36
|
+
if (!links || !show) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const copyJoinLink = async () => {
|
|
41
|
+
// Feature-detected: `clipboard-write` is delegated to this frame, but
|
|
42
|
+
// Permissions Policy is implemented unevenly and a browser may gate the
|
|
43
|
+
// write on a gesture it does not think it had. Falling back to showing
|
|
44
|
+
// the URL is worse than copying and better than a button that does
|
|
45
|
+
// nothing.
|
|
46
|
+
try {
|
|
47
|
+
await navigator.clipboard.writeText(links.joinUrl);
|
|
48
|
+
setCopied(true);
|
|
49
|
+
setReveal(false);
|
|
50
|
+
} catch {
|
|
51
|
+
setReveal(true);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<Stack spacing={0.5}>
|
|
57
|
+
<Stack direction="row" spacing={1}>
|
|
58
|
+
<Button
|
|
59
|
+
size="small"
|
|
60
|
+
variant="outlined"
|
|
61
|
+
component="a"
|
|
62
|
+
href={links.observeUrl}
|
|
63
|
+
target="_blank"
|
|
64
|
+
rel="noopener"
|
|
65
|
+
>
|
|
66
|
+
{t('door.observe')}
|
|
67
|
+
</Button>
|
|
68
|
+
<Button
|
|
69
|
+
size="small"
|
|
70
|
+
component="a"
|
|
71
|
+
href={links.joinUrl}
|
|
72
|
+
target="_blank"
|
|
73
|
+
rel="noopener"
|
|
74
|
+
>
|
|
75
|
+
{t('door.join')}
|
|
76
|
+
</Button>
|
|
77
|
+
<Tooltip title={t('door.copyHint', { team: teamName })}>
|
|
78
|
+
<Button
|
|
79
|
+
size="small"
|
|
80
|
+
color="inherit"
|
|
81
|
+
aria-label={t('door.copy', { team: teamName })}
|
|
82
|
+
onClick={() => void copyJoinLink()}
|
|
83
|
+
onMouseLeave={() => setCopied(false)}
|
|
84
|
+
>
|
|
85
|
+
{copied ? t('door.copied') : t('door.copyShort')}
|
|
86
|
+
</Button>
|
|
87
|
+
</Tooltip>
|
|
88
|
+
</Stack>
|
|
89
|
+
{reveal && (
|
|
90
|
+
<Typography variant="caption" sx={{ fontFamily: 'monospace', userSelect: 'all' }}>
|
|
91
|
+
{links.joinUrl}
|
|
92
|
+
</Typography>
|
|
93
|
+
)}
|
|
94
|
+
</Stack>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Display helpers shared by the panels, so one round of a number is decided once. */
|
|
2
|
+
|
|
3
|
+
export const money = (prefix: string, value: number) =>
|
|
4
|
+
`${value < 0 ? '-' : ''}${prefix}${Math.abs(Math.round(value)).toLocaleString()}`;
|
|
5
|
+
|
|
6
|
+
export const percent = (fraction: number) => `${Math.round(fraction * 100)}%`;
|
|
7
|
+
|
|
8
|
+
export const units = (value: number) => Math.round(value).toLocaleString();
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import i18n from 'i18next';
|
|
2
|
+
import { initReactI18next } from 'react-i18next';
|
|
3
|
+
|
|
4
|
+
const resources = {
|
|
5
|
+
en: {
|
|
6
|
+
translation: {
|
|
7
|
+
session: {
|
|
8
|
+
waitingRoom: 'Waiting room',
|
|
9
|
+
waitingRoomHint:
|
|
10
|
+
'Holds every player on the holding screen. Nothing about the session changes, so you can park it for a discussion and pick up where the stalls were.',
|
|
11
|
+
guide: 'Facilitator guide',
|
|
12
|
+
readOnly: 'This session is read only, so the controls below will be refused.',
|
|
13
|
+
stalls: 'Stalls',
|
|
14
|
+
movedOn: '{{movedOn}} of {{total}} have changed their numbers today',
|
|
15
|
+
team: 'Stall',
|
|
16
|
+
people: 'People',
|
|
17
|
+
day: 'Day',
|
|
18
|
+
making: 'Making',
|
|
19
|
+
ofCapacity: '{{planned}} of {{capacity}}',
|
|
20
|
+
status: 'Today',
|
|
21
|
+
purse: 'In the jar',
|
|
22
|
+
wayIn: 'Way in',
|
|
23
|
+
controls: '',
|
|
24
|
+
unchanged: 'Same as yesterday',
|
|
25
|
+
changed: 'Changed',
|
|
26
|
+
undo: 'Undo',
|
|
27
|
+
notice: 'Notice to the room',
|
|
28
|
+
noticeHint: 'One note, shown on every stall’s screen and in the waiting room.',
|
|
29
|
+
noticeLabel: 'Message',
|
|
30
|
+
send: 'Send',
|
|
31
|
+
},
|
|
32
|
+
door: {
|
|
33
|
+
observe: 'Observe',
|
|
34
|
+
join: 'Join',
|
|
35
|
+
copy: 'Copy the join link for {{team}}',
|
|
36
|
+
copyShort: 'Copy link',
|
|
37
|
+
copyHint: 'Copy {{team}}’s join link, to hand out or put on a slide',
|
|
38
|
+
copied: 'Copied',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
i18n.use(initReactI18next).init({
|
|
45
|
+
resources,
|
|
46
|
+
lng: 'en',
|
|
47
|
+
fallbackLng: 'en',
|
|
48
|
+
interpolation: { escapeValue: false },
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export default i18n;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import createCache from '@emotion/cache';
|
|
2
|
+
import { CacheProvider } from '@emotion/react';
|
|
3
|
+
import '@fontsource-variable/roboto-mono';
|
|
4
|
+
import '@fontsource-variable/work-sans';
|
|
5
|
+
import rtlPlugin from '@mui/stylis-plugin-rtl';
|
|
6
|
+
import { SessionUserInterfaceWrapper, useSessionUserInterfaceLocale } from '@seriousgaming/sdk/ui';
|
|
7
|
+
|
|
8
|
+
import './i18n';
|
|
9
|
+
import i18n from 'i18next';
|
|
10
|
+
import React, { StrictMode, useEffect } from 'react';
|
|
11
|
+
import { createRoot } from 'react-dom/client';
|
|
12
|
+
import { prefixer } from 'stylis';
|
|
13
|
+
|
|
14
|
+
import App from './App';
|
|
15
|
+
|
|
16
|
+
// Create RTL cache
|
|
17
|
+
const cacheRtl = createCache({
|
|
18
|
+
key: 'muirtl',
|
|
19
|
+
stylisPlugins: [prefixer, rtlPlugin],
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const cacheLtr = createCache({
|
|
23
|
+
key: 'muiltr',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Wrapper component to sync locale with i18next and setup RTL
|
|
27
|
+
function RootWrapper({ children }: { children: React.ReactNode }) {
|
|
28
|
+
const { locale } = useSessionUserInterfaceLocale();
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const i18nextLocale = locale.split('-')[0];
|
|
32
|
+
i18n.changeLanguage(i18nextLocale);
|
|
33
|
+
}, [locale]);
|
|
34
|
+
|
|
35
|
+
const isRtl = i18n.dir(locale.split('-')[0]) === 'rtl';
|
|
36
|
+
|
|
37
|
+
return <CacheProvider value={isRtl ? cacheRtl : cacheLtr}>{children}</CacheProvider>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
createRoot(document.getElementById('root')!).render(
|
|
41
|
+
<StrictMode>
|
|
42
|
+
<SessionUserInterfaceWrapper>
|
|
43
|
+
<RootWrapper>
|
|
44
|
+
<App />
|
|
45
|
+
</RootWrapper>
|
|
46
|
+
</SessionUserInterfaceWrapper>
|
|
47
|
+
</StrictMode>
|
|
48
|
+
);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createTheme } from '@mui/material/styles';
|
|
2
|
+
import { useSessionUserInterfaceTheme } from '@seriousgaming/sdk/ui';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The host owns the palette, the game owns the typography and the component
|
|
7
|
+
* shapes. Reading `theme.mode` rather than the browser's preference is what
|
|
8
|
+
* keeps a participant's screen and the facilitator's looking like one product.
|
|
9
|
+
*/
|
|
10
|
+
export const useAppTheme = () => {
|
|
11
|
+
const theme = useSessionUserInterfaceTheme();
|
|
12
|
+
|
|
13
|
+
return useMemo(() => {
|
|
14
|
+
const colors = theme.mode === 'light' ? theme.light : theme.dark;
|
|
15
|
+
return createTheme({
|
|
16
|
+
palette: {
|
|
17
|
+
mode: theme.mode,
|
|
18
|
+
primary: { main: colors.primary, contrastText: colors.contrastText.primary },
|
|
19
|
+
secondary: { main: colors.secondary, contrastText: colors.contrastText.secondary },
|
|
20
|
+
success: { main: colors.success, contrastText: colors.contrastText.success },
|
|
21
|
+
error: { main: colors.error, contrastText: colors.contrastText.error },
|
|
22
|
+
warning: { main: colors.warning, contrastText: colors.contrastText.warning },
|
|
23
|
+
info: { main: colors.info, contrastText: colors.contrastText.info },
|
|
24
|
+
},
|
|
25
|
+
shape: { borderRadius: 10 },
|
|
26
|
+
components: {
|
|
27
|
+
MuiButton: { styleOverrides: { root: { textTransform: 'none' } } },
|
|
28
|
+
MuiTab: {
|
|
29
|
+
styleOverrides: { root: { textTransform: 'none', fontSize: '0.95rem' } },
|
|
30
|
+
},
|
|
31
|
+
MuiToggleButton: { styleOverrides: { root: { textTransform: 'none' } } },
|
|
32
|
+
MuiTableCell: {
|
|
33
|
+
styleOverrides: {
|
|
34
|
+
head: {
|
|
35
|
+
fontSize: '0.75rem',
|
|
36
|
+
fontWeight: 700,
|
|
37
|
+
letterSpacing: '0.07em',
|
|
38
|
+
textTransform: 'uppercase',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}, [theme]);
|
|
45
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// This file is auto-generated from the session user interface's capability definitions.
|
|
2
|
+
// Do not edit this file directly. It will be regenerated on build.
|
|
3
|
+
|
|
4
|
+
export interface Context {
|
|
5
|
+
plan: {
|
|
6
|
+
/**
|
|
7
|
+
* How many of each menu item to make today, keyed by item id. Keyed rather than a flat set of fields so that two people changing two different items write different keys, and the host's merge keeps both.
|
|
8
|
+
*/
|
|
9
|
+
Make: {
|
|
10
|
+
[k: string]: number;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
results: {
|
|
14
|
+
/**
|
|
15
|
+
* The day these results are for
|
|
16
|
+
*/
|
|
17
|
+
Day: number;
|
|
18
|
+
/**
|
|
19
|
+
* What the weather actually did
|
|
20
|
+
*/
|
|
21
|
+
Weather: string;
|
|
22
|
+
/**
|
|
23
|
+
* What happened to each menu item, keyed by item id
|
|
24
|
+
*/
|
|
25
|
+
Lines: {
|
|
26
|
+
[k: string]: DayLine;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Money in, in pence
|
|
30
|
+
*/
|
|
31
|
+
Takings: number;
|
|
32
|
+
/**
|
|
33
|
+
* Cost of everything made, in pence
|
|
34
|
+
*/
|
|
35
|
+
Spent: number;
|
|
36
|
+
/**
|
|
37
|
+
* Takings less spend, in pence
|
|
38
|
+
*/
|
|
39
|
+
Profit: number;
|
|
40
|
+
/**
|
|
41
|
+
* Everything made so far, in pence
|
|
42
|
+
*/
|
|
43
|
+
Purse: number;
|
|
44
|
+
};
|
|
45
|
+
roles: {
|
|
46
|
+
/**
|
|
47
|
+
* Which menu item each participant is in charge of, keyed by participant id. Written by the participantJoin hook, and the reason two people normally edit two different keys.
|
|
48
|
+
*/
|
|
49
|
+
LooksAfter: {
|
|
50
|
+
[k: string]: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
briefing: {
|
|
54
|
+
/**
|
|
55
|
+
* Facilitator note shown on every team's screen. Shared scope: one value for the whole session, written only from the session surface. Session lifetime: an undo or a reset leaves it as the facilitator last wrote it.
|
|
56
|
+
*/
|
|
57
|
+
Message: string;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export interface DayLine {
|
|
61
|
+
Made: number;
|
|
62
|
+
/**
|
|
63
|
+
* How many people asked for one
|
|
64
|
+
*/
|
|
65
|
+
Wanted: number;
|
|
66
|
+
Sold: number;
|
|
67
|
+
/**
|
|
68
|
+
* Made and not sold
|
|
69
|
+
*/
|
|
70
|
+
PouredAway: number;
|
|
71
|
+
/**
|
|
72
|
+
* Asked for and not available
|
|
73
|
+
*/
|
|
74
|
+
TurnedAway: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type TeamContext = Pick<Context, 'plan' | 'results' | 'roles'>;
|
|
78
|
+
|
|
79
|
+
export type SharedContext = Pick<Context, 'briefing'>;
|
|
80
|
+
|
|
81
|
+
export type SharedWrites = Pick<Context, 'briefing'>;
|
|
82
|
+
|
|
83
|
+
export type TeamWrites = Record<string, never>;
|
|
84
|
+
|
|
85
|
+
import type { SessionData as SurfaceSessionData } from '@seriousgaming/sdk/ui';
|
|
86
|
+
|
|
87
|
+
export type SessionData = SurfaceSessionData<TeamContext, SharedContext>;
|
|
88
|
+
|
|
89
|
+
export interface Settings {
|
|
90
|
+
menu: {
|
|
91
|
+
/**
|
|
92
|
+
* How many items the stall can make in a day, across the whole menu
|
|
93
|
+
*/
|
|
94
|
+
Capacity: number;
|
|
95
|
+
Menu: Menu;
|
|
96
|
+
};
|
|
97
|
+
session: {
|
|
98
|
+
/**
|
|
99
|
+
* Whether the session surface offers the per-team join and observe links
|
|
100
|
+
*/
|
|
101
|
+
ShowJoinLinks: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Symbol for money on the session surface. Prices are the same numbers whichever symbol is shown
|
|
104
|
+
*/
|
|
105
|
+
CurrencySymbol: '£' | '$' | '€';
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* What the stall sells, keyed by item id. Money is in pence, so the sums stay in whole numbers. Read by the engine and every surface, so the price on screen and the price in the sums are the same number.
|
|
110
|
+
*/
|
|
111
|
+
export interface Menu {
|
|
112
|
+
[k: string]: MenuItem;
|
|
113
|
+
}
|
|
114
|
+
export interface MenuItem {
|
|
115
|
+
/**
|
|
116
|
+
* What the item is called on every screen
|
|
117
|
+
*/
|
|
118
|
+
Name: string;
|
|
119
|
+
/**
|
|
120
|
+
* Where it sits on the menu, so every screen lists it in the same order. 1 comes first
|
|
121
|
+
*/
|
|
122
|
+
Order: number;
|
|
123
|
+
/**
|
|
124
|
+
* Cost to make one, in pence
|
|
125
|
+
*/
|
|
126
|
+
Cost: number;
|
|
127
|
+
/**
|
|
128
|
+
* Sale price, in pence
|
|
129
|
+
*/
|
|
130
|
+
Price: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
import type { SessionUserInterfaceCallbacks } from '@seriousgaming/sdk';
|
|
134
|
+
|
|
135
|
+
export type Callbacks = Pick<SessionUserInterfaceCallbacks, never>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"definition": {
|
|
3
|
+
"settingsSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"UsualDemand": {
|
|
7
|
+
"title": "Usual demand",
|
|
8
|
+
"description": "How many people want each menu item on an ordinary cloudy day, keyed by item id. Kept apart from the menu because only the engine reads it: a surface that could see it would be showing the answer. An item on the menu with no entry here has no custom at all, so its forecast reads 0 and nobody buys one.",
|
|
9
|
+
"type": "object",
|
|
10
|
+
"default": {
|
|
11
|
+
"lemonade": 55,
|
|
12
|
+
"icedtea": 30,
|
|
13
|
+
"cookies": 20
|
|
14
|
+
},
|
|
15
|
+
"additionalProperties": {
|
|
16
|
+
"type": "integer",
|
|
17
|
+
"description": "People a day who want this item when it is cloudy",
|
|
18
|
+
"minimum": 0,
|
|
19
|
+
"maximum": 1000
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"SunnyPull": {
|
|
23
|
+
"title": "Sunny day pull",
|
|
24
|
+
"description": "How much busier a sunny day is than a cloudy one, as a multiplier on usual demand. 1.3 brings 30% more people",
|
|
25
|
+
"type": "number",
|
|
26
|
+
"default": 1.3,
|
|
27
|
+
"minimum": 0,
|
|
28
|
+
"maximum": 5
|
|
29
|
+
},
|
|
30
|
+
"RainyPull": {
|
|
31
|
+
"title": "Rainy day pull",
|
|
32
|
+
"description": "How much quieter a rainy day is than a cloudy one, as a multiplier on usual demand. 0.65 brings 35% fewer people, and above 1 makes rain busier",
|
|
33
|
+
"type": "number",
|
|
34
|
+
"default": 0.65,
|
|
35
|
+
"minimum": 0,
|
|
36
|
+
"maximum": 5
|
|
37
|
+
},
|
|
38
|
+
"Variation": {
|
|
39
|
+
"title": "Day-to-day variation",
|
|
40
|
+
"description": "How far a day can land either side of its forecast, as a fraction. 0.2 lands within 20% of it, and 0 makes every forecast exact",
|
|
41
|
+
"type": "number",
|
|
42
|
+
"default": 0.2,
|
|
43
|
+
"minimum": 0,
|
|
44
|
+
"maximum": 1
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"additionalProperties": false
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"definition": {
|
|
3
|
+
"settingsSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"Capacity": {
|
|
7
|
+
"title": "Daily capacity",
|
|
8
|
+
"description": "How many items the stall can make in a day, across the whole menu",
|
|
9
|
+
"type": "integer",
|
|
10
|
+
"default": 120,
|
|
11
|
+
"minimum": 1,
|
|
12
|
+
"maximum": 1000
|
|
13
|
+
},
|
|
14
|
+
"Menu": {
|
|
15
|
+
"title": "Menu",
|
|
16
|
+
"description": "What the stall sells, keyed by item id. Money is in pence, so the sums stay in whole numbers. Read by the engine and every surface, so the price on screen and the price in the sums are the same number.",
|
|
17
|
+
"type": "object",
|
|
18
|
+
"default": {
|
|
19
|
+
"lemonade": {
|
|
20
|
+
"Name": "Lemonade",
|
|
21
|
+
"Order": 1,
|
|
22
|
+
"Cost": 15,
|
|
23
|
+
"Price": 50
|
|
24
|
+
},
|
|
25
|
+
"icedtea": {
|
|
26
|
+
"Name": "Iced tea",
|
|
27
|
+
"Order": 2,
|
|
28
|
+
"Cost": 20,
|
|
29
|
+
"Price": 60
|
|
30
|
+
},
|
|
31
|
+
"cookies": {
|
|
32
|
+
"Name": "Cookies",
|
|
33
|
+
"Order": 3,
|
|
34
|
+
"Cost": 25,
|
|
35
|
+
"Price": 70
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"additionalProperties": {
|
|
39
|
+
"title": "MenuItem",
|
|
40
|
+
"type": "object",
|
|
41
|
+
"properties": {
|
|
42
|
+
"Name": {
|
|
43
|
+
"title": "Name",
|
|
44
|
+
"description": "What the item is called on every screen",
|
|
45
|
+
"type": "string",
|
|
46
|
+
"minLength": 1,
|
|
47
|
+
"maxLength": 40
|
|
48
|
+
},
|
|
49
|
+
"Order": {
|
|
50
|
+
"title": "Menu position",
|
|
51
|
+
"description": "Where it sits on the menu, so every screen lists it in the same order. 1 comes first",
|
|
52
|
+
"type": "integer",
|
|
53
|
+
"minimum": 1
|
|
54
|
+
},
|
|
55
|
+
"Cost": {
|
|
56
|
+
"title": "Cost",
|
|
57
|
+
"description": "Cost to make one, in pence",
|
|
58
|
+
"type": "integer",
|
|
59
|
+
"minimum": 0,
|
|
60
|
+
"maximum": 10000
|
|
61
|
+
},
|
|
62
|
+
"Price": {
|
|
63
|
+
"title": "Price",
|
|
64
|
+
"description": "Sale price, in pence",
|
|
65
|
+
"type": "integer",
|
|
66
|
+
"minimum": 0,
|
|
67
|
+
"maximum": 10000
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"required": ["Name", "Order", "Cost", "Price"],
|
|
71
|
+
"additionalProperties": false
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"additionalProperties": false
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"definition": {
|
|
3
|
+
"settingsSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"ShowJoinLinks": {
|
|
7
|
+
"title": "Show join links",
|
|
8
|
+
"description": "Whether the session surface offers the per-team join and observe links",
|
|
9
|
+
"type": "boolean",
|
|
10
|
+
"default": true
|
|
11
|
+
},
|
|
12
|
+
"CurrencySymbol": {
|
|
13
|
+
"title": "Currency symbol",
|
|
14
|
+
"description": "Symbol for money on the session surface. Prices are the same numbers whichever symbol is shown",
|
|
15
|
+
"type": "string",
|
|
16
|
+
"default": "£",
|
|
17
|
+
"enum": ["£", "$", "€"]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"additionalProperties": false
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"definition": {
|
|
3
|
+
"settingsSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"Step": {
|
|
7
|
+
"title": "Slider step",
|
|
8
|
+
"description": "How many items each nudge of a slider adds to or takes off the plan",
|
|
9
|
+
"type": "integer",
|
|
10
|
+
"default": 5,
|
|
11
|
+
"minimum": 1,
|
|
12
|
+
"maximum": 50
|
|
13
|
+
},
|
|
14
|
+
"CurrencySymbol": {
|
|
15
|
+
"title": "Currency symbol",
|
|
16
|
+
"description": "Symbol for money on the participant surface. Prices are the same numbers whichever symbol is shown",
|
|
17
|
+
"type": "string",
|
|
18
|
+
"default": "£",
|
|
19
|
+
"enum": ["£", "$", "€"]
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"additionalProperties": false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import '@testing-library/jest-dom/vitest';
|
|
2
|
+
import { cleanup } from '@testing-library/react';
|
|
3
|
+
import { afterEach } from 'vitest';
|
|
4
|
+
|
|
5
|
+
// RTL does not auto-detect Vitest without globals mode enabled,
|
|
6
|
+
// so we explicitly clean up the DOM after each test.
|
|
7
|
+
afterEach(cleanup);
|