@highstate/pulumi 0.20.0 → 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 +104 -63
- package/package.json +13 -13
- package/LICENSE +0 -21
- package/dist/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
export * from '@pulumi/pulumi';
|
|
3
|
-
import { HighstateSignature, getEntityId, HighstateConfigKey, unitConfigSchema, parseArgumentValue, runtimeSchema, z, parseInstanceId, camelCaseToHumanReadable, unitArtifactSchema } from '@highstate/contract';
|
|
4
|
-
import { crc32 } from 'node:zlib';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { pathToFileURL } from 'node:url';
|
|
7
|
-
import { mapValues, isPlainObject } from 'remeda';
|
|
8
|
-
|
|
1
|
+
// @bun
|
|
9
2
|
// src/index.ts
|
|
3
|
+
export * from "@pulumi/pulumi";
|
|
4
|
+
|
|
5
|
+
// src/entity.ts
|
|
6
|
+
import {
|
|
7
|
+
getEntityId,
|
|
8
|
+
HighstateSignature
|
|
9
|
+
} from "@highstate/contract";
|
|
10
|
+
import { output as output2 } from "@pulumi/pulumi";
|
|
11
|
+
|
|
12
|
+
// src/utils.ts
|
|
13
|
+
import { output } from "@pulumi/pulumi";
|
|
10
14
|
function toPromise(input) {
|
|
11
15
|
return new Promise((resolve) => output(input).apply(resolve));
|
|
12
16
|
}
|
|
@@ -53,7 +57,7 @@ function makeSecret(value) {
|
|
|
53
57
|
};
|
|
54
58
|
}
|
|
55
59
|
function makeSecretOutput(value) {
|
|
56
|
-
return
|
|
60
|
+
return output2(value).apply(makeSecret);
|
|
57
61
|
}
|
|
58
62
|
function makeSecretAsync(value) {
|
|
59
63
|
return toPromise(makeSecretOutput(value));
|
|
@@ -64,7 +68,7 @@ function makeEntityOutput({
|
|
|
64
68
|
meta,
|
|
65
69
|
value
|
|
66
70
|
}) {
|
|
67
|
-
return
|
|
71
|
+
return output2({
|
|
68
72
|
...value,
|
|
69
73
|
$meta: {
|
|
70
74
|
type: entity.type,
|
|
@@ -81,11 +85,14 @@ function getCombinedIdentity(entities) {
|
|
|
81
85
|
return sortedIds.join(":");
|
|
82
86
|
}
|
|
83
87
|
function getCombinedIdentityOutput(entities) {
|
|
84
|
-
return
|
|
88
|
+
return output2(entities).apply(getCombinedIdentity);
|
|
85
89
|
}
|
|
86
90
|
function getCombinedIdentityAsync(entities) {
|
|
87
91
|
return toPromise(getCombinedIdentityOutput(entities));
|
|
88
92
|
}
|
|
93
|
+
// src/file.ts
|
|
94
|
+
import { crc32 } from "zlib";
|
|
95
|
+
import { output as output3 } from "@pulumi/pulumi";
|
|
89
96
|
function makeFile({
|
|
90
97
|
name,
|
|
91
98
|
content,
|
|
@@ -102,7 +109,6 @@ function makeFile({
|
|
|
102
109
|
$meta: {
|
|
103
110
|
type: "common.file.v1",
|
|
104
111
|
identity: identity ?? crc32(stringContent).toString(16)
|
|
105
|
-
// use crc32 hash of the content as the default identity
|
|
106
112
|
},
|
|
107
113
|
meta: {
|
|
108
114
|
name,
|
|
@@ -114,12 +120,11 @@ function makeFile({
|
|
|
114
120
|
};
|
|
115
121
|
}
|
|
116
122
|
function makeFileOutput(options) {
|
|
117
|
-
return
|
|
123
|
+
return output3(options).apply((opts) => makeFile(opts));
|
|
118
124
|
}
|
|
119
125
|
function makeFileAsync(options) {
|
|
120
126
|
return toPromise(makeFileOutput(options));
|
|
121
127
|
}
|
|
122
|
-
|
|
123
128
|
// src/resource-hooks.ts
|
|
124
129
|
var hasResourceHooks = false;
|
|
125
130
|
function setResourceHooks() {
|
|
@@ -128,6 +133,26 @@ function setResourceHooks() {
|
|
|
128
133
|
function getHasResourceHooks() {
|
|
129
134
|
return hasResourceHooks;
|
|
130
135
|
}
|
|
136
|
+
// src/unit.ts
|
|
137
|
+
import { join } from "path";
|
|
138
|
+
import { pathToFileURL } from "url";
|
|
139
|
+
import {
|
|
140
|
+
camelCaseToHumanReadable,
|
|
141
|
+
HighstateConfigKey,
|
|
142
|
+
HighstateSignature as HighstateSignature2,
|
|
143
|
+
parseArgumentValue,
|
|
144
|
+
parseInstanceId,
|
|
145
|
+
runtimeSchema,
|
|
146
|
+
unitArtifactSchema,
|
|
147
|
+
unitConfigSchema,
|
|
148
|
+
z
|
|
149
|
+
} from "@highstate/contract";
|
|
150
|
+
import {
|
|
151
|
+
Config,
|
|
152
|
+
output as output4,
|
|
153
|
+
secret as pulumiSecret
|
|
154
|
+
} from "@pulumi/pulumi";
|
|
155
|
+
import { isPlainObject, mapValues } from "remeda";
|
|
131
156
|
var instanceId;
|
|
132
157
|
var stateId;
|
|
133
158
|
var instanceName;
|
|
@@ -182,7 +207,7 @@ function getInputValue(unit, inputName, input, entries) {
|
|
|
182
207
|
return values;
|
|
183
208
|
}
|
|
184
209
|
function forUnit(unit) {
|
|
185
|
-
const config = new Config
|
|
210
|
+
const config = new Config;
|
|
186
211
|
const rawHSConfig = config.requireObject(HighstateConfigKey.Config);
|
|
187
212
|
const hsConfig = unitConfigSchema.parse(rawHSConfig);
|
|
188
213
|
const args = mapValues(unit.model.args, (arg, argName) => {
|
|
@@ -193,21 +218,21 @@ function forUnit(unit) {
|
|
|
193
218
|
}
|
|
194
219
|
return result.data;
|
|
195
220
|
});
|
|
196
|
-
const secrets = mapValues(unit.model.secrets, (secret
|
|
221
|
+
const secrets = mapValues(unit.model.secrets, (secret, secretName) => {
|
|
197
222
|
const hasValue = secretName in hsConfig.secretValues;
|
|
198
|
-
if (!hasValue && !secret
|
|
199
|
-
return secret
|
|
223
|
+
if (!hasValue && !secret.required) {
|
|
224
|
+
return secret.schema.default ? pulumiSecret(secret.schema.default) : undefined;
|
|
200
225
|
}
|
|
201
|
-
if (!hasValue && secret
|
|
226
|
+
if (!hasValue && secret.required) {
|
|
202
227
|
throw new Error(`Secret "${secretName}" is required but not provided.`);
|
|
203
228
|
}
|
|
204
229
|
const rawValue = hsConfig.secretValues[secretName];
|
|
205
230
|
const value = parseArgumentValue(rawValue);
|
|
206
|
-
const result = secret
|
|
231
|
+
const result = secret[runtimeSchema].safeParse(value);
|
|
207
232
|
if (!result.success) {
|
|
208
233
|
throw new Error(`Invalid secret "${secretName}": ${z.prettifyError(result.error)}`);
|
|
209
234
|
}
|
|
210
|
-
return
|
|
235
|
+
return pulumiSecret(result.data);
|
|
211
236
|
});
|
|
212
237
|
const inputs = mapValues(unit.model.inputs, (input, inputName) => {
|
|
213
238
|
const value = hsConfig.inputs[inputName];
|
|
@@ -215,7 +240,7 @@ function forUnit(unit) {
|
|
|
215
240
|
if (input.multiple) {
|
|
216
241
|
return [];
|
|
217
242
|
}
|
|
218
|
-
return
|
|
243
|
+
return;
|
|
219
244
|
}
|
|
220
245
|
return getInputValue(unit, inputName, input, value);
|
|
221
246
|
});
|
|
@@ -233,17 +258,17 @@ function forUnit(unit) {
|
|
|
233
258
|
secrets,
|
|
234
259
|
inputs,
|
|
235
260
|
invokedTriggers: hsConfig.invokedTriggers,
|
|
236
|
-
getSecret: (
|
|
261
|
+
getSecret: (name2, factory) => {
|
|
237
262
|
if (!factory) {
|
|
238
263
|
return secrets[name2];
|
|
239
264
|
}
|
|
240
|
-
const value = secrets[name2] ??
|
|
265
|
+
const value = secrets[name2] ?? pulumiSecret(factory());
|
|
241
266
|
secrets[name2] = value;
|
|
242
267
|
return value;
|
|
243
|
-
}
|
|
244
|
-
setSecret: (
|
|
245
|
-
secrets[name2] =
|
|
246
|
-
}
|
|
268
|
+
},
|
|
269
|
+
setSecret: (name2, value) => {
|
|
270
|
+
secrets[name2] = pulumiSecret(value);
|
|
271
|
+
},
|
|
247
272
|
outputs: async (outputs = {}) => {
|
|
248
273
|
const resolvedOutputs = await toPromise(outputs);
|
|
249
274
|
const result = mapValues(resolvedOutputs, (outputValue, outputName) => {
|
|
@@ -267,24 +292,16 @@ function forUnit(unit) {
|
|
|
267
292
|
}
|
|
268
293
|
const outputModel = unit.model.outputs[outputName];
|
|
269
294
|
if (!outputModel) {
|
|
270
|
-
throw new Error(
|
|
271
|
-
`Output "${outputName}" not found in the unit "${unit.model.type}", but was passed to outputs(...).`
|
|
272
|
-
);
|
|
295
|
+
throw new Error(`Output "${outputName}" not found in the unit "${unit.model.type}", but was passed to outputs(...).`);
|
|
273
296
|
}
|
|
274
297
|
const entity = unit.entities.get(outputModel.type);
|
|
275
298
|
if (!entity) {
|
|
276
|
-
throw new Error(
|
|
277
|
-
`Entity "${outputModel.type}" not found in the unit "${unit.model.type}". It looks like a bug in the unit definition.`
|
|
278
|
-
);
|
|
299
|
+
throw new Error(`Entity "${outputModel.type}" not found in the unit "${unit.model.type}". It looks like a bug in the unit definition.`);
|
|
279
300
|
}
|
|
280
301
|
const schema = outputModel.multiple ? entity.schema.array() : entity.schema;
|
|
281
302
|
const result2 = schema.safeParse(outputValue);
|
|
282
303
|
if (!result2.success) {
|
|
283
|
-
throw new Error(
|
|
284
|
-
`Invalid value for output "${outputName}" of type "${outputModel.type}": ${z.prettifyError(
|
|
285
|
-
result2.error
|
|
286
|
-
)}`
|
|
287
|
-
);
|
|
304
|
+
throw new Error(`Invalid value for output "${outputName}" of type "${outputModel.type}": ${z.prettifyError(result2.error)}`);
|
|
288
305
|
}
|
|
289
306
|
return result2.data;
|
|
290
307
|
});
|
|
@@ -306,9 +323,9 @@ function forUnit(unit) {
|
|
|
306
323
|
};
|
|
307
324
|
}
|
|
308
325
|
function wrapHighstateSecretValues(data) {
|
|
309
|
-
const cache =
|
|
326
|
+
const cache = new WeakMap;
|
|
310
327
|
const traverse = (value) => {
|
|
311
|
-
if (value === null || value ===
|
|
328
|
+
if (value === null || value === undefined || typeof value !== "object") {
|
|
312
329
|
return value;
|
|
313
330
|
}
|
|
314
331
|
if (Array.isArray(value)) {
|
|
@@ -336,8 +353,8 @@ function wrapHighstateSecretValues(data) {
|
|
|
336
353
|
for (const [key, nestedValue] of Object.entries(record)) {
|
|
337
354
|
mapped[key] = traverse(nestedValue);
|
|
338
355
|
}
|
|
339
|
-
if (record[
|
|
340
|
-
return
|
|
356
|
+
if (record[HighstateSignature2.Secret] === true && "value" in record) {
|
|
357
|
+
return pulumiSecret(mapped);
|
|
341
358
|
}
|
|
342
359
|
return mapped;
|
|
343
360
|
};
|
|
@@ -348,7 +365,7 @@ function mapStatusFields(status) {
|
|
|
348
365
|
return [];
|
|
349
366
|
}
|
|
350
367
|
if (Array.isArray(status)) {
|
|
351
|
-
return status.filter((field) => field?.value !==
|
|
368
|
+
return status.filter((field) => field?.value !== undefined).map((field) => {
|
|
352
369
|
return {
|
|
353
370
|
name: field.name,
|
|
354
371
|
meta: {
|
|
@@ -360,7 +377,7 @@ function mapStatusFields(status) {
|
|
|
360
377
|
}
|
|
361
378
|
return Object.entries(status).map(([name, field]) => {
|
|
362
379
|
if (!field) {
|
|
363
|
-
return
|
|
380
|
+
return;
|
|
364
381
|
}
|
|
365
382
|
if (typeof field === "string" || typeof field === "number" || typeof field === "boolean" || Array.isArray(field)) {
|
|
366
383
|
return {
|
|
@@ -379,68 +396,68 @@ function mapStatusFields(status) {
|
|
|
379
396
|
},
|
|
380
397
|
name
|
|
381
398
|
};
|
|
382
|
-
}).filter((field) => field?.value !==
|
|
399
|
+
}).filter((field) => field?.value !== undefined);
|
|
383
400
|
}
|
|
384
401
|
function mapPages(pages) {
|
|
385
402
|
if (!pages) {
|
|
386
|
-
return
|
|
403
|
+
return output4([]);
|
|
387
404
|
}
|
|
388
405
|
if (!Array.isArray(pages)) {
|
|
389
406
|
pages = Object.entries(pages).map(([name, page]) => {
|
|
390
407
|
if (!page) {
|
|
391
|
-
return
|
|
408
|
+
return;
|
|
392
409
|
}
|
|
393
410
|
return { ...page, name };
|
|
394
411
|
});
|
|
395
412
|
}
|
|
396
|
-
return
|
|
413
|
+
return output4(pages.filter((page) => !!page));
|
|
397
414
|
}
|
|
398
415
|
function mapTerminals(terminals) {
|
|
399
416
|
if (!terminals) {
|
|
400
|
-
return
|
|
417
|
+
return output4([]);
|
|
401
418
|
}
|
|
402
419
|
if (!Array.isArray(terminals)) {
|
|
403
420
|
terminals = Object.entries(terminals).map(([name, terminal]) => {
|
|
404
421
|
if (!terminal) {
|
|
405
|
-
return
|
|
422
|
+
return;
|
|
406
423
|
}
|
|
407
424
|
return { ...terminal, name };
|
|
408
425
|
});
|
|
409
426
|
}
|
|
410
|
-
return
|
|
427
|
+
return output4(terminals.filter((terminal) => !!terminal));
|
|
411
428
|
}
|
|
412
429
|
function mapTriggers(triggers) {
|
|
413
430
|
if (!triggers) {
|
|
414
|
-
return
|
|
431
|
+
return output4([]);
|
|
415
432
|
}
|
|
416
433
|
if (!Array.isArray(triggers)) {
|
|
417
434
|
triggers = Object.entries(triggers).map(([name, trigger]) => {
|
|
418
435
|
if (!trigger) {
|
|
419
|
-
return
|
|
436
|
+
return;
|
|
420
437
|
}
|
|
421
438
|
return { ...trigger, name };
|
|
422
439
|
});
|
|
423
440
|
}
|
|
424
|
-
return
|
|
441
|
+
return output4(triggers.filter((trigger) => !!trigger));
|
|
425
442
|
}
|
|
426
443
|
function mapWorkers(workers) {
|
|
427
444
|
if (!workers) {
|
|
428
|
-
return
|
|
445
|
+
return output4([]);
|
|
429
446
|
}
|
|
430
447
|
if (!Array.isArray(workers)) {
|
|
431
448
|
workers = Object.entries(workers).map(([name, worker]) => {
|
|
432
449
|
if (!worker) {
|
|
433
|
-
return
|
|
450
|
+
return;
|
|
434
451
|
}
|
|
435
452
|
return { ...worker, name };
|
|
436
453
|
});
|
|
437
454
|
}
|
|
438
|
-
return
|
|
455
|
+
return output4(workers.filter((worker) => !!worker));
|
|
439
456
|
}
|
|
440
457
|
function extractObjectsFromValue(schema, data) {
|
|
441
458
|
const result = [];
|
|
442
459
|
function traverse(obj) {
|
|
443
|
-
if (obj === null || obj ===
|
|
460
|
+
if (obj === null || obj === undefined || typeof obj !== "object") {
|
|
444
461
|
return;
|
|
445
462
|
}
|
|
446
463
|
if (Array.isArray(obj)) {
|
|
@@ -464,7 +481,31 @@ function extractObjectsFromValue(schema, data) {
|
|
|
464
481
|
function getUnitTempPath() {
|
|
465
482
|
return join("/tmp/highstate", getUnitStateId());
|
|
466
483
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
484
|
+
export {
|
|
485
|
+
toPromise,
|
|
486
|
+
setResourceHooks,
|
|
487
|
+
normalizeInputsAndMap,
|
|
488
|
+
normalizeInputs,
|
|
489
|
+
normalize,
|
|
490
|
+
makeSecretOutput,
|
|
491
|
+
makeSecretAsync,
|
|
492
|
+
makeSecret,
|
|
493
|
+
makeFileOutput,
|
|
494
|
+
makeFileAsync,
|
|
495
|
+
makeFile,
|
|
496
|
+
makeEntityOutput,
|
|
497
|
+
makeEntityAsync,
|
|
498
|
+
makeEntity,
|
|
499
|
+
getUnitTempPath,
|
|
500
|
+
getUnitStateId,
|
|
501
|
+
getUnitInstanceName,
|
|
502
|
+
getUnitInstanceId,
|
|
503
|
+
getResourceComment,
|
|
504
|
+
getImportBaseUrl,
|
|
505
|
+
getHasResourceHooks,
|
|
506
|
+
getCombinedIdentityOutput,
|
|
507
|
+
getCombinedIdentityAsync,
|
|
508
|
+
getCombinedIdentity,
|
|
509
|
+
forUnit,
|
|
510
|
+
apply
|
|
511
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highstate/pulumi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -28,25 +28,25 @@
|
|
|
28
28
|
"platform"
|
|
29
29
|
]
|
|
30
30
|
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "highstate build",
|
|
33
|
+
"typecheck": "tsgo --noEmit --skipLibCheck",
|
|
34
|
+
"biome": "biome check --write --unsafe --error-on-warnings",
|
|
35
|
+
"biome:check": "biome check --error-on-warnings"
|
|
36
|
+
},
|
|
31
37
|
"dependencies": {
|
|
32
|
-
"@
|
|
38
|
+
"@highstate/contract": "0.20.0",
|
|
39
|
+
"@pulumi/pulumi": "3.232.0",
|
|
33
40
|
"deepmerge-ts": "^7.1.5",
|
|
34
41
|
"remeda": "^2.21.0",
|
|
35
|
-
"type-fest": "^4.41.0"
|
|
36
|
-
"@highstate/contract": "0.20.0"
|
|
42
|
+
"type-fest": "^4.41.0"
|
|
37
43
|
},
|
|
38
44
|
"devDependencies": {
|
|
39
45
|
"@biomejs/biome": "2.2.0",
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
46
|
+
"@highstate/cli": "0.20.0",
|
|
47
|
+
"@typescript/native-preview": "^7.0.0-dev.20250920.1"
|
|
42
48
|
},
|
|
43
49
|
"repository": {
|
|
44
50
|
"url": "https://github.com/highstate-io/highstate"
|
|
45
|
-
},
|
|
46
|
-
"scripts": {
|
|
47
|
-
"build": "highstate build",
|
|
48
|
-
"typecheck": "tsgo --noEmit --skipLibCheck",
|
|
49
|
-
"biome": "biome check --write --unsafe --error-on-warnings",
|
|
50
|
-
"biome:check": "biome check --error-on-warnings"
|
|
51
51
|
}
|
|
52
|
-
}
|
|
52
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Exeteres
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/entity.ts","../src/file.ts","../src/resource-hooks.ts","../src/unit.ts"],"names":["item","collection","output","secret","pulumiSecret","name","result","cached","mapped","HighstateSignature"],"mappings":"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","file":"index.js","sourcesContent":["import { type Input, type Output, output, type Unwrap } from \"@pulumi/pulumi\"\n\n/**\n * The input type for an array of inputs.\n * The same as `Input<Input<T>[]>`, but more readable.\n */\nexport type InputArray<T> = Input<Input<T>[]>\n\n/**\n * The input type for a record of inputs.\n * The same as `Input<Record<string, Input<T>>>`, but more readable.\n */\nexport type InputRecord<T> = Input<Record<string, Input<T>>>\n\n/**\n * The input or input array type for a value.\n */\nexport type InputOrArray<T> = Input<T> | InputArray<T>\n\ntype LeafValue = string | number | boolean | null | undefined\ntype IsUnknown<T> = unknown extends T ? (T extends unknown ? true : false) : false\n\n/**\n * The recursive input type for a value.\n */\nexport type DeepInput<T> = [T] extends [LeafValue]\n ? Input<T>\n : IsUnknown<T> extends true\n ? Input<unknown>\n : Input<{ [K in keyof T]: DeepInput<T[K]> }>\n\n/**\n * Transforms an input value to a promise that resolves to the unwrapped value.\n *\n * @param input The input value to transform.\n * @returns A promise that resolves to the unwrapped value.\n */\nexport function toPromise<T>(input: Input<T>): Promise<Unwrap<T>> {\n return new Promise(resolve => output(input).apply(resolve))\n}\n\n/**\n * Receives an item and a collection, and returns an array containing the item and the collection.\n *\n * Excludes the item if it is undefined.\n *\n * @param item The single item input.\n * @param collection The collection of items input.\n */\nexport function normalize<T>(item: T | undefined, collection: T[] | undefined): T[] {\n if (item && collection) {\n return [item, ...collection]\n }\n\n if (item) {\n return [item]\n }\n\n return collection ?? []\n}\n\n/**\n * The same as `normalize`, but accepts inputs and returns output.\n *\n * @param item The single item input.\n * @param collection The collection of items input.\n */\nexport function normalizeInputs<T>(\n item: Input<T> | undefined,\n collection: InputArray<T> | undefined,\n): Output<Unwrap<T>[]> {\n return (\n output({ item, collection })\n //\n .apply(({ item, collection }) => normalize(item, collection)) as Output<Unwrap<T>[]>\n )\n}\n\n/**\n * The convenience function to normalize inputs and map them to a new type.\n *\n * @param item The single item input.\n * @param collection The collection of items input.\n * @param mapFn The function to map each item to a new type.\n */\nexport function normalizeInputsAndMap<T, U>(\n item: Input<T> | undefined,\n collection: InputArray<T> | undefined,\n mapFn: (value: Unwrap<T>) => U,\n): Output<U[]> {\n return normalizeInputs(item, collection).apply(values => values.map(mapFn))\n}\n\n/**\n * Applies a function to the input and returns an output.\n *\n * Can be used in `remeda` pipelines.\n *\n * @param fn The function to apply to the input.\n */\nexport function apply<T, U>(fn: (value: Unwrap<T>) => U): (input: Input<T>) => Output<U> {\n return input => output(input).apply(fn)\n}\n","import {\n type Entity,\n type EntityMeta,\n type EntityValue,\n type EntityValueInput,\n type EntityWithMeta,\n getEntityId,\n HighstateSignature,\n type Secret,\n} from \"@highstate/contract\"\nimport { type Input, type Output, output, type Unwrap } from \"@pulumi/pulumi\"\nimport { type DeepInput, type InputArray, toPromise } from \"./utils\"\n\nexport type MakeEntityOptions<TEntity extends Entity> = {\n entity: TEntity\n identity: string\n meta?: Omit<EntityMeta, \"type\" | \"identity\">\n value: Omit<EntityValueInput<TEntity>, \"$meta\">\n}\n\nexport function makeEntity<TEntity extends Entity>({\n entity,\n identity,\n meta,\n value,\n}: MakeEntityOptions<TEntity>): EntityValue<TEntity> {\n const built = {\n ...(value as Record<string, unknown>),\n $meta: {\n type: entity.type,\n identity,\n ...meta,\n },\n }\n\n return entity.schema.parse(built) as EntityValue<TEntity>\n}\n\ntype CommonEntityMeta = Omit<EntityMeta, \"type\" | \"identity\">\n\nexport type MakeEntityAsyncOptions<TEntity extends Entity> = {\n entity: TEntity\n identity: Input<string>\n meta?: { [K in keyof CommonEntityMeta]?: Input<CommonEntityMeta[K]> }\n value: {\n [K in keyof Omit<EntityValueInput<TEntity>, \"$meta\">]: DeepInput<EntityValueInput<TEntity>[K]>\n }\n}\n\nexport function makeSecret<TValue>(value: TValue): Secret<TValue> {\n return {\n [HighstateSignature.Secret]: true,\n value,\n }\n}\n\nexport function makeSecretOutput<TValue>(value: Input<TValue>): Output<Secret<Unwrap<TValue>>> {\n return output(value).apply(makeSecret)\n}\n\nexport function makeSecretAsync<TValue>(value: Input<TValue>): Promise<Secret<Unwrap<TValue>>> {\n return toPromise(makeSecretOutput(value)) as Promise<Secret<Unwrap<TValue>>>\n}\n\nexport function makeEntityOutput<TEntity extends Entity>({\n entity,\n identity,\n meta,\n value,\n}: MakeEntityAsyncOptions<TEntity>): Output<EntityValue<TEntity>> {\n return output({\n ...value,\n $meta: {\n type: entity.type,\n identity,\n ...meta,\n },\n }).apply(built => entity.schema.parse(built)) as Output<EntityValue<TEntity>>\n}\n\nexport function makeEntityAsync<TEntity extends Entity>(\n options: MakeEntityAsyncOptions<TEntity>,\n): Promise<EntityValue<TEntity>> {\n return toPromise(makeEntityOutput(options)) as Promise<EntityValue<TEntity>>\n}\n\nexport type IdentitySource = EntityWithMeta | string\n\n/**\n * Get the combined identity based on the ids of the given entities.\n *\n * This function can be used for entities that do not have their own identity but are defined by the combination of other entities (e.g. a server defined by its network endpoints).\n */\nexport function getCombinedIdentity(entities: IdentitySource[]): string {\n const sortedIds = entities\n .map(source => (typeof source === \"string\" ? source : getEntityId(source)))\n .sort() // sort to ensure consistent identity regardless of the order of entities\n\n return sortedIds.join(\":\")\n}\n\nexport function getCombinedIdentityOutput(entities: InputArray<IdentitySource>): Output<string> {\n return output(entities).apply(getCombinedIdentity)\n}\n\nexport function getCombinedIdentityAsync(entities: IdentitySource[]): Promise<string> {\n return toPromise(getCombinedIdentityOutput(entities))\n}\n","import type { EntityWithMeta, FileContent, FileMeta } from \"@highstate/contract\"\nimport { crc32 } from \"node:zlib\"\nimport { type Input, type Output, output, type Unwrap } from \"@pulumi/pulumi\"\nimport { makeSecret } from \"./entity\"\nimport { toPromise } from \"./utils\"\n\n/**\n * The BaseFile is type that compatible with both the contract's File type and the file entity used in the library.\n *\n * It should be used in most places instead of the contract's File type to avoid unnecessary conversions, and it can be safely cast to the contract's File type when needed.\n */\nexport type BaseFile = EntityWithMeta & {\n meta: FileMeta\n content: FileContent\n}\n\nexport type FileOptions = {\n /**\n * The name of the file.\n */\n name: Input<string>\n\n /**\n * The content of the file as a string or a buffer.\n */\n content: Input<string | Buffer>\n\n /**\n * The identity to use for the file entity.\n *\n * If not provided, defaults to the hash of the content.\n */\n identity?: Input<string>\n\n /**\n * Whether the content should be treated as a secret or not.\n */\n isSecret?: Input<boolean>\n\n /**\n * The content type of the file.\n *\n * Defaults to \"text/plain\" if the content is a string and \"application/octet-stream\" if the content is a buffer.\n */\n contentType?: Input<string>\n\n /**\n * The file mode (permissions) to set on the file when materialized.\n *\n * Defaults to 0o644.\n */\n mode?: Input<number>\n}\n\n/**\n * Creates a file entity from the given options.\n *\n * This file can also be used for both:\n * - core Highstate capabilities like terminals and pages;\n * - as inputs for other units requiring files.\n */\nexport function makeFile({\n name,\n content,\n contentType,\n identity,\n isSecret,\n mode,\n}: Unwrap<FileOptions>): BaseFile {\n const stringContent = typeof content === \"string\" ? content : content.toString(\"base64\")\n const isBinary = typeof content !== \"string\"\n const inferredContentType =\n contentType ?? (typeof content === \"string\" ? \"text/plain\" : \"application/octet-stream\")\n const size =\n typeof content === \"string\" ? Buffer.byteLength(content, \"utf-8\") : content.byteLength\n\n return {\n $meta: {\n type: \"common.file.v1\",\n identity: identity ?? crc32(stringContent).toString(16), // use crc32 hash of the content as the default identity\n },\n meta: {\n name,\n contentType: inferredContentType,\n size,\n mode,\n },\n content: isSecret\n ? { type: \"embedded-secret\", value: makeSecret(stringContent), isBinary }\n : { type: \"embedded\", value: stringContent, isBinary },\n }\n}\n\n/**\n * Similar to `makeFile`, but returns a Pulumi Output that resolves to a file entity.\n */\nexport function makeFileOutput(options: FileOptions): Output<BaseFile> {\n return output(options).apply(opts => makeFile(opts))\n}\n\n/**\n * Similar to `makeFile`, but returns a Promise that resolves to a file entity.\n */\nexport function makeFileAsync(options: FileOptions): Promise<BaseFile> {\n return toPromise(makeFileOutput(options))\n}\n","let hasResourceHooks = false\n\n/**\n * Marks the current Pulumi program as using resource hooks.\n *\n * The backend uses `$hasResourceHooks` output to decide whether it should run the Pulumi program on destroy.\n */\nexport function setResourceHooks(): void {\n hasResourceHooks = true\n}\n\nexport function getHasResourceHooks(): boolean {\n return hasResourceHooks\n}\n","/** biome-ignore-all lint/suspicious/noExplicitAny: здесь орать запрещено */\n\nimport type { IsEmptyObject } from \"type-fest\"\nimport { join } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport {\n type ComponentInput,\n type ComponentInputSpec,\n camelCaseToHumanReadable,\n type EntityValue,\n type EntityValueInput,\n HighstateConfigKey,\n HighstateSignature,\n type InstanceStatusField,\n type InstanceStatusFieldValue,\n type PartialKeys,\n parseArgumentValue,\n parseInstanceId,\n runtimeSchema,\n type TriggerInvocation,\n type Unit,\n type UnitArtifact,\n type UnitInputValue,\n type UnitPage,\n type UnitTerminal,\n type UnitTrigger,\n type UnitWorker,\n unitArtifactSchema,\n unitConfigSchema,\n type VersionedName,\n z,\n} from \"@highstate/contract\"\nimport {\n Config,\n type Input,\n type Output,\n output,\n secret as pulumiSecret,\n type Unwrap,\n} from \"@pulumi/pulumi\"\nimport { isPlainObject, mapValues } from \"remeda\"\nimport { getHasResourceHooks } from \"./resource-hooks\"\nimport { type DeepInput, toPromise } from \"./utils\"\n\ntype StatusField<TArgName extends string = string> = Omit<\n InstanceStatusField,\n \"complementaryTo\" | \"meta\"\n> & {\n meta?: PartialKeys<InstanceStatusField[\"meta\"], \"title\">\n complementaryTo?: TArgName\n}\n\ntype ExtraOutputs<TArgName extends string = string> = {\n $statusFields?:\n | Input<\n Record<\n string,\n DeepInput<Omit<StatusField<TArgName>, \"name\"> | InstanceStatusFieldValue | undefined>\n >\n >\n | Input<DeepInput<StatusField<TArgName> | undefined>[]>\n\n $terminals?:\n | Input<Record<string, DeepInput<Omit<UnitTerminal, \"name\"> | undefined>>>\n | Input<DeepInput<UnitTerminal | undefined>[]>\n\n $pages?:\n | Input<Record<string, DeepInput<Omit<UnitPage, \"name\"> | undefined>>>\n | Input<DeepInput<UnitPage | undefined>[]>\n\n $triggers?:\n | Input<Record<string, DeepInput<Omit<UnitTrigger, \"name\"> | undefined>>>\n | Input<DeepInput<UnitTrigger | undefined>[]>\n\n $workers?:\n | Input<Record<string, DeepInput<Omit<UnitWorker, \"name\"> | undefined>>>\n | Input<DeepInput<UnitWorker | undefined>[]>\n}\n\ntype OutputMapToDeepInputMap<\n T extends Record<string, unknown>,\n TArgName extends string,\n> = IsEmptyObject<T> extends true\n ? ExtraOutputs\n : { [K in keyof T]: DeepInput<T[K]> } & ExtraOutputs<TArgName>\n\ninterface UnitContext<\n TArgs extends Record<string, unknown>,\n TInputs extends Record<string, unknown>,\n TOutputs extends Record<string, unknown>,\n TSecrets extends Record<string, unknown>,\n> {\n args: TArgs\n instanceId: string\n stateId: string\n type: string\n name: string\n\n secrets: {\n [K in keyof TSecrets]: undefined extends TSecrets[K]\n ? Output<NonNullable<TSecrets[K]>> | undefined\n : Output<TSecrets[K]>\n }\n\n getSecret<K extends keyof TSecrets>(\n this: void,\n name: K,\n ): Output<NonNullable<TSecrets[K]> | undefined>\n\n getSecret<K extends keyof TSecrets>(\n this: void,\n name: K,\n factory: () => Input<NonNullable<TSecrets[K]>>,\n ): Output<NonNullable<TSecrets[K]>>\n\n setSecret<K extends keyof TSecrets>(\n this: void,\n name: K,\n value: Input<NonNullable<TSecrets[K]>>,\n ): void\n\n inputs: TInputs\n invokedTriggers: TriggerInvocation[]\n\n outputs(\n this: void,\n outputs?: OutputMapToDeepInputMap<TOutputs, keyof TArgs & string>,\n ): Promise<unknown>\n}\n\n// z.output since the values are validated/transformed and passed to the user\ntype InputSpecToWrappedValue<T extends ComponentInputSpec> = T[2] extends true\n ? NonNullable<EntityValue<T[0]>>[]\n : T[1] extends true\n ? NonNullable<EntityValue<T[0]>>\n : NonNullable<EntityValue<T[0]>> | undefined\n\n// z.input since the values are passed from the user and should be validated/transformed before returning from the unit\ntype OutputSpecToValue<T extends ComponentInputSpec> = T[2] extends true\n ? T[1] extends true\n ? NonNullable<EntityValueInput<T[0]>>[]\n : NonNullable<EntityValueInput<T[0]>>[] | undefined\n : T[1] extends true\n ? NonNullable<EntityValueInput<T[0]>>\n : NonNullable<EntityValueInput<T[0]>> | undefined\n\nlet instanceId: string | undefined\nlet stateId: string | undefined\nlet instanceName: string | undefined\nlet importBaseUrl: URL | undefined\n\n/**\n * Returns the current unit instance id.\n *\n * Only available after calling `forUnit` function.\n */\nexport function getUnitInstanceId(): string {\n if (!instanceId) {\n throw new Error(`Instance id is not set. Did you call \"forUnit\" function?`)\n }\n\n return instanceId\n}\n\n/**\n * Returns the current unit instance state id.\n *\n * The state id is provided by the runner via Pulumi config.\n * Only available after calling `forUnit` function.\n */\nexport function getUnitStateId(): string {\n if (!stateId) {\n throw new Error(`State id is not set. Did you call \"forUnit\" function?`)\n }\n\n return stateId\n}\n\n/**\n * Returns the current unit instance name.\n */\nexport function getUnitInstanceName(): string {\n if (!instanceName) {\n throw new Error(`Instance name is not set. Did you call \"forUnit\" function?`)\n }\n\n return instanceName\n}\n\n/**\n * Returns the base URL for dynamic imports.\n */\nexport function getImportBaseUrl(): URL {\n if (!importBaseUrl) {\n throw new Error(`Import base URL is not set. Did you call \"forUnit\" function?`)\n }\n\n return importBaseUrl\n}\n\n/**\n * Returns a comment that can be used in resources to indicate that they are managed by Highstate.\n */\nexport function getResourceComment(): string {\n return `Managed by Highstate [${getUnitStateId()}]`\n}\n\nfunction getInputValue(\n unit: Unit,\n inputName: string,\n input: ComponentInput,\n entries: UnitInputValue[],\n) {\n const entity = unit.entities.get(input.type)\n if (!entity) {\n throw new Error(`Entity \"${input.type}\" not found in the unit \"${unit.model.type}\".`)\n }\n\n const values = entries.flatMap(entry => {\n const value = parseArgumentValue(entry.value)\n const schema = Array.isArray(value) ? entity.schema.array() : entity.schema\n const result = schema.safeParse(value)\n\n if (!result.success) {\n throw new Error(`Invalid value for input \"${inputName}\": ${z.prettifyError(result.error)}`)\n }\n\n if (Array.isArray(result.data)) {\n return result.data\n }\n\n return input.multiple ? [result.data] : [result.data]\n })\n\n if (!input.multiple) {\n return values[0]\n }\n\n return values\n}\n\nexport function forUnit<\n TType extends VersionedName,\n TArgs extends Record<string, z.ZodType>,\n TInputs extends Record<string, ComponentInputSpec>,\n TOutputs extends Record<string, ComponentInputSpec>,\n TSecrets extends Record<string, z.ZodType>,\n>(\n unit: Unit<TType, TArgs, TInputs, TOutputs, TSecrets>,\n): UnitContext<\n { [K in keyof TArgs]: z.output<TArgs[K]> },\n { [K in keyof TInputs]: InputSpecToWrappedValue<TInputs[K]> },\n { [K in keyof TOutputs]: OutputSpecToValue<TOutputs[K]> },\n { [K in keyof TSecrets]: z.output<TSecrets[K]> }\n> {\n const config = new Config()\n const rawHSConfig = config.requireObject(HighstateConfigKey.Config)\n const hsConfig = unitConfigSchema.parse(rawHSConfig)\n\n const args = mapValues(unit.model.args, (arg, argName) => {\n const value = parseArgumentValue(hsConfig.args[argName])\n const result = arg[runtimeSchema]!.safeParse(value)\n\n if (!result.success) {\n throw new Error(`Invalid argument \"${argName}\": ${z.prettifyError(result.error)}`)\n }\n\n return result.data\n })\n\n const secrets = mapValues(unit.model.secrets, (secret, secretName) => {\n const hasValue = secretName in hsConfig.secretValues\n\n if (!hasValue && !secret.required) {\n return secret.schema.default ? pulumiSecret(secret.schema.default) : undefined\n }\n\n if (!hasValue && secret.required) {\n throw new Error(`Secret \"${secretName}\" is required but not provided.`)\n }\n\n const rawValue = hsConfig.secretValues[secretName]\n const value = parseArgumentValue(rawValue)\n const result = secret[runtimeSchema]!.safeParse(value)\n\n if (!result.success) {\n throw new Error(`Invalid secret \"${secretName}\": ${z.prettifyError(result.error)}`)\n }\n\n return pulumiSecret(result.data)\n })\n\n const inputs = mapValues(unit.model.inputs, (input, inputName) => {\n const value = hsConfig.inputs[inputName]\n\n if (!value) {\n if (input.multiple) {\n return []\n }\n\n return undefined\n }\n\n return getInputValue(unit as unknown as Unit, inputName, input, value)\n })\n\n const [type, name] = parseInstanceId(hsConfig.instanceId)\n\n instanceId = hsConfig.instanceId\n stateId = hsConfig.stateId\n instanceName = name\n importBaseUrl = pathToFileURL(hsConfig.importBasePath)\n\n return {\n instanceId: hsConfig.instanceId,\n stateId: hsConfig.stateId,\n type,\n name,\n\n args: args as any,\n secrets: secrets as any,\n inputs: inputs as any,\n invokedTriggers: hsConfig.invokedTriggers,\n\n getSecret: (<K extends keyof TSecrets>(\n name: K,\n factory?: () => Input<NonNullable<TSecrets[K]>>,\n ) => {\n if (!factory) {\n return secrets[name as string]\n }\n\n const value = secrets[name as string] ?? pulumiSecret(factory())\n secrets[name as string] = value\n\n return value\n }) as any,\n\n setSecret: ((name: keyof TSecrets, value: Input<NonNullable<TSecrets[keyof TSecrets]>>) => {\n secrets[name as string] = pulumiSecret(value)\n }) as any,\n\n outputs: async (outputs: any = {}) => {\n const resolvedOutputs = await toPromise(outputs)\n\n const result: any = mapValues(resolvedOutputs, (outputValue, outputName) => {\n if (outputName === \"$statusFields\") {\n return mapStatusFields(outputValue)\n }\n\n if (outputName === \"$pages\") {\n return mapPages(outputValue)\n }\n\n if (outputName === \"$terminals\") {\n return mapTerminals(outputValue)\n }\n\n if (outputName === \"$triggers\") {\n return mapTriggers(outputValue)\n }\n\n if (outputName === \"$workers\") {\n return mapWorkers(outputValue)\n }\n\n if (outputName.startsWith(\"$\")) {\n throw new Error(`Unknown extra output \"${outputName}\".`)\n }\n\n const outputModel = unit.model.outputs[outputName]\n if (!outputModel) {\n throw new Error(\n `Output \"${outputName}\" not found in the unit \"${unit.model.type}\", but was passed to outputs(...).`,\n )\n }\n\n const entity = unit.entities.get(outputModel.type)\n if (!entity) {\n throw new Error(\n `Entity \"${outputModel.type}\" not found in the unit \"${unit.model.type}\". It looks like a bug in the unit definition.`,\n )\n }\n\n const schema = outputModel.multiple ? entity.schema.array() : entity.schema\n const result = schema.safeParse(outputValue)\n\n if (!result.success) {\n throw new Error(\n `Invalid value for output \"${outputName}\" of type \"${outputModel.type}\": ${z.prettifyError(\n result.error,\n )}`,\n )\n }\n\n return result.data\n })\n\n result.$secrets = secrets\n\n // collect artifacts from all outputs\n const artifactsMap: Record<string, UnitArtifact[]> = {}\n for (const [outputName, outputValue] of Object.entries(outputs)) {\n const resolvedValue = await toPromise(outputValue)\n const artifacts = extractObjectsFromValue(unitArtifactSchema, resolvedValue)\n if (artifacts.length > 0) {\n artifactsMap[outputName] = artifacts\n }\n }\n\n if (Object.keys(artifactsMap).length > 0) {\n result.$artifacts = artifactsMap\n }\n\n result.$hasResourceHooks = getHasResourceHooks()\n\n return wrapHighstateSecretValues(result)\n },\n }\n}\n\nfunction wrapHighstateSecretValues<T>(data: T): T {\n const cache = new WeakMap<object, unknown>()\n\n const traverse = (value: unknown): unknown => {\n if (value === null || value === undefined || typeof value !== \"object\") {\n return value\n }\n\n if (Array.isArray(value)) {\n const cached = cache.get(value)\n if (cached) {\n return cached\n }\n\n const mapped: unknown[] = []\n cache.set(value, mapped)\n\n for (const item of value) {\n mapped.push(traverse(item))\n }\n\n return mapped\n }\n\n if (!isPlainObject(value)) {\n return value\n }\n\n const cached = cache.get(value)\n if (cached) {\n return cached\n }\n\n const record = value as Record<string, unknown>\n const mapped: Record<string, unknown> = {}\n cache.set(value, mapped)\n\n for (const [key, nestedValue] of Object.entries(record)) {\n mapped[key] = traverse(nestedValue)\n }\n\n if (record[HighstateSignature.Secret] === true && \"value\" in record) {\n return pulumiSecret(mapped)\n }\n\n return mapped\n }\n\n return traverse(data) as T\n}\n\nfunction mapStatusFields(status: Unwrap<ExtraOutputs[\"$statusFields\"]>): InstanceStatusField[] {\n if (!status) {\n return []\n }\n\n if (Array.isArray(status)) {\n return status\n .filter((field): field is NonNullable<StatusField> => field?.value !== undefined)\n .map(field => {\n return {\n name: field.name,\n meta: {\n title: field.meta?.title ?? camelCaseToHumanReadable(field.name),\n },\n value: field.value,\n }\n })\n }\n\n return Object.entries(status)\n .map(([name, field]) => {\n if (!field) {\n return undefined\n }\n\n if (\n typeof field === \"string\" ||\n typeof field === \"number\" ||\n typeof field === \"boolean\" ||\n Array.isArray(field)\n ) {\n return {\n name,\n meta: {\n title: camelCaseToHumanReadable(name),\n },\n value: field,\n }\n }\n\n return {\n ...field,\n meta: {\n ...field.meta,\n title: field.meta?.title ?? camelCaseToHumanReadable(name),\n },\n name,\n }\n })\n .filter((field): field is InstanceStatusField => field?.value !== undefined)\n}\n\nfunction mapPages(pages: Unwrap<ExtraOutputs[\"$pages\"]>): Output<UnitPage[]> {\n if (!pages) {\n return output([])\n }\n\n if (!Array.isArray(pages)) {\n pages = Object.entries(pages).map(([name, page]) => {\n if (!page) {\n return undefined\n }\n\n return { ...page, name }\n })\n }\n\n return output(pages.filter((page): page is NonNullable<UnitPage> => !!page))\n}\n\nfunction mapTerminals(terminals: Unwrap<ExtraOutputs[\"$terminals\"]>): Output<UnitTerminal[]> {\n if (!terminals) {\n return output([])\n }\n\n if (!Array.isArray(terminals)) {\n terminals = Object.entries(terminals).map(([name, terminal]) => {\n if (!terminal) {\n return undefined\n }\n\n return { ...terminal, name }\n })\n }\n\n return output(terminals.filter((terminal): terminal is NonNullable<UnitTerminal> => !!terminal))\n}\n\nfunction mapTriggers(triggers: Unwrap<ExtraOutputs[\"$triggers\"]>): Output<UnitTrigger[]> {\n if (!triggers) {\n return output([])\n }\n\n if (!Array.isArray(triggers)) {\n triggers = Object.entries(triggers).map(([name, trigger]) => {\n if (!trigger) {\n return undefined\n }\n\n return { ...trigger, name }\n })\n }\n\n return output(triggers.filter((trigger): trigger is NonNullable<UnitTrigger> => !!trigger))\n}\n\nfunction mapWorkers(workers: Unwrap<ExtraOutputs[\"$workers\"]>): Output<Unwrap<UnitWorker>[]> {\n if (!workers) {\n return output([])\n }\n\n if (!Array.isArray(workers)) {\n workers = Object.entries(workers).map(([name, worker]) => {\n if (!worker) {\n return undefined\n }\n\n return { ...worker, name }\n })\n }\n\n return output(workers.filter((worker): worker is NonNullable<Unwrap<UnitWorker>> => !!worker))\n}\n\n/**\n * Extracts all objects with the specified schema from a value.\n */\nfunction extractObjectsFromValue<TSchema extends z.ZodType>(\n schema: TSchema,\n data: unknown,\n): z.infer<TSchema>[] {\n const result: z.infer<TSchema>[] = []\n\n function traverse(obj: unknown): void {\n if (obj === null || obj === undefined || typeof obj !== \"object\") {\n return\n }\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n traverse(item)\n }\n return\n }\n\n const parseResult = schema.safeParse(obj)\n if (parseResult.success) {\n result.push(parseResult.data)\n return\n }\n\n // recursively traverse all properties\n for (const value of Object.values(obj)) {\n traverse(value)\n }\n }\n\n traverse(data)\n return result\n}\n\n/**\n * Returns a temporary file path for the current unit instance.\n *\n * The format is `/tmp/highstate/{stateId}`.\n * This directory does not change between different runs of the same unit instance.\n */\nexport function getUnitTempPath(): string {\n return join(\"/tmp/highstate\", getUnitStateId())\n}\n"]}
|