@scenar/cli 0.10.0 → 0.11.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.
- package/example-bundle/assets/index-DxmqjG-8.js +388 -0
- package/example-bundle/assets/style-B2sxnVVZ.css +1 -0
- package/example-bundle/embed.js +1 -1
- package/example-bundle/index.html +2 -2
- package/example-bundle/logo.png +0 -0
- package/example-bundle/pack-manifest.json +33 -9
- package/example-bundle/soundtrack/music.mp3 +0 -0
- package/example-bundle/soundtrack/sfx/click.mp3 +0 -0
- package/example-bundle/soundtrack/sfx/keystroke.mp3 +0 -0
- package/package.json +4 -4
- package/src/__tests__/collect-pack-shots.test.ts +8 -0
- package/src/__tests__/elevenlabs-provider.test.ts +187 -0
- package/src/__tests__/embed-snippet.test.ts +5 -0
- package/src/__tests__/find-authored-soundtrack.test.ts +54 -0
- package/src/__tests__/find-authored-title-cards.test.ts +65 -0
- package/src/__tests__/load-bundle.test.ts +67 -0
- package/src/__tests__/narrate-command.test.ts +65 -1
- package/src/__tests__/narration-cache.test.ts +134 -0
- package/src/__tests__/pack-bundle-contract.test.ts +2 -0
- package/src/__tests__/pack-generate-embed-entry.test.ts +95 -16
- package/src/__tests__/presenter-command.test.ts +366 -0
- package/src/__tests__/render-command.test.ts +11 -0
- package/src/__tests__/render-generate-entry.test.ts +102 -0
- package/src/__tests__/resolve-provider.test.ts +32 -3
- package/src/__tests__/scenario-validator.test.ts +174 -0
- package/src/__tests__/stage-assets.test.ts +269 -0
- package/src/commands/narrate.js +1 -1
- package/src/commands/narrate.js.map +1 -1
- package/src/commands/narrate.ts +1 -1
- package/src/commands/presenter.d.ts +3 -0
- package/src/commands/presenter.d.ts.map +1 -0
- package/src/commands/presenter.js +89 -0
- package/src/commands/presenter.js.map +1 -0
- package/src/commands/presenter.ts +107 -0
- package/src/commands/render.d.ts.map +1 -1
- package/src/commands/render.js +2 -0
- package/src/commands/render.js.map +1 -1
- package/src/commands/render.ts +6 -0
- package/src/embed/embed-snippet.d.ts +5 -0
- package/src/embed/embed-snippet.d.ts.map +1 -1
- package/src/embed/embed-snippet.js +6 -1
- package/src/embed/embed-snippet.js.map +1 -1
- package/src/embed/embed-snippet.ts +6 -1
- package/src/index.d.ts.map +1 -1
- package/src/index.js +2 -0
- package/src/index.js.map +1 -1
- package/src/index.ts +2 -0
- package/src/narrate/run-narrate.d.ts +15 -1
- package/src/narrate/run-narrate.d.ts.map +1 -1
- package/src/narrate/run-narrate.js +11 -4
- package/src/narrate/run-narrate.js.map +1 -1
- package/src/narrate/run-narrate.ts +15 -6
- package/src/pack/bundle-contract.d.ts +1 -0
- package/src/pack/bundle-contract.d.ts.map +1 -1
- package/src/pack/bundle-contract.js +3 -0
- package/src/pack/bundle-contract.js.map +1 -1
- package/src/pack/bundle-contract.ts +3 -0
- package/src/pack/collect-pack-shots.d.ts +5 -1
- package/src/pack/collect-pack-shots.d.ts.map +1 -1
- package/src/pack/collect-pack-shots.js +3 -1
- package/src/pack/collect-pack-shots.js.map +1 -1
- package/src/pack/collect-pack-shots.ts +15 -1
- package/src/pack/generate-embed-entry.d.ts +7 -0
- package/src/pack/generate-embed-entry.d.ts.map +1 -1
- package/src/pack/generate-embed-entry.js +102 -7
- package/src/pack/generate-embed-entry.js.map +1 -1
- package/src/pack/generate-embed-entry.ts +107 -7
- package/src/pack/run-pack.d.ts +1 -0
- package/src/pack/run-pack.d.ts.map +1 -1
- package/src/pack/run-pack.js +100 -9
- package/src/pack/run-pack.js.map +1 -1
- package/src/pack/run-pack.ts +133 -9
- package/src/presenter/heygen-client.d.ts +69 -0
- package/src/presenter/heygen-client.d.ts.map +1 -0
- package/src/presenter/heygen-client.js +154 -0
- package/src/presenter/heygen-client.js.map +1 -0
- package/src/presenter/heygen-client.ts +224 -0
- package/src/presenter/run-presenter.d.ts +67 -0
- package/src/presenter/run-presenter.d.ts.map +1 -0
- package/src/presenter/run-presenter.js +348 -0
- package/src/presenter/run-presenter.js.map +1 -0
- package/src/presenter/run-presenter.ts +536 -0
- package/src/render/generate-entry.d.ts +4 -0
- package/src/render/generate-entry.d.ts.map +1 -1
- package/src/render/generate-entry.js +75 -7
- package/src/render/generate-entry.js.map +1 -1
- package/src/render/generate-entry.ts +84 -7
- package/src/render/run-render.d.ts +6 -0
- package/src/render/run-render.d.ts.map +1 -1
- package/src/render/run-render.js +58 -0
- package/src/render/run-render.js.map +1 -1
- package/src/render/run-render.ts +72 -0
- package/src/render/stage-assets.d.ts +44 -0
- package/src/render/stage-assets.d.ts.map +1 -0
- package/src/render/stage-assets.js +91 -0
- package/src/render/stage-assets.js.map +1 -0
- package/src/render/stage-assets.ts +130 -0
- package/src/tts/echogarden.d.ts.map +1 -1
- package/src/tts/echogarden.js +4 -2
- package/src/tts/echogarden.js.map +1 -1
- package/src/tts/echogarden.ts +5 -2
- package/src/tts/edge-tts.d.ts.map +1 -1
- package/src/tts/edge-tts.js +2 -1
- package/src/tts/edge-tts.js.map +1 -1
- package/src/tts/edge-tts.ts +2 -1
- package/src/tts/elevenlabs.d.ts +15 -0
- package/src/tts/elevenlabs.d.ts.map +1 -0
- package/src/tts/elevenlabs.js +73 -0
- package/src/tts/elevenlabs.js.map +1 -0
- package/src/tts/elevenlabs.ts +105 -0
- package/src/tts/openai.d.ts.map +1 -1
- package/src/tts/openai.js +2 -1
- package/src/tts/openai.js.map +1 -1
- package/src/tts/openai.ts +2 -1
- package/src/tts/resolve-provider.d.ts +1 -1
- package/src/tts/resolve-provider.d.ts.map +1 -1
- package/src/tts/resolve-provider.js +10 -3
- package/src/tts/resolve-provider.js.map +1 -1
- package/src/tts/resolve-provider.ts +12 -4
- package/src/tts/types.d.ts +9 -0
- package/src/tts/types.d.ts.map +1 -1
- package/src/tts/types.ts +10 -0
- package/src/util/confirm.d.ts +11 -0
- package/src/util/confirm.d.ts.map +1 -0
- package/src/util/confirm.js +24 -0
- package/src/util/confirm.js.map +1 -0
- package/src/util/confirm.ts +23 -0
- package/src/util/load-bundle.d.ts +17 -1
- package/src/util/load-bundle.d.ts.map +1 -1
- package/src/util/load-bundle.js +19 -11
- package/src/util/load-bundle.js.map +1 -1
- package/src/util/load-bundle.ts +38 -12
- package/src/util/load-ts.d.ts +77 -0
- package/src/util/load-ts.d.ts.map +1 -1
- package/src/util/load-ts.js +125 -0
- package/src/util/load-ts.js.map +1 -1
- package/src/util/load-ts.ts +165 -0
- package/src/util/narration-cache.d.ts +13 -5
- package/src/util/narration-cache.d.ts.map +1 -1
- package/src/util/narration-cache.js +10 -8
- package/src/util/narration-cache.js.map +1 -1
- package/src/util/narration-cache.ts +22 -6
- package/src/util/presenter-cache.d.ts +44 -0
- package/src/util/presenter-cache.d.ts.map +1 -0
- package/src/util/presenter-cache.js +43 -0
- package/src/util/presenter-cache.js.map +1 -0
- package/src/util/presenter-cache.ts +101 -0
- package/src/util/scenario-assets.d.ts +47 -0
- package/src/util/scenario-assets.d.ts.map +1 -0
- package/src/util/scenario-assets.js +71 -0
- package/src/util/scenario-assets.js.map +1 -0
- package/src/util/scenario-assets.ts +111 -0
- package/src/util/soundtrack-assets.d.ts +34 -0
- package/src/util/soundtrack-assets.d.ts.map +1 -0
- package/src/util/soundtrack-assets.js +48 -0
- package/src/util/soundtrack-assets.js.map +1 -0
- package/src/util/soundtrack-assets.ts +69 -0
- package/src/validate/scenario-validator.d.ts.map +1 -1
- package/src/validate/scenario-validator.js +82 -0
- package/src/validate/scenario-validator.js.map +1 -1
- package/src/validate/scenario-validator.ts +110 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/example-bundle/assets/index-DpJUOVBT.js +0 -388
- package/example-bundle/assets/style-ix_q0zsc.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenario-assets.js","sourceRoot":"","sources":["../../../src/util/scenario-assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAevF;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,WAAmB,EACnB,GAAW,EACX,UAAkB,EAClB,WAAmB;IAEnB,IAAI,WAAW,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACxD,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACrF,MAAM,IAAI,KAAK,CACb,GAAG,UAAU,KAAK,GAAG,4CAA4C;YAC/D,yBAAyB,WAAW,oCAAoC;YACxE,qBAAqB,CACxB,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,GAAG,UAAU,KAAK,GAAG,kBAAkB,UAAU,KAAK;YACpD,iBAAiB,WAAW,mCAAmC,CAClE,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAsB,MAAM,CAAC,OAAO,CAC/D,yBAAyB,CAC1B;KACE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;KAC7D,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,WAAmB,EACnB,OAAe,EACf,UAAkB;IAElB,MAAM,KAAK,GAAG,MAAM,oBAAoB,CACtC,WAAW,EACX,OAAO,EACP,UAAU,EACV,0DAA0D,CAC3D,CAAC;IACF,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEhC,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,GAAG,UAAU,KAAK,OAAO,sCAAsC;YAC7D,+BAA+B,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YAC9D,8EAA8E,CACjF,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { isAbsolute, join, normalize } from "node:path";
|
|
3
|
+
import { CONTENT_TYPE_BY_EXTENSION, finalExtension } from "../pack/bundle-contract.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A scenario-local asset reference resolved for shipping: where the
|
|
7
|
+
* authored file is, and where it lands in a staged public dir or packed
|
|
8
|
+
* bundle (the authored path with its leading `./` removed, so the
|
|
9
|
+
* runtime reference resolves onto the shipped file in both outputs).
|
|
10
|
+
*/
|
|
11
|
+
export interface ScenarioAsset {
|
|
12
|
+
/** Absolute path of the authored file. */
|
|
13
|
+
readonly sourcePath: string;
|
|
14
|
+
/** Destination path relative to the public dir / bundle root. */
|
|
15
|
+
readonly destRelPath: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* True when an asset src is a remote URL (has a scheme) rather than a
|
|
20
|
+
* scenario-relative path. Remote assets are referenced, never copied.
|
|
21
|
+
*/
|
|
22
|
+
export function isRemoteUrl(src: string): boolean {
|
|
23
|
+
return /^[a-z][a-z0-9+.-]*:\/\//i.test(src);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a scenario-relative asset reference against its scenario
|
|
28
|
+
* directory — the shared containment-and-existence contract behind
|
|
29
|
+
* every shipped asset (soundtrack music, title-card logos).
|
|
30
|
+
*
|
|
31
|
+
* Returns `null` for remote URLs (used from where they live). Throws
|
|
32
|
+
* with an actionable message when the path escapes the scenario
|
|
33
|
+
* directory or the file does not exist — both would otherwise surface
|
|
34
|
+
* as a broken reference in the packed embed or the rendered video.
|
|
35
|
+
*
|
|
36
|
+
* @param configPath - The authored field, for error messages
|
|
37
|
+
* (e.g. "soundtrack.musicSrc").
|
|
38
|
+
* @param expectation - What a valid reference looks like, appended to
|
|
39
|
+
* the error (e.g. 'an MP3 inside the scenario directory').
|
|
40
|
+
*/
|
|
41
|
+
export async function resolveScenarioAsset(
|
|
42
|
+
scenarioDir: string,
|
|
43
|
+
src: string,
|
|
44
|
+
configPath: string,
|
|
45
|
+
expectation: string,
|
|
46
|
+
): Promise<ScenarioAsset | null> {
|
|
47
|
+
if (isRemoteUrl(src)) return null;
|
|
48
|
+
|
|
49
|
+
const destRelPath = normalize(src).replace(/^\.\//, "");
|
|
50
|
+
if (isAbsolute(destRelPath) || destRelPath === ".." || destRelPath.startsWith("../")) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`${configPath} "${src}" points outside the scenario directory.\n` +
|
|
53
|
+
`The reference must be ${expectation} so it can ship with the bundle,\n` +
|
|
54
|
+
"or an absolute URL.",
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const sourcePath = join(scenarioDir, destRelPath);
|
|
59
|
+
try {
|
|
60
|
+
await access(sourcePath);
|
|
61
|
+
} catch {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`${configPath} "${src}" not found at ${sourcePath}.\n` +
|
|
64
|
+
`Add the file (${expectation}), or fix the path in the config.`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return { sourcePath, destRelPath };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The image extensions the packed-embed deploy contract serves —
|
|
73
|
+
* derived from the canonical extension table so this can never drift
|
|
74
|
+
* from the server's allowlist. Notably NO svg (active content).
|
|
75
|
+
*/
|
|
76
|
+
export const IMAGE_EXTENSIONS: readonly string[] = Object.entries(
|
|
77
|
+
CONTENT_TYPE_BY_EXTENSION,
|
|
78
|
+
)
|
|
79
|
+
.filter(([, contentType]) => contentType.startsWith("image/"))
|
|
80
|
+
.map(([extension]) => extension);
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Resolve a title card's `logo_src` against its scenario directory,
|
|
84
|
+
* additionally enforcing the deploy contract's image formats — an
|
|
85
|
+
* unservable extension must fail at build time, not as a 404 (or a
|
|
86
|
+
* rejected deploy) later.
|
|
87
|
+
*/
|
|
88
|
+
export async function resolveLogoAsset(
|
|
89
|
+
scenarioDir: string,
|
|
90
|
+
logoSrc: string,
|
|
91
|
+
configPath: string,
|
|
92
|
+
): Promise<ScenarioAsset | null> {
|
|
93
|
+
const asset = await resolveScenarioAsset(
|
|
94
|
+
scenarioDir,
|
|
95
|
+
logoSrc,
|
|
96
|
+
configPath,
|
|
97
|
+
"an image inside the scenario directory (e.g. ./logo.png)",
|
|
98
|
+
);
|
|
99
|
+
if (asset === null) return null;
|
|
100
|
+
|
|
101
|
+
const extension = finalExtension(asset.destRelPath);
|
|
102
|
+
if (!IMAGE_EXTENSIONS.includes(extension)) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`${configPath} "${logoSrc}" is not a supported image format.\n` +
|
|
105
|
+
`The deploy contract serves: ${IMAGE_EXTENSIONS.join(", ")}. ` +
|
|
106
|
+
"SVG is deliberately excluded (active content) — inline it in a view instead.",
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return asset;
|
|
111
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ScenarioAsset } from "./scenario-assets.js";
|
|
2
|
+
export { isRemoteUrl } from "./scenario-assets.js";
|
|
3
|
+
/** Absolute filesystem locations of the built-in SFX asset files. */
|
|
4
|
+
export interface SfxAssetPaths {
|
|
5
|
+
readonly click: string;
|
|
6
|
+
readonly keystroke: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Where the built-in SFX set lives inside a staged render public dir and
|
|
10
|
+
* inside a packed bundle — one convention, shared with the composition's
|
|
11
|
+
* `sfxSrcs` default and the embed entry's `soundtrackSources`, so every
|
|
12
|
+
* consumer looks in the same place.
|
|
13
|
+
*/
|
|
14
|
+
export declare const SFX_DEST_PATHS: SfxAssetPaths;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the built-in SFX asset files from `@scenar/react`, using the
|
|
17
|
+
* given directory as the resolution context — the scenario directory, so
|
|
18
|
+
* the assets come from the same installed `@scenar/react` the generated
|
|
19
|
+
* entry imports.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveSfxAssetPaths(fromDir: string): SfxAssetPaths;
|
|
22
|
+
/** A scenario-local music asset: where it is, and where it ships. */
|
|
23
|
+
export type MusicAsset = ScenarioAsset;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve a soundtrack's `music_src` against its scenario directory —
|
|
26
|
+
* the shared {@link resolveScenarioAsset} contract with music wording.
|
|
27
|
+
*
|
|
28
|
+
* Returns `null` for remote URLs (played from where they live). Throws
|
|
29
|
+
* with an actionable message when the referenced file does not exist or
|
|
30
|
+
* the path escapes the scenario directory — both would otherwise surface
|
|
31
|
+
* as a silently music-less video or a 404 in the packed embed.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveMusicAsset(scenarioDir: string, musicSrc: string): Promise<MusicAsset | null>;
|
|
34
|
+
//# sourceMappingURL=soundtrack-assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soundtrack-assets.d.ts","sourceRoot":"","sources":["../../../src/util/soundtrack-assets.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,aAG5B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAenE;AAED,qEAAqE;AACrE,MAAM,MAAM,UAAU,GAAG,aAAa,CAAC;AAEvC;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAO5B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { resolveScenarioAsset } from "./scenario-assets.js";
|
|
4
|
+
export { isRemoteUrl } from "./scenario-assets.js";
|
|
5
|
+
/**
|
|
6
|
+
* Where the built-in SFX set lives inside a staged render public dir and
|
|
7
|
+
* inside a packed bundle — one convention, shared with the composition's
|
|
8
|
+
* `sfxSrcs` default and the embed entry's `soundtrackSources`, so every
|
|
9
|
+
* consumer looks in the same place.
|
|
10
|
+
*/
|
|
11
|
+
export const SFX_DEST_PATHS = {
|
|
12
|
+
click: "soundtrack/sfx/click.mp3",
|
|
13
|
+
keystroke: "soundtrack/sfx/keystroke.mp3",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the built-in SFX asset files from `@scenar/react`, using the
|
|
17
|
+
* given directory as the resolution context — the scenario directory, so
|
|
18
|
+
* the assets come from the same installed `@scenar/react` the generated
|
|
19
|
+
* entry imports.
|
|
20
|
+
*/
|
|
21
|
+
export function resolveSfxAssetPaths(fromDir) {
|
|
22
|
+
const require = createRequire(join(fromDir, "__scenar_resolver__.js"));
|
|
23
|
+
try {
|
|
24
|
+
return {
|
|
25
|
+
click: require.resolve("@scenar/react/assets/sfx/click.mp3"),
|
|
26
|
+
keystroke: require.resolve("@scenar/react/assets/sfx/keystroke.mp3"),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
throw new Error("soundtrack.sfx is enabled, but @scenar/react's sound-effect assets could not be\n" +
|
|
31
|
+
`resolved from ${fromDir}.\n\n` +
|
|
32
|
+
"The default SFX set ships inside @scenar/react (assets/sfx/). Install or update\n" +
|
|
33
|
+
"it in this project: pnpm add @scenar/react");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a soundtrack's `music_src` against its scenario directory —
|
|
38
|
+
* the shared {@link resolveScenarioAsset} contract with music wording.
|
|
39
|
+
*
|
|
40
|
+
* Returns `null` for remote URLs (played from where they live). Throws
|
|
41
|
+
* with an actionable message when the referenced file does not exist or
|
|
42
|
+
* the path escapes the scenario directory — both would otherwise surface
|
|
43
|
+
* as a silently music-less video or a 404 in the packed embed.
|
|
44
|
+
*/
|
|
45
|
+
export async function resolveMusicAsset(scenarioDir, musicSrc) {
|
|
46
|
+
return resolveScenarioAsset(scenarioDir, musicSrc, "soundtrack.musicSrc", "an MP3 inside the scenario directory (e.g. ./soundtrack/music.mp3)");
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=soundtrack-assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soundtrack-assets.js","sourceRoot":"","sources":["../../../src/util/soundtrack-assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAsB,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQnD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAkB;IAC3C,KAAK,EAAE,0BAA0B;IACjC,SAAS,EAAE,8BAA8B;CAC1C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,oCAAoC,CAAC;YAC5D,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,wCAAwC,CAAC;SACrE,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,mFAAmF;YACjF,iBAAiB,OAAO,OAAO;YAC/B,mFAAmF;YACnF,4CAA4C,CAC/C,CAAC;IACJ,CAAC;AACH,CAAC;AAKD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,WAAmB,EACnB,QAAgB;IAEhB,OAAO,oBAAoB,CACzB,WAAW,EACX,QAAQ,EACR,qBAAqB,EACrB,oEAAoE,CACrE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { resolveScenarioAsset, type ScenarioAsset } from "./scenario-assets.js";
|
|
4
|
+
|
|
5
|
+
export { isRemoteUrl } from "./scenario-assets.js";
|
|
6
|
+
|
|
7
|
+
/** Absolute filesystem locations of the built-in SFX asset files. */
|
|
8
|
+
export interface SfxAssetPaths {
|
|
9
|
+
readonly click: string;
|
|
10
|
+
readonly keystroke: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Where the built-in SFX set lives inside a staged render public dir and
|
|
15
|
+
* inside a packed bundle — one convention, shared with the composition's
|
|
16
|
+
* `sfxSrcs` default and the embed entry's `soundtrackSources`, so every
|
|
17
|
+
* consumer looks in the same place.
|
|
18
|
+
*/
|
|
19
|
+
export const SFX_DEST_PATHS: SfxAssetPaths = {
|
|
20
|
+
click: "soundtrack/sfx/click.mp3",
|
|
21
|
+
keystroke: "soundtrack/sfx/keystroke.mp3",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the built-in SFX asset files from `@scenar/react`, using the
|
|
26
|
+
* given directory as the resolution context — the scenario directory, so
|
|
27
|
+
* the assets come from the same installed `@scenar/react` the generated
|
|
28
|
+
* entry imports.
|
|
29
|
+
*/
|
|
30
|
+
export function resolveSfxAssetPaths(fromDir: string): SfxAssetPaths {
|
|
31
|
+
const require = createRequire(join(fromDir, "__scenar_resolver__.js"));
|
|
32
|
+
try {
|
|
33
|
+
return {
|
|
34
|
+
click: require.resolve("@scenar/react/assets/sfx/click.mp3"),
|
|
35
|
+
keystroke: require.resolve("@scenar/react/assets/sfx/keystroke.mp3"),
|
|
36
|
+
};
|
|
37
|
+
} catch {
|
|
38
|
+
throw new Error(
|
|
39
|
+
"soundtrack.sfx is enabled, but @scenar/react's sound-effect assets could not be\n" +
|
|
40
|
+
`resolved from ${fromDir}.\n\n` +
|
|
41
|
+
"The default SFX set ships inside @scenar/react (assets/sfx/). Install or update\n" +
|
|
42
|
+
"it in this project: pnpm add @scenar/react",
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** A scenario-local music asset: where it is, and where it ships. */
|
|
48
|
+
export type MusicAsset = ScenarioAsset;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Resolve a soundtrack's `music_src` against its scenario directory —
|
|
52
|
+
* the shared {@link resolveScenarioAsset} contract with music wording.
|
|
53
|
+
*
|
|
54
|
+
* Returns `null` for remote URLs (played from where they live). Throws
|
|
55
|
+
* with an actionable message when the referenced file does not exist or
|
|
56
|
+
* the path escapes the scenario directory — both would otherwise surface
|
|
57
|
+
* as a silently music-less video or a 404 in the packed embed.
|
|
58
|
+
*/
|
|
59
|
+
export async function resolveMusicAsset(
|
|
60
|
+
scenarioDir: string,
|
|
61
|
+
musicSrc: string,
|
|
62
|
+
): Promise<MusicAsset | null> {
|
|
63
|
+
return resolveScenarioAsset(
|
|
64
|
+
scenarioDir,
|
|
65
|
+
musicSrc,
|
|
66
|
+
"soundtrack.musicSrc",
|
|
67
|
+
"an MP3 inside the scenario directory (e.g. ./soundtrack/music.mp3)",
|
|
68
|
+
);
|
|
69
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenario-validator.d.ts","sourceRoot":"","sources":["../../../src/validate/scenario-validator.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CAC7C;AAgBD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"scenario-validator.d.ts","sourceRoot":"","sources":["../../../src/validate/scenario-validator.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CAC7C;AAgBD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB,CAgBpE"}
|
|
@@ -25,6 +25,8 @@ export function validateScenario(scenario) {
|
|
|
25
25
|
const obj = scenario;
|
|
26
26
|
validateViewport(obj["viewport"], errors);
|
|
27
27
|
validateSteps(obj["steps"], errors);
|
|
28
|
+
validateSoundtrack(obj["soundtrack"], errors);
|
|
29
|
+
validateTitleCards(obj["titleCards"], errors);
|
|
28
30
|
return { valid: errors.length === 0, errors };
|
|
29
31
|
}
|
|
30
32
|
function validateViewport(viewport, errors) {
|
|
@@ -42,6 +44,71 @@ function validateViewport(viewport, errors) {
|
|
|
42
44
|
errors.push({ path: "viewport.height", reason: "height must be a positive integer." });
|
|
43
45
|
}
|
|
44
46
|
}
|
|
47
|
+
function validateSoundtrack(soundtrack, errors) {
|
|
48
|
+
if (soundtrack === undefined || soundtrack === null)
|
|
49
|
+
return;
|
|
50
|
+
if (typeof soundtrack !== "object" || Array.isArray(soundtrack)) {
|
|
51
|
+
errors.push({ path: "soundtrack", reason: "soundtrack must be an object." });
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const st = soundtrack;
|
|
55
|
+
if (st["musicSrc"] !== undefined) {
|
|
56
|
+
if (typeof st["musicSrc"] !== "string" || st["musicSrc"].length === 0) {
|
|
57
|
+
errors.push({
|
|
58
|
+
path: "soundtrack.musicSrc",
|
|
59
|
+
reason: "musicSrc must be a non-empty asset reference (e.g. \"./soundtrack/music.mp3\").",
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
validateVolume(st["musicVolume"], "soundtrack.musicVolume", errors);
|
|
64
|
+
validateVolume(st["duckingVolume"], "soundtrack.duckingVolume", errors);
|
|
65
|
+
if (st["sfx"] !== undefined && typeof st["sfx"] !== "boolean") {
|
|
66
|
+
errors.push({ path: "soundtrack.sfx", reason: "sfx must be a boolean." });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function validateVolume(value, path, errors) {
|
|
70
|
+
if (value === undefined)
|
|
71
|
+
return;
|
|
72
|
+
if (typeof value !== "number" || value < 0 || value > 1) {
|
|
73
|
+
errors.push({ path, reason: "must be a number between 0.0 and 1.0." });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function validateTitleCards(titleCards, errors) {
|
|
77
|
+
if (titleCards === undefined || titleCards === null)
|
|
78
|
+
return;
|
|
79
|
+
if (typeof titleCards !== "object" || Array.isArray(titleCards)) {
|
|
80
|
+
errors.push({ path: "titleCards", reason: "titleCards must be an object." });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const cards = titleCards;
|
|
84
|
+
for (const side of ["intro", "outro"]) {
|
|
85
|
+
if (cards[side] !== undefined) {
|
|
86
|
+
validateTitleCard(cards[side], `titleCards.${side}`, errors);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function validateTitleCard(card, path, errors) {
|
|
91
|
+
if (card === null || typeof card !== "object" || Array.isArray(card)) {
|
|
92
|
+
errors.push({ path, reason: "card must be an object." });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const c = card;
|
|
96
|
+
if (typeof c["title"] !== "string" || c["title"].length === 0) {
|
|
97
|
+
errors.push({ path: `${path}.title`, reason: "title is required and must be a non-empty string." });
|
|
98
|
+
}
|
|
99
|
+
for (const field of ["subtitle", "logoSrc", "ctaText"]) {
|
|
100
|
+
if (c[field] !== undefined) {
|
|
101
|
+
if (typeof c[field] !== "string" || c[field].length === 0) {
|
|
102
|
+
errors.push({ path: `${path}.${field}`, reason: `${field} must be a non-empty string when present.` });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (c["durationMs"] !== undefined) {
|
|
107
|
+
if (typeof c["durationMs"] !== "number" || c["durationMs"] <= 0) {
|
|
108
|
+
errors.push({ path: `${path}.durationMs`, reason: "durationMs must be a positive integer." });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
45
112
|
function validateSteps(steps, errors) {
|
|
46
113
|
if (!Array.isArray(steps)) {
|
|
47
114
|
errors.push({ path: "steps", reason: "steps must be an array." });
|
|
@@ -69,6 +136,21 @@ function validateStep(step, path, errors) {
|
|
|
69
136
|
errors.push({ path: `${path}.delayMs`, reason: "delayMs must be a non-negative integer." });
|
|
70
137
|
}
|
|
71
138
|
}
|
|
139
|
+
if (s["presenter"] !== undefined) {
|
|
140
|
+
if (typeof s["presenter"] !== "boolean") {
|
|
141
|
+
errors.push({ path: `${path}.presenter`, reason: "presenter must be a boolean." });
|
|
142
|
+
}
|
|
143
|
+
else if (s["presenter"] === true &&
|
|
144
|
+
(typeof s["narrationText"] !== "string" || s["narrationText"].length === 0)) {
|
|
145
|
+
// Cross-field rule (see the Step.presenter proto doc comment):
|
|
146
|
+
// caught here so `scenar validate` flags the contradiction before
|
|
147
|
+
// the paid `scenar presenter` command runs.
|
|
148
|
+
errors.push({
|
|
149
|
+
path: `${path}.presenter`,
|
|
150
|
+
reason: "presenter requires narration_text — a presenter clip is derived from the step's narration audio.",
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
72
154
|
if (s["interactions"] !== undefined) {
|
|
73
155
|
if (!Array.isArray(s["interactions"])) {
|
|
74
156
|
errors.push({ path: `${path}.interactions`, reason: "interactions must be an array." });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenario-validator.js","sourceRoot":"","sources":["../../../src/validate/scenario-validator.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scenario-validator.js","sourceRoot":"","sources":["../../../src/validate/scenario-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAahD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAChC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAa,CAC7C,CAAC;AAEF,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAuB;IAC7D,iBAAiB,CAAC,UAAU;IAC5B,iBAAiB,CAAC,KAAK;IACvB,iBAAiB,CAAC,IAAI;IACtB,iBAAiB,CAAC,KAAK;IACvB,iBAAiB,CAAC,IAAI;IACtB,iBAAiB,CAAC,SAAS;IAC3B,iBAAiB,CAAC,mBAAmB;CACtC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAiB;IAChD,MAAM,MAAM,GAAsB,EAAE,CAAC;IAErC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChF,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC,CAAC;QACjE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,GAAG,GAAG,QAAmC,CAAC;IAEhD,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;IAC1C,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IACpC,kBAAkB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;IAC9C,kBAAkB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;IAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC;AAED,SAAS,gBAAgB,CACvB,QAAiB,EACjB,MAAyB;IAEzB,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO;IAExD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,MAAM,EAAE,GAAG,QAAmC,CAAC;IAE/C,IAAI,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,mCAAmC,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,OAAO,EAAE,CAAC,QAAQ,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC,CAAC;IACzF,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,UAAmB,EACnB,MAAyB;IAEzB,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO;IAE5D,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAC;QAC7E,OAAO;IACT,CAAC;IAED,MAAM,EAAE,GAAG,UAAqC,CAAC;IAEjD,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,OAAO,EAAE,CAAC,UAAU,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtE,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,qBAAqB;gBAC3B,MAAM,EAAE,iFAAiF;aAC1F,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,cAAc,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,wBAAwB,EAAE,MAAM,CAAC,CAAC;IACpE,cAAc,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE,0BAA0B,EAAE,MAAM,CAAC,CAAC;IAExE,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,OAAO,EAAE,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;QAC9D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CACrB,KAAc,EACd,IAAY,EACZ,MAAyB;IAEzB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,uCAAuC,EAAE,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,UAAmB,EACnB,MAAyB;IAEzB,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO;IAE5D,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAC;QAC7E,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,UAAqC,CAAC;IACpD,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,CAAU,EAAE,CAAC;QAC/C,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YAC9B,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,cAAc,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CACxB,IAAa,EACb,IAAY,EACZ,MAAyB;IAEzB,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,MAAM,CAAC,GAAG,IAA+B,CAAC;IAE1C,IAAI,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,QAAQ,EAAE,MAAM,EAAE,mDAAmD,EAAE,CAAC,CAAC;IACtG,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,CAAU,EAAE,CAAC;QAChE,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;YAC3B,IAAI,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAK,CAAC,CAAC,KAAK,CAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,KAAK,2CAA2C,EAAE,CAAC,CAAC;YACzG,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,CAAC,YAAY,CAAC,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,CAAC,YAAY,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,EAAE,wCAAwC,EAAE,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,KAAc,EACd,MAAyB;IAEzB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAC;QAClE,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,uCAAuC,EAAE,CAAC,CAAC;QAChF,OAAO;IACT,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CACnB,IAAa,EACb,IAAY,EACZ,MAAyB;IAEzB,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,MAAM,CAAC,GAAG,IAA+B,CAAC;IAE1C,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,EAAE,kDAAkD,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YACzD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,UAAU,EAAE,MAAM,EAAE,yCAAyC,EAAE,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED,IAAI,CAAC,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,YAAY,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC,CAAC;QACrF,CAAC;aAAM,IACL,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI;YACvB,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,EAC3E,CAAC;YACD,+DAA+D;YAC/D,kEAAkE;YAClE,4CAA4C;YAC5C,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,GAAG,IAAI,YAAY;gBACzB,MAAM,EAAE,kGAAkG;aAC3G,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,CAAC,CAAC,cAAc,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;YACtC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,eAAe,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC,CAAC;QAC1F,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAClD,mBAAmB,CACjB,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EACpB,GAAG,IAAI,iBAAiB,CAAC,GAAG,EAC5B,MAAM,CACP,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAC1B,MAAe,EACf,IAAY,EACZ,MAAyB;IAEzB,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,MAAM,CAAC,GAAG,MAAiC,CAAC;IAE5C,IAAI,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACnF,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,YAAY,EAAE,MAAM,EAAE,iDAAiD,EAAE,CAAC,CAAC;IACxG,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACrE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;IACrE,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,WAAW,KAAK,SAAS,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACtE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,EAAE,wBAAwB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/F,CAAC;aAAM,IAAI,WAAW,KAAK,iBAAiB,CAAC,WAAW,EAAE,CAAC;YACzD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,EAAE,wCAAwC,EAAE,CAAC,CAAC;QAC1F,CAAC;aAAM,CAAC;YACN,IAAI,wBAAwB,CAAC,GAAG,CAAC,WAAmC,CAAC,EAAE,CAAC;gBACtE,IAAI,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAChE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,SAAS,EAAE,MAAM,EAAE,0CAA0C,EAAE,CAAC,CAAC;gBAC9F,CAAC;YACH,CAAC;QACH,CAAC;QAED,oBAAoB,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,MAAM,mBAAmB,GAA2B,EAAE,CAAC;AACvD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;IAC9D,mBAAmB,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;AACpC,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAsB;IAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAA+B,EAC/B,UAA8B,EAC9B,IAAY,EACZ,MAAyB;IAEzB,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;QACjC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAC;QACvF,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,GAAG,GAA8B,CAAC;YAC1C,IAAI,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,kBAAkB,EAAE,MAAM,EAAE,kDAAkD,EAAE,CAAC,CAAC;YAC/G,CAAC;YACD,IAAI,EAAE,CAAC,aAAa,CAAC,KAAK,SAAS,EAAE,CAAC;gBACpC,IAAI,OAAO,EAAE,CAAC,aAAa,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;oBACnE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,yBAAyB,EAAE,MAAM,EAAE,6CAA6C,EAAE,CAAC,CAAC;gBACjH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,UAAU,KAAK,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,EAAE,4CAA4C,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,SAAS,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;QAClC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,cAAc,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,GAAG,GAA8B,CAAC;YAC1C,IAAI,EAAE,CAAC,iBAAiB,CAAC,KAAK,SAAS,EAAE,CAAC;gBACxC,IAAI,OAAO,EAAE,CAAC,iBAAiB,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,8BAA8B,EAAE,MAAM,EAAE,iDAAiD,EAAE,CAAC,CAAC;gBAC1H,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;QACjC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAC;QACvF,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,GAAG,GAA8B,CAAC;YAC1C,IAAI,OAAO,EAAE,CAAC,YAAY,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,wBAAwB,EAAE,MAAM,EAAE,wDAAwD,EAAE,CAAC,CAAC;YAC3H,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,UAAU,KAAK,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,EAAE,4CAA4C,EAAE,CAAC,CAAC;IACpG,CAAC;AACH,CAAC"}
|
|
@@ -44,6 +44,8 @@ export function validateScenario(scenario: unknown): ValidationResult {
|
|
|
44
44
|
|
|
45
45
|
validateViewport(obj["viewport"], errors);
|
|
46
46
|
validateSteps(obj["steps"], errors);
|
|
47
|
+
validateSoundtrack(obj["soundtrack"], errors);
|
|
48
|
+
validateTitleCards(obj["titleCards"], errors);
|
|
47
49
|
|
|
48
50
|
return { valid: errors.length === 0, errors };
|
|
49
51
|
}
|
|
@@ -69,6 +71,97 @@ function validateViewport(
|
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
|
|
74
|
+
function validateSoundtrack(
|
|
75
|
+
soundtrack: unknown,
|
|
76
|
+
errors: ValidationError[],
|
|
77
|
+
): void {
|
|
78
|
+
if (soundtrack === undefined || soundtrack === null) return;
|
|
79
|
+
|
|
80
|
+
if (typeof soundtrack !== "object" || Array.isArray(soundtrack)) {
|
|
81
|
+
errors.push({ path: "soundtrack", reason: "soundtrack must be an object." });
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const st = soundtrack as Record<string, unknown>;
|
|
86
|
+
|
|
87
|
+
if (st["musicSrc"] !== undefined) {
|
|
88
|
+
if (typeof st["musicSrc"] !== "string" || st["musicSrc"].length === 0) {
|
|
89
|
+
errors.push({
|
|
90
|
+
path: "soundtrack.musicSrc",
|
|
91
|
+
reason: "musicSrc must be a non-empty asset reference (e.g. \"./soundtrack/music.mp3\").",
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
validateVolume(st["musicVolume"], "soundtrack.musicVolume", errors);
|
|
97
|
+
validateVolume(st["duckingVolume"], "soundtrack.duckingVolume", errors);
|
|
98
|
+
|
|
99
|
+
if (st["sfx"] !== undefined && typeof st["sfx"] !== "boolean") {
|
|
100
|
+
errors.push({ path: "soundtrack.sfx", reason: "sfx must be a boolean." });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function validateVolume(
|
|
105
|
+
value: unknown,
|
|
106
|
+
path: string,
|
|
107
|
+
errors: ValidationError[],
|
|
108
|
+
): void {
|
|
109
|
+
if (value === undefined) return;
|
|
110
|
+
if (typeof value !== "number" || value < 0 || value > 1) {
|
|
111
|
+
errors.push({ path, reason: "must be a number between 0.0 and 1.0." });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function validateTitleCards(
|
|
116
|
+
titleCards: unknown,
|
|
117
|
+
errors: ValidationError[],
|
|
118
|
+
): void {
|
|
119
|
+
if (titleCards === undefined || titleCards === null) return;
|
|
120
|
+
|
|
121
|
+
if (typeof titleCards !== "object" || Array.isArray(titleCards)) {
|
|
122
|
+
errors.push({ path: "titleCards", reason: "titleCards must be an object." });
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const cards = titleCards as Record<string, unknown>;
|
|
127
|
+
for (const side of ["intro", "outro"] as const) {
|
|
128
|
+
if (cards[side] !== undefined) {
|
|
129
|
+
validateTitleCard(cards[side], `titleCards.${side}`, errors);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function validateTitleCard(
|
|
135
|
+
card: unknown,
|
|
136
|
+
path: string,
|
|
137
|
+
errors: ValidationError[],
|
|
138
|
+
): void {
|
|
139
|
+
if (card === null || typeof card !== "object" || Array.isArray(card)) {
|
|
140
|
+
errors.push({ path, reason: "card must be an object." });
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const c = card as Record<string, unknown>;
|
|
145
|
+
|
|
146
|
+
if (typeof c["title"] !== "string" || c["title"].length === 0) {
|
|
147
|
+
errors.push({ path: `${path}.title`, reason: "title is required and must be a non-empty string." });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
for (const field of ["subtitle", "logoSrc", "ctaText"] as const) {
|
|
151
|
+
if (c[field] !== undefined) {
|
|
152
|
+
if (typeof c[field] !== "string" || (c[field] as string).length === 0) {
|
|
153
|
+
errors.push({ path: `${path}.${field}`, reason: `${field} must be a non-empty string when present.` });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (c["durationMs"] !== undefined) {
|
|
159
|
+
if (typeof c["durationMs"] !== "number" || c["durationMs"] <= 0) {
|
|
160
|
+
errors.push({ path: `${path}.durationMs`, reason: "durationMs must be a positive integer." });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
72
165
|
function validateSteps(
|
|
73
166
|
steps: unknown,
|
|
74
167
|
errors: ValidationError[],
|
|
@@ -110,6 +203,23 @@ function validateStep(
|
|
|
110
203
|
}
|
|
111
204
|
}
|
|
112
205
|
|
|
206
|
+
if (s["presenter"] !== undefined) {
|
|
207
|
+
if (typeof s["presenter"] !== "boolean") {
|
|
208
|
+
errors.push({ path: `${path}.presenter`, reason: "presenter must be a boolean." });
|
|
209
|
+
} else if (
|
|
210
|
+
s["presenter"] === true &&
|
|
211
|
+
(typeof s["narrationText"] !== "string" || s["narrationText"].length === 0)
|
|
212
|
+
) {
|
|
213
|
+
// Cross-field rule (see the Step.presenter proto doc comment):
|
|
214
|
+
// caught here so `scenar validate` flags the contradiction before
|
|
215
|
+
// the paid `scenar presenter` command runs.
|
|
216
|
+
errors.push({
|
|
217
|
+
path: `${path}.presenter`,
|
|
218
|
+
reason: "presenter requires narration_text — a presenter clip is derived from the step's narration audio.",
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
113
223
|
if (s["interactions"] !== undefined) {
|
|
114
224
|
if (!Array.isArray(s["interactions"])) {
|
|
115
225
|
errors.push({ path: `${path}.interactions`, reason: "interactions must be an array." });
|