@scenar/cli 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/package.json +4 -9
  2. package/src/__tests__/embed-snippet.test.ts +1 -1
  3. package/src/__tests__/install-command.test.ts +97 -0
  4. package/src/__tests__/local-url.test.ts +17 -0
  5. package/src/__tests__/run-install.test.ts +222 -0
  6. package/src/api.d.ts +3 -1
  7. package/src/api.d.ts.map +1 -1
  8. package/src/api.js +3 -1
  9. package/src/api.js.map +1 -1
  10. package/src/api.ts +10 -1
  11. package/src/commands/install.d.ts +3 -0
  12. package/src/commands/install.d.ts.map +1 -0
  13. package/src/commands/install.js +67 -0
  14. package/src/commands/install.js.map +1 -0
  15. package/src/commands/install.ts +89 -0
  16. package/src/commands/pack.js +2 -2
  17. package/src/commands/pack.js.map +1 -1
  18. package/src/commands/pack.ts +2 -2
  19. package/src/commands/serve.d.ts.map +1 -1
  20. package/src/commands/serve.js +1 -2
  21. package/src/commands/serve.js.map +1 -1
  22. package/src/commands/serve.ts +1 -2
  23. package/src/commands/try.js +1 -1
  24. package/src/commands/try.ts +1 -1
  25. package/src/embed/embed-snippet.d.ts.map +1 -0
  26. package/src/embed/embed-snippet.js.map +1 -0
  27. package/src/index.d.ts.map +1 -1
  28. package/src/index.js +3 -5
  29. package/src/index.js.map +1 -1
  30. package/src/index.ts +3 -5
  31. package/src/install/run-install.d.ts +72 -0
  32. package/src/install/run-install.d.ts.map +1 -0
  33. package/src/install/run-install.js +378 -0
  34. package/src/install/run-install.js.map +1 -0
  35. package/src/install/run-install.ts +461 -0
  36. package/src/install/scaffold.d.ts +29 -0
  37. package/src/install/scaffold.d.ts.map +1 -0
  38. package/src/install/scaffold.js +233 -0
  39. package/src/install/scaffold.js.map +1 -0
  40. package/src/install/scaffold.ts +255 -0
  41. package/src/pack/pack-manifest.d.ts +1 -1
  42. package/src/pack/pack-manifest.d.ts.map +1 -1
  43. package/src/pack/pack-manifest.ts +1 -1
  44. package/src/publish/publish-flow.d.ts +3 -3
  45. package/src/publish/publish-flow.js +3 -3
  46. package/src/publish/publish-flow.ts +3 -3
  47. package/src/publish/run-publish.js +1 -1
  48. package/src/publish/run-publish.js.map +1 -1
  49. package/src/publish/run-publish.ts +1 -1
  50. package/src/render/detect-render-export.d.ts +2 -2
  51. package/src/render/detect-render-export.js +2 -2
  52. package/src/render/detect-render-export.ts +2 -2
  53. package/src/serve/local-url.d.ts +8 -0
  54. package/src/serve/local-url.d.ts.map +1 -0
  55. package/src/serve/local-url.js +21 -0
  56. package/src/serve/local-url.js.map +1 -0
  57. package/src/serve/local-url.ts +20 -0
  58. package/src/serve/run-serve.js +2 -2
  59. package/src/serve/run-serve.js.map +1 -1
  60. package/src/serve/run-serve.ts +2 -2
  61. package/tsconfig.tsbuildinfo +1 -1
  62. package/src/__tests__/deploy-command.test.ts +0 -45
  63. package/src/__tests__/deploy-flow.test.ts +0 -125
  64. package/src/__tests__/deploy-upload.test.ts +0 -39
  65. package/src/commands/deploy.d.ts +0 -3
  66. package/src/commands/deploy.d.ts.map +0 -1
  67. package/src/commands/deploy.js +0 -150
  68. package/src/commands/deploy.js.map +0 -1
  69. package/src/commands/deploy.ts +0 -186
  70. package/src/commands/preview.d.ts +0 -3
  71. package/src/commands/preview.d.ts.map +0 -1
  72. package/src/commands/preview.js +0 -93
  73. package/src/commands/preview.js.map +0 -1
  74. package/src/commands/preview.ts +0 -138
  75. package/src/deploy/client.d.ts +0 -20
  76. package/src/deploy/client.d.ts.map +0 -1
  77. package/src/deploy/client.js +0 -22
  78. package/src/deploy/client.js.map +0 -1
  79. package/src/deploy/client.ts +0 -28
  80. package/src/deploy/deploy-flow.d.ts +0 -78
  81. package/src/deploy/deploy-flow.d.ts.map +0 -1
  82. package/src/deploy/deploy-flow.js +0 -53
  83. package/src/deploy/deploy-flow.js.map +0 -1
  84. package/src/deploy/deploy-flow.ts +0 -115
  85. package/src/deploy/embed-snippet.d.ts.map +0 -1
  86. package/src/deploy/embed-snippet.js.map +0 -1
  87. package/src/deploy/upload.d.ts +0 -10
  88. package/src/deploy/upload.d.ts.map +0 -1
  89. package/src/deploy/upload.js +0 -23
  90. package/src/deploy/upload.js.map +0 -1
  91. package/src/deploy/upload.ts +0 -29
  92. /package/src/{deploy → embed}/embed-snippet.d.ts +0 -0
  93. /package/src/{deploy → embed}/embed-snippet.js +0 -0
  94. /package/src/{deploy → embed}/embed-snippet.ts +0 -0
@@ -0,0 +1,233 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ /**
4
+ * Base dependencies every Scenar demos project needs to author tours. The
5
+ * starter tour is built from `@scenar/react` shells, so `@scenar/react` is
6
+ * recorded as `"*"` (resolves to the latest published — pin it once you know
7
+ * the version you want). React is constrained to the major the `@scenar/*`
8
+ * packages target so the embed and the user's real components (added later)
9
+ * share a single React.
10
+ */
11
+ export const BASE_DEPENDENCIES = {
12
+ "@scenar/react": "*",
13
+ react: "^19.0.0",
14
+ "react-dom": "^19.0.0",
15
+ };
16
+ /**
17
+ * Scaffold a fresh Scenar demos project in `dir`.
18
+ *
19
+ * Creates a minimal `package.json`, a `tsconfig.json` tuned for JSX, a
20
+ * `.gitignore` that ignores build output, and a runnable **starter tour** under
21
+ * `tours/example-tour/` (a `steps.ts` timeline, an `index.tsx` that exports
22
+ * `renderStep`, and a `.scenar/providers.tsx`). The starter is built from
23
+ * `@scenar/react` shells so `scenar pack` works immediately; the author then
24
+ * swaps in their real components and wires data in `providers.tsx`.
25
+ *
26
+ * Existing files are never overwritten — this only fills in what is missing, so
27
+ * it is safe to re-run.
28
+ */
29
+ export function scaffoldProject(dir) {
30
+ const created = [];
31
+ writeIfMissing(dir, "package.json", renderPackageJson(path.basename(dir)), created);
32
+ writeIfMissing(dir, "tsconfig.json", TSCONFIG, created);
33
+ writeIfMissing(dir, ".gitignore", GITIGNORE, created);
34
+ writeIfMissing(dir, path.join(TOUR_DIR, "steps.ts"), TOUR_STEPS, created);
35
+ writeIfMissing(dir, path.join(TOUR_DIR, "index.tsx"), TOUR_INDEX, created);
36
+ writeIfMissing(dir, path.join(TOUR_DIR, ".scenar", "providers.tsx"), TOUR_PROVIDERS, created);
37
+ return { created };
38
+ }
39
+ function writeIfMissing(dir, relPath, content, created) {
40
+ const target = path.join(dir, relPath);
41
+ if (fs.existsSync(target))
42
+ return;
43
+ fs.mkdirSync(path.dirname(target), { recursive: true });
44
+ fs.writeFileSync(target, content, "utf-8");
45
+ created.push(relPath);
46
+ }
47
+ function renderPackageJson(name) {
48
+ const pkg = {
49
+ name: toPackageName(name),
50
+ version: "0.0.0",
51
+ private: true,
52
+ type: "module",
53
+ scripts: {
54
+ pack: `scenar pack ${TOUR_DIR}`,
55
+ },
56
+ dependencies: { ...BASE_DEPENDENCIES },
57
+ };
58
+ return JSON.stringify(pkg, null, 2) + "\n";
59
+ }
60
+ /** Coerce a directory name into a valid npm package name. */
61
+ function toPackageName(dirName) {
62
+ const slug = dirName
63
+ .trim()
64
+ .toLowerCase()
65
+ .replace(/[^a-z0-9._-]+/g, "-")
66
+ .replace(/^-+|-+$/g, "");
67
+ return slug.length > 0 ? slug : "scenar-demos";
68
+ }
69
+ /** Where the starter tour is scaffolded (also the default `pack` target). */
70
+ const TOUR_DIR = "tours/example-tour";
71
+ const TSCONFIG = `{
72
+ "compilerOptions": {
73
+ "target": "ES2022",
74
+ "module": "ESNext",
75
+ "moduleResolution": "Bundler",
76
+ "jsx": "react-jsx",
77
+ "strict": true,
78
+ "skipLibCheck": true,
79
+ "esModuleInterop": true,
80
+ "lib": ["ES2022", "DOM", "DOM.Iterable"]
81
+ },
82
+ "include": ["tours"]
83
+ }
84
+ `;
85
+ const GITIGNORE = `node_modules/
86
+
87
+ # Packed embeds — regenerate with \`scenar pack\`
88
+ *-bundle/
89
+ `;
90
+ const TOUR_STEPS = `import type { ScenarioStep } from "@scenar/core";
91
+
92
+ /** The screen shown at a given step (maps to a view in index.tsx). */
93
+ export type ExampleScreen = "login" | "dashboard";
94
+
95
+ /** Data snapshot for one step of the tour. */
96
+ export interface ExampleStepData {
97
+ /** Address-bar URL shown in the browser chrome (no scheme). */
98
+ readonly url: string;
99
+ /** Which screen is shown at this step. */
100
+ readonly screen: ExampleScreen;
101
+ }
102
+
103
+ /**
104
+ * The tour timeline. \`delayMs\` is the dwell before each step (the first is
105
+ * shown immediately); \`caption\` renders under the player; \`narration\` is the
106
+ * spoken script synthesized by \`scenar narrate\`.
107
+ */
108
+ export const steps: ScenarioStep<ExampleStepData>[] = [
109
+ {
110
+ delayMs: 0,
111
+ caption: "Sign in",
112
+ narration: "Sign in to your workspace.",
113
+ data: { url: "app.example.com/login", screen: "login" },
114
+ },
115
+ {
116
+ delayMs: 2400,
117
+ caption: "Your dashboard",
118
+ narration: "And you land on your dashboard.",
119
+ data: { url: "app.example.com/home", screen: "dashboard" },
120
+ },
121
+ ];
122
+ `;
123
+ const TOUR_INDEX = `import type { ReactNode } from "react";
124
+ import {
125
+ BrowserView,
126
+ DashboardPage,
127
+ LoginCardPage,
128
+ type SideNavItem,
129
+ } from "@scenar/react";
130
+ import type { ExampleStepData } from "./steps";
131
+
132
+ /**
133
+ * renderStep: a pure (data, stepIndex) -> ReactNode. Both \`scenar pack\` (embed)
134
+ * and \`scenar render\` (video) consume this contract.
135
+ *
136
+ * This starter draws CSS-only @scenar/react shells so it packs with no extra
137
+ * setup. To show your REAL product UI, install your components
138
+ * (\`scenar install <your-pkg>\`), import and render them here, and wire any data
139
+ * they fetch in .scenar/providers.tsx.
140
+ */
141
+ export function renderStep(data: ExampleStepData, stepIndex: number): ReactNode {
142
+ return (
143
+ <BrowserView url={"https://" + data.url} contentKey={String(stepIndex)}>
144
+ {data.screen === "login" ? <LoginScreen /> : <DashboardScreen />}
145
+ </BrowserView>
146
+ );
147
+ }
148
+
149
+ function LoginScreen(): ReactNode {
150
+ return (
151
+ <LoginCardPage
152
+ appName="Example"
153
+ subtitle="Sign in to your workspace"
154
+ fields={[
155
+ { label: "Email", value: "you@example.com", type: "email" },
156
+ { label: "Password", type: "password" },
157
+ ]}
158
+ submitLabel="Sign in"
159
+ />
160
+ );
161
+ }
162
+
163
+ const SIDEBAR: SideNavItem[] = [
164
+ { label: "Workspace", isSection: true },
165
+ { label: "Overview", active: true },
166
+ { label: "Projects" },
167
+ ];
168
+
169
+ function DashboardScreen(): ReactNode {
170
+ return (
171
+ <DashboardPage
172
+ appName="Example"
173
+ userName="You"
174
+ navLinks={[{ label: "Home", active: true }]}
175
+ sidebarItems={SIDEBAR}
176
+ >
177
+ <div style={{ padding: 20 }}>
178
+ <h2
179
+ style={{
180
+ margin: 0,
181
+ fontSize: 15,
182
+ fontWeight: 600,
183
+ color: "var(--scenar-foreground)",
184
+ }}
185
+ >
186
+ Welcome back
187
+ </h2>
188
+ </div>
189
+ </DashboardPage>
190
+ );
191
+ }
192
+ `;
193
+ const TOUR_PROVIDERS = `/**
194
+ * .scenar/providers.tsx — wraps every step of THIS tour in \`scenar pack\` (embed)
195
+ * and \`scenar render\` (video).
196
+ *
197
+ * You only need this when your tour renders real, data-fetching components that
198
+ * need a client/provider to render in isolation (no backend). A tour built only
199
+ * from @scenar/react shells (like the starter) can leave this as a pass-through
200
+ * or delete it.
201
+ *
202
+ * Recommended pattern for Connect-RPC SDKs (e.g. @stigmer/react): mock data with
203
+ * an in-process router transport — no network, no service worker — and resolve
204
+ * the embed's light/dark mode from \`getEmbedColorMode()\`. Fill in your client,
205
+ * provider, and fixtures, then return the provider instead of the fragment:
206
+ *
207
+ * import "@your-org/react/styles.css";
208
+ * import { createRouterTransport } from "@connectrpc/connect";
209
+ * import { getEmbedColorMode } from "@scenar/react";
210
+ * import { YourClient } from "@your-org/sdk";
211
+ * import { YourProvider } from "@your-org/react";
212
+ * import { YourController } from "@your-org/protos/...";
213
+ *
214
+ * const transport = createRouterTransport((router) => {
215
+ * router.service(YourController, { get: () => yourFixtureObject });
216
+ * });
217
+ * const client = new YourClient({ baseUrl: "/", customTransport: transport });
218
+ *
219
+ * export function PreviewProviders({ children }: { readonly children: ReactNode }) {
220
+ * return (
221
+ * <YourProvider client={client} colorMode={getEmbedColorMode()}>
222
+ * {children}
223
+ * </YourProvider>
224
+ * );
225
+ * }
226
+ */
227
+ import type { ReactNode } from "react";
228
+
229
+ export function PreviewProviders({ children }: { readonly children: ReactNode }) {
230
+ return <>{children}</>;
231
+ }
232
+ `;
233
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../../src/install/scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,255 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+
4
+ /**
5
+ * Base dependencies every Scenar demos project needs to author tours. The
6
+ * starter tour is built from `@scenar/react` shells, so `@scenar/react` is
7
+ * recorded as `"*"` (resolves to the latest published — pin it once you know
8
+ * the version you want). React is constrained to the major the `@scenar/*`
9
+ * packages target so the embed and the user's real components (added later)
10
+ * share a single React.
11
+ */
12
+ export const BASE_DEPENDENCIES: Readonly<Record<string, string>> = {
13
+ "@scenar/react": "*",
14
+ react: "^19.0.0",
15
+ "react-dom": "^19.0.0",
16
+ };
17
+
18
+ /** Result of scaffolding a fresh demos project. */
19
+ export interface ScaffoldResult {
20
+ /** Files created, relative to the project directory. */
21
+ readonly created: readonly string[];
22
+ }
23
+
24
+ /**
25
+ * Scaffold a fresh Scenar demos project in `dir`.
26
+ *
27
+ * Creates a minimal `package.json`, a `tsconfig.json` tuned for JSX, a
28
+ * `.gitignore` that ignores build output, and a runnable **starter tour** under
29
+ * `tours/example-tour/` (a `steps.ts` timeline, an `index.tsx` that exports
30
+ * `renderStep`, and a `.scenar/providers.tsx`). The starter is built from
31
+ * `@scenar/react` shells so `scenar pack` works immediately; the author then
32
+ * swaps in their real components and wires data in `providers.tsx`.
33
+ *
34
+ * Existing files are never overwritten — this only fills in what is missing, so
35
+ * it is safe to re-run.
36
+ */
37
+ export function scaffoldProject(dir: string): ScaffoldResult {
38
+ const created: string[] = [];
39
+
40
+ writeIfMissing(dir, "package.json", renderPackageJson(path.basename(dir)), created);
41
+ writeIfMissing(dir, "tsconfig.json", TSCONFIG, created);
42
+ writeIfMissing(dir, ".gitignore", GITIGNORE, created);
43
+ writeIfMissing(dir, path.join(TOUR_DIR, "steps.ts"), TOUR_STEPS, created);
44
+ writeIfMissing(dir, path.join(TOUR_DIR, "index.tsx"), TOUR_INDEX, created);
45
+ writeIfMissing(dir, path.join(TOUR_DIR, ".scenar", "providers.tsx"), TOUR_PROVIDERS, created);
46
+
47
+ return { created };
48
+ }
49
+
50
+ function writeIfMissing(
51
+ dir: string,
52
+ relPath: string,
53
+ content: string,
54
+ created: string[],
55
+ ): void {
56
+ const target = path.join(dir, relPath);
57
+ if (fs.existsSync(target)) return;
58
+ fs.mkdirSync(path.dirname(target), { recursive: true });
59
+ fs.writeFileSync(target, content, "utf-8");
60
+ created.push(relPath);
61
+ }
62
+
63
+ function renderPackageJson(name: string): string {
64
+ const pkg = {
65
+ name: toPackageName(name),
66
+ version: "0.0.0",
67
+ private: true,
68
+ type: "module",
69
+ scripts: {
70
+ pack: `scenar pack ${TOUR_DIR}`,
71
+ },
72
+ dependencies: { ...BASE_DEPENDENCIES },
73
+ };
74
+ return JSON.stringify(pkg, null, 2) + "\n";
75
+ }
76
+
77
+ /** Coerce a directory name into a valid npm package name. */
78
+ function toPackageName(dirName: string): string {
79
+ const slug = dirName
80
+ .trim()
81
+ .toLowerCase()
82
+ .replace(/[^a-z0-9._-]+/g, "-")
83
+ .replace(/^-+|-+$/g, "");
84
+ return slug.length > 0 ? slug : "scenar-demos";
85
+ }
86
+
87
+ /** Where the starter tour is scaffolded (also the default `pack` target). */
88
+ const TOUR_DIR = "tours/example-tour";
89
+
90
+ const TSCONFIG = `{
91
+ "compilerOptions": {
92
+ "target": "ES2022",
93
+ "module": "ESNext",
94
+ "moduleResolution": "Bundler",
95
+ "jsx": "react-jsx",
96
+ "strict": true,
97
+ "skipLibCheck": true,
98
+ "esModuleInterop": true,
99
+ "lib": ["ES2022", "DOM", "DOM.Iterable"]
100
+ },
101
+ "include": ["tours"]
102
+ }
103
+ `;
104
+
105
+ const GITIGNORE = `node_modules/
106
+
107
+ # Packed embeds — regenerate with \`scenar pack\`
108
+ *-bundle/
109
+ `;
110
+
111
+ const TOUR_STEPS = `import type { ScenarioStep } from "@scenar/core";
112
+
113
+ /** The screen shown at a given step (maps to a view in index.tsx). */
114
+ export type ExampleScreen = "login" | "dashboard";
115
+
116
+ /** Data snapshot for one step of the tour. */
117
+ export interface ExampleStepData {
118
+ /** Address-bar URL shown in the browser chrome (no scheme). */
119
+ readonly url: string;
120
+ /** Which screen is shown at this step. */
121
+ readonly screen: ExampleScreen;
122
+ }
123
+
124
+ /**
125
+ * The tour timeline. \`delayMs\` is the dwell before each step (the first is
126
+ * shown immediately); \`caption\` renders under the player; \`narration\` is the
127
+ * spoken script synthesized by \`scenar narrate\`.
128
+ */
129
+ export const steps: ScenarioStep<ExampleStepData>[] = [
130
+ {
131
+ delayMs: 0,
132
+ caption: "Sign in",
133
+ narration: "Sign in to your workspace.",
134
+ data: { url: "app.example.com/login", screen: "login" },
135
+ },
136
+ {
137
+ delayMs: 2400,
138
+ caption: "Your dashboard",
139
+ narration: "And you land on your dashboard.",
140
+ data: { url: "app.example.com/home", screen: "dashboard" },
141
+ },
142
+ ];
143
+ `;
144
+
145
+ const TOUR_INDEX = `import type { ReactNode } from "react";
146
+ import {
147
+ BrowserView,
148
+ DashboardPage,
149
+ LoginCardPage,
150
+ type SideNavItem,
151
+ } from "@scenar/react";
152
+ import type { ExampleStepData } from "./steps";
153
+
154
+ /**
155
+ * renderStep: a pure (data, stepIndex) -> ReactNode. Both \`scenar pack\` (embed)
156
+ * and \`scenar render\` (video) consume this contract.
157
+ *
158
+ * This starter draws CSS-only @scenar/react shells so it packs with no extra
159
+ * setup. To show your REAL product UI, install your components
160
+ * (\`scenar install <your-pkg>\`), import and render them here, and wire any data
161
+ * they fetch in .scenar/providers.tsx.
162
+ */
163
+ export function renderStep(data: ExampleStepData, stepIndex: number): ReactNode {
164
+ return (
165
+ <BrowserView url={"https://" + data.url} contentKey={String(stepIndex)}>
166
+ {data.screen === "login" ? <LoginScreen /> : <DashboardScreen />}
167
+ </BrowserView>
168
+ );
169
+ }
170
+
171
+ function LoginScreen(): ReactNode {
172
+ return (
173
+ <LoginCardPage
174
+ appName="Example"
175
+ subtitle="Sign in to your workspace"
176
+ fields={[
177
+ { label: "Email", value: "you@example.com", type: "email" },
178
+ { label: "Password", type: "password" },
179
+ ]}
180
+ submitLabel="Sign in"
181
+ />
182
+ );
183
+ }
184
+
185
+ const SIDEBAR: SideNavItem[] = [
186
+ { label: "Workspace", isSection: true },
187
+ { label: "Overview", active: true },
188
+ { label: "Projects" },
189
+ ];
190
+
191
+ function DashboardScreen(): ReactNode {
192
+ return (
193
+ <DashboardPage
194
+ appName="Example"
195
+ userName="You"
196
+ navLinks={[{ label: "Home", active: true }]}
197
+ sidebarItems={SIDEBAR}
198
+ >
199
+ <div style={{ padding: 20 }}>
200
+ <h2
201
+ style={{
202
+ margin: 0,
203
+ fontSize: 15,
204
+ fontWeight: 600,
205
+ color: "var(--scenar-foreground)",
206
+ }}
207
+ >
208
+ Welcome back
209
+ </h2>
210
+ </div>
211
+ </DashboardPage>
212
+ );
213
+ }
214
+ `;
215
+
216
+ const TOUR_PROVIDERS = `/**
217
+ * .scenar/providers.tsx — wraps every step of THIS tour in \`scenar pack\` (embed)
218
+ * and \`scenar render\` (video).
219
+ *
220
+ * You only need this when your tour renders real, data-fetching components that
221
+ * need a client/provider to render in isolation (no backend). A tour built only
222
+ * from @scenar/react shells (like the starter) can leave this as a pass-through
223
+ * or delete it.
224
+ *
225
+ * Recommended pattern for Connect-RPC SDKs (e.g. @stigmer/react): mock data with
226
+ * an in-process router transport — no network, no service worker — and resolve
227
+ * the embed's light/dark mode from \`getEmbedColorMode()\`. Fill in your client,
228
+ * provider, and fixtures, then return the provider instead of the fragment:
229
+ *
230
+ * import "@your-org/react/styles.css";
231
+ * import { createRouterTransport } from "@connectrpc/connect";
232
+ * import { getEmbedColorMode } from "@scenar/react";
233
+ * import { YourClient } from "@your-org/sdk";
234
+ * import { YourProvider } from "@your-org/react";
235
+ * import { YourController } from "@your-org/protos/...";
236
+ *
237
+ * const transport = createRouterTransport((router) => {
238
+ * router.service(YourController, { get: () => yourFixtureObject });
239
+ * });
240
+ * const client = new YourClient({ baseUrl: "/", customTransport: transport });
241
+ *
242
+ * export function PreviewProviders({ children }: { readonly children: ReactNode }) {
243
+ * return (
244
+ * <YourProvider client={client} colorMode={getEmbedColorMode()}>
245
+ * {children}
246
+ * </YourProvider>
247
+ * );
248
+ * }
249
+ */
250
+ import type { ReactNode } from "react";
251
+
252
+ export function PreviewProviders({ children }: { readonly children: ReactNode }) {
253
+ return <>{children}</>;
254
+ }
255
+ `;
@@ -10,7 +10,7 @@ export interface PackFile {
10
10
  /** Content type the server binds into the presign and the edge serves. */
11
11
  readonly contentType: string;
12
12
  }
13
- /** The deploy instruction file `scenar deploy` consumes. */
13
+ /** The deploy instruction file the upload backend consumes. */
14
14
  export interface PackManifest {
15
15
  readonly schemaVersion: number;
16
16
  readonly scenarioId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"pack-manifest.d.ts","sourceRoot":"","sources":["../../../src/pack/pack-manifest.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,6EAA6E;AAC7E,MAAM,WAAW,QAAQ;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yBAAyB;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;CAC5B;AAED,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,mEAAmE;AACnE,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA+BjG;AAED,mDAAmD;AACnD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7F;AAiBD,oFAAoF;AACpF,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpG"}
1
+ {"version":3,"file":"pack-manifest.d.ts","sourceRoot":"","sources":["../../../src/pack/pack-manifest.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,6EAA6E;AAC7E,MAAM,WAAW,QAAQ;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yBAAyB;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;CAC5B;AAED,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,mEAAmE;AACnE,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA+BjG;AAED,mDAAmD;AACnD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7F;AAiBD,oFAAoF;AACpF,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpG"}
@@ -21,7 +21,7 @@ export interface PackFile {
21
21
  readonly contentType: string;
22
22
  }
23
23
 
24
- /** The deploy instruction file `scenar deploy` consumes. */
24
+ /** The deploy instruction file the upload backend consumes. */
25
25
  export interface PackManifest {
26
26
  readonly schemaVersion: number;
27
27
  readonly scenarioId: string;
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * GitHub Pages publishing — the OSS "permanent public URL" path of Phase 1.
3
3
  *
4
- * The flow is dependency-injected (mirroring deploy-flow.ts) so its ordering and
5
- * payloads are unit-testable against fakes, with zero live GitHub calls in the
6
- * test suite. The real `gh`/`git` implementations live in ./github.ts.
4
+ * The flow is dependency-injected so its ordering and payloads are unit-testable
5
+ * against fakes, with zero live GitHub calls in the test suite. The real
6
+ * `gh`/`git` implementations live in ./github.ts.
7
7
  */
8
8
  /** Identity for the target GitHub repository + how to write to it. */
9
9
  export interface PublishOptions {
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * GitHub Pages publishing — the OSS "permanent public URL" path of Phase 1.
3
3
  *
4
- * The flow is dependency-injected (mirroring deploy-flow.ts) so its ordering and
5
- * payloads are unit-testable against fakes, with zero live GitHub calls in the
6
- * test suite. The real `gh`/`git` implementations live in ./github.ts.
4
+ * The flow is dependency-injected so its ordering and payloads are unit-testable
5
+ * against fakes, with zero live GitHub calls in the test suite. The real
6
+ * `gh`/`git` implementations live in ./github.ts.
7
7
  */
8
8
  /** A repo name's allowed characters (GitHub: alphanumerics, ., _, -). */
9
9
  const REPO_NAME_PATTERN = /^[A-Za-z0-9._-]+$/;
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * GitHub Pages publishing — the OSS "permanent public URL" path of Phase 1.
3
3
  *
4
- * The flow is dependency-injected (mirroring deploy-flow.ts) so its ordering and
5
- * payloads are unit-testable against fakes, with zero live GitHub calls in the
6
- * test suite. The real `gh`/`git` implementations live in ./github.ts.
4
+ * The flow is dependency-injected so its ordering and payloads are unit-testable
5
+ * against fakes, with zero live GitHub calls in the test suite. The real
6
+ * `gh`/`git` implementations live in ./github.ts.
7
7
  */
8
8
 
9
9
  /** A repo name's allowed characters (GitHub: alphanumerics, ., _, -). */
@@ -1,7 +1,7 @@
1
1
  import { resolve, join, basename } from "node:path";
2
2
  import { stat, readFile } from "node:fs/promises";
3
3
  import { PACK_MANIFEST_FILE } from "../pack/pack-manifest.js";
4
- import { buildEmbedSnippet, buildEnhancedEmbedSnippet } from "../deploy/embed-snippet.js";
4
+ import { buildEmbedSnippet, buildEnhancedEmbedSnippet } from "../embed/embed-snippet.js";
5
5
  import { readBundleViewport } from "../bundle/read-viewport.js";
6
6
  import { createGithubPublisher } from "./github.js";
7
7
  import { runPublishFlow, validateRepoName, validatePublishPath, normalizePath, } from "./publish-flow.js";
@@ -1 +1 @@
1
- {"version":3,"file":"run-publish.js","sourceRoot":"","sources":["../../../src/publish/run-publish.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-publish.js","sourceRoot":"","sources":["../../../src/publish/run-publish.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { resolve, join, basename } from "node:path";
2
2
  import { stat, readFile } from "node:fs/promises";
3
3
  import { PACK_MANIFEST_FILE } from "../pack/pack-manifest.js";
4
- import { buildEmbedSnippet, buildEnhancedEmbedSnippet } from "../deploy/embed-snippet.js";
4
+ import { buildEmbedSnippet, buildEnhancedEmbedSnippet } from "../embed/embed-snippet.js";
5
5
  import { readBundleViewport } from "../bundle/read-viewport.js";
6
6
  import type { Viewport } from "../pack/viewport.js";
7
7
  import { createGithubPublisher } from "./github.js";
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * Checks `render.tsx` first (recommended — a lean file that only imports
5
5
  * view components), then falls back to `index.tsx`. Using a dedicated
6
- * `render.tsx` avoids pulling browser-only dependencies (preview
7
- * runtime, MSW, etc.) into the Remotion webpack bundle.
6
+ * `render.tsx` avoids pulling browser-only dependencies (a product SDK
7
+ * client, data-mock wiring, etc.) into the Remotion webpack bundle.
8
8
  *
9
9
  * Uses a lightweight source-text scan rather than a dynamic import.
10
10
  * The actual module resolution and type checking happens later when
@@ -7,8 +7,8 @@ const RENDER_FILE_CANDIDATES = ["render.tsx", "render.ts", "index.tsx", "index.t
7
7
  *
8
8
  * Checks `render.tsx` first (recommended — a lean file that only imports
9
9
  * view components), then falls back to `index.tsx`. Using a dedicated
10
- * `render.tsx` avoids pulling browser-only dependencies (preview
11
- * runtime, MSW, etc.) into the Remotion webpack bundle.
10
+ * `render.tsx` avoids pulling browser-only dependencies (a product SDK
11
+ * client, data-mock wiring, etc.) into the Remotion webpack bundle.
12
12
  *
13
13
  * Uses a lightweight source-text scan rather than a dynamic import.
14
14
  * The actual module resolution and type checking happens later when
@@ -9,8 +9,8 @@ const RENDER_FILE_CANDIDATES = ["render.tsx", "render.ts", "index.tsx", "index.t
9
9
  *
10
10
  * Checks `render.tsx` first (recommended — a lean file that only imports
11
11
  * view components), then falls back to `index.tsx`. Using a dedicated
12
- * `render.tsx` avoids pulling browser-only dependencies (preview
13
- * runtime, MSW, etc.) into the Remotion webpack bundle.
12
+ * `render.tsx` avoids pulling browser-only dependencies (a product SDK
13
+ * client, data-mock wiring, etc.) into the Remotion webpack bundle.
14
14
  *
15
15
  * Uses a lightweight source-text scan rather than a dynamic import.
16
16
  * The actual module resolution and type checking happens later when
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Derive a locally-viewable URL from an embed URL. Some local edges serve over
3
+ * http on `*.localhost` even when the URL is emitted as https; for those hosts
4
+ * we downgrade the scheme so the printed link is clickable. Production https
5
+ * URLs and non-URL input are returned unchanged.
6
+ */
7
+ export declare function localViewUrl(embedUrl: string): string;
8
+ //# sourceMappingURL=local-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-url.d.ts","sourceRoot":"","sources":["../../../src/serve/local-url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAarD"}