@highstate/contract 0.9.18 → 0.9.20

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/dist/index.js CHANGED
@@ -1,10 +1,34 @@
1
1
  import z5, { z } from 'zod';
2
2
  export { z } from 'zod';
3
- import { mapValues, pickBy, isNonNullish } from 'remeda';
4
- import { Ajv } from 'ajv';
3
+ import { mapValues, pickBy, isNonNullish, uniqueBy } from 'remeda';
4
+ import { parse } from 'yaml';
5
5
 
6
6
  // src/entity.ts
7
- var userObjectMetaSchema = z.object({
7
+
8
+ // src/i18n.ts
9
+ var knownAbbreviationsMap = /* @__PURE__ */ new Map();
10
+ function registerKnownAbbreviations(abbreviations) {
11
+ for (const abbr of abbreviations) {
12
+ const lower = abbr.toLowerCase();
13
+ if (!knownAbbreviationsMap.has(lower)) {
14
+ knownAbbreviationsMap.set(lower, abbr);
15
+ }
16
+ }
17
+ }
18
+ function clearKnownAbbreviations() {
19
+ knownAbbreviationsMap.clear();
20
+ }
21
+ function camelCaseToHumanReadable(text2) {
22
+ const words = text2.split(/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|_|-|\./).filter((word) => word.length > 0);
23
+ return words.map((word) => {
24
+ const lower = word.toLowerCase();
25
+ if (knownAbbreviationsMap.has(lower)) {
26
+ return knownAbbreviationsMap.get(lower);
27
+ }
28
+ return word.charAt(0).toUpperCase() + word.slice(1);
29
+ }).join(" ");
30
+ }
31
+ var objectMetaSchema = z.object({
8
32
  /**
9
33
  * Human-readable name of the object.
10
34
  *
@@ -41,6 +65,10 @@ var userObjectMetaSchema = z.object({
41
65
  * The color of the primary icon.
42
66
  */
43
67
  iconColor: z.string().optional(),
68
+ /**
69
+ * The URL of the custom image that should be used as the icon or avatar.
70
+ */
71
+ avatarUrl: z.string().optional(),
44
72
  /**
45
73
  * The secondary icon identifier.
46
74
  *
@@ -54,56 +82,86 @@ var userObjectMetaSchema = z.object({
54
82
  */
55
83
  secondaryIconColor: z.string().optional()
56
84
  });
57
- var objectMetaSchema = userObjectMetaSchema.extend({
58
- /**
59
- * Creation timestamp in milliseconds.
60
- *
61
- * Managed automatically by the system.
62
- */
63
- createdAt: z.number().optional(),
85
+ var commonObjectMetaSchema = objectMetaSchema.pick({
86
+ title: true,
87
+ description: true,
88
+ icon: true,
89
+ iconColor: true
90
+ }).required({
91
+ title: true
92
+ });
93
+ var globalCommonObjectMetaSchema = objectMetaSchema.pick({
94
+ title: true,
95
+ globalTitle: true,
96
+ description: true,
97
+ icon: true,
98
+ iconColor: true
99
+ }).required({
100
+ title: true
101
+ });
102
+ var serviceAccountMetaSchema = objectMetaSchema.pick({
103
+ title: true,
104
+ description: true,
105
+ avatarUrl: true,
106
+ icon: true,
107
+ iconColor: true
108
+ }).required({ title: true });
109
+ var timestampsSchema = z.object({
64
110
  /**
65
- * Last update timestamp in milliseconds.
66
- *
67
- * Managed automatically by the system.
111
+ * The timestamp when the object was created.
68
112
  */
69
- updatedAt: z.number().optional(),
113
+ createdAt: z.date(),
70
114
  /**
71
- * The optional version of the document to support optimistic concurrency control.
72
- *
73
- * Managed automatically by the system.
115
+ * The timestamp when the object was last updated.
74
116
  */
75
- version: z.number().optional()
117
+ updatedAt: z.date()
76
118
  });
77
119
  var genericNameSchema = z.string().regex(/^[a-z][a-z0-9-_.]+$/).min(2).max(64);
78
- var fieldNameSchema = z.string().regex(/^[a-z][a-zA-Z0-9]+$/).min(2).max(64);
79
-
80
- // src/i18n.ts
81
- var knownAbbreviationsMap = /* @__PURE__ */ new Map();
82
- function registerKnownAbbreviations(abbreviations) {
83
- for (const abbr of abbreviations) {
84
- const lower = abbr.toLowerCase();
85
- if (!knownAbbreviationsMap.has(lower)) {
86
- knownAbbreviationsMap.set(lower, abbr);
87
- }
120
+ var versionedNameSchema = z.union([
121
+ z.templateLiteral([genericNameSchema, z.literal("."), z.literal("v"), z.number().int().min(1)]),
122
+ // to prevent TypeScript matching "proxmox.virtual-machine.v2" as
123
+ // 1. "proxmox.v"
124
+ // 2. "irtual-machine.v2" and thinking it should be a number
125
+ z.templateLiteral([
126
+ genericNameSchema,
127
+ z.literal("."),
128
+ genericNameSchema,
129
+ z.literal("."),
130
+ z.literal("v"),
131
+ z.number().int().min(1)
132
+ ]),
133
+ z.templateLiteral([
134
+ genericNameSchema,
135
+ z.literal("."),
136
+ genericNameSchema,
137
+ z.literal("."),
138
+ genericNameSchema,
139
+ z.literal("."),
140
+ z.literal("v"),
141
+ z.number().int().min(1)
142
+ ])
143
+ ]);
144
+ function parseVersionedName(name) {
145
+ const lastDotVIndex = name.lastIndexOf(".v");
146
+ if (lastDotVIndex === -1) {
147
+ throw new Error(`Invalid versioned name: ${name}`);
88
148
  }
149
+ const baseName = name.substring(0, lastDotVIndex);
150
+ const versionPart = name.substring(lastDotVIndex + 2);
151
+ const version = parseInt(versionPart, 10);
152
+ if (Number.isNaN(version) || version < 1) {
153
+ throw new Error(`Invalid version in versioned name: ${name}`);
154
+ }
155
+ return [baseName, version];
89
156
  }
90
- function camelCaseToHumanReadable(text2) {
91
- const words = text2.split(/(?=[A-Z])|_|-|\./);
92
- return words.map((word) => {
93
- const lower = word.toLowerCase();
94
- if (knownAbbreviationsMap.has(lower)) {
95
- return knownAbbreviationsMap.get(lower);
96
- }
97
- return word.charAt(0).toUpperCase() + word.slice(1);
98
- }).join(" ");
99
- }
157
+ var fieldNameSchema = z.string().regex(/^[a-z][a-zA-Z0-9]+$/).min(2).max(64);
100
158
 
101
159
  // src/entity.ts
102
160
  var entityModelSchema = z.object({
103
161
  /**
104
162
  * The static type of the entity.
105
163
  */
106
- type: z.string(),
164
+ type: versionedNameSchema,
107
165
  /**
108
166
  * The JSON schema of the entity value.
109
167
  */
@@ -124,8 +182,10 @@ var entityModelSchema = z.object({
124
182
  definitionHash: z.number()
125
183
  });
126
184
  function defineEntity(options) {
127
- if (!options.type) {
128
- throw new Error("Entity type is required");
185
+ try {
186
+ entityModelSchema.shape.type.parse(options.type);
187
+ } catch (error) {
188
+ throw new Error(`Invalid entity type "${options.type}"`, { cause: error });
129
189
  }
130
190
  if (!options.schema) {
131
191
  throw new Error("Entity schema is required");
@@ -139,9 +199,9 @@ function defineEntity(options) {
139
199
  schema: z.toJSONSchema(options.schema, { target: "draft-7" }),
140
200
  meta: {
141
201
  ...options.meta,
142
- title: options.meta?.title ?? camelCaseToHumanReadable(options.type)
202
+ title: options.meta?.title || camelCaseToHumanReadable(parseVersionedName(options.type)[0])
143
203
  },
144
- // will be calculated by the library loader
204
+ // biome-ignore lint/style/noNonNullAssertion: will be calculated by the library loader
145
205
  definitionHash: null
146
206
  }
147
207
  };
@@ -152,371 +212,159 @@ function defineEntity(options) {
152
212
  function isEntity(value) {
153
213
  return typeof value === "object" && value !== null && "model" in value;
154
214
  }
155
- var positionSchema = z.object({
156
- x: z.number(),
157
- y: z.number()
158
- });
159
- var instanceIdSchema = z.templateLiteral([genericNameSchema, ":", genericNameSchema]);
160
- var instanceInputSchema = z.object({
161
- instanceId: instanceIdSchema,
162
- output: z.string()
163
- });
164
- var hubInputSchema = z.object({
165
- hubId: z.string()
166
- });
167
- var instanceModelPatchSchema = z.object({
168
- /**
169
- * The static arguments passed to the instance.
170
- */
171
- args: z.record(z.string(), z.unknown()).optional(),
215
+ var boundaryInput = Symbol("boundaryInput");
216
+ var boundaryInputs = Symbol("boundaryInputs");
217
+ function formatInstancePath(instance) {
218
+ let result = instance.id;
219
+ while (instance.parentId) {
220
+ const parent = runtimeInstances.get(instance.parentId)?.instance;
221
+ if (!parent) {
222
+ break;
223
+ }
224
+ result = `${parent.id} -> ${result}`;
225
+ instance = parent;
226
+ }
227
+ return result;
228
+ }
229
+ var InstanceNameConflictError = class extends Error {
230
+ constructor(instanceId, firstPath, secondPath) {
231
+ super(
232
+ `Multiple instances produced with the same instance ID "${instanceId}":
233
+ 1. ${firstPath}
234
+ 2. ${secondPath}`
235
+ );
236
+ this.instanceId = instanceId;
237
+ this.firstPath = firstPath;
238
+ this.secondPath = secondPath;
239
+ this.name = "InstanceNameConflictError";
240
+ }
241
+ };
242
+ var currentInstance = null;
243
+ var runtimeInstances = /* @__PURE__ */ new Map();
244
+ function resetEvaluation() {
245
+ runtimeInstances.clear();
246
+ currentInstance = null;
247
+ }
248
+ function getRuntimeInstances() {
249
+ return Array.from(runtimeInstances.values());
250
+ }
251
+ function registerInstance(component, instance, fn) {
252
+ const conflicting = runtimeInstances.get(instance.id);
253
+ if (conflicting) {
254
+ throw new InstanceNameConflictError(
255
+ instance.id,
256
+ formatInstancePath(conflicting.instance),
257
+ formatInstancePath(instance)
258
+ );
259
+ }
260
+ runtimeInstances.set(instance.id, { instance, component });
261
+ let previousParentInstance = null;
262
+ if (currentInstance) {
263
+ instance.parentId = currentInstance.id;
264
+ }
265
+ if (component.model.kind === "composite") {
266
+ previousParentInstance = currentInstance;
267
+ currentInstance = instance;
268
+ }
269
+ try {
270
+ const outputs = fn();
271
+ instance.resolvedOutputs = outputs;
272
+ instance.outputs = mapValues(
273
+ outputs ?? {},
274
+ (outputs2) => outputs2.map((output) => output[boundaryInput] ?? output)
275
+ );
276
+ return mapValues(
277
+ outputs,
278
+ (outputs2, outputKey) => outputs2.map((output) => ({
279
+ ...output,
280
+ [boundaryInput]: { instanceId: instance.id, output: outputKey }
281
+ }))
282
+ );
283
+ } finally {
284
+ if (previousParentInstance) {
285
+ currentInstance = previousParentInstance;
286
+ }
287
+ }
288
+ }
289
+
290
+ // src/component.ts
291
+ var runtimeSchema = Symbol("runtimeSchema");
292
+ var validationEnabled = true;
293
+ function setValidationEnabled(enabled) {
294
+ validationEnabled = enabled;
295
+ }
296
+ var componentKindSchema = z.enum(["composite", "unit"]);
297
+ var componentArgumentSchema = z.object({
172
298
  /**
173
- * The direct instances passed as inputs to the instance.
299
+ * The JSON schema of the argument value.
174
300
  */
175
- inputs: z.record(z.string(), z.array(instanceInputSchema)).optional(),
301
+ schema: z.custom(),
176
302
  /**
177
- * The resolved unit inputs for the instance.
303
+ * The original Zod schema of the argument.
178
304
  *
179
- * Only for computed composite instances.
305
+ * Only available at runtime.
180
306
  */
181
- hubInputs: z.record(z.string(), z.array(hubInputSchema)).optional(),
307
+ [runtimeSchema]: z.instanceof(z.ZodType).optional(),
182
308
  /**
183
- * The inputs injected to the instance from the hubs.
184
- *
185
- * While `hubInputs` allows to pass hubs to distinct inputs,
186
- * `injectionInputs` allows to pass hubs to the instance as a whole filling all inputs with matching types.
187
- *
188
- * Only for designer-first instances.
309
+ * Whether the argument is required.
189
310
  */
190
- injectionInputs: z.array(hubInputSchema).optional(),
311
+ required: z.boolean(),
191
312
  /**
192
- * The position of the instance on the canvas.
193
- *
194
- * Only for designer-first instances.
313
+ * The extra metadata of the argument.
195
314
  */
196
- position: positionSchema.optional()
315
+ meta: objectMetaSchema.required({ title: true }).pick({
316
+ title: true,
317
+ globalTitle: true,
318
+ description: true,
319
+ color: true,
320
+ icon: true,
321
+ iconColor: true
322
+ })
197
323
  });
198
- var instanceModelSchema = z.object({
199
- /**
200
- * The id of the instance unique within the project.
201
- *
202
- * The format is `${instanceType}:${instanceName}`.
203
- */
204
- id: instanceIdSchema,
324
+ var componentInputSchema = z.object({
205
325
  /**
206
- * The type of the instance.
326
+ * The type of the entity passed through the input.
207
327
  */
208
- type: genericNameSchema,
328
+ type: versionedNameSchema,
209
329
  /**
210
- * The name of the instance.
211
- *
212
- * Must be unique within instances of the same type in the project.
330
+ * Whether the input is required.
213
331
  */
214
- name: genericNameSchema,
215
- ...instanceModelPatchSchema.shape,
332
+ required: z.boolean(),
216
333
  /**
217
- * The id of the top level parent instance.
218
- *
219
- * Only for child instances of the composite instances.
334
+ * Whether the input can have multiple values.
220
335
  */
221
- resolvedInputs: z.record(z.string(), z.array(instanceInputSchema)).optional(),
336
+ multiple: z.boolean(),
222
337
  /**
223
- * The position of the instance on the canvas.
224
- *
225
- * Only for designer-first instances.
338
+ * The extra metadata of the input.
226
339
  */
227
- parentId: z.string().optional(),
340
+ meta: objectMetaSchema.required({ title: true }).pick({
341
+ title: true,
342
+ description: true
343
+ })
344
+ });
345
+ var componentModelSchema = z.object({
228
346
  /**
229
- * The direct instance outputs returned by the instance as outputs.
230
- *
231
- * Only for computed composite instances.
347
+ * The type of the component.
232
348
  */
233
- outputs: z.record(z.string(), z.array(instanceInputSchema)).optional(),
349
+ type: genericNameSchema,
234
350
  /**
235
- * The resolved unit outputs for the instance.
236
- *
237
- * Only for computed composite instances.
351
+ * The kind of the component.
238
352
  */
239
- resolvedOutputs: z.record(z.string(), z.array(instanceInputSchema)).optional()
240
- });
241
- var hubModelPatchSchema = z.object({
353
+ kind: componentKindSchema,
242
354
  /**
243
- * The position of the hub on the canvas.
355
+ * The record of the argument schemas.
244
356
  */
245
- position: positionSchema.optional(),
357
+ args: z.record(fieldNameSchema, componentArgumentSchema),
246
358
  /**
247
- * The inputs of the hub.
359
+ * The record of the input schemas.
248
360
  */
249
- inputs: z.array(instanceInputSchema).optional(),
361
+ inputs: z.record(fieldNameSchema, componentInputSchema),
250
362
  /**
251
- * The inputs injected to the hub from the hubs.
252
- *
253
- * While `inputs` allows to pass hubs to distinct inputs,
254
- * `injectionInputs` allows to pass hubs to the hub as a whole filling all inputs with matching types.
363
+ * The record of the output schemas.
255
364
  */
256
- injectionInputs: z.array(hubInputSchema).optional()
257
- });
258
- var hubModelSchema = z.object({
365
+ outputs: z.record(fieldNameSchema, componentInputSchema),
259
366
  /**
260
- * The id of the hub unique within the project.
261
- */
262
- id: z.nanoid(),
263
- ...hubModelPatchSchema.shape
264
- });
265
- function getInstanceId(instanceType, instanceName) {
266
- return `${instanceType}:${instanceName}`;
267
- }
268
- function parseInstanceId(instanceId) {
269
- const parts = instanceId.split(":");
270
- if (parts.length !== 2) {
271
- throw new Error(`Invalid instance ID: ${instanceId}`);
272
- }
273
- return parts;
274
- }
275
- function findInput(inputs, name) {
276
- const matchedInputs = inputs.filter(
277
- (input) => parseInstanceId(input.instanceId)[1] === name || input.instanceId === name
278
- );
279
- if (matchedInputs.length === 0) {
280
- return null;
281
- }
282
- if (matchedInputs.length > 1) {
283
- throw new Error(
284
- `Multiple inputs found for "${name}": ${matchedInputs.map((input) => input.instanceId).join(", ")}. Specify the full instance id to disambiguate.`
285
- );
286
- }
287
- return matchedInputs[0];
288
- }
289
- function findRequiredInput(inputs, name) {
290
- const input = findInput(inputs, name);
291
- if (input === null) {
292
- throw new Error(`Required input "${name}" not found.`);
293
- }
294
- return input;
295
- }
296
- function findInputs(inputs, names) {
297
- return names.map((name) => findInput(inputs, name)).filter(Boolean);
298
- }
299
- function findRequiredInputs(inputs, names) {
300
- return names.map((name) => findRequiredInput(inputs, name));
301
- }
302
- var HighstateSignature = /* @__PURE__ */ ((HighstateSignature2) => {
303
- HighstateSignature2["Artifact"] = "d55c63ac-3174-4756-808f-f778e99af0d1";
304
- HighstateSignature2["Secret"] = "56ebf97b-57de-4985-8c86-bc1bc5871e6e";
305
- HighstateSignature2["Yaml"] = "c857cac5-caa6-4421-b82c-e561fbce6367";
306
- return HighstateSignature2;
307
- })(HighstateSignature || {});
308
- var yamlValueSchema = z.object({
309
- ["c857cac5-caa6-4421-b82c-e561fbce6367" /* Yaml */]: z.literal(true),
310
- value: z.string()
311
- });
312
- var fileMetaSchema = z.object({
313
- name: z.string(),
314
- contentType: z.string().optional(),
315
- size: z.number().optional(),
316
- mode: z.number().optional(),
317
- isBinary: z.boolean().optional()
318
- });
319
- var unitObjectMetaSchema = z.object({
320
- displayName: z.string().optional(),
321
- description: z.string().optional(),
322
- primaryIcon: z.string().optional()
323
- });
324
- var unitSecretSchema = z.object({
325
- ["56ebf97b-57de-4985-8c86-bc1bc5871e6e" /* Secret */]: z.literal(true),
326
- id: z.uuidv7(),
327
- value: z.unknown()
328
- });
329
- var unitArtifactSchema = z.object({
330
- ["d55c63ac-3174-4756-808f-f778e99af0d1" /* Artifact */]: z.literal(true),
331
- hash: z.string(),
332
- meta: unitObjectMetaSchema.optional()
333
- });
334
- var fileContentSchema = z.union([
335
- z.object({
336
- type: z.literal("embedded"),
337
- value: z.string()
338
- }),
339
- z.object({
340
- type: z.literal("artifact"),
341
- ...unitArtifactSchema.shape
342
- })
343
- ]);
344
- var fileSchema = z.object({
345
- meta: fileMetaSchema,
346
- content: fileContentSchema
347
- });
348
-
349
- // src/utils.ts
350
- function text(strings, ...values) {
351
- const stringValues = values.map(String);
352
- let result = "";
353
- for (let i = 0; i < strings.length; i++) {
354
- result += strings[i];
355
- if (i < stringValues.length) {
356
- const value = stringValues[i];
357
- const lines = value.split("\n");
358
- const lastLineIndentMatch = strings[i].match(/(?:^|\n)([ \t]*)$/);
359
- const indent = lastLineIndentMatch ? lastLineIndentMatch[1] : "";
360
- result += lines.map((line, j) => j === 0 ? line : indent + line).join("\n");
361
- }
362
- }
363
- return trimIndentation(result);
364
- }
365
- function trimIndentation(text2) {
366
- const lines = text2.split("\n");
367
- const indent = lines.filter((line) => line.trim() !== "").map((line) => line.match(/^\s*/)?.[0].length ?? 0).reduce((min, indent2) => Math.min(min, indent2), Infinity);
368
- return lines.map((line) => line.slice(indent)).join("\n").trim();
369
- }
370
- function bytesToHumanReadable(bytes) {
371
- const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
372
- if (bytes === 0) return "0 Bytes";
373
- const i = Math.floor(Math.log(bytes) / Math.log(1024));
374
- return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + " " + sizes[i];
375
- }
376
- function formatInstancePath(instance) {
377
- let result = instance.id;
378
- while (instance.parentId) {
379
- const parent = runtimeInstances.get(instance.parentId)?.instance;
380
- if (!parent) {
381
- break;
382
- }
383
- result = `${parent.id} -> ${result}`;
384
- instance = parent;
385
- }
386
- return result;
387
- }
388
- var InstanceNameConflictError = class extends Error {
389
- constructor(instanceId, firstPath, secondPath) {
390
- super(
391
- `Multiple instances produced with the same instance ID "${instanceId}":
392
- 1. ${firstPath}
393
- 2. ${secondPath}`
394
- );
395
- this.instanceId = instanceId;
396
- this.firstPath = firstPath;
397
- this.secondPath = secondPath;
398
- this.name = "InstanceNameConflictError";
399
- }
400
- };
401
- var currentInstance = null;
402
- var runtimeInstances = /* @__PURE__ */ new Map();
403
- function resetEvaluation() {
404
- runtimeInstances.clear();
405
- currentInstance = null;
406
- }
407
- function getRuntimeInstances() {
408
- return Array.from(runtimeInstances.values());
409
- }
410
- function registerInstance(component, instance, fn) {
411
- if (runtimeInstances.has(instance.id)) {
412
- const existing = runtimeInstances.get(instance.id);
413
- throw new InstanceNameConflictError(
414
- instance.id,
415
- formatInstancePath(existing.instance),
416
- formatInstancePath(instance)
417
- );
418
- }
419
- runtimeInstances.set(instance.id, { instance, component });
420
- let previousParentInstance = null;
421
- if (currentInstance) {
422
- instance.parentId = currentInstance.id;
423
- }
424
- if (!isUnitModel(component.model)) {
425
- previousParentInstance = currentInstance;
426
- currentInstance = instance;
427
- }
428
- try {
429
- const outputs = fn();
430
- instance.resolvedOutputs = outputs;
431
- instance.outputs = mapValues(
432
- outputs ?? {},
433
- (outputs2) => outputs2.map((output) => output[boundaryInput] ?? output)
434
- );
435
- return mapValues(
436
- outputs,
437
- (outputs2, outputKey) => outputs2.map((output) => ({
438
- ...output,
439
- [boundaryInput]: { instanceId: instance.id, output: outputKey }
440
- }))
441
- );
442
- } finally {
443
- if (previousParentInstance) {
444
- currentInstance = previousParentInstance;
445
- }
446
- }
447
- }
448
-
449
- // src/component.ts
450
- var boundaryInput = Symbol("boundaryInput");
451
- var ajv = new Ajv({ strict: false });
452
- var validationEnabled = true;
453
- function setValidationEnabled(enabled) {
454
- validationEnabled = enabled;
455
- }
456
- var componentArgumentSchema = z.object({
457
- /**
458
- * The JSON schema of the argument value.
459
- */
460
- schema: z.custom(),
461
- /**
462
- * Whether the argument is required.
463
- */
464
- required: z.boolean(),
465
- /**
466
- * The extra metadata of the argument.
467
- */
468
- meta: objectMetaSchema.required({ title: true }).pick({
469
- title: true,
470
- globalTitle: true,
471
- description: true,
472
- color: true,
473
- icon: true,
474
- iconColor: true
475
- })
476
- });
477
- function isSchemaOptional(schema) {
478
- return schema.safeParse(void 0).success;
479
- }
480
- var componentInputSchema = z.object({
481
- /**
482
- * The type of the input.
483
- */
484
- type: genericNameSchema,
485
- /**
486
- * Whether the input is required.
487
- */
488
- required: z.boolean(),
489
- /**
490
- * Whether the input can have multiple values.
491
- */
492
- multiple: z.boolean(),
493
- /**
494
- * The extra metadata of the input.
495
- */
496
- meta: objectMetaSchema.required({ title: true }).pick({
497
- title: true,
498
- description: true
499
- })
500
- });
501
- var componentModelSchema = z.object({
502
- /**
503
- * The type of the component.
504
- */
505
- type: genericNameSchema,
506
- /**
507
- * The record of the argument schemas.
508
- */
509
- args: z.record(fieldNameSchema, componentArgumentSchema),
510
- /**
511
- * The record of the input schemas.
512
- */
513
- inputs: z.record(fieldNameSchema, componentInputSchema),
514
- /**
515
- * The record of the output schemas.
516
- */
517
- outputs: z.record(fieldNameSchema, componentInputSchema),
518
- /**
519
- * The extra metadata of the component.
367
+ * The extra metadata of the component.
520
368
  */
521
369
  meta: objectMetaSchema.required({ title: true }).pick({
522
370
  title: true,
@@ -538,7 +386,7 @@ var componentModelSchema = z.object({
538
386
  *
539
387
  * Used to generate default names for the instances.
540
388
  */
541
- defaultNamePrefix: z.string().optional()
389
+ defaultNamePrefix: z.string()
542
390
  }),
543
391
  /**
544
392
  * The CRC32 of the component definition.
@@ -546,48 +394,90 @@ var componentModelSchema = z.object({
546
394
  definitionHash: z.number()
547
395
  });
548
396
  var originalCreate = Symbol("originalCreate");
397
+ var kind = Symbol("kind");
549
398
  function defineComponent(options) {
550
- if (!options.type) {
551
- throw new Error("Component type is required");
399
+ try {
400
+ componentModelSchema.shape.type.parse(options.type);
401
+ } catch (error) {
402
+ throw new Error(`Invalid component type "${options.type}"`, { cause: error });
552
403
  }
553
404
  if (!options.create) {
554
405
  throw new Error("Component create function is required");
555
406
  }
407
+ const entities = /* @__PURE__ */ new Map();
408
+ const mapInput = createInputMapper(entities);
409
+ const model = {
410
+ type: options.type,
411
+ kind: options[kind] ?? "composite",
412
+ args: mapValues(options.args ?? {}, mapArgument),
413
+ inputs: mapValues(options.inputs ?? {}, mapInput),
414
+ outputs: mapValues(options.outputs ?? {}, mapInput),
415
+ meta: {
416
+ ...options.meta,
417
+ title: options.meta?.title || camelCaseToHumanReadable(parseVersionedName(options.type)[0]),
418
+ defaultNamePrefix: options.meta?.defaultNamePrefix || parseVersionedName(options.type)[0].split(".").slice(-1)[0]
419
+ },
420
+ // biome-ignore lint/style/noNonNullAssertion: will be calculated by library loader
421
+ definitionHash: null
422
+ };
556
423
  function create(params) {
557
- const { name, args, inputs } = params;
424
+ const { name, args = {}, inputs } = params;
558
425
  const instanceId = getInstanceId(options.type, name);
559
- const flatInputs = mapValues(pickBy(inputs ?? {}, isNonNullish), (inputs2) => [inputs2].flat(2));
426
+ const flatInputs = {};
427
+ const tracedInputs = {};
428
+ for (const [key, inputGroup] of Object.entries(inputs ?? {})) {
429
+ if (!inputGroup) {
430
+ continue;
431
+ }
432
+ if (!Array.isArray(inputGroup)) {
433
+ if (inputGroup[boundaryInput]) {
434
+ tracedInputs[key] = [inputGroup[boundaryInput]];
435
+ }
436
+ flatInputs[key] = [inputGroup];
437
+ continue;
438
+ }
439
+ const group = [...inputGroup[boundaryInputs] ?? []];
440
+ const inputs2 = [];
441
+ for (const item of inputGroup.flat(1)) {
442
+ if (item[boundaryInput]) {
443
+ group.push(item[boundaryInput]);
444
+ }
445
+ inputs2.push(item);
446
+ }
447
+ tracedInputs[key] = uniqueBy(group, inputKey);
448
+ flatInputs[key] = uniqueBy(inputs2, inputKey);
449
+ }
560
450
  return registerInstance(
561
451
  create,
562
452
  {
563
453
  id: instanceId,
564
454
  type: options.type,
455
+ kind: options[kind] ?? "composite",
565
456
  name,
566
- args: args ?? {},
567
- inputs: mapValues(flatInputs, (inputs2) => inputs2.map((input) => input[boundaryInput] ?? input)),
568
- resolvedInputs: flatInputs
457
+ args,
458
+ inputs: tracedInputs,
459
+ resolvedInputs: mapValues(
460
+ flatInputs,
461
+ (inputs2) => inputs2.filter((input) => !("provided" in input && input.provided === false))
462
+ )
569
463
  },
570
464
  () => {
571
- const componentInputs = create.model.inputs;
572
- const markedInputs = mapValues(componentInputs, (componentInput, key) => {
573
- const inputs2 = flatInputs[key];
574
- if (!inputs2 || inputs2.length === 0) {
575
- return create.model.inputs[key].multiple ? [{ instanceId, output: key }] : { instanceId, output: key };
465
+ const markedInputs = mapValues(model.inputs, (componentInput, key) => {
466
+ if (!componentInput.multiple) {
467
+ const input = flatInputs[key]?.[0];
468
+ if (input) {
469
+ return { ...input, [boundaryInput]: { instanceId, output: key } };
470
+ }
471
+ return { provided: false, [boundaryInput]: { instanceId, output: key } };
576
472
  }
577
- const result = inputs2.map((input) => ({
578
- ...input,
579
- [boundaryInput]: { instanceId, output: key }
580
- }));
581
- return create.model.inputs?.[key]?.multiple === false ? result[0] : result;
473
+ const inputs2 = flatInputs[key] ?? [];
474
+ inputs2[boundaryInputs] = [{ instanceId, output: key }];
475
+ return inputs2;
582
476
  });
583
477
  const outputs = options.create({
584
478
  id: instanceId,
585
479
  name,
586
- args: validateArgsAndFillDefaults(
587
- instanceId,
588
- create.model,
589
- args ? { ...args } : {}
590
- ),
480
+ args: processArgs(instanceId, create.model, args),
591
481
  inputs: markedInputs
592
482
  }) ?? {};
593
483
  return mapValues(pickBy(outputs, isNonNullish), (outputs2) => [outputs2].flat(2));
@@ -595,42 +485,55 @@ function defineComponent(options) {
595
485
  );
596
486
  }
597
487
  try {
598
- create.entities = /* @__PURE__ */ new Map();
599
- const mapInput = createInputMapper(create.entities);
600
- create.model = {
601
- type: options.type,
602
- args: mapValues(options.args ?? {}, mapArgument),
603
- inputs: mapValues(options.inputs ?? {}, mapInput),
604
- outputs: mapValues(options.outputs ?? {}, mapInput),
605
- meta: {
606
- ...options.meta,
607
- title: options.meta?.title ?? camelCaseToHumanReadable(options.type)
608
- },
609
- definitionHash: null
610
- // will be calculated by library loader
611
- };
488
+ create.entities = entities;
489
+ create.model = model;
612
490
  create[originalCreate] = options.create;
613
491
  return create;
614
492
  } catch (error) {
615
493
  throw new Error(`Failed to define component "${options.type}"`, { cause: error });
616
494
  }
617
495
  }
496
+ function processArgs(instanceId, model, args) {
497
+ if (!validationEnabled) {
498
+ return args;
499
+ }
500
+ const validatedArgs = {};
501
+ for (const [key, arg] of Object.entries(model.args)) {
502
+ if (arg.schema) {
503
+ const result = arg[runtimeSchema].safeParse(args[key]);
504
+ if (!result.success) {
505
+ throw new Error(
506
+ `Invalid argument "${key}" in instance "${instanceId}": ${result.error.message}`
507
+ );
508
+ }
509
+ validatedArgs[key] = result.data;
510
+ } else {
511
+ validatedArgs[key] = args[key];
512
+ }
513
+ }
514
+ return validatedArgs;
515
+ }
618
516
  function isComponent(value) {
619
517
  return typeof value === "function" && "model" in value;
620
518
  }
519
+ function isSchemaOptional(schema) {
520
+ return schema.safeParse(void 0).success;
521
+ }
621
522
  function mapArgument(value, key) {
622
523
  if ("schema" in value) {
623
524
  return {
624
- schema: z.toJSONSchema(value.schema, { target: "draft-7" }),
625
- required: value.required ?? !isSchemaOptional(value.schema),
525
+ schema: z.toJSONSchema(value.schema, { target: "draft-7", io: "input" }),
526
+ [runtimeSchema]: value.schema,
527
+ required: !isSchemaOptional(value.schema),
626
528
  meta: {
627
529
  ...value.meta,
628
- title: value.meta?.title ?? camelCaseToHumanReadable(key)
530
+ title: value.meta?.title || camelCaseToHumanReadable(key)
629
531
  }
630
532
  };
631
533
  }
632
534
  return {
633
- schema: z.toJSONSchema(value, { target: "draft-7" }),
535
+ schema: z.toJSONSchema(value, { target: "draft-7", io: "input" }),
536
+ [runtimeSchema]: value,
634
537
  required: !isSchemaOptional(value),
635
538
  meta: {
636
539
  title: camelCaseToHumanReadable(key)
@@ -650,7 +553,7 @@ function createInputMapper(entities) {
650
553
  multiple: value.multiple ?? false,
651
554
  meta: {
652
555
  ...value.meta,
653
- title: value.meta?.title ?? camelCaseToHumanReadable(key)
556
+ title: value.meta?.title || camelCaseToHumanReadable(key)
654
557
  }
655
558
  };
656
559
  }
@@ -665,37 +568,284 @@ function createInputMapper(entities) {
665
568
  };
666
569
  };
667
570
  }
668
- function validateArgsAndFillDefaults(instanceId, model, args) {
669
- for (const [key, argModel] of Object.entries(model.args)) {
670
- let value = args[key];
671
- if (!value) {
672
- if (argModel.required && validationEnabled) {
673
- throw new Error(`Missing required argument "${key}" for instance "${instanceId}"`);
674
- }
675
- value = argModel.schema.default;
676
- args[key] = value;
677
- }
678
- if (validationEnabled && value && !ajv.validate(argModel.schema, value)) {
679
- throw new Error(`Invalid argument "${key}" for instance "${instanceId}": ${ajv.errorsText()}`);
680
- }
681
- }
682
- return args;
571
+ function getInstanceId(instanceType, instanceName) {
572
+ return `${instanceType}:${instanceName}`;
683
573
  }
684
- function isUnitModel(model) {
685
- return "source" in model;
574
+ function toFullComponentArgumentOptions(args) {
575
+ return mapValues(args, (arg) => "schema" in arg ? arg : { schema: arg });
576
+ }
577
+ function toFullComponentInputOptions(inputs) {
578
+ return mapValues(inputs, (input) => "entity" in input ? input : { entity: input });
686
579
  }
687
580
  function $args(args) {
688
- return args;
581
+ return toFullComponentArgumentOptions(args);
689
582
  }
690
583
  function $inputs(inputs) {
691
- return inputs;
584
+ return toFullComponentInputOptions(inputs);
692
585
  }
693
586
  function $outputs(outputs) {
694
- return outputs;
587
+ return toFullComponentInputOptions(outputs);
695
588
  }
696
-
697
- // src/unit.ts
698
- var componentSecretSchema = componentArgumentSchema.extend({
589
+ function $addArgumentDescription(argument, description) {
590
+ if ("schema" in argument) {
591
+ return {
592
+ ...argument,
593
+ meta: {
594
+ ...argument.meta,
595
+ description: argument.meta?.description ?? description
596
+ }
597
+ };
598
+ }
599
+ return {
600
+ schema: argument,
601
+ meta: {
602
+ description
603
+ }
604
+ };
605
+ }
606
+ function $addInputDescription(input, description) {
607
+ if ("entity" in input) {
608
+ return {
609
+ ...input,
610
+ meta: {
611
+ ...input.meta,
612
+ description: input.meta?.description ?? description
613
+ }
614
+ };
615
+ }
616
+ return {
617
+ entity: input,
618
+ meta: {
619
+ description
620
+ }
621
+ };
622
+ }
623
+
624
+ // src/instance.ts
625
+ function inputKey(input) {
626
+ return `${input.instanceId}:${input.output}`;
627
+ }
628
+ var positionSchema = z.object({
629
+ x: z.number(),
630
+ y: z.number()
631
+ });
632
+ var instanceIdSchema = z.templateLiteral([versionedNameSchema, ":", genericNameSchema]);
633
+ var instanceInputSchema = z.object({
634
+ instanceId: instanceIdSchema,
635
+ output: z.string()
636
+ });
637
+ var hubInputSchema = z.object({
638
+ hubId: z.string()
639
+ });
640
+ var instanceModelPatchSchema = z.object({
641
+ /**
642
+ * The static arguments passed to the instance.
643
+ */
644
+ args: z.record(z.string(), z.unknown()).optional(),
645
+ /**
646
+ * The direct instances passed as inputs to the instance.
647
+ */
648
+ inputs: z.record(z.string(), z.array(instanceInputSchema)).optional(),
649
+ /**
650
+ * The resolved unit inputs for the instance.
651
+ *
652
+ * Only for computed composite instances.
653
+ */
654
+ hubInputs: z.record(z.string(), z.array(hubInputSchema)).optional(),
655
+ /**
656
+ * The inputs injected to the instance from the hubs.
657
+ *
658
+ * While `hubInputs` allows to pass hubs to distinct inputs,
659
+ * `injectionInputs` allows to pass hubs to the instance as a whole filling all inputs with matching types.
660
+ *
661
+ * Only for designer-first instances.
662
+ */
663
+ injectionInputs: z.array(hubInputSchema).optional(),
664
+ /**
665
+ * The position of the instance on the canvas.
666
+ *
667
+ * Only for designer-first instances.
668
+ */
669
+ position: positionSchema.optional()
670
+ });
671
+ var instanceModelSchema = z.object({
672
+ /**
673
+ * The id of the instance unique within the project.
674
+ *
675
+ * The format is `${instanceType}:${instanceName}`.
676
+ */
677
+ id: instanceIdSchema,
678
+ /**
679
+ * The kind of the instance.
680
+ *
681
+ * Can be either "unit" or "composite".
682
+ */
683
+ kind: componentKindSchema,
684
+ /**
685
+ * The type of the instance.
686
+ */
687
+ type: versionedNameSchema,
688
+ /**
689
+ * The name of the instance.
690
+ *
691
+ * Must be unique within instances of the same type in the project.
692
+ */
693
+ name: genericNameSchema,
694
+ ...instanceModelPatchSchema.shape,
695
+ /**
696
+ * The id of the top level parent instance.
697
+ *
698
+ * Only for child instances of the composite instances.
699
+ */
700
+ resolvedInputs: z.record(z.string(), z.array(instanceInputSchema)).optional(),
701
+ /**
702
+ * The ID of the parent instance.
703
+ *
704
+ * Only for child instances of the composite instances.
705
+ */
706
+ parentId: instanceIdSchema.optional(),
707
+ /**
708
+ * The direct instance outputs returned by the instance as outputs.
709
+ *
710
+ * Only for computed composite instances.
711
+ */
712
+ outputs: z.record(z.string(), z.array(instanceInputSchema)).optional(),
713
+ /**
714
+ * The resolved unit outputs for the instance.
715
+ *
716
+ * Only for computed composite instances.
717
+ */
718
+ resolvedOutputs: z.record(z.string(), z.array(instanceInputSchema)).optional()
719
+ });
720
+ var hubModelPatchSchema = z.object({
721
+ /**
722
+ * The position of the hub on the canvas.
723
+ */
724
+ position: positionSchema.optional(),
725
+ /**
726
+ * The inputs of the hub.
727
+ */
728
+ inputs: z.array(instanceInputSchema).optional(),
729
+ /**
730
+ * The inputs injected to the hub from the hubs.
731
+ *
732
+ * While `inputs` allows to pass hubs to distinct inputs,
733
+ * `injectionInputs` allows to pass hubs to the hub as a whole filling all inputs with matching types.
734
+ */
735
+ injectionInputs: z.array(hubInputSchema).optional()
736
+ });
737
+ var hubModelSchema = z.object({
738
+ /**
739
+ * The id of the hub unique within the project.
740
+ */
741
+ id: z.cuid2(),
742
+ ...hubModelPatchSchema.shape
743
+ });
744
+ function parseInstanceId(instanceId) {
745
+ const parts = instanceId.split(":");
746
+ if (parts.length !== 2) {
747
+ throw new Error(`Invalid instance ID: ${instanceId}`);
748
+ }
749
+ return parts;
750
+ }
751
+ function findInput(inputs, name) {
752
+ const matchedInputs = inputs.filter(
753
+ (input) => parseInstanceId(input.instanceId)[1] === name || input.instanceId === name
754
+ );
755
+ if (matchedInputs.length === 0) {
756
+ return null;
757
+ }
758
+ if (matchedInputs.length > 1) {
759
+ throw new Error(
760
+ `Multiple inputs found for "${name}": ${matchedInputs.map((input) => input.instanceId).join(", ")}. Specify the full instance id to disambiguate.`
761
+ );
762
+ }
763
+ return matchedInputs[0];
764
+ }
765
+ function findRequiredInput(inputs, name) {
766
+ const input = findInput(inputs, name);
767
+ if (input === null) {
768
+ throw new Error(`Required input "${name}" not found.`);
769
+ }
770
+ return input;
771
+ }
772
+ function findInputs(inputs, names) {
773
+ return names.map((name) => findInput(inputs, name)).filter(Boolean);
774
+ }
775
+ function findRequiredInputs(inputs, names) {
776
+ return names.map((name) => findRequiredInput(inputs, name));
777
+ }
778
+ var HighstateSignature = /* @__PURE__ */ ((HighstateSignature2) => {
779
+ HighstateSignature2["Artifact"] = "d55c63ac-3174-4756-808f-f778e99af0d1";
780
+ HighstateSignature2["Yaml"] = "c857cac5-caa6-4421-b82c-e561fbce6367";
781
+ return HighstateSignature2;
782
+ })(HighstateSignature || {});
783
+ var yamlValueSchema = z.object({
784
+ ["c857cac5-caa6-4421-b82c-e561fbce6367" /* Yaml */]: z.literal(true),
785
+ value: z.string()
786
+ });
787
+ var fileMetaSchema = z.object({
788
+ name: z.string(),
789
+ contentType: z.string().optional(),
790
+ size: z.number().optional(),
791
+ mode: z.number().optional()
792
+ });
793
+ var unitArtifactSchema = z.object({
794
+ ["d55c63ac-3174-4756-808f-f778e99af0d1" /* Artifact */]: z.literal(true),
795
+ hash: z.string(),
796
+ meta: commonObjectMetaSchema.optional()
797
+ });
798
+ var fileContentSchema = z.union([
799
+ z.object({
800
+ type: z.literal("embedded"),
801
+ /**
802
+ * Whether the content is binary or not.
803
+ *
804
+ * If true, the `value` will be a base64 encoded string.
805
+ */
806
+ isBinary: z.boolean().optional(),
807
+ /**
808
+ * The content of the file.
809
+ *
810
+ * If `isBinary` is true, this will be a base64 encoded string.
811
+ */
812
+ value: z.string()
813
+ }),
814
+ z.object({
815
+ type: z.literal("artifact"),
816
+ ...unitArtifactSchema.shape
817
+ })
818
+ ]);
819
+ var fileSchema = z.object({
820
+ meta: fileMetaSchema,
821
+ content: fileContentSchema
822
+ });
823
+ var WellKnownInstanceCustomStatus = /* @__PURE__ */ ((WellKnownInstanceCustomStatus2) => {
824
+ WellKnownInstanceCustomStatus2["Healthy"] = "healthy";
825
+ WellKnownInstanceCustomStatus2["Degraded"] = "degraded";
826
+ WellKnownInstanceCustomStatus2["Down"] = "down";
827
+ WellKnownInstanceCustomStatus2["Warning"] = "warning";
828
+ WellKnownInstanceCustomStatus2["Progressing"] = "progressing";
829
+ WellKnownInstanceCustomStatus2["Error"] = "error";
830
+ return WellKnownInstanceCustomStatus2;
831
+ })(WellKnownInstanceCustomStatus || {});
832
+ var instanceStatusFieldValueSchema = z.union([
833
+ z.string(),
834
+ z.number(),
835
+ z.boolean(),
836
+ z.string().array()
837
+ ]);
838
+ var instanceStatusFieldSchema = z.object({
839
+ name: z.string(),
840
+ meta: objectMetaSchema.pick({
841
+ title: true,
842
+ icon: true,
843
+ iconColor: true
844
+ }).required({ title: true }),
845
+ complementaryTo: z.string().optional(),
846
+ value: instanceStatusFieldValueSchema.optional()
847
+ });
848
+ var componentSecretSchema = componentArgumentSchema.extend({
699
849
  /**
700
850
  * The secret cannot be modified by the user, but can be modified by the unit.
701
851
  */
@@ -705,12 +855,38 @@ var componentSecretSchema = componentArgumentSchema.extend({
705
855
  */
706
856
  computed: z5.boolean()
707
857
  });
858
+ var unitSourceSchema = z5.object({
859
+ /**
860
+ * The package where the unit implementation is located.
861
+ *
862
+ * May be both: local monorepo package or a remote NPM package.
863
+ */
864
+ package: z5.string(),
865
+ /**
866
+ * The path to the unit implementation within the package.
867
+ *
868
+ * If not provided, the root of the package is assumed.
869
+ */
870
+ path: z5.string().optional()
871
+ });
872
+ var unitModelSchema = z5.object({
873
+ ...componentModelSchema.shape,
874
+ /**
875
+ * The source of the unit.
876
+ */
877
+ source: unitSourceSchema,
878
+ /**
879
+ * The record of the secret specs.
880
+ */
881
+ secrets: z5.record(z5.string(), componentSecretSchema)
882
+ });
708
883
  function defineUnit(options) {
709
884
  if (!options.source) {
710
885
  throw new Error("Unit source is required");
711
886
  }
712
887
  const component = defineComponent({
713
888
  ...options,
889
+ [kind]: "unit",
714
890
  create({ id }) {
715
891
  const outputs = {};
716
892
  for (const key in options.outputs ?? {}) {
@@ -724,12 +900,16 @@ function defineUnit(options) {
724
900
  return outputs;
725
901
  }
726
902
  });
727
- component.model.source = options.source ?? {};
728
- component.model.secrets = mapValues(options.secrets ?? {}, mapSecret);
903
+ try {
904
+ component.model.source = options.source ?? {};
905
+ component.model.secrets = mapValues(options.secrets ?? {}, mapSecret);
906
+ } catch (error) {
907
+ throw new Error(`Failed to map secrets for unit "${options.type}"`, { cause: error });
908
+ }
729
909
  return component;
730
910
  }
731
- function $secrets(secrets) {
732
- return secrets;
911
+ function $secrets(secrets2) {
912
+ return toFullComponentArgumentOptions(secrets2);
733
913
  }
734
914
  function mapSecret(value, key) {
735
915
  if ("schema" in value) {
@@ -745,7 +925,209 @@ function mapSecret(value, key) {
745
925
  computed: false
746
926
  };
747
927
  }
928
+ function isUnitModel(model) {
929
+ return "source" in model;
930
+ }
931
+ var terminalSpecSchema = z.object({
932
+ /**
933
+ * The Docker image to run the terminal.
934
+ */
935
+ image: z.string(),
936
+ /**
937
+ * The command to run in the terminal.
938
+ */
939
+ command: z.string().array(),
940
+ /**
941
+ * The working directory to run the command in.
942
+ */
943
+ cwd: z.string().optional(),
944
+ /**
945
+ * The environment variables to set in the terminal.
946
+ */
947
+ env: z.record(z.string(), z.string()).optional(),
948
+ /**
949
+ * The files to mount in the terminal.
950
+ *
951
+ * The key is the path where the file will be mounted,
952
+ * and the value is the file content or a reference to an artifact.
953
+ */
954
+ files: z.record(z.string(), fileSchema).optional()
955
+ });
956
+ var unitTerminalSchema = z.object({
957
+ name: z.string(),
958
+ meta: objectMetaSchema.pick({
959
+ title: true,
960
+ globalTitle: true,
961
+ description: true,
962
+ icon: true,
963
+ iconColor: true
964
+ }).required({ title: true }),
965
+ spec: terminalSpecSchema
966
+ });
967
+ var pageBlockSchema = z.union([
968
+ z.object({
969
+ type: z.literal("markdown"),
970
+ content: z.string()
971
+ }),
972
+ z.object({
973
+ type: z.literal("qr"),
974
+ content: z.string(),
975
+ showContent: z.coerce.boolean(),
976
+ language: z.string().optional()
977
+ }),
978
+ z.object({
979
+ type: z.literal("file"),
980
+ file: fileSchema
981
+ })
982
+ ]);
983
+ var unitPageSchema = z.object({
984
+ name: z.string(),
985
+ meta: objectMetaSchema.pick({
986
+ title: true,
987
+ globalTitle: true,
988
+ description: true,
989
+ icon: true,
990
+ iconColor: true
991
+ }).required({ title: true }),
992
+ content: pageBlockSchema.array()
993
+ });
994
+ var triggerSpecSchema = z.union([
995
+ z.object({
996
+ type: z.literal("before-destroy")
997
+ })
998
+ ]);
999
+ var unitTriggerSchema = z.object({
1000
+ name: z.string(),
1001
+ meta: objectMetaSchema.pick({
1002
+ title: true,
1003
+ globalTitle: true,
1004
+ description: true,
1005
+ icon: true,
1006
+ iconColor: true
1007
+ }).required({ title: true }),
1008
+ /**
1009
+ * The specification of the trigger.
1010
+ *
1011
+ * Defines the type of trigger and its behavior.
1012
+ */
1013
+ spec: triggerSpecSchema
1014
+ });
1015
+ var triggerInvocationSchema = z.object({
1016
+ /**
1017
+ * The name of the trigger being invoked.
1018
+ */
1019
+ name: z.string()
1020
+ });
1021
+ var unitWorkerSchema = z.object({
1022
+ name: z.string(),
1023
+ image: z.string(),
1024
+ params: z.record(z.string(), z.unknown())
1025
+ });
1026
+ var workerRunOptionsSchema = z.object({
1027
+ /**
1028
+ * The ID of the project for which the worker is running.
1029
+ */
1030
+ projectId: z.cuid2(),
1031
+ /**
1032
+ * The ID of the worker version.
1033
+ */
1034
+ workerVersionId: z.cuid2(),
1035
+ /**
1036
+ * The URL of the backend API to connect to.
1037
+ */
1038
+ apiUrl: z.url(),
1039
+ /**
1040
+ * The API key used to authenticate the worker with the backend.
1041
+ */
1042
+ apiKey: z.string()
1043
+ });
1044
+ function text(strings, ...values) {
1045
+ const stringValues = values.map(String);
1046
+ let result = "";
1047
+ for (let i = 0; i < strings.length; i++) {
1048
+ result += strings[i];
1049
+ if (i < stringValues.length) {
1050
+ const value = stringValues[i];
1051
+ const lines = value.split("\n");
1052
+ const lastLineIndentMatch = strings[i].match(/(?:^|\n)([ \t]*)$/);
1053
+ const indent = lastLineIndentMatch ? lastLineIndentMatch[1] : "";
1054
+ result += lines.map((line, j) => j === 0 ? line : indent + line).join("\n");
1055
+ }
1056
+ }
1057
+ return trimIndentation(result);
1058
+ }
1059
+ function trimIndentation(text2) {
1060
+ const lines = text2.split("\n");
1061
+ const indent = lines.filter((line) => line.trim() !== "").map((line) => line.match(/^\s*/)?.[0].length ?? 0).reduce((min, indent2) => Math.min(min, indent2), Infinity);
1062
+ return lines.map((line) => line.slice(indent)).join("\n").trim();
1063
+ }
1064
+ function bytesToHumanReadable(bytes) {
1065
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
1066
+ if (bytes === 0) return "0 Bytes";
1067
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
1068
+ return `${parseFloat((bytes / 1024 ** i).toFixed(2))} ${sizes[i]}`;
1069
+ }
1070
+ function check(schema, value) {
1071
+ return schema.safeParse(value).success;
1072
+ }
1073
+ function getOrCreate(map, key, createFn) {
1074
+ const existing = map.get(key);
1075
+ if (existing !== void 0) {
1076
+ return existing;
1077
+ }
1078
+ const value = createFn(key);
1079
+ map.set(key, value);
1080
+ return value;
1081
+ }
1082
+ function stripNullish(obj) {
1083
+ return pickBy(obj, isNonNullish);
1084
+ }
1085
+ var unitConfigSchema = z.object({
1086
+ /**
1087
+ * The ID of the instance.
1088
+ */
1089
+ instanceId: z.string(),
1090
+ /**
1091
+ * The record of argument values for the unit.
1092
+ */
1093
+ args: z.record(z.string(), z.unknown()),
1094
+ /**
1095
+ * The record of input references for the unit.
1096
+ */
1097
+ inputs: z.record(z.string(), instanceInputSchema.array()),
1098
+ /**
1099
+ * The list of triggers that have been invoked for this unit.
1100
+ */
1101
+ invokedTriggers: triggerInvocationSchema.array(),
1102
+ /**
1103
+ * The list of secret names that exists and provided to the unit.
1104
+ */
1105
+ secretNames: z.string().array(),
1106
+ /**
1107
+ * The map of instance ID to state ID in order to resolve instance references.
1108
+ */
1109
+ stateIdMap: z.record(instanceIdSchema, z.string())
1110
+ });
1111
+ var yamlResultCache = /* @__PURE__ */ new WeakMap();
1112
+ function parseArgumentValue(value) {
1113
+ const yamlResult = yamlValueSchema.safeParse(value);
1114
+ if (!yamlResult.success) {
1115
+ return value;
1116
+ }
1117
+ const existingResult = yamlResultCache.get(value);
1118
+ if (existingResult !== void 0) {
1119
+ return existingResult;
1120
+ }
1121
+ const result = parse(yamlResult.data.value);
1122
+ yamlResultCache.set(value, result);
1123
+ return result;
1124
+ }
1125
+ var HighstateConfigKey = /* @__PURE__ */ ((HighstateConfigKey2) => {
1126
+ HighstateConfigKey2["Config"] = "highstate";
1127
+ HighstateConfigKey2["Secrets"] = "highstate.secrets";
1128
+ return HighstateConfigKey2;
1129
+ })(HighstateConfigKey || {});
748
1130
 
749
- export { $args, $inputs, $outputs, $secrets, HighstateSignature, InstanceNameConflictError, bytesToHumanReadable, camelCaseToHumanReadable, componentArgumentSchema, componentInputSchema, componentModelSchema, componentSecretSchema, defineComponent, defineEntity, defineUnit, entityModelSchema, fieldNameSchema, fileContentSchema, fileMetaSchema, fileSchema, findInput, findInputs, findRequiredInput, findRequiredInputs, genericNameSchema, getInstanceId, getRuntimeInstances, hubInputSchema, hubModelPatchSchema, hubModelSchema, instanceIdSchema, instanceInputSchema, instanceModelPatchSchema, instanceModelSchema, isComponent, isEntity, isUnitModel, objectMetaSchema, originalCreate, parseInstanceId, positionSchema, registerKnownAbbreviations, resetEvaluation, setValidationEnabled, text, trimIndentation, unitArtifactSchema, unitObjectMetaSchema, unitSecretSchema, userObjectMetaSchema, yamlValueSchema };
1131
+ export { $addArgumentDescription, $addInputDescription, $args, $inputs, $outputs, $secrets, HighstateConfigKey, HighstateSignature, InstanceNameConflictError, WellKnownInstanceCustomStatus, bytesToHumanReadable, camelCaseToHumanReadable, check, clearKnownAbbreviations, commonObjectMetaSchema, componentArgumentSchema, componentInputSchema, componentModelSchema, componentSecretSchema, defineComponent, defineEntity, defineUnit, entityModelSchema, fieldNameSchema, fileContentSchema, fileMetaSchema, fileSchema, findInput, findInputs, findRequiredInput, findRequiredInputs, genericNameSchema, getInstanceId, getOrCreate, getRuntimeInstances, globalCommonObjectMetaSchema, hubInputSchema, hubModelPatchSchema, hubModelSchema, inputKey, instanceIdSchema, instanceInputSchema, instanceModelPatchSchema, instanceModelSchema, instanceStatusFieldSchema, instanceStatusFieldValueSchema, isComponent, isEntity, isUnitModel, objectMetaSchema, originalCreate, pageBlockSchema, parseArgumentValue, parseInstanceId, parseVersionedName, positionSchema, registerKnownAbbreviations, resetEvaluation, runtimeSchema, serviceAccountMetaSchema, setValidationEnabled, stripNullish, terminalSpecSchema, text, timestampsSchema, triggerInvocationSchema, triggerSpecSchema, trimIndentation, unitArtifactSchema, unitConfigSchema, unitModelSchema, unitPageSchema, unitSourceSchema, unitTerminalSchema, unitTriggerSchema, unitWorkerSchema, versionedNameSchema, workerRunOptionsSchema, yamlValueSchema };
750
1132
  //# sourceMappingURL=index.js.map
751
1133
  //# sourceMappingURL=index.js.map