@norskvideo/ctl-product-template-schema 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -127,7 +127,7 @@ export const ProductTemplateManifestSchema = z
127
127
  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
128
  }),
129
129
  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.",
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. 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
131
  }),
132
132
  })
133
133
  .meta({ id: "ProductTemplateManifest", outputId: "ProductTemplateManifest" });
@@ -191,7 +191,8 @@ const ProductTemplateFileSchema = z.object({
191
191
  // accepts both via the same union.
192
192
  content: z.union([z.string(), z.instanceof(Uint8Array)]),
193
193
  });
194
- // In-memory bundle the producer builds; the tar packer turns this into bytes.
194
+ // In-memory bundle the producer builds; packProductTemplate (the `./pack`
195
+ // subpath) turns this into tar bytes at the paths below.
195
196
  //
196
197
  // `workflow`, `components` and `dashboards` are known top-level paths in the
197
198
  // 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.1",
3
+ "version": "0.1.2",
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": {