@highstate/contract 0.19.1 → 0.21.1

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,12 +1,43 @@
1
- import { z } from 'zod';
2
- export { z } from 'zod';
3
- import { mapValues, pickBy, isNonNullish, uniqueBy } from 'remeda';
4
- import { parse } from 'yaml';
5
-
1
+ // @bun
6
2
  // src/entity.ts
3
+ import { z as z2 } from "zod";
4
+
5
+ // src/cuidv2d.ts
6
+ import { sha256 } from "@noble/hashes/sha2.js";
7
+ var cuidv2DefaultLength = 24;
8
+ function bufToBigInt(buf) {
9
+ const bits = 8n;
10
+ let value = 0n;
11
+ for (const byte of buf.values()) {
12
+ value = (value << bits) + BigInt(byte);
13
+ }
14
+ return value;
15
+ }
16
+ function hashCuid2(input) {
17
+ const bytes = new TextEncoder().encode(input);
18
+ const digest = sha256(bytes);
19
+ return bufToBigInt(digest).toString(36).slice(1);
20
+ }
21
+ function normalizeCuid2Prefix(prefix) {
22
+ if (prefix >= "a" && prefix <= "z") {
23
+ return prefix;
24
+ }
25
+ if (prefix >= "0" && prefix <= "9") {
26
+ const digit = prefix.charCodeAt(0) - 48;
27
+ return String.fromCharCode(97 + digit);
28
+ }
29
+ throw new Error(`Invalid CUID prefix character: ${prefix}`);
30
+ }
31
+ function cuidv2d(namespace, identity) {
32
+ const hashInput = `${namespace}:${identity}`;
33
+ const hashed = hashCuid2(hashInput);
34
+ const raw = hashed.slice(0, cuidv2DefaultLength);
35
+ const prefix = normalizeCuid2Prefix(raw[0]);
36
+ return `${prefix}${raw.slice(1)}`;
37
+ }
7
38
 
8
39
  // src/i18n.ts
9
- var knownAbbreviationsMap = /* @__PURE__ */ new Map();
40
+ var knownAbbreviationsMap = new Map;
10
41
  function registerKnownAbbreviations(abbreviations) {
11
42
  for (const abbr of abbreviations) {
12
43
  const lower = abbr.toLowerCase();
@@ -18,8 +49,8 @@ function registerKnownAbbreviations(abbreviations) {
18
49
  function clearKnownAbbreviations() {
19
50
  knownAbbreviationsMap.clear();
20
51
  }
21
- function camelCaseToHumanReadable(text2) {
22
- const words = text2.split(/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|_|-|\./).filter((word) => word.length > 0);
52
+ function camelCaseToHumanReadable(text) {
53
+ const words = text.split(/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|_|-|\./).filter((word) => word.length > 0);
23
54
  return words.map((word) => {
24
55
  const lower = word.toLowerCase();
25
56
  if (knownAbbreviationsMap.has(lower)) {
@@ -28,58 +59,106 @@ function camelCaseToHumanReadable(text2) {
28
59
  return word.charAt(0).toUpperCase() + word.slice(1);
29
60
  }).join(" ");
30
61
  }
62
+
63
+ // src/json-schema.ts
64
+ function isRecord(value) {
65
+ return typeof value === "object" && value !== null && !Array.isArray(value);
66
+ }
67
+ function fixJsonSchema(schema) {
68
+ if (!isRecord(schema)) {
69
+ return schema;
70
+ }
71
+ const allOf = schema.allOf;
72
+ if (Array.isArray(allOf) && allOf.length > 0) {
73
+ const objectSchemas = [];
74
+ const otherSchemas = [];
75
+ for (const item of allOf) {
76
+ if (isRecord(item) && item.type === "object") {
77
+ objectSchemas.push(item);
78
+ continue;
79
+ }
80
+ otherSchemas.push(item);
81
+ }
82
+ if (objectSchemas.length > 1) {
83
+ const required = new Set;
84
+ const properties = {};
85
+ let additionalProperties;
86
+ for (const objectSchema of objectSchemas) {
87
+ const objectRequired = objectSchema.required;
88
+ if (Array.isArray(objectRequired)) {
89
+ for (const key of objectRequired) {
90
+ if (typeof key === "string") {
91
+ required.add(key);
92
+ }
93
+ }
94
+ }
95
+ const objectProperties = objectSchema.properties;
96
+ if (isRecord(objectProperties)) {
97
+ for (const [key, value] of Object.entries(objectProperties)) {
98
+ const existing = properties[key];
99
+ if (existing === undefined) {
100
+ properties[key] = value;
101
+ continue;
102
+ }
103
+ properties[key] = { allOf: [existing, value] };
104
+ }
105
+ }
106
+ if ("additionalProperties" in objectSchema) {
107
+ if (additionalProperties === undefined) {
108
+ additionalProperties = objectSchema.additionalProperties;
109
+ } else if (additionalProperties !== objectSchema.additionalProperties) {
110
+ additionalProperties = false;
111
+ }
112
+ }
113
+ }
114
+ const mergedObjectSchema = {
115
+ type: "object",
116
+ properties,
117
+ ...required.size > 0 ? { required: Array.from(required) } : {},
118
+ ...additionalProperties !== undefined ? { additionalProperties } : { additionalProperties: false }
119
+ };
120
+ const merged = otherSchemas.length === 0 ? mergedObjectSchema : {
121
+ ...schema,
122
+ allOf: [mergedObjectSchema, ...otherSchemas]
123
+ };
124
+ return fixJsonSchema(merged);
125
+ }
126
+ }
127
+ const next = { ...schema };
128
+ if (Array.isArray(next.allOf)) {
129
+ next.allOf = next.allOf.map(fixJsonSchema);
130
+ }
131
+ if (Array.isArray(next.anyOf)) {
132
+ next.anyOf = next.anyOf.map(fixJsonSchema);
133
+ }
134
+ if (Array.isArray(next.oneOf)) {
135
+ next.oneOf = next.oneOf.map(fixJsonSchema);
136
+ }
137
+ if (isRecord(next.properties)) {
138
+ next.properties = Object.fromEntries(Object.entries(next.properties).map(([key, value]) => [key, fixJsonSchema(value)]));
139
+ }
140
+ if (isRecord(next.items)) {
141
+ next.items = fixJsonSchema(next.items);
142
+ } else if (Array.isArray(next.items)) {
143
+ next.items = next.items.map(fixJsonSchema);
144
+ }
145
+ if (isRecord(next.additionalProperties)) {
146
+ next.additionalProperties = fixJsonSchema(next.additionalProperties);
147
+ }
148
+ return next;
149
+ }
150
+
151
+ // src/meta.ts
152
+ import { z } from "zod";
31
153
  var objectMetaSchema = z.object({
32
- /**
33
- * Human-readable name of the object.
34
- *
35
- * Used in UI components for better user experience.
36
- */
37
154
  title: z.string().optional(),
38
- /**
39
- * The title used globally for the object.
40
- *
41
- * For example, the title of an instance secret is "Password" which is okay
42
- * to display in the instance secret list, but when the secret is displayed in a
43
- * global secret list the name should be more descriptive, like "Proxmox Password".
44
- */
45
155
  globalTitle: z.string().optional(),
46
- /**
47
- * Description of the object.
48
- *
49
- * Provides additional context for users and developers.
50
- */
51
156
  description: z.string().optional(),
52
- /**
53
- * The color of the object.
54
- *
55
- * Used in UI components to visually distinguish objects.
56
- */
57
157
  color: z.string().optional(),
58
- /**
59
- * Primary icon identifier.
60
- *
61
- * Should reference a iconify icon name, like "mdi:server" or "gg:remote".
62
- */
63
158
  icon: z.string().optional(),
64
- /**
65
- * The color of the primary icon.
66
- */
67
159
  iconColor: z.string().optional(),
68
- /**
69
- * The URL of the custom image that should be used as the icon or avatar.
70
- */
71
160
  avatarUrl: z.string().optional(),
72
- /**
73
- * The secondary icon identifier.
74
- *
75
- * Used to provide additional context or actions related to the object.
76
- *
77
- * Should reference a iconify icon name, like "mdi:edit" or "mdi:delete".
78
- */
79
161
  secondaryIcon: z.string().optional(),
80
- /**
81
- * The color of the secondary icon.
82
- */
83
162
  secondaryIconColor: z.string().optional()
84
163
  });
85
164
  var commonObjectMetaSchema = objectMetaSchema.pick({
@@ -107,24 +186,12 @@ var serviceAccountMetaSchema = objectMetaSchema.pick({
107
186
  iconColor: true
108
187
  }).required({ title: true });
109
188
  var timestampsSchema = z.object({
110
- /**
111
- * The timestamp when the object was created.
112
- */
113
189
  createdAt: z.date(),
114
- /**
115
- * The timestamp when the object was last updated.
116
- */
117
190
  updatedAt: z.date()
118
191
  });
119
- var genericNameSchema = z.string().regex(
120
- /^[a-z][a-z0-9-.]+$/,
121
- "Name must start with a letter and can only contain lowercase letters, numbers, dashes (-) and dots (.)"
122
- ).min(2).max(64);
192
+ var genericNameSchema = z.string().regex(/^[a-z][a-z0-9-.]+$/, "Name must start with a letter and can only contain lowercase letters, numbers, dashes (-) and dots (.)").min(2).max(64);
123
193
  var versionedNameSchema = z.union([
124
194
  z.templateLiteral([genericNameSchema, z.literal("."), z.literal("v"), z.number().int().min(1)]),
125
- // to prevent TypeScript matching "proxmox.virtual-machine.v2" as
126
- // 1. "proxmox.v"
127
- // 2. "irtual-machine.v2" and thinking it should be a number
128
195
  z.templateLiteral([
129
196
  genericNameSchema,
130
197
  z.literal("."),
@@ -160,53 +227,19 @@ function parseVersionedName(name) {
160
227
  var fieldNameSchema = z.string().regex(/^[a-z][a-zA-Z0-9]+$/, "Field name must start with a letter and be in camelCase format").min(2).max(64);
161
228
 
162
229
  // src/entity.ts
163
- var entityInclusionSchema = z.object({
164
- /**
165
- * The static type of the included entity.
166
- */
230
+ var entityInclusionSchema = z2.object({
167
231
  type: versionedNameSchema,
168
- /**
169
- * Whether the included entity is required.
170
- * If false, the entity may be omitted.
171
- */
172
- required: z.boolean(),
173
- /**
174
- * Whether the included entity is multiple.
175
- */
176
- multiple: z.boolean(),
177
- /**
178
- * The name of the field where the included entity is embedded.
179
- */
180
- field: z.string()
232
+ required: z2.boolean(),
233
+ multiple: z2.boolean(),
234
+ field: z2.string()
181
235
  });
182
- var entityModelSchema = z.object({
183
- /**
184
- * The static type of the entity.
185
- */
236
+ var entityModelSchema = z2.object({
186
237
  type: versionedNameSchema,
187
- /**
188
- * The list of all extended entity types (direct and indirect).
189
- */
190
- extensions: z.string().array().optional(),
191
- /**
192
- * The list of directly extended entity types.
193
- */
194
- directExtensions: z.string().array().optional(),
195
- /**
196
- * The list of all included entities (directly or inherited from extensions).
197
- */
238
+ extensions: z2.string().array().optional(),
239
+ directExtensions: z2.string().array().optional(),
198
240
  inclusions: entityInclusionSchema.array().optional(),
199
- /**
200
- * The list of directly included entities.
201
- */
202
241
  directInclusions: entityInclusionSchema.array().optional(),
203
- /**
204
- * The JSON schema of the entity value.
205
- */
206
- schema: z.custom(),
207
- /**
208
- * The extra metadata of the entity.
209
- */
242
+ schema: z2.custom(),
210
243
  meta: objectMetaSchema.required({ title: true }).pick({
211
244
  title: true,
212
245
  description: true,
@@ -214,13 +247,14 @@ var entityModelSchema = z.object({
214
247
  icon: true,
215
248
  iconColor: true
216
249
  }),
217
- /**
218
- * The CRC32 of the entity definition.
219
- */
220
- definitionHash: z.number()
250
+ definitionHash: z2.number()
221
251
  });
222
252
  function isEntityIncludeRef(value) {
223
- return typeof value === "object" && value !== null && "entity" in value;
253
+ if (typeof value !== "object" || value === null || !("entity" in value)) {
254
+ return false;
255
+ }
256
+ const entity = value.entity;
257
+ return typeof entity === "function" || isEntity(entity);
224
258
  }
225
259
  function defineEntity(options) {
226
260
  try {
@@ -231,57 +265,54 @@ function defineEntity(options) {
231
265
  if (!options.schema) {
232
266
  throw new Error("Entity schema is required");
233
267
  }
234
- const includedEntities = Object.entries(options.includes ?? {}).map(([field, entityRef]) => {
268
+ const includeRefs = Object.entries(options.includes ?? {}).map(([field, entityRef]) => {
235
269
  if (isEntityIncludeRef(entityRef)) {
236
- return {
237
- entity: entityRef.entity,
238
- inclusion: {
239
- type: entityRef.entity.type,
240
- required: entityRef.required ?? true,
241
- multiple: entityRef.multiple ?? false,
242
- field
243
- }
244
- };
245
- }
246
- return {
247
- entity: entityRef,
248
- inclusion: {
249
- type: entityRef.type,
250
- required: true,
251
- multiple: false,
252
- field
253
- }
254
- };
255
- });
256
- const inclusionShape = includedEntities.reduce(
257
- (shape, { entity, inclusion }) => {
258
- if (inclusion.multiple) {
259
- shape[inclusion.field] = inclusion.required ? entity.schema.array() : entity.schema.array().optional();
270
+ const required = entityRef.required ?? true;
271
+ const multiple = entityRef.multiple ?? false;
272
+ let getEntity2;
273
+ if (typeof entityRef.entity === "function") {
274
+ const entity = entityRef.entity;
275
+ getEntity2 = entity;
260
276
  } else {
261
- shape[inclusion.field] = inclusion.required ? entity.schema : entity.schema.optional();
277
+ const entity = entityRef.entity;
278
+ getEntity2 = () => entity;
262
279
  }
263
- return shape;
264
- },
265
- {}
266
- );
267
- let finalSchema = Object.values(options.extends ?? {}).reduce(
268
- (schema, entity) => z.intersection(schema, entity.schema),
269
- options.schema
270
- );
271
- if (includedEntities.length > 0) {
272
- finalSchema = z.intersection(finalSchema, z.object(inclusionShape));
280
+ return { field, required, multiple, getEntity: getEntity2 };
281
+ }
282
+ const getEntity = () => entityRef;
283
+ return { field, required: true, multiple: false, getEntity };
284
+ });
285
+ const inclusionShape = includeRefs.reduce((shape, includeRef) => {
286
+ let schema = z2.lazy(() => includeRef.getEntity().schema);
287
+ if (includeRef.multiple) {
288
+ schema = includeRef.required ? schema.array().min(1) : schema.array().default([]);
289
+ } else {
290
+ schema = includeRef.required ? schema : schema.optional();
291
+ }
292
+ shape[includeRef.field] = schema;
293
+ return shape;
294
+ }, {});
295
+ let finalSchema = Object.values(options.extends ?? {}).reduce((schema, entity) => z2.intersection(schema, entity.schema), options.schema);
296
+ if (includeRefs.length > 0) {
297
+ finalSchema = z2.intersection(finalSchema, z2.object(inclusionShape));
273
298
  }
274
- const directInclusions = includedEntities.map(({ inclusion }) => inclusion);
299
+ finalSchema = z2.intersection(finalSchema, entityWithMetaSchema);
300
+ const directInclusions = () => includeRefs.map((includeRef) => ({
301
+ type: includeRef.getEntity().type,
302
+ required: includeRef.required,
303
+ multiple: includeRef.multiple,
304
+ field: includeRef.field
305
+ }));
275
306
  const directExtensions = Object.values(options.extends ?? {}).map((entity) => entity.type);
276
- const inclusions = Object.values(options.extends ?? {}).reduce(
277
- (incs, entity) => {
307
+ const getInclusions = () => {
308
+ const incs = [...directInclusions()];
309
+ for (const entity of Object.values(options.extends ?? {})) {
278
310
  if (entity.model.inclusions) {
279
311
  incs.push(...entity.model.inclusions);
280
312
  }
281
- return incs;
282
- },
283
- [...directInclusions]
284
- );
313
+ }
314
+ return incs;
315
+ };
285
316
  const extensions = Object.values(options.extends ?? {}).reduce((exts, entity) => {
286
317
  exts.push(...entity.model.extensions ?? [], entity.type);
287
318
  return exts;
@@ -293,13 +324,23 @@ function defineEntity(options) {
293
324
  schema: finalSchema,
294
325
  model: {
295
326
  type: options.type,
296
- extensions: extensions.length > 0 ? extensions : void 0,
297
- directExtensions: directExtensions.length > 0 ? directExtensions : void 0,
298
- inclusions: inclusions.length > 0 ? inclusions : void 0,
299
- directInclusions: directInclusions.length > 0 ? directInclusions : void 0,
327
+ extensions: extensions.length > 0 ? extensions : undefined,
328
+ directExtensions: directExtensions.length > 0 ? directExtensions : undefined,
329
+ get inclusions() {
330
+ const incs = getInclusions();
331
+ return incs.length > 0 ? incs : undefined;
332
+ },
333
+ get directInclusions() {
334
+ const incs = directInclusions();
335
+ return incs.length > 0 ? incs : undefined;
336
+ },
300
337
  get schema() {
301
338
  if (!_schema) {
302
- _schema = z.toJSONSchema(finalSchema, { target: "draft-7", unrepresentable: "any" });
339
+ const rawSchema = z2.toJSONSchema(finalSchema, {
340
+ target: "draft-7",
341
+ unrepresentable: "any"
342
+ });
343
+ _schema = fixJsonSchema(rawSchema);
303
344
  }
304
345
  return _schema;
305
346
  },
@@ -307,10 +348,8 @@ function defineEntity(options) {
307
348
  ...options.meta,
308
349
  title: options.meta?.title || camelCaseToHumanReadable(parseVersionedName(options.type)[0])
309
350
  },
310
- // will be calculated by the library loader
311
351
  definitionHash: null
312
352
  }
313
- // biome-ignore lint/suspicious/noExplicitAny: we already typed return type
314
353
  };
315
354
  } catch (error) {
316
355
  throw new Error(`Failed to define entity "${options.type}"`, { cause: error });
@@ -328,8 +367,315 @@ function isAssignableTo(entity, target) {
328
367
  }
329
368
  return entity.inclusions?.some((implementation) => implementation.type === target) ?? false;
330
369
  }
370
+ var entityMetaSchema = z2.object({
371
+ type: versionedNameSchema,
372
+ identity: z2.string(),
373
+ references: z2.record(z2.string(), z2.string().array()).optional(),
374
+ ...objectMetaSchema.pick({
375
+ title: true,
376
+ description: true,
377
+ icon: true,
378
+ iconColor: true
379
+ }).shape
380
+ });
381
+ var entityWithMetaSchema = z2.object({
382
+ $meta: entityMetaSchema
383
+ });
384
+ var entityIdCache = new WeakMap;
385
+ var entityIdNamespace = "3cd37048-7c50-43a9-a2b9-ff7ff2b5ee79";
386
+ function getEntityId(entity) {
387
+ if (!entity.$meta) {
388
+ throw new Error("Entity $meta is required to generate an entity id");
389
+ }
390
+ const existingId = entityIdCache.get(entity);
391
+ if (existingId) {
392
+ return existingId;
393
+ }
394
+ const { type, identity } = entity.$meta;
395
+ const id = cuidv2d(entityIdNamespace, `${type}:${identity}`);
396
+ entityIdCache.set(entity, id);
397
+ return id;
398
+ }
399
+ // src/instance.ts
400
+ import { z as z4 } from "zod";
401
+
402
+ // src/shared.ts
403
+ import { z as z3 } from "zod";
404
+ var componentKindSchema = z3.enum(["composite", "unit"]);
405
+ var runtimeSchema = Symbol("runtimeSchema");
406
+ var kind = Symbol("kind");
331
407
  var boundaryInput = Symbol("boundaryInput");
332
- var boundaryInputs = Symbol("boundaryInputs");
408
+ function inputKey(input) {
409
+ return input.path ? `${input.instanceId}:${input.output}:${input.path}` : `${input.instanceId}:${input.output}`;
410
+ }
411
+
412
+ // src/instance-input.ts
413
+ function appendInputPath(currentPath, segment) {
414
+ return currentPath ? `${currentPath}.${segment}` : segment;
415
+ }
416
+ function createRuntimeInputAccessor(input, boundary) {
417
+ const accessorCache = input.provided ? undefined : new Map;
418
+ let currentBoundary = boundary;
419
+ return new Proxy(input, {
420
+ get(target, property, receiver) {
421
+ const runtimeTarget = target;
422
+ if (property === boundaryInput) {
423
+ return currentBoundary;
424
+ }
425
+ if (typeof property !== "string") {
426
+ return Reflect.get(target, property, receiver);
427
+ }
428
+ if (property in target) {
429
+ return Reflect.get(target, property, receiver);
430
+ }
431
+ if (property === "instanceId" || property === "output" || property === "path") {
432
+ return Reflect.get(target, property, receiver);
433
+ }
434
+ if (runtimeTarget.provided) {
435
+ return Reflect.get(runtimeTarget, property, receiver);
436
+ }
437
+ const cached = accessorCache?.get(property);
438
+ if (cached) {
439
+ return cached;
440
+ }
441
+ const nested = createNonProvidedInput(boundary, appendInputPath(runtimeTarget.path, property));
442
+ accessorCache?.set(property, nested);
443
+ return nested;
444
+ },
445
+ set(target, property, value, receiver) {
446
+ if (property === boundaryInput) {
447
+ currentBoundary = value;
448
+ return true;
449
+ }
450
+ return Reflect.set(target, property, value, receiver);
451
+ }
452
+ });
453
+ }
454
+ function createInput(input, options = {}) {
455
+ if (!("provided" in input)) {
456
+ const boundary2 = options.boundary ?? input;
457
+ const normalizedInput = {
458
+ provided: true,
459
+ instanceId: input.instanceId,
460
+ output: input.output,
461
+ ...input.path ? { path: input.path } : {},
462
+ [boundaryInput]: boundary2
463
+ };
464
+ return createRuntimeInputAccessor(normalizedInput, boundary2);
465
+ }
466
+ if (!input.provided) {
467
+ const boundary2 = options.boundary ?? input[boundaryInput];
468
+ if (!boundary2) {
469
+ throw new Error("Cannot create non-provided input without boundary metadata");
470
+ }
471
+ return createNonProvidedInput(boundary2, input.path);
472
+ }
473
+ const boundary = options.boundary ?? input[boundaryInput];
474
+ if (!boundary) {
475
+ throw new Error("Cannot create provided input without boundary metadata");
476
+ }
477
+ return createRuntimeInputAccessor(input, boundary);
478
+ }
479
+ function createNonProvidedInput(boundary, path) {
480
+ const target = {
481
+ provided: false,
482
+ ...path ? { path } : {},
483
+ [boundaryInput]: boundary
484
+ };
485
+ return createRuntimeInputAccessor(target, boundary);
486
+ }
487
+ function createMultipleInputAccessor(inputs, boundary) {
488
+ const arrayInputs = [...inputs];
489
+ arrayInputs[boundaryInput] = boundary;
490
+ return new Proxy(arrayInputs, {
491
+ get(target, property, receiver) {
492
+ if (typeof property !== "string") {
493
+ return Reflect.get(target, property, receiver);
494
+ }
495
+ if (property === "length" || property === "map" || property === "filter" || property === "path" || property in target) {
496
+ return Reflect.get(target, property, receiver);
497
+ }
498
+ const unfolded = target.flatMap((input) => {
499
+ if (!input.provided) {
500
+ return [];
501
+ }
502
+ const selected = input[property];
503
+ if (selected === undefined || selected === null) {
504
+ return [];
505
+ }
506
+ if (Array.isArray(selected)) {
507
+ return selected;
508
+ }
509
+ return [selected];
510
+ });
511
+ return createMultipleInputAccessor(unfolded, boundary);
512
+ }
513
+ });
514
+ }
515
+ function createDeepOutputAccessor(output) {
516
+ const normalizedOutput = createInput(output);
517
+ if (!normalizedOutput.provided) {
518
+ return normalizedOutput;
519
+ }
520
+ const accessorCache = new Map;
521
+ return new Proxy(normalizedOutput, {
522
+ get(target, property, receiver) {
523
+ if (typeof property !== "string") {
524
+ return Reflect.get(target, property, receiver);
525
+ }
526
+ if (property === "provided" || property === "instanceId" || property === "output" || property === "path") {
527
+ return Reflect.get(target, property, receiver);
528
+ }
529
+ if (property in target) {
530
+ return Reflect.get(target, property, receiver);
531
+ }
532
+ const cached = accessorCache.get(property);
533
+ if (cached !== undefined) {
534
+ return cached;
535
+ }
536
+ const providedTarget = target;
537
+ const nextInput = createInput({
538
+ ...providedTarget,
539
+ path: appendInputPath(providedTarget.path, property)
540
+ }, { boundary: providedTarget[boundaryInput] });
541
+ const resolved = createDeepOutputAccessor(nextInput);
542
+ accessorCache.set(property, resolved);
543
+ return resolved;
544
+ }
545
+ });
546
+ }
547
+
548
+ // src/instance.ts
549
+ var positionSchema = z4.object({
550
+ x: z4.number(),
551
+ y: z4.number()
552
+ });
553
+ var instanceIdSchema = z4.templateLiteral([versionedNameSchema, ":", genericNameSchema]);
554
+ var instanceInputSchema = z4.object({
555
+ instanceId: instanceIdSchema,
556
+ output: z4.string(),
557
+ path: z4.string().optional()
558
+ });
559
+ var hubInputSchema = z4.object({
560
+ hubId: z4.string()
561
+ });
562
+ var instanceModelPatchSchema = z4.object({
563
+ args: z4.record(z4.string(), z4.unknown()).optional(),
564
+ inputs: z4.record(z4.string(), z4.array(instanceInputSchema)).optional(),
565
+ hubInputs: z4.record(z4.string(), z4.array(hubInputSchema)).optional(),
566
+ injectionInputs: z4.array(hubInputSchema).optional(),
567
+ position: positionSchema.optional()
568
+ });
569
+ var instanceModelSchema = z4.object({
570
+ id: instanceIdSchema,
571
+ kind: componentKindSchema,
572
+ type: versionedNameSchema,
573
+ name: genericNameSchema,
574
+ ...instanceModelPatchSchema.shape,
575
+ resolvedInputs: z4.record(z4.string(), z4.array(instanceInputSchema)).optional(),
576
+ parentId: instanceIdSchema.optional(),
577
+ outputs: z4.record(z4.string(), z4.array(instanceInputSchema)).optional(),
578
+ resolvedOutputs: z4.record(z4.string(), z4.array(instanceInputSchema)).optional()
579
+ });
580
+ var hubModelPatchSchema = z4.object({
581
+ position: positionSchema.optional(),
582
+ inputs: z4.array(instanceInputSchema).optional(),
583
+ injectionInputs: z4.array(hubInputSchema).optional()
584
+ });
585
+ var hubModelSchema = z4.object({
586
+ id: z4.cuid2(),
587
+ ...hubModelPatchSchema.shape
588
+ });
589
+ function parseInstanceId(instanceId) {
590
+ const parts = instanceId.split(":");
591
+ if (parts.length !== 2) {
592
+ throw new Error(`Invalid instance ID: ${instanceId}`);
593
+ }
594
+ return parts;
595
+ }
596
+ function selectInput(inputs, name) {
597
+ const groupBoundary = inputs[boundaryInput] ?? inputs[0]?.[boundaryInput];
598
+ if (inputs.length === 0 && !groupBoundary) {
599
+ throw new Error(`Cannot select input "${name}": empty input group has no boundary metadata to build a missing input reference.`);
600
+ }
601
+ const input = inputs.find((input2) => input2.provided && (input2.instanceId === name || parseInstanceId(input2.instanceId)[1] === name));
602
+ if (!input || !input.provided) {
603
+ const fallbackBoundary = groupBoundary ?? inputs.find((input2) => Boolean(input2[boundaryInput]))?.[boundaryInput] ?? inputs[0]?.[boundaryInput];
604
+ if (!fallbackBoundary) {
605
+ throw new Error(`Cannot select input "${name}": input group has no boundary metadata to build a missing input reference.`);
606
+ }
607
+ return createNonProvidedInput(fallbackBoundary);
608
+ }
609
+ const boundary = groupBoundary ?? input[boundaryInput];
610
+ return createInput(input, { boundary });
611
+ }
612
+ var HighstateSignature;
613
+ ((HighstateSignature2) => {
614
+ HighstateSignature2["Artifact"] = "d55c63ac-3174-4756-808f-f778e99af0d1";
615
+ HighstateSignature2["Yaml"] = "c857cac5-caa6-4421-b82c-e561fbce6367";
616
+ HighstateSignature2["Secret"] = "240e5789-6ae4-4b22-b9d8-87169e8b4bab";
617
+ })(HighstateSignature ||= {});
618
+ var yamlValueSchema = z4.object({
619
+ ["c857cac5-caa6-4421-b82c-e561fbce6367" /* Yaml */]: z4.literal(true),
620
+ value: z4.string()
621
+ });
622
+ var fileMetaSchema = z4.object({
623
+ name: z4.string(),
624
+ contentType: z4.string().optional(),
625
+ size: z4.number().optional(),
626
+ mode: z4.number().optional()
627
+ });
628
+ var WellKnownInstanceCustomStatus;
629
+ ((WellKnownInstanceCustomStatus2) => {
630
+ WellKnownInstanceCustomStatus2["Healthy"] = "healthy";
631
+ WellKnownInstanceCustomStatus2["Degraded"] = "degraded";
632
+ WellKnownInstanceCustomStatus2["Down"] = "down";
633
+ WellKnownInstanceCustomStatus2["Warning"] = "warning";
634
+ WellKnownInstanceCustomStatus2["Progressing"] = "progressing";
635
+ WellKnownInstanceCustomStatus2["Error"] = "error";
636
+ })(WellKnownInstanceCustomStatus ||= {});
637
+ var instanceStatusFieldValueSchema = z4.union([
638
+ z4.string(),
639
+ z4.number(),
640
+ z4.boolean(),
641
+ z4.string().array()
642
+ ]);
643
+ var instanceStatusFieldSchema = z4.object({
644
+ name: z4.string(),
645
+ meta: objectMetaSchema.pick({
646
+ title: true,
647
+ icon: true,
648
+ iconColor: true
649
+ }).required({ title: true }),
650
+ complementaryTo: z4.string().optional(),
651
+ value: instanceStatusFieldValueSchema.optional()
652
+ });
653
+ function secretSchema(schema) {
654
+ const secretType = z4.object({
655
+ ["240e5789-6ae4-4b22-b9d8-87169e8b4bab" /* Secret */]: z4.literal(true),
656
+ value: schema
657
+ });
658
+ return z4.codec(z4.union([secretType, schema]), secretType, {
659
+ decode: (value) => typeof value === "object" && value !== null && ("240e5789-6ae4-4b22-b9d8-87169e8b4bab" /* Secret */ in value) ? value : { ["240e5789-6ae4-4b22-b9d8-87169e8b4bab" /* Secret */]: true, value },
660
+ encode: (value) => value
661
+ });
662
+ }
663
+ function isSecret(value) {
664
+ return typeof value === "object" && value !== null && "240e5789-6ae4-4b22-b9d8-87169e8b4bab" /* Secret */ in value;
665
+ }
666
+ // src/unit.ts
667
+ import { mapValues as mapValues3 } from "remeda";
668
+ import { z as z6 } from "zod";
669
+
670
+ // src/component.ts
671
+ import { isNonNullish, mapValues as mapValues2, pickBy, uniqueBy } from "remeda";
672
+ import { z as z5 } from "zod";
673
+
674
+ // src/evaluation.ts
675
+ import { mapValues } from "remeda";
676
+ function isStableInstanceInput(value) {
677
+ return typeof value === "object" && value !== null && "instanceId" in value && "output" in value && typeof value.instanceId === "string" && typeof value.output === "string";
678
+ }
333
679
  function formatInstancePath(instance) {
334
680
  let result = instance.id;
335
681
  while (instance.parentId) {
@@ -342,21 +688,23 @@ function formatInstancePath(instance) {
342
688
  }
343
689
  return result;
344
690
  }
345
- var InstanceNameConflictError = class extends Error {
691
+
692
+ class InstanceNameConflictError extends Error {
693
+ instanceId;
694
+ firstPath;
695
+ secondPath;
346
696
  constructor(instanceId, firstPath, secondPath) {
347
- super(
348
- `Multiple instances produced with the same instance ID "${instanceId}":
349
- 1. ${firstPath}
350
- 2. ${secondPath}`
351
- );
697
+ super(`Multiple instances produced with the same instance ID "${instanceId}":
698
+ ` + `1. ${firstPath}
699
+ ` + `2. ${secondPath}`);
352
700
  this.instanceId = instanceId;
353
701
  this.firstPath = firstPath;
354
702
  this.secondPath = secondPath;
355
703
  this.name = "InstanceNameConflictError";
356
704
  }
357
- };
705
+ }
358
706
  var currentInstance = null;
359
- var runtimeInstances = /* @__PURE__ */ new Map();
707
+ var runtimeInstances = new Map;
360
708
  function resetEvaluation() {
361
709
  runtimeInstances.clear();
362
710
  currentInstance = null;
@@ -367,11 +715,7 @@ function getRuntimeInstances() {
367
715
  function registerInstance(component, instance, fn) {
368
716
  const conflicting = runtimeInstances.get(instance.id);
369
717
  if (conflicting) {
370
- throw new InstanceNameConflictError(
371
- instance.id,
372
- formatInstancePath(conflicting.instance),
373
- formatInstancePath(instance)
374
- );
718
+ throw new InstanceNameConflictError(instance.id, formatInstancePath(conflicting.instance), formatInstancePath(instance));
375
719
  }
376
720
  runtimeInstances.set(instance.id, { instance, component });
377
721
  let previousParentInstance = null;
@@ -383,19 +727,38 @@ function registerInstance(component, instance, fn) {
383
727
  currentInstance = instance;
384
728
  }
385
729
  try {
386
- const outputs = fn();
387
- instance.resolvedOutputs = outputs;
388
- instance.outputs = mapValues(
389
- outputs ?? {},
390
- (outputs2) => outputs2.map((output) => output[boundaryInput] ?? output)
391
- );
392
- return mapValues(
393
- outputs,
394
- (outputs2, outputKey) => outputs2.map((output) => ({
395
- ...output,
396
- [boundaryInput]: { instanceId: instance.id, output: outputKey }
397
- }))
398
- );
730
+ const rawOutputs = fn();
731
+ const outputs = mapValues(rawOutputs ?? {}, (outputGroup) => {
732
+ return [outputGroup].flat(2).filter(Boolean);
733
+ });
734
+ const toStableInputs = (outputGroup, useBoundaryFallback) => {
735
+ return outputGroup.map((output) => useBoundaryFallback ? output[boundaryInput] : output).filter(isStableInstanceInput).map((output) => {
736
+ return output.path ? {
737
+ instanceId: output.instanceId,
738
+ output: output.output,
739
+ path: output.path
740
+ } : {
741
+ instanceId: output.instanceId,
742
+ output: output.output
743
+ };
744
+ });
745
+ };
746
+ instance.resolvedOutputs = mapValues(outputs ?? {}, (outputGroup) => toStableInputs(outputGroup, false));
747
+ instance.outputs = mapValues(outputs ?? {}, (outputGroup) => toStableInputs(outputGroup, true));
748
+ return mapValues(rawOutputs, (rawOutputGroup, outputKey) => {
749
+ const outputRefs = (outputs[outputKey] ?? []).map((output) => {
750
+ if (output.provided) {
751
+ output[boundaryInput] = { instanceId: instance.id, output: outputKey };
752
+ }
753
+ return output;
754
+ });
755
+ if (component.model.outputs[outputKey]?.multiple) {
756
+ const multipleOutput = Array.isArray(rawOutputGroup) ? rawOutputGroup : outputRefs;
757
+ multipleOutput[boundaryInput] ??= { instanceId: instance.id, output: outputKey };
758
+ return multipleOutput;
759
+ }
760
+ return rawOutputGroup ?? outputRefs[0];
761
+ });
399
762
  } finally {
400
763
  if (previousParentInstance) {
401
764
  currentInstance = previousParentInstance;
@@ -404,30 +767,14 @@ function registerInstance(component, instance, fn) {
404
767
  }
405
768
 
406
769
  // src/component.ts
407
- var runtimeSchema = Symbol("runtimeSchema");
408
770
  var validationEnabled = true;
409
771
  function setValidationEnabled(enabled) {
410
772
  validationEnabled = enabled;
411
773
  }
412
- var componentKindSchema = z.enum(["composite", "unit"]);
413
- var componentArgumentSchema = z.object({
414
- /**
415
- * The JSON schema of the argument value.
416
- */
417
- schema: z.custom(),
418
- /**
419
- * The original Zod schema of the argument.
420
- *
421
- * Only available at runtime.
422
- */
423
- [runtimeSchema]: z.instanceof(z.ZodType).optional(),
424
- /**
425
- * Whether the argument is required.
426
- */
427
- required: z.boolean(),
428
- /**
429
- * The extra metadata of the argument.
430
- */
774
+ var componentArgumentSchema = z5.object({
775
+ schema: z5.custom(),
776
+ [runtimeSchema]: z5.instanceof(z5.ZodType).optional(),
777
+ required: z5.boolean(),
431
778
  meta: objectMetaSchema.required({ title: true }).pick({
432
779
  title: true,
433
780
  globalTitle: true,
@@ -437,51 +784,22 @@ var componentArgumentSchema = z.object({
437
784
  iconColor: true
438
785
  })
439
786
  });
440
- var componentInputSchema = z.object({
441
- /**
442
- * The type of the entity passed through the input.
443
- */
787
+ var componentInputSchema = z5.object({
444
788
  type: versionedNameSchema,
445
- /**
446
- * Whether the input is required.
447
- */
448
- required: z.boolean(),
449
- /**
450
- * Whether the input can have multiple values.
451
- */
452
- multiple: z.boolean(),
453
- /**
454
- * The extra metadata of the input.
455
- */
789
+ fromInput: fieldNameSchema.optional(),
790
+ required: z5.boolean(),
791
+ multiple: z5.boolean(),
456
792
  meta: objectMetaSchema.required({ title: true }).pick({
457
793
  title: true,
458
794
  description: true
459
795
  })
460
796
  });
461
- var componentModelSchema = z.object({
462
- /**
463
- * The type of the component.
464
- */
797
+ var componentModelSchema = z5.object({
465
798
  type: genericNameSchema,
466
- /**
467
- * The kind of the component.
468
- */
469
799
  kind: componentKindSchema,
470
- /**
471
- * The record of the argument schemas.
472
- */
473
- args: z.record(fieldNameSchema, componentArgumentSchema),
474
- /**
475
- * The record of the input schemas.
476
- */
477
- inputs: z.record(fieldNameSchema, componentInputSchema),
478
- /**
479
- * The record of the output schemas.
480
- */
481
- outputs: z.record(fieldNameSchema, componentInputSchema),
482
- /**
483
- * The extra metadata of the component.
484
- */
800
+ args: z5.record(fieldNameSchema, componentArgumentSchema),
801
+ inputs: z5.record(fieldNameSchema, componentInputSchema),
802
+ outputs: z5.record(fieldNameSchema, componentInputSchema),
485
803
  meta: objectMetaSchema.required({ title: true }).pick({
486
804
  title: true,
487
805
  description: true,
@@ -491,26 +809,12 @@ var componentModelSchema = z.object({
491
809
  secondaryIcon: true,
492
810
  secondaryIconColor: true
493
811
  }).extend({
494
- /**
495
- * The category of the component.
496
- *
497
- * Used to group components in the UI.
498
- */
499
- category: z.string().optional(),
500
- /**
501
- * The default name prefix for the component instances.
502
- *
503
- * Used to generate default names for the instances.
504
- */
505
- defaultNamePrefix: z.string()
812
+ category: z5.string().optional(),
813
+ defaultNamePrefix: z5.string()
506
814
  }),
507
- /**
508
- * The CRC32 of the component definition.
509
- */
510
- definitionHash: z.number()
815
+ definitionHash: z5.number()
511
816
  });
512
817
  var originalCreate = Symbol("originalCreate");
513
- var kind = Symbol("kind");
514
818
  function defineComponent(options) {
515
819
  try {
516
820
  componentModelSchema.shape.type.parse(options.type);
@@ -520,20 +824,20 @@ function defineComponent(options) {
520
824
  if (!options.create) {
521
825
  throw new Error("Component create function is required");
522
826
  }
523
- const entities = /* @__PURE__ */ new Map();
827
+ const entities = new Map;
524
828
  const mapInput = createInputMapper(entities);
829
+ const mapOutput = createOutputMapper(options.inputs, entities);
525
830
  const model = {
526
831
  type: options.type,
527
832
  kind: options[kind] ?? "composite",
528
- args: mapValues(options.args ?? {}, mapArgument),
529
- inputs: mapValues(options.inputs ?? {}, mapInput),
530
- outputs: mapValues(options.outputs ?? {}, mapInput),
833
+ args: mapValues2(options.args ?? {}, mapArgument),
834
+ inputs: mapValues2(options.inputs ?? {}, mapInput),
835
+ outputs: mapValues2(options.outputs ?? {}, mapOutput),
531
836
  meta: {
532
837
  ...options.meta,
533
838
  title: options.meta?.title || camelCaseToHumanReadable(parseVersionedName(options.type)[0]),
534
839
  defaultNamePrefix: options.meta?.defaultNamePrefix || parseVersionedName(options.type)[0].split(".").slice(-1)[0]
535
840
  },
536
- // will be calculated by library loader
537
841
  definitionHash: null
538
842
  };
539
843
  function create(params) {
@@ -541,64 +845,110 @@ function defineComponent(options) {
541
845
  const instanceId = getInstanceId(options.type, name);
542
846
  const flatInputs = {};
543
847
  const tracedInputs = {};
848
+ const runtimeInputKey = (input) => {
849
+ if (input.provided) {
850
+ return inputKey(input);
851
+ }
852
+ return `missing:${input[boundaryInput].instanceId}:${input[boundaryInput].output}`;
853
+ };
544
854
  for (const [key, inputGroup] of Object.entries(inputs ?? {})) {
855
+ if (!(key in model.inputs)) {
856
+ continue;
857
+ }
545
858
  if (!inputGroup) {
546
859
  continue;
547
860
  }
548
861
  if (!Array.isArray(inputGroup)) {
549
- if (inputGroup[boundaryInput]) {
550
- tracedInputs[key] = [inputGroup[boundaryInput]];
551
- }
552
- flatInputs[key] = [inputGroup];
862
+ const normalizedInput = normalizeIncomingInput(inputGroup, key);
863
+ tracedInputs[key] = [normalizedInput[boundaryInput]];
864
+ flatInputs[key] = [normalizedInput];
553
865
  continue;
554
866
  }
555
- const group = [...inputGroup[boundaryInputs] ?? []];
556
- const inputs2 = [];
557
- for (const item of inputGroup.flat(1)) {
558
- if (item[boundaryInput]) {
559
- group.push(item[boundaryInput]);
560
- }
561
- inputs2.push(item);
562
- }
867
+ const { group, inputs: inputs2 } = normalizeIncomingInputGroup(inputGroup, key);
563
868
  tracedInputs[key] = uniqueBy(group, inputKey);
564
- flatInputs[key] = uniqueBy(inputs2, inputKey);
869
+ flatInputs[key] = uniqueBy(inputs2, runtimeInputKey);
565
870
  }
566
- return registerInstance(
567
- create,
568
- {
871
+ return registerInstance(create, {
872
+ id: instanceId,
873
+ type: options.type,
874
+ kind: options[kind] ?? "composite",
875
+ name,
876
+ args,
877
+ inputs: tracedInputs,
878
+ resolvedInputs: mapValues2(flatInputs, (inputs2) => {
879
+ return inputs2.filter((input) => input.provided).map((input) => ({
880
+ instanceId: input.instanceId,
881
+ output: input.output,
882
+ ...input.path ? { path: input.path } : {}
883
+ }));
884
+ })
885
+ }, () => {
886
+ const markedInputs = mapValues2(model.inputs, (componentInput, key) => {
887
+ if (!componentInput.multiple) {
888
+ const input = flatInputs[key]?.[0];
889
+ if (input?.provided) {
890
+ return createDeepOutputAccessor({
891
+ ...input,
892
+ [boundaryInput]: { instanceId, output: key }
893
+ });
894
+ }
895
+ return createNonProvidedInput({ instanceId, output: key });
896
+ }
897
+ const inputs2 = (flatInputs[key] ?? []).filter(isProvidedRuntimeInput).map((input) => createDeepOutputAccessor({
898
+ ...input,
899
+ [boundaryInput]: { instanceId, output: key }
900
+ }));
901
+ const multipleBoundary = { instanceId, output: key };
902
+ return createMultipleInputAccessor(inputs2, multipleBoundary);
903
+ });
904
+ const outputs = options.create({
569
905
  id: instanceId,
570
- type: options.type,
571
- kind: options[kind] ?? "composite",
572
906
  name,
573
- args,
574
- inputs: tracedInputs,
575
- resolvedInputs: mapValues(
576
- flatInputs,
577
- (inputs2) => inputs2.filter((input) => !("provided" in input && input.provided === false))
578
- )
579
- },
580
- () => {
581
- const markedInputs = mapValues(model.inputs, (componentInput, key) => {
582
- if (!componentInput.multiple) {
583
- const input = flatInputs[key]?.[0];
584
- if (input) {
585
- return { ...input, [boundaryInput]: { instanceId, output: key } };
907
+ args: processArgs(instanceId, create.model, args),
908
+ inputs: markedInputs
909
+ }) ?? {};
910
+ const normalizedOutputs = normalizeCreateOutputs(outputs, model, instanceId);
911
+ return withDeepOutputAccessors(normalizedOutputs, model, instanceId);
912
+ });
913
+ function normalizeIncomingInput(input, inputName) {
914
+ if (isStableInstanceInput2(input)) {
915
+ return createInput(input);
916
+ }
917
+ const runtimeInput = input;
918
+ if (runtimeInput.provided) {
919
+ const inputBoundary = runtimeInput[boundaryInput] ?? {
920
+ instanceId: runtimeInput.instanceId,
921
+ output: runtimeInput.output,
922
+ ...runtimeInput.path ? { path: runtimeInput.path } : {}
923
+ };
924
+ return createInput(runtimeInput, { boundary: inputBoundary });
925
+ }
926
+ return createNonProvidedInput(runtimeInput[boundaryInput] ?? { instanceId, output: inputName });
927
+ }
928
+ function normalizeIncomingInputGroup(inputGroup, inputName) {
929
+ const group = [];
930
+ const inputs2 = [];
931
+ const visit = (value) => {
932
+ if (Array.isArray(value)) {
933
+ const arrayBoundary = value[boundaryInput];
934
+ if (arrayBoundary) {
935
+ group.push(arrayBoundary);
936
+ }
937
+ for (const item of value) {
938
+ if (!item) {
939
+ continue;
586
940
  }
587
- return { provided: false, [boundaryInput]: { instanceId, output: key } };
941
+ visit(item);
588
942
  }
589
- const inputs2 = flatInputs[key] ?? [];
590
- inputs2[boundaryInputs] = [{ instanceId, output: key }];
591
- return inputs2;
592
- });
593
- const outputs = options.create({
594
- id: instanceId,
595
- name,
596
- args: processArgs(instanceId, create.model, args),
597
- inputs: markedInputs
598
- }) ?? {};
599
- return mapValues(pickBy(outputs, isNonNullish), (outputs2) => [outputs2].flat(2));
600
- }
601
- );
943
+ return;
944
+ }
945
+ const normalizedInput = normalizeIncomingInput(value, inputName);
946
+ group.push(normalizedInput[boundaryInput]);
947
+ inputs2.push(normalizedInput);
948
+ };
949
+ visit(inputGroup);
950
+ return { group, inputs: inputs2 };
951
+ }
602
952
  }
603
953
  try {
604
954
  create.entities = entities;
@@ -618,9 +968,7 @@ function processArgs(instanceId, model, args) {
618
968
  if (arg.schema) {
619
969
  const result = arg[runtimeSchema].safeParse(args[key]);
620
970
  if (!result.success) {
621
- throw new Error(
622
- `Invalid argument "${key}" in instance "${instanceId}": ${result.error.message}`
623
- );
971
+ throw new Error(`Invalid argument "${key}" in instance "${instanceId}": ${result.error.message}`);
624
972
  }
625
973
  validatedArgs[key] = result.data;
626
974
  } else {
@@ -629,16 +977,92 @@ function processArgs(instanceId, model, args) {
629
977
  }
630
978
  return validatedArgs;
631
979
  }
980
+ function withDeepOutputAccessors(outputs, model, instanceId) {
981
+ return mapValues2(outputs, (outputGroup, outputName) => {
982
+ const outputSpec = model.outputs[outputName];
983
+ if (!outputSpec) {
984
+ return outputGroup[0];
985
+ }
986
+ const normalizedOutputs = outputGroup.map((output) => createDeepOutputAccessor(output));
987
+ if (outputSpec.multiple) {
988
+ return createMultipleInputAccessor(normalizedOutputs, {
989
+ instanceId,
990
+ output: outputName
991
+ });
992
+ }
993
+ return normalizedOutputs[0];
994
+ });
995
+ }
996
+ function isProvidedRuntimeInput(input) {
997
+ return input.provided;
998
+ }
999
+ function normalizeCreateOutputGroup(outputGroup, instanceId, outputName) {
1000
+ return [outputGroup].flat(2).filter(isNonNullish).map((output) => {
1001
+ if (isStableInstanceInput2(output)) {
1002
+ return createInput(output);
1003
+ }
1004
+ const runtimeOutput = output;
1005
+ if (runtimeOutput.provided) {
1006
+ const stableBoundary = runtimeOutput[boundaryInput] ?? {
1007
+ instanceId: runtimeOutput.instanceId,
1008
+ output: runtimeOutput.output,
1009
+ ...runtimeOutput.path ? { path: runtimeOutput.path } : {}
1010
+ };
1011
+ return createInput(runtimeOutput, { boundary: stableBoundary });
1012
+ }
1013
+ return createNonProvidedInput(runtimeOutput[boundaryInput] ?? { instanceId, output: outputName });
1014
+ });
1015
+ }
1016
+ function normalizeCreateOutputs(outputs, model, instanceId) {
1017
+ const normalizedOutputs = {};
1018
+ for (const [outputName, outputSpec] of Object.entries(model.outputs)) {
1019
+ const outputGroup = outputs[outputName];
1020
+ if (!isNonNullish(outputGroup)) {
1021
+ if (model.kind === "unit") {
1022
+ throw new Error(`Unit output "${outputName}" in instance "${instanceId}" must be provided`);
1023
+ }
1024
+ normalizedOutputs[outputName] = outputSpec.multiple ? [] : [createNonProvidedInput({ instanceId, output: outputName })];
1025
+ continue;
1026
+ }
1027
+ const normalizedGroup = normalizeCreateOutputGroup(outputGroup, instanceId, outputName);
1028
+ if (outputSpec.multiple && normalizedGroup.some((output) => !output.provided)) {
1029
+ throw new Error(`Multiple output "${outputName}" in instance "${instanceId}" cannot contain non-provided items`);
1030
+ }
1031
+ if (model.kind === "unit") {
1032
+ if (normalizedGroup.length === 0 || normalizedGroup.some((output) => !output.provided)) {
1033
+ throw new Error(`Unit output "${outputName}" in instance "${instanceId}" must be provided`);
1034
+ }
1035
+ }
1036
+ normalizedOutputs[outputName] = outputSpec.multiple || normalizedGroup.length > 0 ? normalizedGroup : [createNonProvidedInput({ instanceId, output: outputName })];
1037
+ }
1038
+ for (const [outputName, outputGroup] of Object.entries(pickBy(outputs, isNonNullish))) {
1039
+ if (!(outputName in model.outputs) || outputName in normalizedOutputs) {
1040
+ continue;
1041
+ }
1042
+ normalizedOutputs[outputName] = normalizeCreateOutputGroup(outputGroup, instanceId, outputName);
1043
+ }
1044
+ return normalizedOutputs;
1045
+ }
1046
+ function isStableInstanceInput2(value) {
1047
+ if (!value || typeof value !== "object") {
1048
+ return false;
1049
+ }
1050
+ if ("provided" in value) {
1051
+ return false;
1052
+ }
1053
+ const input = value;
1054
+ return typeof input.instanceId === "string" && typeof input.output === "string";
1055
+ }
632
1056
  function isComponent(value) {
633
1057
  return typeof value === "function" && "model" in value;
634
1058
  }
635
1059
  function isSchemaOptional(schema) {
636
- return schema.safeParse(void 0).success;
1060
+ return schema.safeParse(undefined).success;
637
1061
  }
638
1062
  function mapArgument(value, key) {
639
1063
  if ("schema" in value) {
640
1064
  return {
641
- schema: z.toJSONSchema(value.schema, {
1065
+ schema: z5.toJSONSchema(value.schema, {
642
1066
  target: "draft-7",
643
1067
  io: "input",
644
1068
  unrepresentable: "any"
@@ -652,7 +1076,7 @@ function mapArgument(value, key) {
652
1076
  };
653
1077
  }
654
1078
  return {
655
- schema: z.toJSONSchema(value, { target: "draft-7", io: "input", unrepresentable: "any" }),
1079
+ schema: z5.toJSONSchema(value, { target: "draft-7", io: "input", unrepresentable: "any" }),
656
1080
  [runtimeSchema]: value,
657
1081
  required: !isSchemaOptional(value),
658
1082
  meta: {
@@ -688,14 +1112,50 @@ function createInputMapper(entities) {
688
1112
  };
689
1113
  };
690
1114
  }
1115
+ function isFromInputOutputOptions(value) {
1116
+ return typeof value === "object" && value !== null && "fromInput" in value;
1117
+ }
1118
+ function createOutputMapper(inputs, entities) {
1119
+ const mapInput = createInputMapper(entities);
1120
+ return (value, key) => {
1121
+ if (!isFromInputOutputOptions(value)) {
1122
+ return mapInput(value, key);
1123
+ }
1124
+ const sourceInput = inputs?.[value.fromInput];
1125
+ if (!sourceInput) {
1126
+ throw new Error(`Output "${key}" references missing input "${value.fromInput}" via fromInput.`);
1127
+ }
1128
+ const mappedInput = mapInput(sourceInput, value.fromInput);
1129
+ return {
1130
+ ...mappedInput,
1131
+ fromInput: value.fromInput,
1132
+ meta: {
1133
+ ...mappedInput.meta,
1134
+ ...value.meta,
1135
+ title: value.meta?.title || camelCaseToHumanReadable(key)
1136
+ }
1137
+ };
1138
+ };
1139
+ }
691
1140
  function getInstanceId(instanceType, instanceName) {
692
1141
  return `${instanceType}:${instanceName}`;
693
1142
  }
694
1143
  function toFullComponentArgumentOptions(args) {
695
- return mapValues(args, (arg) => "schema" in arg ? arg : { schema: arg });
1144
+ return mapValues2(args, (arg) => ("schema" in arg) ? arg : { schema: arg });
696
1145
  }
697
1146
  function toFullComponentInputOptions(inputs) {
698
- return mapValues(inputs, (input) => "entity" in input ? input : { entity: input });
1147
+ return mapValues2(inputs, (input) => ("entity" in input) ? input : { entity: input });
1148
+ }
1149
+ function toFullComponentOutputOptions(outputs) {
1150
+ return mapValues2(outputs, (output) => {
1151
+ if (typeof output !== "object" || output === null) {
1152
+ return { entity: output };
1153
+ }
1154
+ if ("entity" in output || "fromInput" in output) {
1155
+ return output;
1156
+ }
1157
+ return { entity: output };
1158
+ });
699
1159
  }
700
1160
  function $args(args) {
701
1161
  return toFullComponentArgumentOptions(args);
@@ -704,7 +1164,7 @@ function $inputs(inputs) {
704
1164
  return toFullComponentInputOptions(inputs);
705
1165
  }
706
1166
  function $outputs(outputs) {
707
- return toFullComponentInputOptions(outputs);
1167
+ return toFullComponentOutputOptions(outputs);
708
1168
  }
709
1169
  function $addArgumentDescription(argument, description) {
710
1170
  if ("schema" in argument) {
@@ -741,245 +1201,19 @@ function $addInputDescription(input, description) {
741
1201
  };
742
1202
  }
743
1203
 
744
- // src/instance.ts
745
- function inputKey(input) {
746
- return `${input.instanceId}:${input.output}`;
747
- }
748
- var positionSchema = z.object({
749
- x: z.number(),
750
- y: z.number()
751
- });
752
- var instanceIdSchema = z.templateLiteral([versionedNameSchema, ":", genericNameSchema]);
753
- var instanceInputSchema = z.object({
754
- instanceId: instanceIdSchema,
755
- output: z.string()
756
- });
757
- var hubInputSchema = z.object({
758
- hubId: z.string()
759
- });
760
- var instanceModelPatchSchema = z.object({
761
- /**
762
- * The static arguments passed to the instance.
763
- */
764
- args: z.record(z.string(), z.unknown()).optional(),
765
- /**
766
- * The direct instances passed as inputs to the instance.
767
- */
768
- inputs: z.record(z.string(), z.array(instanceInputSchema)).optional(),
769
- /**
770
- * The resolved unit inputs for the instance.
771
- *
772
- * Only for computed composite instances.
773
- */
774
- hubInputs: z.record(z.string(), z.array(hubInputSchema)).optional(),
775
- /**
776
- * The inputs injected to the instance from the hubs.
777
- *
778
- * While `hubInputs` allows to pass hubs to distinct inputs,
779
- * `injectionInputs` allows to pass hubs to the instance as a whole filling all inputs with matching types.
780
- *
781
- * Only for designer-first instances.
782
- */
783
- injectionInputs: z.array(hubInputSchema).optional(),
784
- /**
785
- * The position of the instance on the canvas.
786
- *
787
- * Only for designer-first instances.
788
- */
789
- position: positionSchema.optional()
790
- });
791
- var instanceModelSchema = z.object({
792
- /**
793
- * The id of the instance unique within the project.
794
- *
795
- * The format is `${instanceType}:${instanceName}`.
796
- */
797
- id: instanceIdSchema,
798
- /**
799
- * The kind of the instance.
800
- *
801
- * Can be either "unit" or "composite".
802
- */
803
- kind: componentKindSchema,
804
- /**
805
- * The type of the instance.
806
- */
807
- type: versionedNameSchema,
808
- /**
809
- * The name of the instance.
810
- *
811
- * Must be unique within instances of the same type in the project.
812
- */
813
- name: genericNameSchema,
814
- ...instanceModelPatchSchema.shape,
815
- /**
816
- * The id of the top level parent instance.
817
- *
818
- * Only for child instances of the composite instances.
819
- */
820
- resolvedInputs: z.record(z.string(), z.array(instanceInputSchema)).optional(),
821
- /**
822
- * The ID of the parent instance.
823
- *
824
- * Only for child instances of the composite instances.
825
- */
826
- parentId: instanceIdSchema.optional(),
827
- /**
828
- * The direct instance outputs returned by the instance as outputs.
829
- *
830
- * Only for computed composite instances.
831
- */
832
- outputs: z.record(z.string(), z.array(instanceInputSchema)).optional(),
833
- /**
834
- * The resolved unit outputs for the instance.
835
- *
836
- * Only for computed composite instances.
837
- */
838
- resolvedOutputs: z.record(z.string(), z.array(instanceInputSchema)).optional()
839
- });
840
- var hubModelPatchSchema = z.object({
841
- /**
842
- * The position of the hub on the canvas.
843
- */
844
- position: positionSchema.optional(),
845
- /**
846
- * The inputs of the hub.
847
- */
848
- inputs: z.array(instanceInputSchema).optional(),
849
- /**
850
- * The inputs injected to the hub from the hubs.
851
- *
852
- * While `inputs` allows to pass hubs to distinct inputs,
853
- * `injectionInputs` allows to pass hubs to the hub as a whole filling all inputs with matching types.
854
- */
855
- injectionInputs: z.array(hubInputSchema).optional()
856
- });
857
- var hubModelSchema = z.object({
858
- /**
859
- * The id of the hub unique within the project.
860
- */
861
- id: z.cuid2(),
862
- ...hubModelPatchSchema.shape
863
- });
864
- function parseInstanceId(instanceId) {
865
- const parts = instanceId.split(":");
866
- if (parts.length !== 2) {
867
- throw new Error(`Invalid instance ID: ${instanceId}`);
868
- }
869
- return parts;
870
- }
871
- function findInput(inputs, name) {
872
- const matchedInputs = inputs.filter(
873
- (input) => parseInstanceId(input.instanceId)[1] === name || input.instanceId === name
874
- );
875
- if (matchedInputs.length === 0) {
876
- return null;
877
- }
878
- if (matchedInputs.length > 1) {
879
- throw new Error(
880
- `Multiple inputs found for "${name}": ${matchedInputs.map((input) => input.instanceId).join(", ")}. Specify the full instance id to disambiguate.`
881
- );
882
- }
883
- return matchedInputs[0];
884
- }
885
- function findRequiredInput(inputs, name) {
886
- const input = findInput(inputs, name);
887
- if (input === null) {
888
- throw new Error(`Required input "${name}" not found.`);
889
- }
890
- return input;
891
- }
892
- function findInputs(inputs, names) {
893
- return names.map((name) => findInput(inputs, name)).filter(Boolean);
894
- }
895
- function findRequiredInputs(inputs, names) {
896
- return names.map((name) => findRequiredInput(inputs, name));
897
- }
898
- var HighstateSignature = /* @__PURE__ */ ((HighstateSignature2) => {
899
- HighstateSignature2["Artifact"] = "d55c63ac-3174-4756-808f-f778e99af0d1";
900
- HighstateSignature2["Yaml"] = "c857cac5-caa6-4421-b82c-e561fbce6367";
901
- HighstateSignature2["Id"] = "348d020e-0d9e-4ae7-9415-b91af99f5339";
902
- HighstateSignature2["Ref"] = "6d7f9da0-9cb6-496d-b72e-cf85ee4d9cf8";
903
- return HighstateSignature2;
904
- })(HighstateSignature || {});
905
- var yamlValueSchema = z.object({
906
- ["c857cac5-caa6-4421-b82c-e561fbce6367" /* Yaml */]: z.literal(true),
907
- value: z.string()
908
- });
909
- var objectWithIdSchema = z.object({
910
- ["348d020e-0d9e-4ae7-9415-b91af99f5339" /* Id */]: z.literal(true),
911
- id: z.number(),
912
- value: z.unknown()
913
- });
914
- var objectRefSchema = z.object({
915
- ["6d7f9da0-9cb6-496d-b72e-cf85ee4d9cf8" /* Ref */]: z.literal(true),
916
- id: z.number()
917
- });
918
- var fileMetaSchema = z.object({
919
- name: z.string(),
920
- contentType: z.string().optional(),
921
- size: z.number().optional(),
922
- mode: z.number().optional()
923
- });
924
- var WellKnownInstanceCustomStatus = /* @__PURE__ */ ((WellKnownInstanceCustomStatus2) => {
925
- WellKnownInstanceCustomStatus2["Healthy"] = "healthy";
926
- WellKnownInstanceCustomStatus2["Degraded"] = "degraded";
927
- WellKnownInstanceCustomStatus2["Down"] = "down";
928
- WellKnownInstanceCustomStatus2["Warning"] = "warning";
929
- WellKnownInstanceCustomStatus2["Progressing"] = "progressing";
930
- WellKnownInstanceCustomStatus2["Error"] = "error";
931
- return WellKnownInstanceCustomStatus2;
932
- })(WellKnownInstanceCustomStatus || {});
933
- var instanceStatusFieldValueSchema = z.union([
934
- z.string(),
935
- z.number(),
936
- z.boolean(),
937
- z.string().array()
938
- ]);
939
- var instanceStatusFieldSchema = z.object({
940
- name: z.string(),
941
- meta: objectMetaSchema.pick({
942
- title: true,
943
- icon: true,
944
- iconColor: true
945
- }).required({ title: true }),
946
- complementaryTo: z.string().optional(),
947
- value: instanceStatusFieldValueSchema.optional()
948
- });
1204
+ // src/unit.ts
949
1205
  var componentSecretSchema = componentArgumentSchema.extend({
950
- /**
951
- * The secret cannot be modified by the user, but can be modified by the unit.
952
- */
953
- readonly: z.boolean(),
954
- /**
955
- * The secret value is computed by the unit and should not be passed to it when invoked.
956
- */
957
- computed: z.boolean()
1206
+ readonly: z6.boolean(),
1207
+ computed: z6.boolean()
958
1208
  });
959
- var unitSourceSchema = z.object({
960
- /**
961
- * The package where the unit implementation is located.
962
- *
963
- * May be both: local monorepo package or a remote NPM package.
964
- */
965
- package: z.string(),
966
- /**
967
- * The path to the unit implementation within the package.
968
- *
969
- * If not provided, the root of the package is assumed.
970
- */
971
- path: z.string().optional()
1209
+ var unitSourceSchema = z6.object({
1210
+ package: z6.string(),
1211
+ path: z6.string().optional()
972
1212
  });
973
- var unitModelSchema = z.object({
1213
+ var unitModelSchema = z6.object({
974
1214
  ...componentModelSchema.shape,
975
- /**
976
- * The source of the unit.
977
- */
978
1215
  source: unitSourceSchema,
979
- /**
980
- * The record of the secret specs.
981
- */
982
- secrets: z.record(z.string(), componentSecretSchema)
1216
+ secrets: z6.record(z6.string(), componentSecretSchema)
983
1217
  });
984
1218
  function defineUnit(options) {
985
1219
  if (!options.source) {
@@ -991,19 +1225,22 @@ function defineUnit(options) {
991
1225
  create({ id }) {
992
1226
  const outputs = {};
993
1227
  for (const key in options.outputs ?? {}) {
994
- outputs[key] = [
995
- {
1228
+ outputs[key] = {
1229
+ provided: true,
1230
+ instanceId: id,
1231
+ output: key,
1232
+ [boundaryInput]: {
996
1233
  instanceId: id,
997
1234
  output: key
998
1235
  }
999
- ];
1236
+ };
1000
1237
  }
1001
1238
  return outputs;
1002
1239
  }
1003
1240
  });
1004
1241
  try {
1005
1242
  component.model.source = options.source ?? {};
1006
- component.model.secrets = mapValues(options.secrets ?? {}, mapSecret);
1243
+ component.model.secrets = mapValues3(options.secrets ?? {}, mapSecret);
1007
1244
  } catch (error) {
1008
1245
  throw new Error(`Failed to map secrets for unit "${options.type}"`, { cause: error });
1009
1246
  }
@@ -1029,13 +1266,22 @@ function mapSecret(value, key) {
1029
1266
  function isUnitModel(model) {
1030
1267
  return "source" in model;
1031
1268
  }
1032
- var triggerSpecSchema = z.union([
1033
- z.object({
1034
- type: z.literal("before-destroy")
1269
+ // src/terminal.ts
1270
+ import { z as z9 } from "zod";
1271
+
1272
+ // src/pulumi.ts
1273
+ import { parse } from "yaml";
1274
+ import { z as z8 } from "zod";
1275
+
1276
+ // src/trigger.ts
1277
+ import { z as z7 } from "zod";
1278
+ var triggerSpecSchema = z7.union([
1279
+ z7.object({
1280
+ type: z7.literal("before-destroy")
1035
1281
  })
1036
1282
  ]);
1037
- var unitTriggerSchema = z.object({
1038
- name: z.string(),
1283
+ var unitTriggerSchema = z7.object({
1284
+ name: z7.string(),
1039
1285
  meta: objectMetaSchema.pick({
1040
1286
  title: true,
1041
1287
  globalTitle: true,
@@ -1043,140 +1289,85 @@ var unitTriggerSchema = z.object({
1043
1289
  icon: true,
1044
1290
  iconColor: true
1045
1291
  }).required({ title: true }),
1046
- /**
1047
- * The specification of the trigger.
1048
- *
1049
- * Defines the type of trigger and its behavior.
1050
- */
1051
1292
  spec: triggerSpecSchema
1052
1293
  });
1053
- var triggerInvocationSchema = z.object({
1054
- /**
1055
- * The name of the trigger being invoked.
1056
- */
1057
- name: z.string()
1294
+ var triggerInvocationSchema = z7.object({
1295
+ name: z7.string()
1058
1296
  });
1059
1297
 
1060
1298
  // src/pulumi.ts
1061
- var unitInputReference = z.object({
1062
- ...instanceInputSchema.shape,
1063
- /**
1064
- * The resolved inclusion needed to extract the input value.
1065
- */
1066
- inclusion: entityInclusionSchema.optional()
1299
+ var unitInputSourceSchema = z8.object({
1300
+ ...instanceInputSchema.shape
1301
+ });
1302
+ var unitInputValueSchema = z8.object({
1303
+ value: z8.unknown(),
1304
+ source: unitInputSourceSchema.optional()
1067
1305
  });
1068
- var unitConfigSchema = z.object({
1069
- /**
1070
- * The ID of the instance.
1071
- */
1072
- instanceId: z.string(),
1073
- /**
1074
- * The record of argument values for the unit.
1075
- */
1076
- args: z.record(z.string(), z.unknown()),
1077
- /**
1078
- * The record of input references for the unit.
1079
- */
1080
- inputs: z.record(z.string(), unitInputReference.array()),
1081
- /**
1082
- * The list of triggers that have been invoked for this unit.
1083
- */
1306
+ var unitConfigSchema = z8.object({
1307
+ instanceId: z8.string(),
1308
+ stateId: z8.string(),
1309
+ args: z8.record(z8.string(), z8.unknown()),
1310
+ inputs: z8.record(z8.string(), unitInputValueSchema.array()),
1084
1311
  invokedTriggers: triggerInvocationSchema.array(),
1085
- /**
1086
- * The list of secret names that exists and provided to the unit.
1087
- */
1088
- secretNames: z.string().array(),
1089
- /**
1090
- * The map of instance ID to state ID in order to resolve instance references.
1091
- */
1092
- stateIdMap: z.record(instanceIdSchema, z.string()),
1093
- /**
1094
- * The base path for imports.
1095
- * Used to resolve dynamic dependencies in strict environments (like in pnpm node_modules isolation).
1096
- */
1097
- importBasePath: z.string()
1312
+ secretValues: z8.record(z8.string(), z8.unknown()),
1313
+ importBasePath: z8.string()
1098
1314
  });
1099
- var yamlResultCache = /* @__PURE__ */ new WeakMap();
1315
+ var yamlResultCache = new WeakMap;
1100
1316
  function parseArgumentValue(value) {
1101
1317
  const yamlResult = yamlValueSchema.safeParse(value);
1102
1318
  if (!yamlResult.success) {
1103
1319
  return value;
1104
1320
  }
1105
1321
  const existingResult = yamlResultCache.get(value);
1106
- if (existingResult !== void 0) {
1322
+ if (existingResult !== undefined) {
1107
1323
  return existingResult;
1108
1324
  }
1109
1325
  const result = parse(yamlResult.data.value);
1110
1326
  yamlResultCache.set(value, result);
1111
1327
  return result;
1112
1328
  }
1113
- var HighstateConfigKey = /* @__PURE__ */ ((HighstateConfigKey2) => {
1329
+ var HighstateConfigKey;
1330
+ ((HighstateConfigKey2) => {
1114
1331
  HighstateConfigKey2["Config"] = "highstate";
1115
- HighstateConfigKey2["Secrets"] = "highstate.secrets";
1116
- return HighstateConfigKey2;
1117
- })(HighstateConfigKey || {});
1332
+ })(HighstateConfigKey ||= {});
1118
1333
  var unitArtifactId = Symbol("unitArtifactId");
1119
- var unitArtifactSchema = z.object({
1120
- ["d55c63ac-3174-4756-808f-f778e99af0d1" /* Artifact */]: z.literal(true),
1121
- // only for internal use
1122
- [unitArtifactId]: z.string().optional(),
1123
- hash: z.string(),
1334
+ var unitArtifactSchema = z8.object({
1335
+ ["d55c63ac-3174-4756-808f-f778e99af0d1" /* Artifact */]: z8.literal(true),
1336
+ [unitArtifactId]: z8.string().optional(),
1337
+ hash: z8.string(),
1124
1338
  meta: commonObjectMetaSchema.optional()
1125
1339
  });
1126
- var fileContentSchema = z.union([
1127
- z.object({
1128
- type: z.literal("embedded"),
1129
- /**
1130
- * Whether the content is binary or not.
1131
- *
1132
- * If true, the `value` will be a base64 encoded string.
1133
- */
1134
- isBinary: z.boolean().optional(),
1135
- /**
1136
- * The content of the file.
1137
- *
1138
- * If `isBinary` is true, this will be a base64 encoded string.
1139
- */
1140
- value: z.string()
1340
+ var fileContentSchema = z8.union([
1341
+ z8.object({
1342
+ type: z8.literal("embedded"),
1343
+ isBinary: z8.boolean().optional(),
1344
+ value: z8.string()
1345
+ }),
1346
+ z8.object({
1347
+ type: z8.literal("embedded-secret"),
1348
+ isBinary: z8.boolean().optional(),
1349
+ value: secretSchema(z8.string())
1141
1350
  }),
1142
- z.object({
1143
- type: z.literal("artifact"),
1351
+ z8.object({
1352
+ type: z8.literal("artifact"),
1144
1353
  ...unitArtifactSchema.shape
1145
1354
  })
1146
1355
  ]);
1147
- var fileSchema = z.object({
1356
+ var fileSchema = z8.object({
1148
1357
  meta: fileMetaSchema,
1149
1358
  content: fileContentSchema
1150
1359
  });
1151
1360
 
1152
1361
  // src/terminal.ts
1153
- var terminalSpecSchema = z.object({
1154
- /**
1155
- * The Docker image to run the terminal.
1156
- */
1157
- image: z.string(),
1158
- /**
1159
- * The command to run in the terminal.
1160
- */
1161
- command: z.string().array(),
1162
- /**
1163
- * The working directory to run the command in.
1164
- */
1165
- cwd: z.string().optional(),
1166
- /**
1167
- * The environment variables to set in the terminal.
1168
- */
1169
- env: z.record(z.string(), z.string()).optional(),
1170
- /**
1171
- * The files to mount in the terminal.
1172
- *
1173
- * The key is the path where the file will be mounted,
1174
- * and the value is the file content or a reference to an artifact.
1175
- */
1176
- files: z.record(z.string(), fileSchema).optional()
1362
+ var terminalSpecSchema = z9.object({
1363
+ image: z9.string(),
1364
+ command: z9.string().array(),
1365
+ cwd: z9.string().optional(),
1366
+ env: z9.record(z9.string(), z9.string()).optional(),
1367
+ files: z9.record(z9.string(), fileSchema).optional()
1177
1368
  });
1178
- var unitTerminalSchema = z.object({
1179
- name: z.string(),
1369
+ var unitTerminalSchema = z9.object({
1370
+ name: z9.string(),
1180
1371
  meta: objectMetaSchema.pick({
1181
1372
  title: true,
1182
1373
  globalTitle: true,
@@ -1186,24 +1377,26 @@ var unitTerminalSchema = z.object({
1186
1377
  }).required({ title: true }),
1187
1378
  spec: terminalSpecSchema
1188
1379
  });
1189
- var pageBlockSchema = z.union([
1190
- z.object({
1191
- type: z.literal("markdown"),
1192
- content: z.string()
1380
+ // src/page.ts
1381
+ import { z as z10 } from "zod";
1382
+ var pageBlockSchema = z10.union([
1383
+ z10.object({
1384
+ type: z10.literal("markdown"),
1385
+ content: z10.string()
1193
1386
  }),
1194
- z.object({
1195
- type: z.literal("qr"),
1196
- content: z.string(),
1197
- showContent: z.coerce.boolean(),
1198
- language: z.string().optional()
1387
+ z10.object({
1388
+ type: z10.literal("qr"),
1389
+ content: z10.string(),
1390
+ showContent: z10.coerce.boolean(),
1391
+ language: z10.string().optional()
1199
1392
  }),
1200
- z.object({
1201
- type: z.literal("file"),
1393
+ z10.object({
1394
+ type: z10.literal("file"),
1202
1395
  file: fileSchema
1203
1396
  })
1204
1397
  ]);
1205
- var unitPageSchema = z.object({
1206
- name: z.string(),
1398
+ var unitPageSchema = z10.object({
1399
+ name: z10.string(),
1207
1400
  meta: objectMetaSchema.pick({
1208
1401
  title: true,
1209
1402
  globalTitle: true,
@@ -1213,347 +1406,49 @@ var unitPageSchema = z.object({
1213
1406
  }).required({ title: true }),
1214
1407
  content: pageBlockSchema.array()
1215
1408
  });
1216
- var unitWorkerSchema = z.object({
1217
- name: z.string(),
1218
- image: z.string(),
1219
- params: z.record(z.string(), z.unknown())
1409
+ // src/worker.ts
1410
+ import { z as z11 } from "zod";
1411
+ var unitWorkerSchema = z11.object({
1412
+ name: z11.string(),
1413
+ image: z11.string(),
1414
+ params: z11.record(z11.string(), z11.unknown())
1220
1415
  });
1221
- var workerRunOptionsSchema = z.object({
1222
- /**
1223
- * The ID of the project for which the worker is running.
1224
- */
1225
- projectId: z.cuid2(),
1226
- /**
1227
- * The ID of the worker version.
1228
- */
1229
- workerVersionId: z.cuid2(),
1230
- /**
1231
- * The URL of the backend API to connect to.
1232
- */
1233
- apiUrl: z.url(),
1234
- /**
1235
- * The API key used to authenticate the worker with the backend.
1236
- */
1237
- apiKey: z.string()
1416
+ var workerRunOptionsSchema = z11.object({
1417
+ projectId: z11.cuid2(),
1418
+ workerVersionId: z11.cuid2(),
1419
+ apiUrl: z11.url(),
1420
+ apiKey: z11.string()
1238
1421
  });
1239
- function compact(value) {
1240
- const counts = /* @__PURE__ */ new WeakMap();
1241
- const cyclic = /* @__PURE__ */ new WeakSet();
1242
- const expanded = /* @__PURE__ */ new WeakSet();
1243
- const inStack = /* @__PURE__ */ new WeakSet();
1244
- const stack = [];
1245
- function countIdentities(current) {
1246
- if (current === null || typeof current !== "object") {
1247
- return;
1248
- }
1249
- counts.set(current, (counts.get(current) ?? 0) + 1);
1250
- if (inStack.has(current)) {
1251
- cyclic.add(current);
1252
- for (const entry of stack) {
1253
- cyclic.add(entry);
1254
- }
1255
- return;
1256
- }
1257
- if (expanded.has(current)) {
1258
- return;
1259
- }
1260
- expanded.add(current);
1261
- inStack.add(current);
1262
- stack.push(current);
1263
- if (Array.isArray(current)) {
1264
- try {
1265
- for (const item of current) {
1266
- countIdentities(item);
1267
- }
1268
- return;
1269
- } finally {
1270
- stack.pop();
1271
- inStack.delete(current);
1272
- }
1273
- }
1274
- try {
1275
- for (const entryValue of Object.values(current)) {
1276
- countIdentities(entryValue);
1277
- }
1278
- } finally {
1279
- stack.pop();
1280
- inStack.delete(current);
1281
- }
1282
- }
1283
- countIdentities(value);
1284
- const ids = /* @__PURE__ */ new WeakMap();
1285
- const definitionSites = /* @__PURE__ */ new WeakMap();
1286
- let nextId = 1;
1287
- function ensureId(current) {
1288
- const existing = ids.get(current);
1289
- if (existing !== void 0) {
1290
- return existing;
1291
- }
1292
- const allocated = nextId;
1293
- nextId += 1;
1294
- ids.set(current, allocated);
1295
- return allocated;
1296
- }
1297
- function assignDefinitionSitesBfs(root) {
1298
- if (root === null || typeof root !== "object") {
1299
- return;
1300
- }
1301
- const queue = [];
1302
- const expandedQueue = /* @__PURE__ */ new WeakSet();
1303
- if (Array.isArray(root)) {
1304
- for (let index = 0; index < root.length; index += 1) {
1305
- queue.push({ parent: root, key: index, value: root[index] });
1306
- }
1307
- } else {
1308
- for (const [key, entryValue] of Object.entries(root)) {
1309
- queue.push({ parent: root, key, value: entryValue });
1310
- }
1311
- }
1312
- while (queue.length > 0) {
1313
- const current = queue.shift();
1314
- if (current === void 0) {
1315
- continue;
1316
- }
1317
- if (current.value === null || typeof current.value !== "object") {
1318
- continue;
1319
- }
1320
- const occurrences = counts.get(current.value) ?? 0;
1321
- if (occurrences > 1 && definitionSites.get(current.value) === void 0) {
1322
- definitionSites.set(current.value, { parent: current.parent, key: current.key });
1323
- ensureId(current.value);
1324
- }
1325
- if (expandedQueue.has(current.value)) {
1326
- continue;
1327
- }
1328
- expandedQueue.add(current.value);
1329
- if (Array.isArray(current.value)) {
1330
- for (let index = 0; index < current.value.length; index += 1) {
1331
- queue.push({ parent: current.value, key: index, value: current.value[index] });
1332
- }
1333
- continue;
1334
- }
1335
- for (const [key, entryValue] of Object.entries(current.value)) {
1336
- queue.push({ parent: current.value, key, value: entryValue });
1337
- }
1338
- }
1339
- }
1340
- assignDefinitionSitesBfs(value);
1341
- const emitted = /* @__PURE__ */ new WeakSet();
1342
- function buildTreeChildren(current, rootOfIdValue) {
1343
- if (Array.isArray(current)) {
1344
- return current.map((item) => buildTree(item, rootOfIdValue));
1345
- }
1346
- return mapValues(current, (entryValue) => buildTree(entryValue, rootOfIdValue));
1347
- }
1348
- function buildTree(current, rootOfIdValue) {
1349
- if (current === null || typeof current !== "object") {
1350
- return current;
1351
- }
1352
- if (rootOfIdValue !== void 0 && emitted.has(current)) {
1353
- const id = ids.get(current);
1354
- if (id === void 0) {
1355
- throw new Error("Compaction invariant violation: missing id for repeated object");
1356
- }
1357
- return {
1358
- ["6d7f9da0-9cb6-496d-b72e-cf85ee4d9cf8" /* Ref */]: true,
1359
- id
1360
- };
1361
- }
1362
- if (rootOfIdValue !== void 0 && cyclic.has(current) && !emitted.has(current)) {
1363
- const id = ensureId(current);
1364
- emitted.add(current);
1365
- return {
1366
- ["348d020e-0d9e-4ae7-9415-b91af99f5339" /* Id */]: true,
1367
- id,
1368
- value: buildTreeChildren(current, current)
1369
- };
1370
- }
1371
- return buildTreeChildren(current, rootOfIdValue);
1372
- }
1373
- function buildAt(parent, key, current) {
1374
- if (current === null || typeof current !== "object") {
1375
- return current;
1376
- }
1377
- const occurrences = counts.get(current) ?? 0;
1378
- if (occurrences <= 1) {
1379
- if (Array.isArray(current)) {
1380
- return current.map((item, index) => buildAt(current, index, item));
1381
- }
1382
- return mapValues(current, (entryValue, entryKey) => buildAt(current, entryKey, entryValue));
1383
- }
1384
- const site = definitionSites.get(current);
1385
- const shouldDefineHere = site?.parent === parent && site.key === key;
1386
- const id = ids.get(current);
1387
- if (id === void 0) {
1388
- throw new Error("Compaction invariant violation: missing id for repeated object");
1389
- }
1390
- if (!shouldDefineHere || emitted.has(current)) {
1391
- return {
1392
- ["6d7f9da0-9cb6-496d-b72e-cf85ee4d9cf8" /* Ref */]: true,
1393
- id
1394
- };
1395
- }
1396
- emitted.add(current);
1397
- return {
1398
- ["348d020e-0d9e-4ae7-9415-b91af99f5339" /* Id */]: true,
1399
- id,
1400
- value: buildTreeChildren(current, current)
1401
- };
1402
- }
1403
- if (value === null || typeof value !== "object") {
1404
- return value;
1405
- }
1406
- const topLevelOccurrences = counts.get(value) ?? 0;
1407
- if (topLevelOccurrences > 1) {
1408
- const id = ensureId(value);
1409
- emitted.add(value);
1410
- return {
1411
- ["348d020e-0d9e-4ae7-9415-b91af99f5339" /* Id */]: true,
1412
- id,
1413
- value: buildTreeChildren(value, value)
1414
- };
1415
- }
1416
- if (Array.isArray(value)) {
1417
- return value.map((item, index) => buildAt(value, index, item));
1418
- }
1419
- return mapValues(
1420
- value,
1421
- (entryValue, entryKey) => buildAt(value, entryKey, entryValue)
1422
- );
1423
- }
1424
- function decompact(value) {
1425
- const rawValuesById = /* @__PURE__ */ new Map();
1426
- const placeholdersById = /* @__PURE__ */ new Map();
1427
- function collect(current, visited) {
1428
- const result = objectWithIdSchema.safeParse(current);
1429
- if (result.success) {
1430
- const { id } = result.data;
1431
- if (rawValuesById.has(id)) {
1432
- throw new Error(`Duplicate compacted id ${id}`);
1433
- }
1434
- rawValuesById.set(id, result.data.value);
1435
- collect(result.data.value, visited);
1436
- return;
1437
- }
1438
- if (current === null || current === void 0 || typeof current !== "object") {
1439
- return;
1440
- }
1441
- if (visited.has(current)) {
1442
- return;
1443
- }
1444
- visited.add(current);
1445
- if (Array.isArray(current)) {
1446
- for (const item of current) {
1447
- collect(item, visited);
1448
- }
1449
- return;
1450
- }
1451
- for (const entryValue of Object.values(current)) {
1452
- collect(entryValue, visited);
1453
- }
1454
- }
1455
- function ensurePlaceholder(id) {
1456
- const existing = placeholdersById.get(id);
1457
- if (existing !== void 0) {
1458
- return existing;
1459
- }
1460
- const raw = rawValuesById.get(id);
1461
- if (raw === void 0) {
1462
- throw new Error(`Unresolved compacted ref id ${id}`);
1463
- }
1464
- let placeholder;
1465
- if (raw !== null && typeof raw === "object") {
1466
- placeholder = Array.isArray(raw) ? [] : {};
1467
- } else {
1468
- placeholder = raw;
1469
- }
1470
- placeholdersById.set(id, placeholder);
1471
- return placeholder;
1472
- }
1473
- function resolve(current) {
1474
- const refResult = objectRefSchema.safeParse(current);
1475
- if (refResult.success) {
1476
- return ensurePlaceholder(refResult.data.id);
1477
- }
1478
- const withIdResult = objectWithIdSchema.safeParse(current);
1479
- if (withIdResult.success) {
1480
- return ensurePlaceholder(withIdResult.data.id);
1481
- }
1482
- if (current === null || current === void 0 || typeof current !== "object") {
1483
- return current;
1484
- }
1485
- if (Array.isArray(current)) {
1486
- return current.map((item) => resolve(item));
1487
- }
1488
- return mapValues(current, (entryValue) => resolve(entryValue));
1489
- }
1490
- function fillPlaceholder(id, visitedIds2) {
1491
- if (visitedIds2.has(id)) {
1492
- return;
1493
- }
1494
- visitedIds2.add(id);
1495
- const raw = rawValuesById.get(id);
1496
- if (raw === void 0) {
1497
- throw new Error(`Unresolved compacted ref id ${id}`);
1498
- }
1499
- const placeholder = ensurePlaceholder(id);
1500
- if (placeholder === null || typeof placeholder !== "object") {
1501
- return;
1502
- }
1503
- if (raw === null || typeof raw !== "object") {
1504
- throw new Error(`Compaction invariant violation: id ${id} points to non-object value`);
1505
- }
1506
- const resolved = resolve(raw);
1507
- if (Array.isArray(placeholder)) {
1508
- if (!Array.isArray(resolved)) {
1509
- throw new Error(`Compaction invariant violation: id ${id} array placeholder mismatch`);
1510
- }
1511
- placeholder.length = 0;
1512
- for (const item of resolved) {
1513
- placeholder.push(item);
1514
- }
1515
- return;
1516
- }
1517
- if (Array.isArray(resolved) || resolved === null || typeof resolved !== "object") {
1518
- throw new Error(`Compaction invariant violation: id ${id} object placeholder mismatch`);
1519
- }
1520
- for (const [key, entryValue] of Object.entries(resolved)) {
1521
- placeholder[key] = entryValue;
1522
- }
1523
- }
1524
- collect(value, /* @__PURE__ */ new WeakSet());
1525
- for (const id of rawValuesById.keys()) {
1526
- ensurePlaceholder(id);
1527
- }
1528
- const visitedIds = /* @__PURE__ */ new Set();
1529
- for (const id of rawValuesById.keys()) {
1530
- fillPlaceholder(id, visitedIds);
1531
- }
1532
- return resolve(value);
1533
- }
1422
+ // src/utils.ts
1423
+ import { isNonNullish as isNonNullish2, pickBy as pickBy2 } from "remeda";
1534
1424
  function text(strings, ...values) {
1535
1425
  const stringValues = values.map(String);
1536
1426
  let result = "";
1537
- for (let i = 0; i < strings.length; i++) {
1427
+ for (let i = 0;i < strings.length; i++) {
1538
1428
  result += strings[i];
1539
1429
  if (i < stringValues.length) {
1540
1430
  const value = stringValues[i];
1541
- const lines = value.split("\n");
1431
+ const lines = value.split(`
1432
+ `);
1542
1433
  const lastLineIndentMatch = strings[i].match(/(?:^|\n)([ \t]*)$/);
1543
1434
  const indent = lastLineIndentMatch ? lastLineIndentMatch[1] : "";
1544
- result += lines.map((line, j) => j === 0 ? line : indent + line).join("\n");
1435
+ result += lines.map((line, j) => j === 0 ? line : indent + line).join(`
1436
+ `);
1545
1437
  }
1546
1438
  }
1547
1439
  return trimIndentation(result);
1548
1440
  }
1549
1441
  function trimIndentation(text2) {
1550
- const lines = text2.split("\n");
1442
+ const lines = text2.split(`
1443
+ `);
1551
1444
  const indent = lines.filter((line) => line.trim() !== "").map((line) => line.match(/^\s*/)?.[0].length ?? 0).reduce((min, indent2) => Math.min(min, indent2), Infinity);
1552
- return lines.map((line) => line.slice(indent)).join("\n").trim();
1445
+ return lines.map((line) => line.slice(indent)).join(`
1446
+ `).trim();
1553
1447
  }
1554
1448
  function bytesToHumanReadable(bytes) {
1555
1449
  const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
1556
- if (bytes === 0) return "0 Bytes";
1450
+ if (bytes === 0)
1451
+ return "0 Bytes";
1557
1452
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
1558
1453
  return `${parseFloat((bytes / 1024 ** i).toFixed(2))} ${sizes[i]}`;
1559
1454
  }
@@ -1562,7 +1457,7 @@ function check(schema, value) {
1562
1457
  }
1563
1458
  function getOrCreate(map, key, createFn) {
1564
1459
  const existing = map.get(key);
1565
- if (existing !== void 0) {
1460
+ if (existing !== undefined) {
1566
1461
  return existing;
1567
1462
  }
1568
1463
  const value = createFn(key);
@@ -1570,9 +1465,100 @@ function getOrCreate(map, key, createFn) {
1570
1465
  return value;
1571
1466
  }
1572
1467
  function stripNullish(obj) {
1573
- return pickBy(obj, isNonNullish);
1468
+ return pickBy2(obj, isNonNullish2);
1574
1469
  }
1575
1470
 
1576
- export { $addArgumentDescription, $addInputDescription, $args, $inputs, $outputs, $secrets, HighstateConfigKey, HighstateSignature, InstanceNameConflictError, WellKnownInstanceCustomStatus, bytesToHumanReadable, camelCaseToHumanReadable, check, clearKnownAbbreviations, commonObjectMetaSchema, compact, componentArgumentSchema, componentInputSchema, componentModelSchema, componentSecretSchema, decompact, 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, isAssignableTo, isComponent, isEntity, isUnitModel, objectMetaSchema, objectRefSchema, objectWithIdSchema, originalCreate, pageBlockSchema, parseArgumentValue, parseInstanceId, parseVersionedName, positionSchema, registerKnownAbbreviations, resetEvaluation, runtimeSchema, serviceAccountMetaSchema, setValidationEnabled, stripNullish, terminalSpecSchema, text, timestampsSchema, triggerInvocationSchema, triggerSpecSchema, trimIndentation, unitArtifactId, unitArtifactSchema, unitConfigSchema, unitInputReference, unitModelSchema, unitPageSchema, unitSourceSchema, unitTerminalSchema, unitTriggerSchema, unitWorkerSchema, versionedNameSchema, workerRunOptionsSchema, yamlValueSchema };
1577
- //# sourceMappingURL=index.js.map
1578
- //# sourceMappingURL=index.js.map
1471
+ // src/index.ts
1472
+ import { z as z12 } from "zod";
1473
+ export {
1474
+ z12 as z,
1475
+ yamlValueSchema,
1476
+ workerRunOptionsSchema,
1477
+ versionedNameSchema,
1478
+ unitWorkerSchema,
1479
+ unitTriggerSchema,
1480
+ unitTerminalSchema,
1481
+ unitSourceSchema,
1482
+ unitPageSchema,
1483
+ unitModelSchema,
1484
+ unitInputValueSchema,
1485
+ unitInputSourceSchema,
1486
+ unitConfigSchema,
1487
+ unitArtifactSchema,
1488
+ unitArtifactId,
1489
+ trimIndentation,
1490
+ triggerSpecSchema,
1491
+ triggerInvocationSchema,
1492
+ timestampsSchema,
1493
+ text,
1494
+ terminalSpecSchema,
1495
+ stripNullish,
1496
+ setValidationEnabled,
1497
+ serviceAccountMetaSchema,
1498
+ selectInput,
1499
+ secretSchema,
1500
+ runtimeSchema,
1501
+ resetEvaluation,
1502
+ registerKnownAbbreviations,
1503
+ positionSchema,
1504
+ parseVersionedName,
1505
+ parseInstanceId,
1506
+ parseArgumentValue,
1507
+ pageBlockSchema,
1508
+ originalCreate,
1509
+ objectMetaSchema,
1510
+ kind,
1511
+ isUnitModel,
1512
+ isSecret,
1513
+ isEntity,
1514
+ isComponent,
1515
+ isAssignableTo,
1516
+ instanceStatusFieldValueSchema,
1517
+ instanceStatusFieldSchema,
1518
+ instanceModelSchema,
1519
+ instanceModelPatchSchema,
1520
+ instanceInputSchema,
1521
+ instanceIdSchema,
1522
+ inputKey,
1523
+ hubModelSchema,
1524
+ hubModelPatchSchema,
1525
+ hubInputSchema,
1526
+ globalCommonObjectMetaSchema,
1527
+ getRuntimeInstances,
1528
+ getOrCreate,
1529
+ getInstanceId,
1530
+ getEntityId,
1531
+ genericNameSchema,
1532
+ fileSchema,
1533
+ fileMetaSchema,
1534
+ fileContentSchema,
1535
+ fieldNameSchema,
1536
+ entityModelSchema,
1537
+ defineUnit,
1538
+ defineEntity,
1539
+ defineComponent,
1540
+ cuidv2d,
1541
+ createNonProvidedInput,
1542
+ createInput,
1543
+ componentSecretSchema,
1544
+ componentModelSchema,
1545
+ componentKindSchema,
1546
+ componentInputSchema,
1547
+ componentArgumentSchema,
1548
+ commonObjectMetaSchema,
1549
+ clearKnownAbbreviations,
1550
+ check,
1551
+ camelCaseToHumanReadable,
1552
+ bytesToHumanReadable,
1553
+ boundaryInput,
1554
+ WellKnownInstanceCustomStatus,
1555
+ InstanceNameConflictError,
1556
+ HighstateSignature,
1557
+ HighstateConfigKey,
1558
+ $secrets,
1559
+ $outputs,
1560
+ $inputs,
1561
+ $args,
1562
+ $addInputDescription,
1563
+ $addArgumentDescription
1564
+ };