@norskvideo/ctl-product-template-schema 0.1.51 → 0.1.53
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 +14 -1
- package/index.js +22 -1
- package/interfaces.d.ts +35 -24
- package/interfaces.js +52 -39
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -150,6 +150,11 @@ export declare const ProductTemplateMigrationSchema: z.ZodObject<{
|
|
|
150
150
|
}>;
|
|
151
151
|
}, z.core.$strip>;
|
|
152
152
|
export type ProductTemplateMigration = z.infer<typeof ProductTemplateMigrationSchema>;
|
|
153
|
+
export declare const ProductTemplateLeaseSchema: z.ZodObject<{
|
|
154
|
+
protected: z.ZodLiteral<true>;
|
|
155
|
+
graceMs: z.ZodOptional<z.ZodNumber>;
|
|
156
|
+
}, z.core.$strip>;
|
|
157
|
+
export type ProductTemplateLease = z.infer<typeof ProductTemplateLeaseSchema>;
|
|
153
158
|
export declare const PRODUCT_TEMPLATE_WORKLOAD_ROLES: readonly ["viewer", "operator", "builder"];
|
|
154
159
|
export declare const ProductTemplateWorkloadSchema: z.ZodObject<{
|
|
155
160
|
role: z.ZodEnum<{
|
|
@@ -352,6 +357,10 @@ export declare const ProductTemplateManifestSchema: z.ZodObject<{
|
|
|
352
357
|
name: z.ZodString;
|
|
353
358
|
version: z.ZodNumber;
|
|
354
359
|
}, z.core.$catchall<z.ZodUnknown>>>>;
|
|
360
|
+
lease: z.ZodOptional<z.ZodObject<{
|
|
361
|
+
protected: z.ZodLiteral<true>;
|
|
362
|
+
graceMs: z.ZodOptional<z.ZodNumber>;
|
|
363
|
+
}, z.core.$strip>>;
|
|
355
364
|
migration: z.ZodOptional<z.ZodObject<{
|
|
356
365
|
strategy: z.ZodEnum<{
|
|
357
366
|
overlap: "overlap";
|
|
@@ -609,6 +618,10 @@ export declare const ProductTemplateMaterialsSchema: z.ZodObject<{
|
|
|
609
618
|
name: z.ZodString;
|
|
610
619
|
version: z.ZodNumber;
|
|
611
620
|
}, z.core.$catchall<z.ZodUnknown>>>>;
|
|
621
|
+
lease: z.ZodOptional<z.ZodObject<{
|
|
622
|
+
protected: z.ZodLiteral<true>;
|
|
623
|
+
graceMs: z.ZodOptional<z.ZodNumber>;
|
|
624
|
+
}, z.core.$strip>>;
|
|
612
625
|
migration: z.ZodOptional<z.ZodObject<{
|
|
613
626
|
strategy: z.ZodEnum<{
|
|
614
627
|
overlap: "overlap";
|
|
@@ -658,5 +671,5 @@ export declare const ProductTemplateMaterialsSchema: z.ZodObject<{
|
|
|
658
671
|
}, z.core.$strip>>>;
|
|
659
672
|
}, z.core.$strip>;
|
|
660
673
|
export type ProductTemplateMaterials = z.infer<typeof ProductTemplateMaterialsSchema>;
|
|
661
|
-
export { declareMediaConversion, interfaceDeclarationProblems, MEDIA_CONVERSION_INTERFACE, type
|
|
674
|
+
export { CONVERSION_TARGET_FORMAT, declareMediaConversion, interfaceDeclarationProblems, MEDIA_CONVERSION_INTERFACE, MEDIA_CONVERSION_VERSION, type MediaConversion, MediaConversionSchema, mediaConversionOf, type ProductTemplateInterface, ProductTemplateInterfaceSchema, } from "./interfaces.js";
|
|
662
675
|
export { composeServiceNamesOf, logsDeclarationProblems, NORSK_MEDIA_SERVICE_LOGS, type ProductTemplateLogs, ProductTemplateLogsSchema, productTemplateLogsProblems, type ServiceLogs, ServiceLogsSchema, STANDARD_LOGS, STUDIO_SERVICE_LOGS, servicesWithoutLogs, } from "./logs.js";
|
package/index.js
CHANGED
|
@@ -320,6 +320,24 @@ export const ProductTemplateMigrationSchema = z
|
|
|
320
320
|
}),
|
|
321
321
|
})
|
|
322
322
|
.meta({ id: "ProductTemplateMigration", outputId: "ProductTemplateMigration" });
|
|
323
|
+
// Lease-protected instances (norsk task 115 Phase 6; protocol 1.6). A product
|
|
324
|
+
// whose instance holds something that must never be in use by two encoders
|
|
325
|
+
// at once — an Akamai entry point, a multicast address, a SIP number —
|
|
326
|
+
// declares it here; the Manager does not need to know what the thing is.
|
|
327
|
+
// An instance lost uncleanly (its worker dropped off the network) is then
|
|
328
|
+
// not started again until `graceMs` has passed (absent: the deployment's,
|
|
329
|
+
// 60 s by default), and its worker stops it when it can no longer reach a
|
|
330
|
+
// live Manager. A clean stop needs no grace. Pair it with the default
|
|
331
|
+
// `stopThenStart` migration: an `overlap` migration would run two at once,
|
|
332
|
+
// which the Manager refuses for a lease-protected instance.
|
|
333
|
+
export const ProductTemplateLeaseSchema = z
|
|
334
|
+
.object({
|
|
335
|
+
protected: z.literal(true).meta({ description: "This product's instances are lease-protected." }),
|
|
336
|
+
graceMs: z.number().int().positive().max(3_600_000).optional().meta({
|
|
337
|
+
description: "How long an instance whose worker was lost uncleanly waits before it may start elsewhere, in ms. Must exceed the workers' lease deadline (30 s by default) by a margin. Absent: the deployment's (60 s by default).",
|
|
338
|
+
}),
|
|
339
|
+
})
|
|
340
|
+
.meta({ id: "ProductTemplateLease", outputId: "ProductTemplateLease" });
|
|
323
341
|
// The roles a template may declare for its instances' workload: at most
|
|
324
342
|
// builder, since registering a template takes builder and that registration is
|
|
325
343
|
// the consent. Built-in names only, whose meaning every host agrees on.
|
|
@@ -388,6 +406,9 @@ export const ProductTemplateManifestSchema = z
|
|
|
388
406
|
interfaces: z.array(ProductTemplateInterfaceSchema).optional().meta({
|
|
389
407
|
description: "Named, versioned contracts this template implements (e.g. norsk.io/media-conversion), so a client can find the templates that implement one whatever product built them. Each entry is carried verbatim; the runner checks only contracts it knows, so a template declaring one an older ctl does not know still launches. Absent = implements none.",
|
|
390
408
|
}),
|
|
409
|
+
lease: ProductTemplateLeaseSchema.optional().meta({
|
|
410
|
+
description: "Lease-protected instances: each holds something that must never be in use by two encoders at once. An instance lost uncleanly is not started again until its grace has passed; a clean stop needs none.",
|
|
411
|
+
}),
|
|
391
412
|
migration: ProductTemplateMigrationSchema.optional().meta({
|
|
392
413
|
description: "How a running instance may be moved between nodes. `strategy` is the strongest promise the product keeps: `overlap` (target started, then source stopped — both may produce briefly), `stopThenStart` (the default when absent — target prepared but not started, source stopped, target started), or `handover` (the job speaks the worker's migration socket and hands over at an exact position). A migrate request may down-grade to a safer strategy but never up-grade past the declaration. Only the manager reads this; the worker never does.",
|
|
393
414
|
}),
|
|
@@ -503,5 +524,5 @@ export const ProductTemplateMaterialsSchema = z
|
|
|
503
524
|
}),
|
|
504
525
|
})
|
|
505
526
|
.meta({ id: "ProductTemplateMaterials" });
|
|
506
|
-
export { declareMediaConversion, interfaceDeclarationProblems, MEDIA_CONVERSION_INTERFACE,
|
|
527
|
+
export { CONVERSION_TARGET_FORMAT, declareMediaConversion, interfaceDeclarationProblems, MEDIA_CONVERSION_INTERFACE, MEDIA_CONVERSION_VERSION, MediaConversionSchema, mediaConversionOf, ProductTemplateInterfaceSchema, } from "./interfaces.js";
|
|
507
528
|
export { composeServiceNamesOf, logsDeclarationProblems, NORSK_MEDIA_SERVICE_LOGS, ProductTemplateLogsSchema, productTemplateLogsProblems, ServiceLogsSchema, STANDARD_LOGS, STUDIO_SERVICE_LOGS, servicesWithoutLogs, } from "./logs.js";
|
package/interfaces.d.ts
CHANGED
|
@@ -6,9 +6,17 @@ export declare const ProductTemplateInterfaceSchema: z.ZodObject<{
|
|
|
6
6
|
}, z.core.$catchall<z.ZodUnknown>>;
|
|
7
7
|
export type ProductTemplateInterface = z.infer<typeof ProductTemplateInterfaceSchema>;
|
|
8
8
|
export declare const MEDIA_CONVERSION_INTERFACE = "norsk.io/media-conversion";
|
|
9
|
-
|
|
9
|
+
/** The version of norsk.io/media-conversion this package knows. Version 1 (a
|
|
10
|
+
* fixed list of outputs, flat parameters) was retired before any caller used
|
|
11
|
+
* it; its number is not reused, so a reader of the old v1 never misreads this. */
|
|
12
|
+
export declare const MEDIA_CONVERSION_VERSION = 2;
|
|
13
|
+
/** The format a conversion's target follows: the conversion core's
|
|
14
|
+
* ConversionTarget (@norskvideo/norsk-studio-standards-conversion). Naming it
|
|
15
|
+
* tells a caller it can plan the conversion itself, with the same core. */
|
|
16
|
+
export declare const CONVERSION_TARGET_FORMAT = "norsk.io/conversion-target";
|
|
17
|
+
export declare const MediaConversionSchema: z.ZodObject<{
|
|
10
18
|
name: z.ZodLiteral<"norsk.io/media-conversion">;
|
|
11
|
-
version: z.ZodLiteral<
|
|
19
|
+
version: z.ZodLiteral<2>;
|
|
12
20
|
inputs: z.ZodArray<z.ZodObject<{
|
|
13
21
|
name: z.ZodString;
|
|
14
22
|
kinds: z.ZodRecord<z.ZodEnum<{
|
|
@@ -21,47 +29,50 @@ export declare const MediaConversionV1Schema: z.ZodObject<{
|
|
|
21
29
|
max: z.ZodNumber;
|
|
22
30
|
}, z.core.$strip>]>>;
|
|
23
31
|
}, z.core.$strip>>;
|
|
24
|
-
|
|
25
|
-
name: z.ZodString;
|
|
26
|
-
kind: z.ZodEnum<{
|
|
27
|
-
video: "video";
|
|
28
|
-
audio: "audio";
|
|
29
|
-
subtitle: "subtitle";
|
|
30
|
-
ancillary: "ancillary";
|
|
31
|
-
}>;
|
|
32
|
-
count: z.ZodOptional<z.ZodNumber>;
|
|
33
|
-
format: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
34
|
-
}, z.core.$strip>>;
|
|
32
|
+
returns: z.ZodLiteral<"programme">;
|
|
35
33
|
transports: z.ZodArray<z.ZodString>;
|
|
36
34
|
timeline: z.ZodString;
|
|
35
|
+
target: z.ZodObject<{
|
|
36
|
+
format: z.ZodString;
|
|
37
|
+
version: z.ZodNumber;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
profiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
40
|
+
name: z.ZodString;
|
|
41
|
+
label: z.ZodString;
|
|
42
|
+
description: z.ZodOptional<z.ZodString>;
|
|
43
|
+
target: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
44
|
+
}, z.core.$strip>>>;
|
|
37
45
|
bindings: z.ZodObject<{
|
|
38
46
|
sourceUrl: z.ZodString;
|
|
39
47
|
returnName: z.ZodString;
|
|
48
|
+
target: z.ZodString;
|
|
40
49
|
engineVersion: z.ZodOptional<z.ZodString>;
|
|
41
50
|
conversionId: z.ZodOptional<z.ZodString>;
|
|
42
51
|
}, z.core.$strip>;
|
|
43
52
|
}, z.core.$strip>;
|
|
44
|
-
export type
|
|
53
|
+
export type MediaConversion = z.infer<typeof MediaConversionSchema>;
|
|
45
54
|
/** Everything wrong with a template's interface declarations, given the
|
|
46
55
|
* parameters it declares. Only known interfaces are checked. Empty = fine. */
|
|
47
56
|
export declare function interfaceDeclarationProblems(template: {
|
|
48
57
|
manifest: Pick<ProductTemplateManifest, "interfaces">;
|
|
49
58
|
parameters: Pick<ProductTemplateParameter, "name">[];
|
|
50
59
|
}): string[];
|
|
51
|
-
/** The template's norsk.io/media-conversion
|
|
60
|
+
/** The template's norsk.io/media-conversion declaration, typed, if it
|
|
52
61
|
* declares a valid one. */
|
|
53
|
-
export declare function mediaConversionOf(manifest: Pick<ProductTemplateManifest, "interfaces">):
|
|
54
|
-
type BindingRole = keyof
|
|
55
|
-
/** A norsk.io/media-conversion
|
|
56
|
-
*
|
|
57
|
-
*
|
|
62
|
+
export declare function mediaConversionOf(manifest: Pick<ProductTemplateManifest, "interfaces">): MediaConversion | undefined;
|
|
63
|
+
type BindingRole = keyof MediaConversion["bindings"];
|
|
64
|
+
/** A norsk.io/media-conversion declaration and the parameters its bindings
|
|
65
|
+
* name, built together so a template cannot bind a parameter it never
|
|
66
|
+
* declared. Spread `parameters` into the template's parameters.yaml and
|
|
58
67
|
* `interface` into its manifest's `interfaces`. Each binding defaults to a
|
|
59
|
-
* conventional parameter name; pass a name to use the template's own, or
|
|
60
|
-
*
|
|
61
|
-
|
|
68
|
+
* conventional parameter name; pass a name to use the template's own, or null
|
|
69
|
+
* to leave an optional role out. The target format defaults to the
|
|
70
|
+
* conversion core's. */
|
|
71
|
+
export declare function declareMediaConversion(shape: Omit<MediaConversion, "name" | "version" | "bindings" | "returns" | "target"> & {
|
|
72
|
+
target?: MediaConversion["target"];
|
|
62
73
|
bindings?: Partial<Record<BindingRole, string | null>>;
|
|
63
74
|
}): {
|
|
64
|
-
interface:
|
|
75
|
+
interface: MediaConversion;
|
|
65
76
|
parameters: ProductTemplateParameter[];
|
|
66
77
|
};
|
|
67
78
|
export {};
|
package/interfaces.js
CHANGED
|
@@ -25,6 +25,10 @@ export const ProductTemplateInterfaceSchema = z
|
|
|
25
25
|
description: "A contract the template implements: its name and version, and the body that contract defines. Carried verbatim; a runner checks only the contracts it knows.",
|
|
26
26
|
});
|
|
27
27
|
export const MEDIA_CONVERSION_INTERFACE = "norsk.io/media-conversion";
|
|
28
|
+
/** The version of norsk.io/media-conversion this package knows. Version 1 (a
|
|
29
|
+
* fixed list of outputs, flat parameters) was retired before any caller used
|
|
30
|
+
* it; its number is not reused, so a reader of the old v1 never misreads this. */
|
|
31
|
+
export const MEDIA_CONVERSION_VERSION = 2;
|
|
28
32
|
const PARAMETER_NAME = /^[A-Z][A-Z0-9_]*$/;
|
|
29
33
|
const parameterName = z.string().regex(PARAMETER_NAME, "a parameter name");
|
|
30
34
|
const MediaKindSchema = z.enum(["video", "audio", "subtitle", "ancillary"]);
|
|
@@ -34,53 +38,62 @@ const KindCountSchema = z.union([
|
|
|
34
38
|
.object({ min: z.number().int().min(0), max: z.number().int().min(0) })
|
|
35
39
|
.refine((r) => r.min <= r.max, { message: "min must be <= max" }),
|
|
36
40
|
]);
|
|
37
|
-
|
|
41
|
+
/** The format a conversion's target follows: the conversion core's
|
|
42
|
+
* ConversionTarget (@norskvideo/norsk-studio-standards-conversion). Naming it
|
|
43
|
+
* tells a caller it can plan the conversion itself, with the same core. */
|
|
44
|
+
export const CONVERSION_TARGET_FORMAT = "norsk.io/conversion-target";
|
|
45
|
+
export const MediaConversionSchema = z.object({
|
|
38
46
|
name: z.literal(MEDIA_CONVERSION_INTERFACE),
|
|
39
|
-
version: z.literal(
|
|
40
|
-
// What the converter takes from the
|
|
47
|
+
version: z.literal(MEDIA_CONVERSION_VERSION),
|
|
48
|
+
// What the converter takes from the caller: per named input, how many tracks
|
|
41
49
|
// of each kind (a count, or a range).
|
|
42
50
|
inputs: z
|
|
43
51
|
.array(z.object({ name: z.string().min(1), kinds: z.partialRecord(MediaKindSchema, KindCountSchema) }))
|
|
44
52
|
.min(1),
|
|
45
|
-
// What
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
.array(z.object({
|
|
49
|
-
name: z.string().min(1),
|
|
50
|
-
kind: MediaKindSchema,
|
|
51
|
-
count: z.number().int().min(1).optional(),
|
|
52
|
-
format: z.record(z.string(), z.string()).optional(),
|
|
53
|
-
}))
|
|
54
|
-
.min(1),
|
|
53
|
+
// What comes back: the input programme, each track converted as the target
|
|
54
|
+
// says or passed, under its own stream key.
|
|
55
|
+
returns: z.literal("programme"),
|
|
55
56
|
// Free strings rather than an enum: a template offering a transport this ctl
|
|
56
57
|
// does not know (srt, moq) must still validate; the client picks one it speaks.
|
|
57
58
|
transports: z.array(z.string().min(1)).min(1),
|
|
58
59
|
timeline: z.string().min(1),
|
|
60
|
+
// The format of the value the target binding carries, and its version.
|
|
61
|
+
target: z.object({ format: z.string().min(1), version: z.number().int().min(1) }),
|
|
62
|
+
// Named targets for the common jobs, which a client offers before the
|
|
63
|
+
// target's own fields. A profile's target is in the target's format.
|
|
64
|
+
profiles: z
|
|
65
|
+
.array(z.object({
|
|
66
|
+
name: z.string().regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "a lower-case slug"),
|
|
67
|
+
label: z.string().min(1),
|
|
68
|
+
description: z.string().optional(),
|
|
69
|
+
target: z.record(z.string(), z.unknown()),
|
|
70
|
+
}))
|
|
71
|
+
.optional(),
|
|
59
72
|
// The template's own parameters the client fills, by role.
|
|
60
73
|
bindings: z.object({
|
|
61
74
|
sourceUrl: parameterName,
|
|
62
75
|
returnName: parameterName,
|
|
76
|
+
target: parameterName,
|
|
63
77
|
engineVersion: parameterName.optional(),
|
|
64
78
|
conversionId: parameterName.optional(),
|
|
65
79
|
}),
|
|
66
80
|
});
|
|
67
|
-
const PARAMETER_REFERENCE = /\$\{([^}]*)\}/g;
|
|
68
81
|
/** Everything wrong with a template's interface declarations, given the
|
|
69
82
|
* parameters it declares. Only known interfaces are checked. Empty = fine. */
|
|
70
83
|
export function interfaceDeclarationProblems(template) {
|
|
71
84
|
const declared = new Set(template.parameters.map((p) => p.name));
|
|
72
|
-
|
|
85
|
+
let seen = false;
|
|
73
86
|
const problems = [];
|
|
74
87
|
(template.manifest.interfaces ?? []).forEach((decl, i) => {
|
|
75
|
-
if (decl.name !== MEDIA_CONVERSION_INTERFACE || decl.version !==
|
|
88
|
+
if (decl.name !== MEDIA_CONVERSION_INTERFACE || decl.version !== MEDIA_CONVERSION_VERSION)
|
|
76
89
|
return;
|
|
77
90
|
const at = `interfaces[${i}] (${decl.name} v${decl.version})`;
|
|
78
|
-
if (seen
|
|
91
|
+
if (seen) {
|
|
79
92
|
problems.push(`${at}: declared more than once`);
|
|
80
93
|
return;
|
|
81
94
|
}
|
|
82
|
-
seen
|
|
83
|
-
const parsed =
|
|
95
|
+
seen = true;
|
|
96
|
+
const parsed = MediaConversionSchema.safeParse(decl);
|
|
84
97
|
if (!parsed.success) {
|
|
85
98
|
for (const issue of parsed.error.issues) {
|
|
86
99
|
problems.push(`${at}: ${issue.path.join(".") || "(declaration)"}: ${issue.message}`);
|
|
@@ -92,25 +105,16 @@ export function interfaceDeclarationProblems(template) {
|
|
|
92
105
|
problems.push(`${at}: binding ${role} names ${param}, which is not a declared parameter`);
|
|
93
106
|
}
|
|
94
107
|
}
|
|
95
|
-
parsed.data.outputs.forEach((output, o) => {
|
|
96
|
-
for (const [key, value] of Object.entries(output.format ?? {})) {
|
|
97
|
-
for (const [, ref] of value.matchAll(PARAMETER_REFERENCE)) {
|
|
98
|
-
if (!declared.has(ref)) {
|
|
99
|
-
problems.push(`${at}: outputs[${o}].format.${key} refers to ${ref}, which is not a declared parameter`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
108
|
});
|
|
105
109
|
return problems;
|
|
106
110
|
}
|
|
107
|
-
/** The template's norsk.io/media-conversion
|
|
111
|
+
/** The template's norsk.io/media-conversion declaration, typed, if it
|
|
108
112
|
* declares a valid one. */
|
|
109
113
|
export function mediaConversionOf(manifest) {
|
|
110
114
|
for (const decl of manifest.interfaces ?? []) {
|
|
111
|
-
if (decl.name !== MEDIA_CONVERSION_INTERFACE || decl.version !==
|
|
115
|
+
if (decl.name !== MEDIA_CONVERSION_INTERFACE || decl.version !== MEDIA_CONVERSION_VERSION)
|
|
112
116
|
continue;
|
|
113
|
-
const parsed =
|
|
117
|
+
const parsed = MediaConversionSchema.safeParse(decl);
|
|
114
118
|
if (parsed.success)
|
|
115
119
|
return parsed.data;
|
|
116
120
|
}
|
|
@@ -129,6 +133,12 @@ const BINDING_DEFAULTS = {
|
|
|
129
133
|
purpose: "The name to publish the converted media under, for the caller to take it back. Filled by the caller.",
|
|
130
134
|
required: true,
|
|
131
135
|
},
|
|
136
|
+
target: {
|
|
137
|
+
name: "CONVERSION_TARGET",
|
|
138
|
+
label: "Conversion target",
|
|
139
|
+
purpose: "What the converted programme should be, as JSON in the declared target format. Filled by the caller.",
|
|
140
|
+
required: true,
|
|
141
|
+
},
|
|
132
142
|
engineVersion: {
|
|
133
143
|
name: "ENGINE_VERSION",
|
|
134
144
|
label: "Engine version",
|
|
@@ -143,14 +153,15 @@ const BINDING_DEFAULTS = {
|
|
|
143
153
|
},
|
|
144
154
|
};
|
|
145
155
|
const BINDING_GROUP = "Conversion link";
|
|
146
|
-
/** A norsk.io/media-conversion
|
|
147
|
-
*
|
|
148
|
-
*
|
|
156
|
+
/** A norsk.io/media-conversion declaration and the parameters its bindings
|
|
157
|
+
* name, built together so a template cannot bind a parameter it never
|
|
158
|
+
* declared. Spread `parameters` into the template's parameters.yaml and
|
|
149
159
|
* `interface` into its manifest's `interfaces`. Each binding defaults to a
|
|
150
|
-
* conventional parameter name; pass a name to use the template's own, or
|
|
151
|
-
*
|
|
160
|
+
* conventional parameter name; pass a name to use the template's own, or null
|
|
161
|
+
* to leave an optional role out. The target format defaults to the
|
|
162
|
+
* conversion core's. */
|
|
152
163
|
export function declareMediaConversion(shape) {
|
|
153
|
-
const { bindings: chosen = {}, ...rest } = shape;
|
|
164
|
+
const { bindings: chosen = {}, target = { format: CONVERSION_TARGET_FORMAT, version: 1 }, ...rest } = shape;
|
|
154
165
|
const bindings = {};
|
|
155
166
|
const parameters = [];
|
|
156
167
|
for (const role of Object.keys(BINDING_DEFAULTS)) {
|
|
@@ -168,9 +179,11 @@ export function declareMediaConversion(shape) {
|
|
|
168
179
|
...(fallback.required ? { required: true } : {}),
|
|
169
180
|
});
|
|
170
181
|
}
|
|
171
|
-
const declaration =
|
|
182
|
+
const declaration = MediaConversionSchema.parse({
|
|
172
183
|
name: MEDIA_CONVERSION_INTERFACE,
|
|
173
|
-
version:
|
|
184
|
+
version: MEDIA_CONVERSION_VERSION,
|
|
185
|
+
returns: "programme",
|
|
186
|
+
target,
|
|
174
187
|
...rest,
|
|
175
188
|
bindings,
|
|
176
189
|
});
|