@norskvideo/ctl-product-template-schema 0.1.1 → 0.1.3
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/index.d.ts +10 -0
- package/index.js +6 -2
- package/pack.d.ts +8 -0
- package/pack.js +48 -0
- package/package.json +7 -1
package/index.d.ts
CHANGED
|
@@ -50,6 +50,11 @@ export declare const ProductTemplateManifestSchema: z.ZodObject<{
|
|
|
50
50
|
runtimeScreenUrl: z.ZodString;
|
|
51
51
|
runtimeScreenLabel: z.ZodOptional<z.ZodString>;
|
|
52
52
|
runtimeScreenService: z.ZodOptional<z.ZodString>;
|
|
53
|
+
runtimeScreenReadyWhen: z.ZodOptional<z.ZodEnum<{
|
|
54
|
+
running: "running";
|
|
55
|
+
healthy: "healthy";
|
|
56
|
+
never: "never";
|
|
57
|
+
}>>;
|
|
53
58
|
}, z.core.$strip>>;
|
|
54
59
|
debug: z.ZodOptional<z.ZodObject<{
|
|
55
60
|
studio: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -154,6 +159,11 @@ export declare const ProductTemplateMaterialsSchema: z.ZodObject<{
|
|
|
154
159
|
runtimeScreenUrl: z.ZodString;
|
|
155
160
|
runtimeScreenLabel: z.ZodOptional<z.ZodString>;
|
|
156
161
|
runtimeScreenService: z.ZodOptional<z.ZodString>;
|
|
162
|
+
runtimeScreenReadyWhen: z.ZodOptional<z.ZodEnum<{
|
|
163
|
+
running: "running";
|
|
164
|
+
healthy: "healthy";
|
|
165
|
+
never: "never";
|
|
166
|
+
}>>;
|
|
157
167
|
}, z.core.$strip>>;
|
|
158
168
|
debug: z.ZodOptional<z.ZodObject<{
|
|
159
169
|
studio: z.ZodOptional<z.ZodBoolean>;
|
package/index.js
CHANGED
|
@@ -31,6 +31,9 @@ const ProductTemplateUiSchema = z.object({
|
|
|
31
31
|
runtimeScreenService: z.string().optional().meta({
|
|
32
32
|
description: "Compose service that hosts the runtime screen. Omit for the conventional `studio`; a product that serves its dashboard from a different service names it here so the runner routes the catch-all there.",
|
|
33
33
|
}),
|
|
34
|
+
runtimeScreenReadyWhen: z.enum(["running", "healthy", "never"]).optional().meta({
|
|
35
|
+
description: "When the runner may offer the runtime-screen link, judged on `runtimeScreenService`'s own container state. Omit for the default `running` — the link goes live as soon as the service is up, which is the only state a service without a healthcheck ever reaches. `healthy` holds it back until the service's healthcheck passes, for a product whose screen 404s or misbehaves before it is fully warm. `never` suppresses the link entirely.",
|
|
36
|
+
}),
|
|
34
37
|
});
|
|
35
38
|
// Per-instance Debug menu toggles. The runner always offers raw Studio +
|
|
36
39
|
// Visualiser debug surfaces for an instance; a product opts a link out when
|
|
@@ -127,7 +130,7 @@ export const ProductTemplateManifestSchema = z
|
|
|
127
130
|
description: "Settings-backed runner knobs the operator may override per instance. Key presence opts the knob into the launch form; `default` pre-fills it (else the runner's daemon-wide default applies).",
|
|
128
131
|
}),
|
|
129
132
|
allocatedPorts: z.array(ProductTemplateAllocatedPortSchema).optional().meta({
|
|
130
|
-
description: "Host-port bindings whose value rides a product-template parameter. Opt-in per launch via the param value: absent = closed, 'auto' = allocate a free port from `preferred`, number = use it. When opened the port is published as a managed host binding and surfaced to the containers via compose interpolation.",
|
|
133
|
+
description: "Host-port bindings whose value rides a product-template parameter. Opt-in per launch via the param value: absent = closed, 'auto' = allocate a free port from `preferred`, number = use it. When opened the port is published as a managed host binding and surfaced to the containers via compose interpolation. Alongside the per-param scalars the runner sets NORSK_ALLOCATED_PORTS: a JSON object keyed by param, each value {port, protocol, service?}, describing every opened port ('{}' when none opted in; unset when nothing is declared) — so a product needing the allocation as data maps one var instead of folding scalars into JSON via interpolation.",
|
|
131
134
|
}),
|
|
132
135
|
})
|
|
133
136
|
.meta({ id: "ProductTemplateManifest", outputId: "ProductTemplateManifest" });
|
|
@@ -191,7 +194,8 @@ const ProductTemplateFileSchema = z.object({
|
|
|
191
194
|
// accepts both via the same union.
|
|
192
195
|
content: z.union([z.string(), z.instanceof(Uint8Array)]),
|
|
193
196
|
});
|
|
194
|
-
// In-memory bundle the producer builds; the
|
|
197
|
+
// In-memory bundle the producer builds; packProductTemplate (the `./pack`
|
|
198
|
+
// subpath) turns this into tar bytes at the paths below.
|
|
195
199
|
//
|
|
196
200
|
// `workflow`, `components` and `dashboards` are known top-level paths in the
|
|
197
201
|
// v1 tar format. The runner detects studio in the compose stack and mounts
|
package/pack.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type TarEntry } from "@norskvideo/ctl-foundation/browser";
|
|
2
|
+
import type { ProductTemplateMaterials } from "./index.js";
|
|
3
|
+
export declare function productTemplateTarEntries(materials: ProductTemplateMaterials): TarEntry[];
|
|
4
|
+
/** `mtime` stamps every tar entry's header with a fixed modification time.
|
|
5
|
+
* Pass it (alongside a fixed manifest `generatedAt`) for a reproducible
|
|
6
|
+
* build — without it packTar defaults each entry to the wall clock, so the
|
|
7
|
+
* bytes differ run to run. */
|
|
8
|
+
export declare function packProductTemplate(materials: ProductTemplateMaterials, mtime?: Date): Uint8Array;
|
package/pack.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// The producer half of the product-template wire format: materials -> tar
|
|
2
|
+
// entries -> tar bytes, at the v1 paths documented on
|
|
3
|
+
// ProductTemplateMaterialsSchema in index.ts. Every product repo used to carry
|
|
4
|
+
// its own copy of this layout and the copies drifted (several silently dropped
|
|
5
|
+
// workdir-seed/); this is the single source. The runner consumes the same
|
|
6
|
+
// paths on the reader side (manifest.json / parameters.yaml / compose.yml
|
|
7
|
+
// validation, workflow.yml + components/ + dashboards/ mounts, workdir-seed/
|
|
8
|
+
// launch copy), so layout changes here are contract changes — additive only.
|
|
9
|
+
//
|
|
10
|
+
// Browser-safe: foundation's packTar and the yaml stringifier are both pure.
|
|
11
|
+
import { packTar } from "@norskvideo/ctl-foundation/browser";
|
|
12
|
+
import { stringify as yamlStringify } from "yaml";
|
|
13
|
+
export function productTemplateTarEntries(materials) {
|
|
14
|
+
const entries = [
|
|
15
|
+
{ name: "manifest.json", content: `${JSON.stringify(materials.manifest, null, 2)}\n` },
|
|
16
|
+
{ name: "compose.yml", content: materials.composeYaml },
|
|
17
|
+
];
|
|
18
|
+
if (materials.workflow !== undefined) {
|
|
19
|
+
entries.push({ name: "workflow.yml", content: materials.workflow });
|
|
20
|
+
}
|
|
21
|
+
if (materials.parameters) {
|
|
22
|
+
entries.push({
|
|
23
|
+
name: "parameters.yaml",
|
|
24
|
+
content: yamlStringify(materials.parameters, { aliasDuplicateObjects: false }),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
for (const c of materials.components) {
|
|
28
|
+
entries.push({ name: `components/${c.path}`, content: c.content });
|
|
29
|
+
}
|
|
30
|
+
for (const d of materials.dashboards) {
|
|
31
|
+
entries.push({ name: `dashboards/${d.path}`, content: d.content });
|
|
32
|
+
}
|
|
33
|
+
for (const a of materials.assets) {
|
|
34
|
+
entries.push({ name: `assets/${a.path}`, content: a.content });
|
|
35
|
+
}
|
|
36
|
+
for (const s of materials.workdirSeed) {
|
|
37
|
+
entries.push({ name: `workdir-seed/${s.path}`, content: s.content });
|
|
38
|
+
}
|
|
39
|
+
return entries;
|
|
40
|
+
}
|
|
41
|
+
/** `mtime` stamps every tar entry's header with a fixed modification time.
|
|
42
|
+
* Pass it (alongside a fixed manifest `generatedAt`) for a reproducible
|
|
43
|
+
* build — without it packTar defaults each entry to the wall clock, so the
|
|
44
|
+
* bytes differ run to run. */
|
|
45
|
+
export function packProductTemplate(materials, mtime) {
|
|
46
|
+
const entries = productTemplateTarEntries(materials);
|
|
47
|
+
return packTar(mtime ? entries.map((e) => ({ ...e, mtime })) : entries);
|
|
48
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@norskvideo/ctl-product-template-schema",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./index.d.ts",
|
|
8
8
|
"default": "./index.js"
|
|
9
9
|
},
|
|
10
|
+
"./pack": {
|
|
11
|
+
"types": "./pack.d.ts",
|
|
12
|
+
"default": "./pack.js"
|
|
13
|
+
},
|
|
10
14
|
"./params": {
|
|
11
15
|
"types": "./params.d.ts",
|
|
12
16
|
"default": "./params.js"
|
|
@@ -15,6 +19,8 @@
|
|
|
15
19
|
"main": "./index.js",
|
|
16
20
|
"types": "./index.d.ts",
|
|
17
21
|
"dependencies": {
|
|
22
|
+
"@norskvideo/ctl-foundation": "^0.1.0",
|
|
23
|
+
"yaml": "^2.8.0",
|
|
18
24
|
"zod": "^4.3.6"
|
|
19
25
|
},
|
|
20
26
|
"publishConfig": {
|