@highstate/backend 0.7.3 → 0.7.6
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/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-EQ4LMS7B.js +290 -0
- package/dist/chunk-EQ4LMS7B.js.map +1 -0
- package/dist/{library-BW5oPM7V.js → chunk-TDCHA47F.js} +190 -124
- package/dist/chunk-TDCHA47F.js.map +1 -0
- package/dist/highstate.manifest.json +8 -0
- package/dist/index.js +330 -359
- package/dist/index.js.map +1 -0
- package/dist/library/source-resolution-worker.js +14 -13
- package/dist/library/source-resolution-worker.js.map +1 -0
- package/dist/library/worker/main.js +54 -32
- package/dist/library/worker/main.js.map +1 -0
- package/dist/shared/index.js +102 -6
- package/dist/shared/index.js.map +1 -0
- package/package.json +8 -8
- package/src/library/worker/loader.ts +17 -0
- package/dist/utils-ByadNcv4.js +0 -102
package/dist/index.js
CHANGED
@@ -1,207 +1,57 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
import {
|
22
|
-
|
23
|
-
|
1
|
+
import {
|
2
|
+
applyPartialInstanceState,
|
3
|
+
compositeInstanceSchema,
|
4
|
+
createInputHashResolver,
|
5
|
+
createInputResolver,
|
6
|
+
createInstanceState,
|
7
|
+
createInstanceStatePatch,
|
8
|
+
diffLibraries,
|
9
|
+
hubModelSchema,
|
10
|
+
instanceFileSchema,
|
11
|
+
instanceModelSchema,
|
12
|
+
instancePageSchema,
|
13
|
+
instanceStateSchema,
|
14
|
+
instanceStatusFieldSchema,
|
15
|
+
instanceTerminalSchema,
|
16
|
+
instanceTriggerSchema,
|
17
|
+
isFinalOperationStatus,
|
18
|
+
projectOperationSchema,
|
19
|
+
terminalSessionSchema
|
20
|
+
} from "./chunk-TDCHA47F.js";
|
21
|
+
import {
|
22
|
+
LocalPulumiHost,
|
23
|
+
createAsyncBatcher,
|
24
|
+
errorToString,
|
25
|
+
isAbortError,
|
26
|
+
isAbortErrorLike,
|
27
|
+
resolveMainLocalProject,
|
28
|
+
runWithRetryOnError,
|
29
|
+
stringArrayType,
|
30
|
+
stringToValue,
|
31
|
+
tryWrapAbortErrorLike,
|
32
|
+
updateResourceCount,
|
33
|
+
valueToString
|
34
|
+
} from "./chunk-EQ4LMS7B.js";
|
35
|
+
import "./chunk-DGUM43GV.js";
|
24
36
|
|
25
|
-
|
37
|
+
// src/secret/abstractions.ts
|
38
|
+
var SecretAccessDeniedError = class extends Error {
|
26
39
|
constructor(projectId, key) {
|
27
40
|
super(`Access to the secrets of component "${projectId}.${key}" is denied.`);
|
28
41
|
}
|
29
|
-
}
|
42
|
+
};
|
30
43
|
|
31
|
-
|
32
|
-
|
33
|
-
this.logger = logger;
|
34
|
-
}
|
35
|
-
lock = new BetterLock();
|
36
|
-
async getCurrentUser() {
|
37
|
-
const { LocalWorkspace } = await import('@pulumi/pulumi/automation/index.js');
|
38
|
-
const workspace = await LocalWorkspace.create({});
|
39
|
-
try {
|
40
|
-
return await workspace.whoAmI();
|
41
|
-
} catch (error) {
|
42
|
-
this.logger.error({ msg: "failed to get current user", error });
|
43
|
-
return null;
|
44
|
-
}
|
45
|
-
}
|
46
|
-
async runEmpty(options, fn, signal) {
|
47
|
-
const { projectId, pulumiProjectName, pulumiStackName, envVars } = options;
|
48
|
-
return await this.lock.acquire(`${pulumiProjectName}.${pulumiStackName}`, async () => {
|
49
|
-
const { LocalWorkspace } = await import('@pulumi/pulumi/automation/index.js');
|
50
|
-
const stack = await LocalWorkspace.createOrSelectStack(
|
51
|
-
{
|
52
|
-
projectName: pulumiProjectName,
|
53
|
-
stackName: pulumiStackName,
|
54
|
-
program: () => Promise.resolve()
|
55
|
-
},
|
56
|
-
{
|
57
|
-
projectSettings: {
|
58
|
-
name: pulumiProjectName,
|
59
|
-
runtime: "nodejs"
|
60
|
-
},
|
61
|
-
envVars: {
|
62
|
-
PULUMI_CONFIG_PASSPHRASE: this.getPassword(projectId),
|
63
|
-
PULUMI_K8S_AWAIT_ALL: "true",
|
64
|
-
...envVars
|
65
|
-
}
|
66
|
-
}
|
67
|
-
);
|
68
|
-
signal?.throwIfAborted();
|
69
|
-
try {
|
70
|
-
return await runWithRetryOnError(
|
71
|
-
() => fn(stack),
|
72
|
-
(error) => this.tryUnlockStack(stack, error)
|
73
|
-
);
|
74
|
-
} catch (e) {
|
75
|
-
if (e instanceof Error && e.message.includes("canceled")) {
|
76
|
-
throw new AbortError();
|
77
|
-
}
|
78
|
-
throw e;
|
79
|
-
}
|
80
|
-
});
|
81
|
-
}
|
82
|
-
async runLocal(options, fn, signal) {
|
83
|
-
const { projectId, pulumiProjectName, pulumiStackName, projectPath, stackConfig, envVars } = options;
|
84
|
-
return await this.lock.acquire(`${pulumiProjectName}.${pulumiStackName}`, async () => {
|
85
|
-
const { LocalWorkspace } = await import('@pulumi/pulumi/automation/index.js');
|
86
|
-
const stack = await LocalWorkspace.createOrSelectStack(
|
87
|
-
{
|
88
|
-
stackName: pulumiStackName,
|
89
|
-
workDir: projectPath
|
90
|
-
},
|
91
|
-
{
|
92
|
-
projectSettings: {
|
93
|
-
name: pulumiProjectName,
|
94
|
-
runtime: "nodejs"
|
95
|
-
},
|
96
|
-
stackSettings: stackConfig ? {
|
97
|
-
[pulumiStackName]: {
|
98
|
-
config: stackConfig
|
99
|
-
}
|
100
|
-
} : void 0,
|
101
|
-
envVars: {
|
102
|
-
PULUMI_CONFIG_PASSPHRASE: this.getPassword(projectId),
|
103
|
-
PULUMI_K8S_AWAIT_ALL: "true",
|
104
|
-
...envVars
|
105
|
-
}
|
106
|
-
}
|
107
|
-
);
|
108
|
-
signal?.throwIfAborted();
|
109
|
-
try {
|
110
|
-
return await runWithRetryOnError(
|
111
|
-
() => fn(stack),
|
112
|
-
(error) => this.tryUnlockStack(stack, error)
|
113
|
-
);
|
114
|
-
} catch (e) {
|
115
|
-
if (e instanceof Error && e.message.includes("canceled")) {
|
116
|
-
throw new AbortError();
|
117
|
-
}
|
118
|
-
throw e;
|
119
|
-
}
|
120
|
-
});
|
121
|
-
}
|
122
|
-
sharedPassword = process.env.PULUMI_CONFIG_PASSPHRASE ?? "";
|
123
|
-
passwords = /* @__PURE__ */ new Map();
|
124
|
-
hasPassword(projectId) {
|
125
|
-
return !!this.sharedPassword || this.passwords.has(projectId);
|
126
|
-
}
|
127
|
-
setPassword(projectId, password) {
|
128
|
-
this.passwords.set(projectId, password);
|
129
|
-
}
|
130
|
-
removePassword(projectId) {
|
131
|
-
this.passwords.delete(projectId);
|
132
|
-
}
|
133
|
-
getPassword(projectId) {
|
134
|
-
return this.sharedPassword || this.passwords.get(projectId) || "";
|
135
|
-
}
|
136
|
-
async tryUnlockStack(stack, error) {
|
137
|
-
if (error instanceof Error && error.message.includes("the stack is currently locked")) {
|
138
|
-
this.logger.warn({ stackName: stack.name }, "inlocking stack");
|
139
|
-
await stack.cancel();
|
140
|
-
return true;
|
141
|
-
}
|
142
|
-
return false;
|
143
|
-
}
|
144
|
-
static create(logger) {
|
145
|
-
return new LocalPulumiHost(logger.child({ service: "LocalPulumiHost" }));
|
146
|
-
}
|
147
|
-
}
|
148
|
-
function valueToString(value) {
|
149
|
-
if (typeof value === "string") {
|
150
|
-
return value;
|
151
|
-
}
|
152
|
-
return JSON.stringify(value);
|
153
|
-
}
|
154
|
-
function stringToValue(value) {
|
155
|
-
try {
|
156
|
-
return JSON.parse(value);
|
157
|
-
} catch {
|
158
|
-
return value;
|
159
|
-
}
|
160
|
-
}
|
161
|
-
function updateResourceCount(opType, currentCount) {
|
162
|
-
switch (opType) {
|
163
|
-
case "same":
|
164
|
-
case "create":
|
165
|
-
case "update":
|
166
|
-
case "replace":
|
167
|
-
case "create-replacement":
|
168
|
-
case "import":
|
169
|
-
case "import-replacement":
|
170
|
-
return currentCount + 1;
|
171
|
-
case "delete":
|
172
|
-
case "delete-replaced":
|
173
|
-
case "discard":
|
174
|
-
case "discard-replaced":
|
175
|
-
case "remove-pending-replace":
|
176
|
-
return currentCount - 1;
|
177
|
-
case "refresh":
|
178
|
-
case "read-replacement":
|
179
|
-
case "read":
|
180
|
-
return currentCount;
|
181
|
-
default:
|
182
|
-
throw new Error(`Unknown operation type: ${opType}`);
|
183
|
-
}
|
184
|
-
}
|
185
|
-
|
186
|
-
async function resolveMainLocalProject(projectPath, projectName) {
|
187
|
-
if (!projectPath) {
|
188
|
-
projectPath = await findWorkspaceDir();
|
189
|
-
}
|
190
|
-
if (!projectName) {
|
191
|
-
const packageJson = await readPackageJSON(projectPath);
|
192
|
-
projectName = packageJson.name;
|
193
|
-
}
|
194
|
-
if (!projectName) {
|
195
|
-
projectName = basename(projectPath);
|
196
|
-
}
|
197
|
-
return [projectPath, projectName];
|
198
|
-
}
|
44
|
+
// src/secret/factory.ts
|
45
|
+
import { z as z2 } from "zod";
|
199
46
|
|
200
|
-
|
47
|
+
// src/secret/local.ts
|
48
|
+
import { mapKeys, mapValues, pickBy } from "remeda";
|
49
|
+
import { z } from "zod";
|
50
|
+
var localSecretBackendConfig = z.object({
|
201
51
|
HIGHSTATE_BACKEND_SECRET_PROJECT_PATH: z.string().optional(),
|
202
52
|
HIGHSTATE_BACKEND_SECRET_PROJECT_NAME: z.string().optional()
|
203
53
|
});
|
204
|
-
|
54
|
+
var LocalSecretBackend = class _LocalSecretBackend {
|
205
55
|
constructor(projectPath, projectName, pulumiProjectHost, logger) {
|
206
56
|
this.projectPath = projectPath;
|
207
57
|
this.projectName = projectName;
|
@@ -294,17 +144,18 @@ class LocalSecretBackend {
|
|
294
144
|
config.HIGHSTATE_BACKEND_SECRET_PROJECT_PATH,
|
295
145
|
config.HIGHSTATE_BACKEND_SECRET_PROJECT_NAME
|
296
146
|
);
|
297
|
-
return new
|
147
|
+
return new _LocalSecretBackend(
|
298
148
|
projectPath,
|
299
149
|
projectName,
|
300
150
|
pulumiProjectHost,
|
301
151
|
logger.child({ backend: "SecretBackend", service: "LocalSecretBackend" })
|
302
152
|
);
|
303
153
|
}
|
304
|
-
}
|
154
|
+
};
|
305
155
|
|
306
|
-
|
307
|
-
|
156
|
+
// src/secret/factory.ts
|
157
|
+
var secretBackendConfig = z2.object({
|
158
|
+
HIGHSTATE_BACKEND_SECRET_TYPE: z2.enum(["local"]).default("local"),
|
308
159
|
...localSecretBackendConfig.shape
|
309
160
|
});
|
310
161
|
function createSecretBackend(config, localPulumiHost, logger) {
|
@@ -315,12 +166,27 @@ function createSecretBackend(config, localPulumiHost, logger) {
|
|
315
166
|
}
|
316
167
|
}
|
317
168
|
|
318
|
-
|
169
|
+
// src/library/factory.ts
|
170
|
+
import { z as z4 } from "zod";
|
171
|
+
|
172
|
+
// src/library/local.ts
|
173
|
+
import { fileURLToPath } from "node:url";
|
174
|
+
import { EventEmitter, on } from "node:events";
|
175
|
+
import { Worker } from "node:worker_threads";
|
176
|
+
import { basename, dirname, relative, resolve } from "node:path";
|
177
|
+
import { readFile } from "node:fs/promises";
|
178
|
+
import { isUnitModel } from "@highstate/contract";
|
179
|
+
import Watcher from "watcher";
|
180
|
+
import { BetterLock } from "better-lock";
|
181
|
+
import { resolve as importMetaResolve } from "import-meta-resolve";
|
182
|
+
import { z as z3 } from "zod";
|
183
|
+
import { readPackageJSON, resolvePackageJSON } from "pkg-types";
|
184
|
+
var localLibraryBackendConfig = z3.object({
|
319
185
|
HIGHSTATE_BACKEND_LIBRARY_LOCAL_MODULES: stringArrayType.default("@highstate/library"),
|
320
|
-
HIGHSTATE_BACKEND_LIBRARY_LOCAL_SOURCE_BASE_PATH:
|
186
|
+
HIGHSTATE_BACKEND_LIBRARY_LOCAL_SOURCE_BASE_PATH: z3.string().optional(),
|
321
187
|
HIGHSTATE_BACKEND_LIBRARY_LOCAL_EXTRA_SOURCE_WATCH_PATHS: stringArrayType.default("")
|
322
188
|
});
|
323
|
-
|
189
|
+
var LocalLibraryBackend = class _LocalLibraryBackend {
|
324
190
|
constructor(modulePaths, sourceBasePath, extraSourceWatchPaths, logger) {
|
325
191
|
this.modulePaths = modulePaths;
|
326
192
|
this.sourceBasePath = sourceBasePath;
|
@@ -402,7 +268,7 @@ class LocalLibraryBackend {
|
|
402
268
|
await this.runSourceResolution(unitsToResolve);
|
403
269
|
}
|
404
270
|
async runSourceResolution(units) {
|
405
|
-
const workerPathUrl =
|
271
|
+
const workerPathUrl = importMetaResolve(
|
406
272
|
`@highstate/backend/source-resolution-worker`,
|
407
273
|
import.meta.url
|
408
274
|
);
|
@@ -517,7 +383,7 @@ class LocalLibraryBackend {
|
|
517
383
|
throw new Error("Worker ended without sending library model");
|
518
384
|
}
|
519
385
|
createWorker(workerData) {
|
520
|
-
const workerPathUrl =
|
386
|
+
const workerPathUrl = importMetaResolve(`@highstate/backend/library-worker`, import.meta.url);
|
521
387
|
const workerPath = fileURLToPath(workerPathUrl);
|
522
388
|
return new Worker(workerPath, { workerData });
|
523
389
|
}
|
@@ -525,7 +391,7 @@ class LocalLibraryBackend {
|
|
525
391
|
const packageJsonPath = await resolvePackageJSON(path);
|
526
392
|
const packageJson = await readPackageJSON(path);
|
527
393
|
const library = await this.loadLibrary();
|
528
|
-
const manifestPath = resolve
|
394
|
+
const manifestPath = resolve(dirname(packageJsonPath), "dist", "highstate.manifest.json");
|
529
395
|
let manifest;
|
530
396
|
try {
|
531
397
|
manifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
@@ -566,7 +432,7 @@ class LocalLibraryBackend {
|
|
566
432
|
static async create(config, logger) {
|
567
433
|
const modulePaths = [];
|
568
434
|
for (const module of config.HIGHSTATE_BACKEND_LIBRARY_LOCAL_MODULES) {
|
569
|
-
const url =
|
435
|
+
const url = importMetaResolve(module, import.meta.url);
|
570
436
|
let path = fileURLToPath(url);
|
571
437
|
if (basename(path).includes(".")) {
|
572
438
|
path = dirname(path);
|
@@ -577,20 +443,21 @@ class LocalLibraryBackend {
|
|
577
443
|
const extraSourceWatchPaths = config.HIGHSTATE_BACKEND_LIBRARY_LOCAL_EXTRA_SOURCE_WATCH_PATHS;
|
578
444
|
if (!sourceBasePath) {
|
579
445
|
const [projectPath] = await resolveMainLocalProject();
|
580
|
-
sourceBasePath = resolve
|
446
|
+
sourceBasePath = resolve(projectPath, "units");
|
581
447
|
extraSourceWatchPaths.push(projectPath);
|
582
448
|
}
|
583
|
-
return new
|
449
|
+
return new _LocalLibraryBackend(
|
584
450
|
modulePaths,
|
585
451
|
sourceBasePath,
|
586
452
|
extraSourceWatchPaths,
|
587
453
|
logger.child({ backend: "LibraryBackend", service: "LocalLibraryBackend" })
|
588
454
|
);
|
589
455
|
}
|
590
|
-
}
|
456
|
+
};
|
591
457
|
|
592
|
-
|
593
|
-
|
458
|
+
// src/library/factory.ts
|
459
|
+
var libraryBackendConfig = z4.object({
|
460
|
+
HIGHSTATE_BACKEND_LIBRARY_TYPE: z4.enum(["local"]).default("local"),
|
594
461
|
...localLibraryBackendConfig.shape
|
595
462
|
});
|
596
463
|
async function createLibraryBackend(config, logger) {
|
@@ -601,14 +468,27 @@ async function createLibraryBackend(config, logger) {
|
|
601
468
|
}
|
602
469
|
}
|
603
470
|
|
604
|
-
|
605
|
-
|
471
|
+
// src/config.ts
|
472
|
+
import { z as z15 } from "zod";
|
473
|
+
|
474
|
+
// src/project/factory.ts
|
475
|
+
import { z as z6 } from "zod";
|
476
|
+
|
477
|
+
// src/project/local.ts
|
478
|
+
import { mkdir, readdir, readFile as readFile2, writeFile } from "node:fs/promises";
|
479
|
+
import { resolve as resolve2 } from "node:path";
|
480
|
+
import { z as z5 } from "zod";
|
481
|
+
import {
|
482
|
+
getInstanceId
|
483
|
+
} from "@highstate/contract";
|
484
|
+
var localProjectBackendConfig = z5.object({
|
485
|
+
HIGHSTATE_BACKEND_PROJECT_PROJECTS_DIR: z5.string().optional()
|
606
486
|
});
|
607
|
-
|
608
|
-
instances:
|
609
|
-
hubs:
|
487
|
+
var projectModelSchema = z5.object({
|
488
|
+
instances: z5.record(instanceModelSchema),
|
489
|
+
hubs: z5.record(hubModelSchema)
|
610
490
|
});
|
611
|
-
|
491
|
+
var LocalProjectBackend = class _LocalProjectBackend {
|
612
492
|
constructor(projectsDir) {
|
613
493
|
this.projectsDir = projectsDir;
|
614
494
|
}
|
@@ -857,7 +737,7 @@ class LocalProjectBackend {
|
|
857
737
|
async loadProject(projectId) {
|
858
738
|
const projectPath = this.getProjectPath(projectId);
|
859
739
|
try {
|
860
|
-
const content = await
|
740
|
+
const content = await readFile2(projectPath, "utf-8");
|
861
741
|
return projectModelSchema.parse(JSON.parse(content));
|
862
742
|
} catch (error) {
|
863
743
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
@@ -890,22 +770,25 @@ class LocalProjectBackend {
|
|
890
770
|
let projectsPath = config.HIGHSTATE_BACKEND_PROJECT_PROJECTS_DIR;
|
891
771
|
if (!projectsPath) {
|
892
772
|
const [mainProjectPath] = await resolveMainLocalProject();
|
893
|
-
projectsPath =
|
773
|
+
projectsPath = resolve2(mainProjectPath, "projects");
|
894
774
|
}
|
895
775
|
await mkdir(projectsPath, { recursive: true });
|
896
|
-
return new
|
776
|
+
return new _LocalProjectBackend(projectsPath);
|
897
777
|
}
|
898
|
-
}
|
778
|
+
};
|
899
779
|
|
900
|
-
|
901
|
-
|
780
|
+
// src/project/factory.ts
|
781
|
+
var projectBackendConfig = z6.object({
|
782
|
+
HIGHSTATE_BACKEND_PROJECT_TYPE: z6.enum(["local"]).default("local"),
|
902
783
|
...localProjectBackendConfig.shape
|
903
784
|
});
|
904
785
|
function createProjectBackend(config) {
|
905
786
|
return LocalProjectBackend.create(config);
|
906
787
|
}
|
907
788
|
|
908
|
-
|
789
|
+
// src/project/lock.ts
|
790
|
+
import { BetterLock as BetterLock2 } from "better-lock";
|
791
|
+
var ProjectLock = class {
|
909
792
|
constructor(lock, projectId) {
|
910
793
|
this.lock = lock;
|
911
794
|
this.projectId = projectId;
|
@@ -930,15 +813,18 @@ class ProjectLock {
|
|
930
813
|
fn
|
931
814
|
);
|
932
815
|
}
|
933
|
-
}
|
934
|
-
|
935
|
-
lock = new
|
816
|
+
};
|
817
|
+
var ProjectLockManager = class {
|
818
|
+
lock = new BetterLock2();
|
936
819
|
getLock(projectId) {
|
937
820
|
return new ProjectLock(this.lock, projectId);
|
938
821
|
}
|
939
|
-
}
|
822
|
+
};
|
940
823
|
|
941
|
-
|
824
|
+
// src/project/manager.ts
|
825
|
+
import { EventEmitter as EventEmitter2, on as on2 } from "node:events";
|
826
|
+
import { isUnitModel as isUnitModel2 } from "@highstate/contract";
|
827
|
+
var ProjectManager = class _ProjectManager {
|
942
828
|
constructor(projectBackend, stateBackend, libraryBackend, projectLockManager, stateManager, logger) {
|
943
829
|
this.projectBackend = projectBackend;
|
944
830
|
this.stateBackend = stateBackend;
|
@@ -948,9 +834,9 @@ class ProjectManager {
|
|
948
834
|
this.logger = logger;
|
949
835
|
void this.watchLibraryChanges();
|
950
836
|
}
|
951
|
-
compositeInstanceEE = new
|
837
|
+
compositeInstanceEE = new EventEmitter2();
|
952
838
|
async *watchCompositeInstances(projectId, signal) {
|
953
|
-
for await (const [children] of
|
839
|
+
for await (const [children] of on2(this.compositeInstanceEE, projectId, {
|
954
840
|
signal
|
955
841
|
})) {
|
956
842
|
yield children;
|
@@ -983,7 +869,7 @@ class ProjectManager {
|
|
983
869
|
if (!component) {
|
984
870
|
return;
|
985
871
|
}
|
986
|
-
if (
|
872
|
+
if (isUnitModel2(component)) {
|
987
873
|
return;
|
988
874
|
}
|
989
875
|
const { inputHash: expectedInputHash } = await resolveInputHash(instance.id);
|
@@ -1099,7 +985,7 @@ class ProjectManager {
|
|
1099
985
|
throw new Error("Expected instance node");
|
1100
986
|
}
|
1101
987
|
let sourceHash;
|
1102
|
-
if (
|
988
|
+
if (isUnitModel2(library.components[instance.type])) {
|
1103
989
|
const resolvedUnit = await this.libraryBackend.getResolvedUnitSource(instance.type);
|
1104
990
|
if (!resolvedUnit) {
|
1105
991
|
throw new Error(`Resolved unit not found: ${instance.type}`);
|
@@ -1157,7 +1043,7 @@ class ProjectManager {
|
|
1157
1043
|
for (const projectId of projects) {
|
1158
1044
|
const { resolveInputHash, instances } = await this.prepareInputHashResolver(projectId);
|
1159
1045
|
const filteredInstances = instances.filter(
|
1160
|
-
(instance) => changedComponents.has(instance.type) && library.components[instance.type] && !
|
1046
|
+
(instance) => changedComponents.has(instance.type) && library.components[instance.type] && !isUnitModel2(library.components[instance.type])
|
1161
1047
|
);
|
1162
1048
|
this.logger.info(
|
1163
1049
|
{ projectId, filteredInstanceIds: filteredInstances.map((instance) => instance.id) },
|
@@ -1179,7 +1065,7 @@ class ProjectManager {
|
|
1179
1065
|
}
|
1180
1066
|
}
|
1181
1067
|
static create(projectBackend, stateBackend, libraryBackend, projectLockManager, stateManager, logger) {
|
1182
|
-
return new
|
1068
|
+
return new _ProjectManager(
|
1183
1069
|
projectBackend,
|
1184
1070
|
stateBackend,
|
1185
1071
|
libraryBackend,
|
@@ -1188,9 +1074,21 @@ class ProjectManager {
|
|
1188
1074
|
logger.child({ service: "ProjectManager" })
|
1189
1075
|
);
|
1190
1076
|
}
|
1191
|
-
}
|
1077
|
+
};
|
1192
1078
|
|
1193
|
-
|
1079
|
+
// src/terminal/factory.ts
|
1080
|
+
import { z as z8 } from "zod";
|
1081
|
+
|
1082
|
+
// src/terminal/docker.ts
|
1083
|
+
import { Readable } from "node:stream";
|
1084
|
+
import { tmpdir } from "node:os";
|
1085
|
+
import { resolve as resolve3 } from "node:path";
|
1086
|
+
import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
|
1087
|
+
import { z as z7 } from "zod";
|
1088
|
+
import spawn from "nano-spawn";
|
1089
|
+
|
1090
|
+
// src/terminal/run.sh.ts
|
1091
|
+
var runScript = `set -e -o pipefail
|
1194
1092
|
read -r data
|
1195
1093
|
|
1196
1094
|
# Extract env and files as key-value pairs, and command as an array
|
@@ -1228,12 +1126,13 @@ cmd=$(printf "%q " "\${commandArr[@]}")
|
|
1228
1126
|
exec script -q -c "stty cols $cols rows $rows; $cmd" /dev/null
|
1229
1127
|
`;
|
1230
1128
|
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1129
|
+
// src/terminal/docker.ts
|
1130
|
+
var dockerTerminalBackendConfig = z7.object({
|
1131
|
+
HIGHSTATE_BACKEND_TERMINAL_DOCKER_BINARY: z7.string().default("docker"),
|
1132
|
+
HIGHSTATE_BACKEND_TERMINAL_DOCKER_USE_SUDO: z7.coerce.boolean().default(false),
|
1133
|
+
HIGHSTATE_BACKEND_TERMINAL_DOCKER_HOST: z7.string().optional()
|
1235
1134
|
});
|
1236
|
-
|
1135
|
+
var DockerTerminalBackend = class _DockerTerminalBackend {
|
1237
1136
|
constructor(binary, useSudo, host, logger) {
|
1238
1137
|
this.binary = binary;
|
1239
1138
|
this.useSudo = useSudo;
|
@@ -1241,10 +1140,10 @@ class DockerTerminalBackend {
|
|
1241
1140
|
this.logger = logger;
|
1242
1141
|
}
|
1243
1142
|
async run({ factory, stdin, stdout, screenSize, signal }) {
|
1244
|
-
const hsTempDir =
|
1245
|
-
await
|
1246
|
-
const runScriptPath =
|
1247
|
-
await
|
1143
|
+
const hsTempDir = resolve3(tmpdir(), "highstate");
|
1144
|
+
await mkdir2(hsTempDir, { recursive: true });
|
1145
|
+
const runScriptPath = resolve3(hsTempDir, "run.sh");
|
1146
|
+
await writeFile2(runScriptPath, runScript, { mode: 493 });
|
1248
1147
|
const args = [
|
1249
1148
|
"run",
|
1250
1149
|
"-i",
|
@@ -1268,32 +1167,33 @@ class DockerTerminalBackend {
|
|
1268
1167
|
if (this.useSudo) {
|
1269
1168
|
args.unshift(this.binary);
|
1270
1169
|
}
|
1271
|
-
const
|
1170
|
+
const process2 = spawn(this.useSudo ? "sudo" : this.binary, args, {
|
1272
1171
|
env: {
|
1273
1172
|
DOCKER_HOST: this.host
|
1274
1173
|
},
|
1275
1174
|
signal
|
1276
1175
|
});
|
1277
|
-
const childProcess = await
|
1176
|
+
const childProcess = await process2.nodeChildProcess;
|
1278
1177
|
initDataStream.pipe(childProcess.stdin, { end: false });
|
1279
1178
|
initDataStream.on("end", () => stdin.pipe(childProcess.stdin));
|
1280
1179
|
childProcess.stdout.pipe(stdout);
|
1281
1180
|
childProcess.stderr.pipe(stdout);
|
1282
1181
|
this.logger.info({ pid: childProcess.pid }, "process started");
|
1283
|
-
await
|
1182
|
+
await process2;
|
1284
1183
|
}
|
1285
1184
|
static create(config, logger) {
|
1286
|
-
return new
|
1185
|
+
return new _DockerTerminalBackend(
|
1287
1186
|
config.HIGHSTATE_BACKEND_TERMINAL_DOCKER_BINARY,
|
1288
1187
|
config.HIGHSTATE_BACKEND_TERMINAL_DOCKER_USE_SUDO,
|
1289
1188
|
config.HIGHSTATE_BACKEND_TERMINAL_DOCKER_HOST,
|
1290
1189
|
logger.child({ backend: "TerminalBackend", service: "DockerTerminalBackend" })
|
1291
1190
|
);
|
1292
1191
|
}
|
1293
|
-
}
|
1192
|
+
};
|
1294
1193
|
|
1295
|
-
|
1296
|
-
|
1194
|
+
// src/terminal/factory.ts
|
1195
|
+
var terminalBackendConfig = z8.object({
|
1196
|
+
HIGHSTATE_BACKEND_TERMINAL_TYPE: z8.enum(["docker"]).default("docker"),
|
1297
1197
|
...dockerTerminalBackendConfig.shape
|
1298
1198
|
});
|
1299
1199
|
function createTerminalBackend(config, logger) {
|
@@ -1304,17 +1204,28 @@ function createTerminalBackend(config, logger) {
|
|
1304
1204
|
}
|
1305
1205
|
}
|
1306
1206
|
|
1307
|
-
|
1207
|
+
// src/terminal/manager.ts
|
1208
|
+
import { PassThrough } from "node:stream";
|
1209
|
+
import { EventEmitter as EventEmitter3, on as on3 } from "node:events";
|
1210
|
+
import { parseInstanceId } from "@highstate/contract";
|
1308
1211
|
|
1309
|
-
|
1310
|
-
|
1212
|
+
// ../../node_modules/nanoid/index.js
|
1213
|
+
import { webcrypto as crypto } from "node:crypto";
|
1214
|
+
|
1215
|
+
// ../../node_modules/nanoid/url-alphabet/index.js
|
1216
|
+
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
1217
|
+
|
1218
|
+
// ../../node_modules/nanoid/index.js
|
1219
|
+
var POOL_SIZE_MULTIPLIER = 128;
|
1220
|
+
var pool;
|
1221
|
+
var poolOffset;
|
1311
1222
|
function fillPool(bytes) {
|
1312
1223
|
if (!pool || pool.length < bytes) {
|
1313
1224
|
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
1314
|
-
|
1225
|
+
crypto.getRandomValues(pool);
|
1315
1226
|
poolOffset = 0;
|
1316
1227
|
} else if (poolOffset + bytes > pool.length) {
|
1317
|
-
|
1228
|
+
crypto.getRandomValues(pool);
|
1318
1229
|
poolOffset = 0;
|
1319
1230
|
}
|
1320
1231
|
poolOffset += bytes;
|
@@ -1328,8 +1239,9 @@ function nanoid(size = 21) {
|
|
1328
1239
|
return id;
|
1329
1240
|
}
|
1330
1241
|
|
1331
|
-
|
1332
|
-
|
1242
|
+
// src/terminal/manager.ts
|
1243
|
+
var notAttachedTerminalLifetime = 5 * 60 * 1e3;
|
1244
|
+
var TerminalManager = class _TerminalManager {
|
1333
1245
|
constructor(terminalBackend, stateBackend, runnerBackend, logger) {
|
1334
1246
|
this.terminalBackend = terminalBackend;
|
1335
1247
|
this.stateBackend = stateBackend;
|
@@ -1339,7 +1251,7 @@ class TerminalManager {
|
|
1339
1251
|
}
|
1340
1252
|
managedTerminals = /* @__PURE__ */ new Map();
|
1341
1253
|
existingSessions = /* @__PURE__ */ new Map();
|
1342
|
-
terminalEE = new
|
1254
|
+
terminalEE = new EventEmitter3();
|
1343
1255
|
isSessionActive(sessionId) {
|
1344
1256
|
return this.managedTerminals.has(sessionId);
|
1345
1257
|
}
|
@@ -1354,7 +1266,7 @@ class TerminalManager {
|
|
1354
1266
|
return;
|
1355
1267
|
}
|
1356
1268
|
yield managedTerminal.session;
|
1357
|
-
for await (const [terminalSession] of
|
1269
|
+
for await (const [terminalSession] of on3(this.terminalEE, sessionId, {
|
1358
1270
|
signal
|
1359
1271
|
})) {
|
1360
1272
|
yield terminalSession;
|
@@ -1517,7 +1429,7 @@ class TerminalManager {
|
|
1517
1429
|
setTimeout(() => this.closeTerminalIfNotAttached(terminal), notAttachedTerminalLifetime);
|
1518
1430
|
}
|
1519
1431
|
static create(terminalBackend, stateBackend, runnerBackend, logger) {
|
1520
|
-
return new
|
1432
|
+
return new _TerminalManager(
|
1521
1433
|
terminalBackend,
|
1522
1434
|
stateBackend,
|
1523
1435
|
runnerBackend,
|
@@ -1538,23 +1450,35 @@ class TerminalManager {
|
|
1538
1450
|
}
|
1539
1451
|
await this.updateActiveTerminalSessions();
|
1540
1452
|
}
|
1541
|
-
}
|
1453
|
+
};
|
1542
1454
|
|
1543
|
-
|
1455
|
+
// src/runner/abstractions.ts
|
1456
|
+
var InvalidInstanceStatusError = class extends Error {
|
1544
1457
|
constructor(currentStatus, expectedStatuses) {
|
1545
1458
|
const expectedString = expectedStatuses.join(", ");
|
1546
1459
|
super(`The current state is "${currentStatus}", but it should be one of "${expectedString}".`);
|
1547
1460
|
this.currentStatus = currentStatus;
|
1548
1461
|
this.expectedStatuses = expectedStatuses;
|
1549
1462
|
}
|
1550
|
-
}
|
1463
|
+
};
|
1464
|
+
|
1465
|
+
// src/runner/factory.ts
|
1466
|
+
import { z as z10 } from "zod";
|
1551
1467
|
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1468
|
+
// src/runner/local.ts
|
1469
|
+
import { EventEmitter as EventEmitter4, on as on4 } from "node:events";
|
1470
|
+
import { resolve as resolve4 } from "node:path";
|
1471
|
+
import { getInstanceId as getInstanceId2 } from "@highstate/contract";
|
1472
|
+
import { ensureDependencyInstalled } from "nypm";
|
1473
|
+
import { mapValues as mapValues2, omit, pick, pickBy as pickBy2 } from "remeda";
|
1474
|
+
import { z as z9 } from "zod";
|
1475
|
+
import { sha256 } from "crypto-hash";
|
1476
|
+
var localRunnerBackendConfig = z9.object({
|
1477
|
+
HIGHSTATE_BACKEND_RUNNER_LOCAL_SKIP_STATE_CHECK: z9.boolean({ coerce: true }).default(false),
|
1478
|
+
HIGHSTATE_BACKEND_RUNNER_LOCAL_PRINT_OUTPUT: z9.boolean({ coerce: true }).default(true),
|
1479
|
+
HIGHSTATE_BACKEND_RUNNER_LOCAL_CACHE_DIR: z9.string().optional()
|
1556
1480
|
});
|
1557
|
-
|
1481
|
+
var LocalRunnerBackend = class _LocalRunnerBackend {
|
1558
1482
|
constructor(skipStateCheck, printOutput, cacheDir, pulumiProjectHost, libraryBackend) {
|
1559
1483
|
this.skipStateCheck = skipStateCheck;
|
1560
1484
|
this.printOutput = printOutput;
|
@@ -1562,12 +1486,12 @@ class LocalRunnerBackend {
|
|
1562
1486
|
this.pulumiProjectHost = pulumiProjectHost;
|
1563
1487
|
this.libraryBackend = libraryBackend;
|
1564
1488
|
}
|
1565
|
-
events = new
|
1489
|
+
events = new EventEmitter4();
|
1566
1490
|
async *watch(options) {
|
1567
|
-
const stream =
|
1491
|
+
const stream = on4(
|
1568
1492
|
//
|
1569
1493
|
this.events,
|
1570
|
-
`state:${
|
1494
|
+
`state:${_LocalRunnerBackend.getInstanceId(options)}`,
|
1571
1495
|
{ signal: options.signal }
|
1572
1496
|
);
|
1573
1497
|
for await (const [statePatch] of stream) {
|
@@ -1582,11 +1506,11 @@ class LocalRunnerBackend {
|
|
1582
1506
|
{
|
1583
1507
|
projectId: options.projectId,
|
1584
1508
|
pulumiProjectName: options.instanceType,
|
1585
|
-
pulumiStackName:
|
1509
|
+
pulumiStackName: _LocalRunnerBackend.getStackName(options)
|
1586
1510
|
},
|
1587
1511
|
async (stack) => {
|
1588
1512
|
const info = await stack.info();
|
1589
|
-
const instanceId =
|
1513
|
+
const instanceId = getInstanceId2(options.instanceType, options.instanceName);
|
1590
1514
|
if (!info) {
|
1591
1515
|
return createInstanceState(instanceId);
|
1592
1516
|
}
|
@@ -1613,14 +1537,14 @@ class LocalRunnerBackend {
|
|
1613
1537
|
{
|
1614
1538
|
projectId: options.projectId,
|
1615
1539
|
pulumiProjectName: options.instanceType,
|
1616
|
-
pulumiStackName:
|
1540
|
+
pulumiStackName: _LocalRunnerBackend.getStackName(options)
|
1617
1541
|
},
|
1618
1542
|
async (stack) => {
|
1619
1543
|
const outputs = await stack.outputs();
|
1620
1544
|
if (!outputs["$terminals"]) {
|
1621
1545
|
return null;
|
1622
1546
|
}
|
1623
|
-
const terminals =
|
1547
|
+
const terminals = z9.array(instanceTerminalSchema).parse(outputs["$terminals"].value);
|
1624
1548
|
const terminal = terminals.find((t) => t.name === terminalName);
|
1625
1549
|
if (!terminal) {
|
1626
1550
|
return null;
|
@@ -1634,14 +1558,14 @@ class LocalRunnerBackend {
|
|
1634
1558
|
{
|
1635
1559
|
projectId: options.projectId,
|
1636
1560
|
pulumiProjectName: options.instanceType,
|
1637
|
-
pulumiStackName:
|
1561
|
+
pulumiStackName: _LocalRunnerBackend.getStackName(options)
|
1638
1562
|
},
|
1639
1563
|
async (stack) => {
|
1640
1564
|
const outputs = await stack.outputs();
|
1641
1565
|
if (!outputs["$pages"]) {
|
1642
1566
|
return null;
|
1643
1567
|
}
|
1644
|
-
const pages =
|
1568
|
+
const pages = z9.array(instancePageSchema).parse(outputs["$pages"].value);
|
1645
1569
|
const page = pages.find((p) => p.name === pageName);
|
1646
1570
|
if (!page) {
|
1647
1571
|
return null;
|
@@ -1655,14 +1579,14 @@ class LocalRunnerBackend {
|
|
1655
1579
|
{
|
1656
1580
|
projectId: options.projectId,
|
1657
1581
|
pulumiProjectName: options.instanceType,
|
1658
|
-
pulumiStackName:
|
1582
|
+
pulumiStackName: _LocalRunnerBackend.getStackName(options)
|
1659
1583
|
},
|
1660
1584
|
async (stack) => {
|
1661
1585
|
const outputs = await stack.outputs();
|
1662
1586
|
if (!outputs["$files"]) {
|
1663
1587
|
return null;
|
1664
1588
|
}
|
1665
|
-
const files =
|
1589
|
+
const files = z9.array(instanceFileSchema).parse(outputs["$files"].value);
|
1666
1590
|
const file = files.find((f) => f.meta.name === fileName);
|
1667
1591
|
if (!file) {
|
1668
1592
|
return null;
|
@@ -1682,8 +1606,8 @@ class LocalRunnerBackend {
|
|
1682
1606
|
return;
|
1683
1607
|
}
|
1684
1608
|
const configMap = {
|
1685
|
-
...
|
1686
|
-
...
|
1609
|
+
...mapValues2(options.config, (value) => ({ value })),
|
1610
|
+
...mapValues2(options.secrets, (value) => ({ value, secret: true }))
|
1687
1611
|
};
|
1688
1612
|
void this.updateWorker(options, configMap, false);
|
1689
1613
|
}
|
@@ -1698,13 +1622,13 @@ class LocalRunnerBackend {
|
|
1698
1622
|
return;
|
1699
1623
|
}
|
1700
1624
|
const configMap = {
|
1701
|
-
...
|
1702
|
-
...
|
1625
|
+
...mapValues2(options.config, (value) => ({ value })),
|
1626
|
+
...mapValues2(options.secrets, (value) => ({ value, secret: true }))
|
1703
1627
|
};
|
1704
1628
|
void this.updateWorker(options, configMap, true);
|
1705
1629
|
}
|
1706
1630
|
async updateWorker(options, configMap, preview) {
|
1707
|
-
const instanceId =
|
1631
|
+
const instanceId = _LocalRunnerBackend.getInstanceId(options);
|
1708
1632
|
try {
|
1709
1633
|
const resolvedSource = await this.libraryBackend.getResolvedUnitSource(options.instanceType);
|
1710
1634
|
if (!resolvedSource) {
|
@@ -1714,7 +1638,7 @@ class LocalRunnerBackend {
|
|
1714
1638
|
{
|
1715
1639
|
projectId: options.projectId,
|
1716
1640
|
pulumiProjectName: options.instanceType,
|
1717
|
-
pulumiStackName:
|
1641
|
+
pulumiStackName: _LocalRunnerBackend.getStackName(options),
|
1718
1642
|
projectPath: resolvedSource.projectPath,
|
1719
1643
|
stackConfig: configMap,
|
1720
1644
|
envVars: {
|
@@ -1811,7 +1735,7 @@ class LocalRunnerBackend {
|
|
1811
1735
|
void this.destroyWorker(options);
|
1812
1736
|
}
|
1813
1737
|
async destroyWorker(options) {
|
1814
|
-
const instanceId =
|
1738
|
+
const instanceId = _LocalRunnerBackend.getInstanceId(options);
|
1815
1739
|
try {
|
1816
1740
|
const resolvedSource = await this.libraryBackend.getResolvedUnitSource(options.instanceType);
|
1817
1741
|
if (!resolvedSource) {
|
@@ -1821,7 +1745,7 @@ class LocalRunnerBackend {
|
|
1821
1745
|
{
|
1822
1746
|
projectId: options.projectId,
|
1823
1747
|
pulumiProjectName: options.instanceType,
|
1824
|
-
pulumiStackName:
|
1748
|
+
pulumiStackName: _LocalRunnerBackend.getStackName(options),
|
1825
1749
|
projectPath: resolvedSource.projectPath,
|
1826
1750
|
envVars: {
|
1827
1751
|
HIGHSTATE_CACHE_DIR: this.cacheDir,
|
@@ -1874,7 +1798,7 @@ class LocalRunnerBackend {
|
|
1874
1798
|
}
|
1875
1799
|
);
|
1876
1800
|
} catch (error) {
|
1877
|
-
const { StackNotFoundError } = await import(
|
1801
|
+
const { StackNotFoundError } = await import("@pulumi/pulumi/automation/index.js");
|
1878
1802
|
if (error instanceof StackNotFoundError) {
|
1879
1803
|
this.updateState({
|
1880
1804
|
id: instanceId,
|
@@ -1909,13 +1833,13 @@ class LocalRunnerBackend {
|
|
1909
1833
|
void this.refreshWorker(options);
|
1910
1834
|
}
|
1911
1835
|
async refreshWorker(options) {
|
1912
|
-
const instanceId =
|
1836
|
+
const instanceId = _LocalRunnerBackend.getInstanceId(options);
|
1913
1837
|
try {
|
1914
1838
|
await this.pulumiProjectHost.runEmpty(
|
1915
1839
|
{
|
1916
1840
|
projectId: options.projectId,
|
1917
1841
|
pulumiProjectName: options.instanceType,
|
1918
|
-
pulumiStackName:
|
1842
|
+
pulumiStackName: _LocalRunnerBackend.getStackName(options)
|
1919
1843
|
},
|
1920
1844
|
async (stack) => {
|
1921
1845
|
const summary = await stack.workspace.stack();
|
@@ -1981,36 +1905,36 @@ class LocalRunnerBackend {
|
|
1981
1905
|
const outputs = await stack.outputs();
|
1982
1906
|
const patch = {};
|
1983
1907
|
if (outputs["$status"]) {
|
1984
|
-
patch.statusFields =
|
1908
|
+
patch.statusFields = z9.array(instanceStatusFieldSchema).parse(outputs["$status"].value);
|
1985
1909
|
} else {
|
1986
1910
|
patch.statusFields = [];
|
1987
1911
|
}
|
1988
1912
|
if (outputs["$pages"]) {
|
1989
|
-
const pages =
|
1913
|
+
const pages = z9.array(instancePageSchema).parse(outputs["$pages"].value);
|
1990
1914
|
patch.pages = pages.map((page) => omit(page, ["content"]));
|
1991
1915
|
} else {
|
1992
1916
|
patch.pages = [];
|
1993
1917
|
}
|
1994
1918
|
if (outputs["$files"]) {
|
1995
|
-
const files =
|
1919
|
+
const files = z9.array(instanceFileSchema).parse(outputs["$files"].value);
|
1996
1920
|
patch.files = files.map((file) => file.meta);
|
1997
1921
|
} else {
|
1998
1922
|
patch.files = [];
|
1999
1923
|
}
|
2000
1924
|
if (outputs["$terminals"]) {
|
2001
|
-
const terminals =
|
1925
|
+
const terminals = z9.array(instanceTerminalSchema).parse(outputs["$terminals"].value);
|
2002
1926
|
patch.terminals = terminals.map((terminal) => pick(terminal, ["name", "title", "description"]));
|
2003
1927
|
} else {
|
2004
1928
|
patch.terminals = [];
|
2005
1929
|
}
|
2006
1930
|
if (outputs["$triggers"]) {
|
2007
|
-
patch.triggers =
|
1931
|
+
patch.triggers = z9.array(instanceTriggerSchema).parse(outputs["$triggers"].value);
|
2008
1932
|
} else {
|
2009
1933
|
patch.triggers = [];
|
2010
1934
|
}
|
2011
1935
|
if (outputs["$secrets"]) {
|
2012
|
-
patch.secrets =
|
2013
|
-
|
1936
|
+
patch.secrets = pickBy2(
|
1937
|
+
z9.record(z9.string().nullish()).parse(outputs["$secrets"].value),
|
2014
1938
|
(v) => !!v
|
2015
1939
|
);
|
2016
1940
|
} else {
|
@@ -2036,7 +1960,7 @@ class LocalRunnerBackend {
|
|
2036
1960
|
return existingState.status;
|
2037
1961
|
}
|
2038
1962
|
static getInstanceId(options) {
|
2039
|
-
return
|
1963
|
+
return getInstanceId2(options.instanceType, options.instanceName);
|
2040
1964
|
}
|
2041
1965
|
async tryInstallMissingDependencies(error, allowedDependencies) {
|
2042
1966
|
if (!(error instanceof Error)) {
|
@@ -2068,9 +1992,9 @@ class LocalRunnerBackend {
|
|
2068
1992
|
"Failed to determine the home directory, please set HIGHSTATE_BACKEND_RUNNER_LOCAL_CACHE_DIR"
|
2069
1993
|
);
|
2070
1994
|
}
|
2071
|
-
cacheDir =
|
1995
|
+
cacheDir = resolve4(homeDir, ".cache", "highstate");
|
2072
1996
|
}
|
2073
|
-
return new
|
1997
|
+
return new _LocalRunnerBackend(
|
2074
1998
|
config.HIGHSTATE_BACKEND_RUNNER_LOCAL_SKIP_STATE_CHECK,
|
2075
1999
|
config.HIGHSTATE_BACKEND_RUNNER_LOCAL_PRINT_OUTPUT,
|
2076
2000
|
cacheDir,
|
@@ -2078,10 +2002,11 @@ class LocalRunnerBackend {
|
|
2078
2002
|
libraryBackend
|
2079
2003
|
);
|
2080
2004
|
}
|
2081
|
-
}
|
2005
|
+
};
|
2082
2006
|
|
2083
|
-
|
2084
|
-
|
2007
|
+
// src/runner/factory.ts
|
2008
|
+
var runnerBackendConfig = z10.object({
|
2009
|
+
HIGHSTATE_BACKEND_RUNNER_TYPE: z10.enum(["local"]).default("local"),
|
2085
2010
|
...localRunnerBackendConfig.shape
|
2086
2011
|
});
|
2087
2012
|
function createRunnerBackend(config, pulumiProjectHost, libraryBackend) {
|
@@ -2092,10 +2017,17 @@ function createRunnerBackend(config, pulumiProjectHost, libraryBackend) {
|
|
2092
2017
|
}
|
2093
2018
|
}
|
2094
2019
|
|
2095
|
-
|
2096
|
-
|
2020
|
+
// src/state/factory.ts
|
2021
|
+
import { z as z12 } from "zod";
|
2022
|
+
|
2023
|
+
// src/state/local.ts
|
2024
|
+
import { resolve as resolve5 } from "node:path";
|
2025
|
+
import { z as z11 } from "zod";
|
2026
|
+
import { uuidv7 } from "uuidv7";
|
2027
|
+
var localStateBackendConfig = z11.object({
|
2028
|
+
HIGHSTATE_BACKEND_STATE_LOCAL_DIR: z11.string().optional()
|
2097
2029
|
});
|
2098
|
-
|
2030
|
+
var LocalStateBackend = class _LocalStateBackend {
|
2099
2031
|
constructor(db, logger) {
|
2100
2032
|
this.db = db;
|
2101
2033
|
this.logger = logger;
|
@@ -2227,7 +2159,7 @@ class LocalStateBackend {
|
|
2227
2159
|
async putCompositeInstances(projectId, instances) {
|
2228
2160
|
this.validateArray(compositeInstanceSchema, instances);
|
2229
2161
|
const sublevel = this.getProjectCompositeInstancesSublevel(projectId);
|
2230
|
-
this.getProjectCompositeInstanceInputHashesSublevel(projectId);
|
2162
|
+
const inputHashesSublevel = this.getProjectCompositeInstanceInputHashesSublevel(projectId);
|
2231
2163
|
await this.db.batch(
|
2232
2164
|
instances.flatMap((instance) => [
|
2233
2165
|
{
|
@@ -2252,7 +2184,7 @@ class LocalStateBackend {
|
|
2252
2184
|
async getTopLevelCompositeChildrenIds(projectId, instanceIds) {
|
2253
2185
|
const sublevel = this.getProjectCompositeChildrenIdsSublevel(projectId);
|
2254
2186
|
const items = await sublevel.getMany(instanceIds);
|
2255
|
-
const schema =
|
2187
|
+
const schema = z11.array(z11.string()).optional();
|
2256
2188
|
const result = {};
|
2257
2189
|
for (let i = 0; i < items.length; i++) {
|
2258
2190
|
const instanceId = instanceIds[i];
|
@@ -2263,7 +2195,7 @@ class LocalStateBackend {
|
|
2263
2195
|
}
|
2264
2196
|
async putTopLevelCompositeChildrenIds(projectId, childrenIds) {
|
2265
2197
|
const sublevel = this.getProjectCompositeChildrenIdsSublevel(projectId);
|
2266
|
-
const schema =
|
2198
|
+
const schema = z11.array(z11.string()).optional();
|
2267
2199
|
await sublevel.batch(
|
2268
2200
|
Object.entries(childrenIds).map(([instanceId, ids]) => ({
|
2269
2201
|
type: "put",
|
@@ -2274,7 +2206,7 @@ class LocalStateBackend {
|
|
2274
2206
|
}
|
2275
2207
|
async getActiveTerminalSessions() {
|
2276
2208
|
const data = await this.db.get("activeTerminalSessionIds", { valueEncoding: "json" });
|
2277
|
-
return data ?
|
2209
|
+
return data ? z11.array(terminalSessionSchema).parse(data) : [];
|
2278
2210
|
}
|
2279
2211
|
putActiveTerminalSessions(sessions) {
|
2280
2212
|
this.validateArray(terminalSessionSchema, sessions);
|
@@ -2469,21 +2401,22 @@ class LocalStateBackend {
|
|
2469
2401
|
);
|
2470
2402
|
}
|
2471
2403
|
const path = currentUser.url.replace("file://", "").replace("~", process.env.HOME);
|
2472
|
-
location =
|
2404
|
+
location = resolve5(path, ".pulumi", ".highstate");
|
2473
2405
|
childLogger.debug({
|
2474
2406
|
msg: "auto-detected state location",
|
2475
2407
|
pulumiStateUrl: currentUser.url,
|
2476
2408
|
location
|
2477
2409
|
});
|
2478
2410
|
}
|
2479
|
-
const { ClassicLevel } = await import(
|
2411
|
+
const { ClassicLevel } = await import("classic-level");
|
2480
2412
|
const db = new ClassicLevel(location);
|
2481
|
-
return new
|
2413
|
+
return new _LocalStateBackend(db, childLogger);
|
2482
2414
|
}
|
2483
|
-
}
|
2415
|
+
};
|
2484
2416
|
|
2485
|
-
|
2486
|
-
|
2417
|
+
// src/state/factory.ts
|
2418
|
+
var stateBackendConfig = z12.object({
|
2419
|
+
HIGHSTATE_BACKEND_STATE_TYPE: z12.enum(["local"]).default("local"),
|
2487
2420
|
...localStateBackendConfig.shape
|
2488
2421
|
});
|
2489
2422
|
function createStateBackend(config, localPulumiHost, logger) {
|
@@ -2494,8 +2427,10 @@ function createStateBackend(config, localPulumiHost, logger) {
|
|
2494
2427
|
}
|
2495
2428
|
}
|
2496
2429
|
|
2497
|
-
|
2498
|
-
|
2430
|
+
// src/state/manager.ts
|
2431
|
+
import EventEmitter5, { on as on5 } from "node:events";
|
2432
|
+
var StateManager = class {
|
2433
|
+
stateEE = new EventEmitter5();
|
2499
2434
|
/**
|
2500
2435
|
* Watches for all instance state changes in the project.
|
2501
2436
|
*
|
@@ -2503,7 +2438,7 @@ class StateManager {
|
|
2503
2438
|
* @param signal The signal to abort the operation.
|
2504
2439
|
*/
|
2505
2440
|
async *watchInstanceStates(projectId, signal) {
|
2506
|
-
for await (const [state] of
|
2441
|
+
for await (const [state] of on5(this.stateEE, projectId, { signal })) {
|
2507
2442
|
yield state;
|
2508
2443
|
}
|
2509
2444
|
}
|
@@ -2516,12 +2451,19 @@ class StateManager {
|
|
2516
2451
|
emitStatePatch(projectId, patch) {
|
2517
2452
|
this.stateEE.emit(projectId, patch);
|
2518
2453
|
}
|
2519
|
-
}
|
2454
|
+
};
|
2455
|
+
|
2456
|
+
// src/workspace/factory.ts
|
2457
|
+
import { z as z14 } from "zod";
|
2520
2458
|
|
2521
|
-
|
2522
|
-
|
2459
|
+
// src/workspace/local.ts
|
2460
|
+
import { homedir } from "node:os";
|
2461
|
+
import { resolve as resolve6 } from "node:path";
|
2462
|
+
import { z as z13 } from "zod";
|
2463
|
+
var localWorkspaceBackendConfig = z13.object({
|
2464
|
+
HIGHSTATE_BACKEND_WORKSPACE_LOCAL_DIR: z13.string().optional()
|
2523
2465
|
});
|
2524
|
-
|
2466
|
+
var LocalWorkspaceBackend = class _LocalWorkspaceBackend {
|
2525
2467
|
constructor(db) {
|
2526
2468
|
this.db = db;
|
2527
2469
|
}
|
@@ -2547,27 +2489,29 @@ class LocalWorkspaceBackend {
|
|
2547
2489
|
let location = config.HIGHSTATE_BACKEND_WORKSPACE_LOCAL_DIR;
|
2548
2490
|
if (!location) {
|
2549
2491
|
const home = homedir();
|
2550
|
-
location =
|
2492
|
+
location = resolve6(home, ".highstate/workspace");
|
2551
2493
|
}
|
2552
|
-
const { ClassicLevel } = await import(
|
2494
|
+
const { ClassicLevel } = await import("classic-level");
|
2553
2495
|
const db = new ClassicLevel(location, { valueEncoding: "json" });
|
2554
|
-
return new
|
2496
|
+
return new _LocalWorkspaceBackend(db);
|
2555
2497
|
}
|
2556
|
-
}
|
2498
|
+
};
|
2557
2499
|
|
2558
|
-
|
2559
|
-
|
2500
|
+
// src/workspace/factory.ts
|
2501
|
+
var workspaceBackendConfig = z14.object({
|
2502
|
+
HIGHSTATE_BACKEND_WORKSPACE_TYPE: z14.enum(["local"]).default("local"),
|
2560
2503
|
...localWorkspaceBackendConfig.shape
|
2561
2504
|
});
|
2562
2505
|
function createWorkspaceBackend(config) {
|
2563
2506
|
return LocalWorkspaceBackend.create(config);
|
2564
2507
|
}
|
2565
2508
|
|
2566
|
-
|
2567
|
-
|
2568
|
-
|
2509
|
+
// src/config.ts
|
2510
|
+
var loggerConfig = z15.object({
|
2511
|
+
HIGHSTATE_BACKEND_LOGGER_NAME: z15.string().default("highstate-backend"),
|
2512
|
+
HIGHSTATE_BACKEND_LOGGER_LEVEL: z15.enum(["fatal", "error", "warn", "info", "debug", "trace"]).default("info")
|
2569
2513
|
});
|
2570
|
-
|
2514
|
+
var configSchema = z15.object({
|
2571
2515
|
...libraryBackendConfig.shape,
|
2572
2516
|
...projectBackendConfig.shape,
|
2573
2517
|
...secretBackendConfig.shape,
|
@@ -2579,12 +2523,22 @@ const configSchema = z.object({
|
|
2579
2523
|
});
|
2580
2524
|
async function loadConfig(env = process.env, useDotenv = true) {
|
2581
2525
|
if (useDotenv) {
|
2582
|
-
await import(
|
2526
|
+
await import("dotenv/config");
|
2583
2527
|
}
|
2584
2528
|
return configSchema.parse(env);
|
2585
2529
|
}
|
2586
2530
|
|
2587
|
-
|
2531
|
+
// src/orchestrator/manager.ts
|
2532
|
+
import { EventEmitter as EventEmitter6, on as on6 } from "node:events";
|
2533
|
+
import { uuidv7 as uuidv72 } from "uuidv7";
|
2534
|
+
|
2535
|
+
// src/orchestrator/operation.ts
|
2536
|
+
import { isUnitModel as isUnitModel4, parseInstanceId as parseInstanceId2 } from "@highstate/contract";
|
2537
|
+
import { mapValues as mapValues3 } from "remeda";
|
2538
|
+
|
2539
|
+
// src/orchestrator/operation-workset.ts
|
2540
|
+
import { isUnitModel as isUnitModel3 } from "@highstate/contract";
|
2541
|
+
var OperationWorkset = class _OperationWorkset {
|
2588
2542
|
constructor(operation, library, stateManager, logger) {
|
2589
2543
|
this.operation = operation;
|
2590
2544
|
this.library = library;
|
@@ -2805,7 +2759,7 @@ class OperationWorkset {
|
|
2805
2759
|
this.operation.affectedInstanceIds = Array.from(this.affectedInstanceIdSet);
|
2806
2760
|
}
|
2807
2761
|
getSourceHashIfApplicable(instance, component) {
|
2808
|
-
if (
|
2762
|
+
if (isUnitModel3(component)) {
|
2809
2763
|
return this.unitSourceHashMap.get(instance.type);
|
2810
2764
|
}
|
2811
2765
|
return void 0;
|
@@ -2841,7 +2795,7 @@ class OperationWorkset {
|
|
2841
2795
|
stateBackend.getCompositeInstances(operation.projectId, signal),
|
2842
2796
|
stateBackend.getAllInstanceStates(operation.projectId, signal)
|
2843
2797
|
]);
|
2844
|
-
const workset = new
|
2798
|
+
const workset = new _OperationWorkset(
|
2845
2799
|
operation,
|
2846
2800
|
library,
|
2847
2801
|
stateManager,
|
@@ -2926,9 +2880,10 @@ class OperationWorkset {
|
|
2926
2880
|
}
|
2927
2881
|
return workset;
|
2928
2882
|
}
|
2929
|
-
}
|
2883
|
+
};
|
2930
2884
|
|
2931
|
-
|
2885
|
+
// src/orchestrator/operation.ts
|
2886
|
+
var RuntimeOperation = class {
|
2932
2887
|
constructor(operation, runnerBackend, stateBackend, libraryBackend, projectBackend, secretBackend, projectLock, stateManager, operationEE, instanceLogsEE, logger) {
|
2933
2888
|
this.operation = operation;
|
2934
2889
|
this.runnerBackend = runnerBackend;
|
@@ -3032,7 +2987,7 @@ class RuntimeOperation {
|
|
3032
2987
|
getInstancePromiseForOperation(instanceId) {
|
3033
2988
|
const instance = this.workset.getInstance(instanceId);
|
3034
2989
|
const component = this.workset.library.components[instance.type];
|
3035
|
-
if (
|
2990
|
+
if (isUnitModel4(component)) {
|
3036
2991
|
return this.getUnitPromise(instance);
|
3037
2992
|
}
|
3038
2993
|
return this.getCompositePromise(instance);
|
@@ -3135,7 +3090,7 @@ class RuntimeOperation {
|
|
3135
3090
|
instanceName: instance.name,
|
3136
3091
|
config: this.prepareUnitConfig(instance),
|
3137
3092
|
refresh: this.operation.options.refresh,
|
3138
|
-
secrets:
|
3093
|
+
secrets: mapValues3(secrets, (value) => valueToString(value)),
|
3139
3094
|
signal: this.abortController.signal
|
3140
3095
|
});
|
3141
3096
|
logger.debug("unit update requested");
|
@@ -3200,7 +3155,7 @@ class RuntimeOperation {
|
|
3200
3155
|
instanceName: instance.name,
|
3201
3156
|
config: this.prepareUnitConfig(instance, invokedTriggers),
|
3202
3157
|
refresh: this.operation.options.refresh,
|
3203
|
-
secrets:
|
3158
|
+
secrets: mapValues3(secrets, (value) => valueToString(value)),
|
3204
3159
|
signal: this.abortController.signal
|
3205
3160
|
});
|
3206
3161
|
logger.debug("unit update requested");
|
@@ -3235,7 +3190,7 @@ class RuntimeOperation {
|
|
3235
3190
|
this.abortController.signal.throwIfAborted();
|
3236
3191
|
await this.processBeforeDestroyTriggers(state, logger);
|
3237
3192
|
logger.info("destroying unit...");
|
3238
|
-
const [type, name] =
|
3193
|
+
const [type, name] = parseInstanceId2(instanceId);
|
3239
3194
|
await this.runnerBackend.destroy({
|
3240
3195
|
projectId: this.operation.projectId,
|
3241
3196
|
instanceType: type,
|
@@ -3266,7 +3221,7 @@ class RuntimeOperation {
|
|
3266
3221
|
totalResourceCount: 0
|
3267
3222
|
});
|
3268
3223
|
logger.info("refreshing unit...");
|
3269
|
-
const [type, name] =
|
3224
|
+
const [type, name] = parseInstanceId2(instanceId);
|
3270
3225
|
await this.runnerBackend.refresh({
|
3271
3226
|
projectId: this.operation.projectId,
|
3272
3227
|
instanceType: type,
|
@@ -3398,9 +3353,10 @@ class RuntimeOperation {
|
|
3398
3353
|
}
|
3399
3354
|
}
|
3400
3355
|
);
|
3401
|
-
}
|
3356
|
+
};
|
3402
3357
|
|
3403
|
-
|
3358
|
+
// src/orchestrator/manager.ts
|
3359
|
+
var OperationManager = class _OperationManager {
|
3404
3360
|
constructor(runnerBackend, stateBackend, libraryBackend, projectBackend, secretBackend, projectLockManager, stateManager, logger) {
|
3405
3361
|
this.runnerBackend = runnerBackend;
|
3406
3362
|
this.stateBackend = stateBackend;
|
@@ -3411,8 +3367,8 @@ class OperationManager {
|
|
3411
3367
|
this.stateManager = stateManager;
|
3412
3368
|
this.logger = logger;
|
3413
3369
|
}
|
3414
|
-
operationEE = new
|
3415
|
-
instanceLogsEE = new
|
3370
|
+
operationEE = new EventEmitter6();
|
3371
|
+
instanceLogsEE = new EventEmitter6();
|
3416
3372
|
runtimeOperations = /* @__PURE__ */ new Map();
|
3417
3373
|
/**
|
3418
3374
|
* Watches for all project operations in the project.
|
@@ -3421,7 +3377,7 @@ class OperationManager {
|
|
3421
3377
|
* @param signal The signal to abort the operation.
|
3422
3378
|
*/
|
3423
3379
|
async *watchOperations(projectId, signal) {
|
3424
|
-
for await (const [operation] of
|
3380
|
+
for await (const [operation] of on6(this.operationEE, projectId, { signal })) {
|
3425
3381
|
yield operation;
|
3426
3382
|
}
|
3427
3383
|
}
|
@@ -3434,7 +3390,7 @@ class OperationManager {
|
|
3434
3390
|
*/
|
3435
3391
|
async *watchInstanceLogs(operationId, instanceId, signal) {
|
3436
3392
|
const eventKey = `${operationId}/${instanceId}`;
|
3437
|
-
for await (const [log] of
|
3393
|
+
for await (const [log] of on6(this.instanceLogsEE, eventKey, { signal })) {
|
3438
3394
|
yield log;
|
3439
3395
|
}
|
3440
3396
|
}
|
@@ -3445,7 +3401,7 @@ class OperationManager {
|
|
3445
3401
|
*/
|
3446
3402
|
async launch(request) {
|
3447
3403
|
const operation = {
|
3448
|
-
id:
|
3404
|
+
id: uuidv72(),
|
3449
3405
|
projectId: request.projectId,
|
3450
3406
|
type: request.type,
|
3451
3407
|
instanceIds: request.instanceIds,
|
@@ -3495,7 +3451,7 @@ class OperationManager {
|
|
3495
3451
|
void runtimeOperation.operateSafe().finally(() => this.runtimeOperations.delete(operation.id));
|
3496
3452
|
}
|
3497
3453
|
static async create(runnerBackend, stateBackend, libraryBackend, projectBackend, secretBackend, projectLockManager, stateManager, logger) {
|
3498
|
-
const operator = new
|
3454
|
+
const operator = new _OperationManager(
|
3499
3455
|
runnerBackend,
|
3500
3456
|
stateBackend,
|
3501
3457
|
libraryBackend,
|
@@ -3513,8 +3469,10 @@ class OperationManager {
|
|
3513
3469
|
}
|
3514
3470
|
return operator;
|
3515
3471
|
}
|
3516
|
-
}
|
3472
|
+
};
|
3517
3473
|
|
3474
|
+
// src/services.ts
|
3475
|
+
import { pino } from "pino";
|
3518
3476
|
async function createServices({
|
3519
3477
|
config,
|
3520
3478
|
services: {
|
@@ -3583,12 +3541,25 @@ async function createServices({
|
|
3583
3541
|
workspaceBackend
|
3584
3542
|
};
|
3585
3543
|
}
|
3586
|
-
|
3544
|
+
var sharedServicesPromise;
|
3587
3545
|
function getSharedServices(options = {}) {
|
3588
3546
|
if (!sharedServicesPromise) {
|
3589
3547
|
sharedServicesPromise = createServices(options);
|
3590
3548
|
}
|
3591
3549
|
return sharedServicesPromise;
|
3592
3550
|
}
|
3593
|
-
|
3594
|
-
|
3551
|
+
export {
|
3552
|
+
OperationManager,
|
3553
|
+
SecretAccessDeniedError,
|
3554
|
+
TerminalManager,
|
3555
|
+
createLibraryBackend,
|
3556
|
+
createSecretBackend,
|
3557
|
+
createServices,
|
3558
|
+
createTerminalBackend,
|
3559
|
+
getSharedServices,
|
3560
|
+
libraryBackendConfig,
|
3561
|
+
loadConfig,
|
3562
|
+
secretBackendConfig,
|
3563
|
+
terminalBackendConfig
|
3564
|
+
};
|
3565
|
+
//# sourceMappingURL=index.js.map
|