@camstack/agent 1.1.43 → 1.1.45
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-L34OOQI3.mjs → chunk-Y6BUFOWG.mjs} +236 -67
- package/dist/chunk-Y6BUFOWG.mjs.map +1 -0
- package/dist/{chunk-MMKRM4RT.mjs → chunk-Z7VZQCFX.mjs} +60 -2
- package/dist/chunk-Z7VZQCFX.mjs.map +1 -0
- package/dist/cli.js +297 -70
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/index.js +293 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/starter.js +235 -66
- package/dist/starter.js.map +1 -1
- package/dist/starter.mjs +1 -1
- package/package.json +4 -4
- package/dist/chunk-L34OOQI3.mjs.map +0 -1
- package/dist/chunk-MMKRM4RT.mjs.map +0 -1
|
@@ -65,6 +65,9 @@ var require_dist = __commonJS({
|
|
|
65
65
|
var src_exports = {};
|
|
66
66
|
__export(src_exports, {
|
|
67
67
|
AGENT_ROOT_SPEC: () => AGENT_ROOT_SPEC,
|
|
68
|
+
DEV_UPLOADS_DIRNAME: () => DEV_UPLOADS_DIRNAME,
|
|
69
|
+
DEV_UPLOADS_KEEP_COUNT: () => DEV_UPLOADS_KEEP_COUNT,
|
|
70
|
+
DEV_UPLOAD_MANIFEST_FILE: () => DEV_UPLOAD_MANIFEST_FILE,
|
|
68
71
|
HOST_EXTERNAL_SPECIFIERS: () => HOST_EXTERNAL_SPECIFIERS,
|
|
69
72
|
HUB_ROOT_SPEC: () => HUB_ROOT_SPEC,
|
|
70
73
|
RESTART_INTENT_FILE: () => RESTART_INTENT_FILE,
|
|
@@ -74,11 +77,17 @@ var require_dist = __commonJS({
|
|
|
74
77
|
clearRestartIntentMarker: () => clearRestartIntentMarker,
|
|
75
78
|
compareSemver: () => compareSemver,
|
|
76
79
|
detectWorkspaceRoot: () => detectWorkspaceRoot,
|
|
80
|
+
devChannelEpoch: () => devChannelEpoch,
|
|
81
|
+
devUploadManifestPath: () => devUploadManifestPath,
|
|
82
|
+
devUploadVersionDir: () => devUploadVersionDir,
|
|
83
|
+
devUploadsDir: () => devUploadsDir,
|
|
77
84
|
emptyServerRootState: () => emptyServerRootState,
|
|
85
|
+
isDevChannelVersion: () => isDevChannelVersion,
|
|
78
86
|
isHostExternal: () => isHostExternal,
|
|
79
87
|
isServerRootState: () => isServerRootState,
|
|
80
88
|
minNodeMajorOf: () => minNodeMajorOf,
|
|
81
89
|
planBoot: () => planBoot,
|
|
90
|
+
readDevUploadManifest: () => readDevUploadManifest,
|
|
82
91
|
readRestartIntentMarker: () => readRestartIntentMarker,
|
|
83
92
|
readServerRootState: () => readServerRootState,
|
|
84
93
|
registerActiveRootResolver: () => registerActiveRootResolver,
|
|
@@ -91,10 +100,58 @@ var require_dist = __commonJS({
|
|
|
91
100
|
validateVersionDir: () => validateVersionDir,
|
|
92
101
|
versionDir: () => versionDir,
|
|
93
102
|
versionsDir: () => versionsDir,
|
|
103
|
+
writeDevUploadManifest: () => writeDevUploadManifest,
|
|
94
104
|
writeRestartIntentMarker: () => writeRestartIntentMarker,
|
|
95
105
|
writeServerRootState: () => writeServerRootState
|
|
96
106
|
});
|
|
97
107
|
module.exports = __toCommonJS(src_exports);
|
|
108
|
+
var fs = __toESM2(__require("fs"));
|
|
109
|
+
var path = __toESM2(__require("path"));
|
|
110
|
+
var DEV_UPLOADS_DIRNAME = "dev-uploads";
|
|
111
|
+
var DEV_UPLOAD_MANIFEST_FILE = "manifest.json";
|
|
112
|
+
var DEV_UPLOADS_KEEP_COUNT = 3;
|
|
113
|
+
var DEV_CHANNEL_VERSION_RE = /-dev\.\d+$/;
|
|
114
|
+
function isDevChannelVersion(version) {
|
|
115
|
+
return DEV_CHANNEL_VERSION_RE.test(version);
|
|
116
|
+
}
|
|
117
|
+
function devChannelEpoch(version) {
|
|
118
|
+
const match = /-dev\.(\d+)$/.exec(version);
|
|
119
|
+
if (match === null) return null;
|
|
120
|
+
const epoch = Number.parseInt(match[1] ?? "", 10);
|
|
121
|
+
return Number.isNaN(epoch) ? null : epoch;
|
|
122
|
+
}
|
|
123
|
+
function devUploadsDir(rootDir) {
|
|
124
|
+
return path.join(rootDir, DEV_UPLOADS_DIRNAME);
|
|
125
|
+
}
|
|
126
|
+
function devUploadVersionDir(rootDir, version) {
|
|
127
|
+
return path.join(devUploadsDir(rootDir), version);
|
|
128
|
+
}
|
|
129
|
+
function devUploadManifestPath(versionDirPath) {
|
|
130
|
+
return path.join(versionDirPath, DEV_UPLOAD_MANIFEST_FILE);
|
|
131
|
+
}
|
|
132
|
+
function isDevUploadManifest(v) {
|
|
133
|
+
if (typeof v !== "object" || v === null) return false;
|
|
134
|
+
const m = v;
|
|
135
|
+
if (typeof m["version"] !== "string") return false;
|
|
136
|
+
const packages = m["packages"];
|
|
137
|
+
if (typeof packages !== "object" || packages === null || Array.isArray(packages)) return false;
|
|
138
|
+
return Object.values(packages).every((filename) => typeof filename === "string");
|
|
139
|
+
}
|
|
140
|
+
function readDevUploadManifest(versionDirPath) {
|
|
141
|
+
try {
|
|
142
|
+
const raw = JSON.parse(fs.readFileSync(devUploadManifestPath(versionDirPath), "utf-8"));
|
|
143
|
+
return isDevUploadManifest(raw) ? raw : null;
|
|
144
|
+
} catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function writeDevUploadManifest(versionDirPath, manifest) {
|
|
149
|
+
fs.mkdirSync(versionDirPath, { recursive: true });
|
|
150
|
+
const target = devUploadManifestPath(versionDirPath);
|
|
151
|
+
const tmp = `${target}.tmp`;
|
|
152
|
+
fs.writeFileSync(tmp, JSON.stringify(manifest, null, 2), "utf-8");
|
|
153
|
+
fs.renameSync(tmp, target);
|
|
154
|
+
}
|
|
98
155
|
var HUB_ROOT_SPEC = {
|
|
99
156
|
packageName: "@camstack/server",
|
|
100
157
|
entryRelPath: ["dist", "launcher.js"]
|
|
@@ -103,8 +160,8 @@ var require_dist = __commonJS({
|
|
|
103
160
|
packageName: "@camstack/agent",
|
|
104
161
|
entryRelPath: ["dist", "cli.js"]
|
|
105
162
|
};
|
|
106
|
-
var
|
|
107
|
-
var
|
|
163
|
+
var fs2 = __toESM2(__require("fs"));
|
|
164
|
+
var path2 = __toESM2(__require("path"));
|
|
108
165
|
var SERVER_ROOT_DIRNAME = "server-root";
|
|
109
166
|
var SERVER_ROOT_STATE_FILE = "state.json";
|
|
110
167
|
var RESTART_INTENT_FILE = ".restart-intent";
|
|
@@ -118,22 +175,22 @@ var require_dist = __commonJS({
|
|
|
118
175
|
};
|
|
119
176
|
}
|
|
120
177
|
function serverRootDir(dataDir) {
|
|
121
|
-
return
|
|
178
|
+
return path2.join(dataDir, SERVER_ROOT_DIRNAME);
|
|
122
179
|
}
|
|
123
180
|
function versionsDir(rootDir) {
|
|
124
|
-
return
|
|
181
|
+
return path2.join(rootDir, "versions");
|
|
125
182
|
}
|
|
126
183
|
function versionDir(rootDir, version) {
|
|
127
|
-
return
|
|
184
|
+
return path2.join(versionsDir(rootDir), version);
|
|
128
185
|
}
|
|
129
186
|
function rootPackageDir(versionDirPath, spec) {
|
|
130
|
-
return
|
|
187
|
+
return path2.join(versionDirPath, "node_modules", ...spec.packageName.split("/"));
|
|
131
188
|
}
|
|
132
189
|
function rootEntryPath(versionDirPath, spec) {
|
|
133
|
-
return
|
|
190
|
+
return path2.join(rootPackageDir(versionDirPath, spec), ...spec.entryRelPath);
|
|
134
191
|
}
|
|
135
192
|
function stateFilePath(rootDir) {
|
|
136
|
-
return
|
|
193
|
+
return path2.join(rootDir, SERVER_ROOT_STATE_FILE);
|
|
137
194
|
}
|
|
138
195
|
function isNullableString(v) {
|
|
139
196
|
return v === null || typeof v === "string";
|
|
@@ -160,21 +217,21 @@ var require_dist = __commonJS({
|
|
|
160
217
|
}
|
|
161
218
|
function readServerRootState(rootDir) {
|
|
162
219
|
try {
|
|
163
|
-
const raw = JSON.parse(
|
|
220
|
+
const raw = JSON.parse(fs2.readFileSync(stateFilePath(rootDir), "utf-8"));
|
|
164
221
|
return isServerRootState(raw) ? raw : null;
|
|
165
222
|
} catch {
|
|
166
223
|
return null;
|
|
167
224
|
}
|
|
168
225
|
}
|
|
169
226
|
function writeServerRootState(rootDir, state) {
|
|
170
|
-
|
|
227
|
+
fs2.mkdirSync(rootDir, { recursive: true });
|
|
171
228
|
const target = stateFilePath(rootDir);
|
|
172
229
|
const tmp = `${target}.tmp`;
|
|
173
|
-
|
|
174
|
-
|
|
230
|
+
fs2.writeFileSync(tmp, JSON.stringify(state, null, 2), "utf-8");
|
|
231
|
+
fs2.renameSync(tmp, target);
|
|
175
232
|
}
|
|
176
233
|
function restartIntentMarkerPath(rootDir) {
|
|
177
|
-
return
|
|
234
|
+
return path2.join(rootDir, RESTART_INTENT_FILE);
|
|
178
235
|
}
|
|
179
236
|
function isRestartIntentMarker(v) {
|
|
180
237
|
if (typeof v !== "object" || v === null) return false;
|
|
@@ -182,15 +239,15 @@ var require_dist = __commonJS({
|
|
|
182
239
|
return typeof m["requestedAtMs"] === "number" && typeof m["reason"] === "string";
|
|
183
240
|
}
|
|
184
241
|
function writeRestartIntentMarker(rootDir, marker) {
|
|
185
|
-
|
|
242
|
+
fs2.mkdirSync(rootDir, { recursive: true });
|
|
186
243
|
const target = restartIntentMarkerPath(rootDir);
|
|
187
244
|
const tmp = `${target}.tmp`;
|
|
188
|
-
|
|
189
|
-
|
|
245
|
+
fs2.writeFileSync(tmp, JSON.stringify(marker, null, 2), "utf-8");
|
|
246
|
+
fs2.renameSync(tmp, target);
|
|
190
247
|
}
|
|
191
248
|
function readRestartIntentMarker(rootDir) {
|
|
192
249
|
try {
|
|
193
|
-
const raw = JSON.parse(
|
|
250
|
+
const raw = JSON.parse(fs2.readFileSync(restartIntentMarkerPath(rootDir), "utf-8"));
|
|
194
251
|
return isRestartIntentMarker(raw) ? raw : null;
|
|
195
252
|
} catch {
|
|
196
253
|
return null;
|
|
@@ -198,7 +255,7 @@ var require_dist = __commonJS({
|
|
|
198
255
|
}
|
|
199
256
|
function clearRestartIntentMarker(rootDir) {
|
|
200
257
|
try {
|
|
201
|
-
|
|
258
|
+
fs2.rmSync(restartIntentMarkerPath(rootDir), { force: true });
|
|
202
259
|
} catch {
|
|
203
260
|
}
|
|
204
261
|
}
|
|
@@ -211,13 +268,13 @@ var require_dist = __commonJS({
|
|
|
211
268
|
function validateVersionDir(rootDir, version, nodeMajor, spec) {
|
|
212
269
|
const vDir = versionDir(rootDir, version);
|
|
213
270
|
const entry = rootEntryPath(vDir, spec);
|
|
214
|
-
if (!
|
|
271
|
+
if (!fs2.existsSync(entry)) {
|
|
215
272
|
return `root entry missing: ${entry}`;
|
|
216
273
|
}
|
|
217
|
-
const pkgJsonPath =
|
|
274
|
+
const pkgJsonPath = path2.join(rootPackageDir(vDir, spec), "package.json");
|
|
218
275
|
let pkg;
|
|
219
276
|
try {
|
|
220
|
-
const raw = JSON.parse(
|
|
277
|
+
const raw = JSON.parse(fs2.readFileSync(pkgJsonPath, "utf-8"));
|
|
221
278
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
222
279
|
return `package.json malformed: ${pkgJsonPath}`;
|
|
223
280
|
}
|
|
@@ -364,25 +421,25 @@ var require_dist = __commonJS({
|
|
|
364
421
|
if (pa.prerelease > pb.prerelease) return 1;
|
|
365
422
|
return 0;
|
|
366
423
|
}
|
|
367
|
-
var
|
|
368
|
-
var
|
|
424
|
+
var fs3 = __toESM2(__require("fs"));
|
|
425
|
+
var path3 = __toESM2(__require("path"));
|
|
369
426
|
function detectWorkspaceRoot(fromDir) {
|
|
370
|
-
let dir =
|
|
427
|
+
let dir = path3.resolve(fromDir);
|
|
371
428
|
for (; ; ) {
|
|
372
|
-
const pkgPath =
|
|
429
|
+
const pkgPath = path3.join(dir, "package.json");
|
|
373
430
|
try {
|
|
374
|
-
const raw = JSON.parse(
|
|
431
|
+
const raw = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
375
432
|
if (typeof raw === "object" && raw !== null && raw["workspaces"] !== void 0) {
|
|
376
433
|
return dir;
|
|
377
434
|
}
|
|
378
435
|
} catch {
|
|
379
436
|
}
|
|
380
|
-
const parent =
|
|
437
|
+
const parent = path3.dirname(dir);
|
|
381
438
|
if (parent === dir) return null;
|
|
382
439
|
dir = parent;
|
|
383
440
|
}
|
|
384
441
|
}
|
|
385
|
-
var
|
|
442
|
+
var path4 = __toESM2(__require("path"));
|
|
386
443
|
var import_node_url = __require("url");
|
|
387
444
|
var HOST_EXTERNAL_SPECIFIERS = [
|
|
388
445
|
"@camstack/system",
|
|
@@ -410,7 +467,7 @@ var require_dist = __commonJS({
|
|
|
410
467
|
return;
|
|
411
468
|
}
|
|
412
469
|
const anchorURL = (0, import_node_url.pathToFileURL)(
|
|
413
|
-
|
|
470
|
+
path4.join(activeRootDir, "node_modules", "__camstack_starter_anchor__.js")
|
|
414
471
|
).href;
|
|
415
472
|
const hooks = {
|
|
416
473
|
resolve: (specifier, context, nextResolve) => {
|
|
@@ -488,8 +545,8 @@ var require_dist = __commonJS({
|
|
|
488
545
|
options.loadEntry(options.seedEntry);
|
|
489
546
|
}
|
|
490
547
|
var import_node_child_process = __require("child_process");
|
|
491
|
-
var
|
|
492
|
-
var
|
|
548
|
+
var fs4 = __toESM2(__require("fs"));
|
|
549
|
+
var path5 = __toESM2(__require("path"));
|
|
493
550
|
var import_node_util = __require("util");
|
|
494
551
|
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
495
552
|
function buildNpmRegistryArgs(registry) {
|
|
@@ -501,7 +558,7 @@ var require_dist = __commonJS({
|
|
|
501
558
|
var RESTART_REASON_PREFIX = "server-update";
|
|
502
559
|
function readPackageVersion(pkgJsonPath) {
|
|
503
560
|
try {
|
|
504
|
-
const raw = JSON.parse(
|
|
561
|
+
const raw = JSON.parse(fs4.readFileSync(pkgJsonPath, "utf-8"));
|
|
505
562
|
if (typeof raw === "object" && raw !== null) {
|
|
506
563
|
const version = raw["version"];
|
|
507
564
|
if (typeof version === "string") return version;
|
|
@@ -528,7 +585,7 @@ var require_dist = __commonJS({
|
|
|
528
585
|
this.envNames = options.envNames;
|
|
529
586
|
this.logger = options.logger;
|
|
530
587
|
this.restartServerFn = options.restartServer;
|
|
531
|
-
this.dataDir =
|
|
588
|
+
this.dataDir = path5.resolve(options.dataDir);
|
|
532
589
|
this.execNpm = options.execNpm ?? (async (args, opts) => {
|
|
533
590
|
const { stdout } = await execFileAsync("npm", [...args], {
|
|
534
591
|
cwd: opts.cwd,
|
|
@@ -557,7 +614,7 @@ var require_dist = __commonJS({
|
|
|
557
614
|
seedVersion() {
|
|
558
615
|
const seedDir = this.env[this.envNames.seedDir];
|
|
559
616
|
if (seedDir === void 0 || seedDir.length === 0) return null;
|
|
560
|
-
return readPackageVersion(
|
|
617
|
+
return readPackageVersion(path5.join(seedDir, "package.json"));
|
|
561
618
|
}
|
|
562
619
|
rootDir() {
|
|
563
620
|
return serverRootDir(this.dataDir);
|
|
@@ -575,7 +632,7 @@ var require_dist = __commonJS({
|
|
|
575
632
|
const rootDir = this.rootDir();
|
|
576
633
|
const raw = readServerRootState(rootDir);
|
|
577
634
|
if (raw !== null) return { state: raw, corrupt: false };
|
|
578
|
-
return { state: emptyServerRootState(), corrupt:
|
|
635
|
+
return { state: emptyServerRootState(), corrupt: fs4.existsSync(stateFilePath(rootDir)) };
|
|
579
636
|
}
|
|
580
637
|
updateState(state) {
|
|
581
638
|
if (this.inFlight === "checking") return "checking";
|
|
@@ -715,6 +772,17 @@ var require_dist = __commonJS({
|
|
|
715
772
|
message: `Refused: ${this.spec.packageName}@${target} is already running.`
|
|
716
773
|
};
|
|
717
774
|
}
|
|
775
|
+
if (isDevChannelVersion(target)) {
|
|
776
|
+
const uploadsDir = devUploadVersionDir(this.rootDir(), target);
|
|
777
|
+
if (!fs4.existsSync(uploadsDir)) {
|
|
778
|
+
return {
|
|
779
|
+
accepted: false,
|
|
780
|
+
targetVersion: target,
|
|
781
|
+
restarting: false,
|
|
782
|
+
message: `Refused: dev-channel version ${target} has no uploaded tarballs on this node (${uploadsDir} is missing). Dev server deploys are hub-only in this phase \u2014 upload via \`camstack deploy-server\` against this node first.`
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
}
|
|
718
786
|
this.inFlight = "staging";
|
|
719
787
|
try {
|
|
720
788
|
await this.stageAndActivate(target);
|
|
@@ -761,34 +829,40 @@ var require_dist = __commonJS({
|
|
|
761
829
|
async stageAndActivate(target) {
|
|
762
830
|
const rootDir = this.rootDir();
|
|
763
831
|
const vDir = versionsDir(rootDir);
|
|
764
|
-
|
|
765
|
-
const stagingDir =
|
|
766
|
-
|
|
832
|
+
fs4.mkdirSync(vDir, { recursive: true });
|
|
833
|
+
const stagingDir = path5.join(vDir, `.staging-${target}-${process.pid}-${this.now()}`);
|
|
834
|
+
fs4.mkdirSync(stagingDir, { recursive: true });
|
|
767
835
|
try {
|
|
768
|
-
|
|
769
|
-
path4.join(stagingDir, "package.json"),
|
|
770
|
-
JSON.stringify({ name: "camstack-node-root", private: true }, null, 2),
|
|
771
|
-
"utf-8"
|
|
772
|
-
);
|
|
836
|
+
const devDir = devUploadVersionDir(rootDir, target);
|
|
773
837
|
const registry = this.env["CAMSTACK_NPM_REGISTRY"];
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
"
|
|
778
|
-
|
|
779
|
-
"
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
838
|
+
const installArgs = ["install", "--omit=dev", "--no-audit", "--no-fund", "--loglevel=error"];
|
|
839
|
+
if (fs4.existsSync(devDir)) {
|
|
840
|
+
fs4.writeFileSync(
|
|
841
|
+
path5.join(stagingDir, "package.json"),
|
|
842
|
+
JSON.stringify(this.buildDevUploadsPackageJson(devDir, target), null, 2),
|
|
843
|
+
"utf-8"
|
|
844
|
+
);
|
|
845
|
+
await this.execNpm([...installArgs, ...buildNpmRegistryArgs(registry)], {
|
|
846
|
+
cwd: stagingDir,
|
|
847
|
+
timeoutMs: NPM_INSTALL_TIMEOUT_MS
|
|
848
|
+
});
|
|
849
|
+
} else {
|
|
850
|
+
fs4.writeFileSync(
|
|
851
|
+
path5.join(stagingDir, "package.json"),
|
|
852
|
+
JSON.stringify({ name: "camstack-node-root", private: true }, null, 2),
|
|
853
|
+
"utf-8"
|
|
854
|
+
);
|
|
855
|
+
await this.execNpm(
|
|
856
|
+
[...installArgs, `${this.spec.packageName}@${target}`, ...buildNpmRegistryArgs(registry)],
|
|
857
|
+
{ cwd: stagingDir, timeoutMs: NPM_INSTALL_TIMEOUT_MS }
|
|
858
|
+
);
|
|
859
|
+
}
|
|
786
860
|
const entry = rootEntryPath(stagingDir, this.spec);
|
|
787
|
-
if (!
|
|
861
|
+
if (!fs4.existsSync(entry)) {
|
|
788
862
|
throw new Error(`staged closure is missing the root entry (${entry})`);
|
|
789
863
|
}
|
|
790
864
|
const stagedVersion = readPackageVersion(
|
|
791
|
-
|
|
865
|
+
path5.join(rootPackageDir(stagingDir, this.spec), "package.json")
|
|
792
866
|
);
|
|
793
867
|
if (stagedVersion !== target) {
|
|
794
868
|
throw new Error(
|
|
@@ -796,17 +870,61 @@ var require_dist = __commonJS({
|
|
|
796
870
|
);
|
|
797
871
|
}
|
|
798
872
|
const dest = versionDir(rootDir, target);
|
|
799
|
-
if (
|
|
873
|
+
if (fs4.existsSync(dest)) {
|
|
800
874
|
const aside = `${dest}.evicted-${this.now()}`;
|
|
801
|
-
await
|
|
802
|
-
await
|
|
875
|
+
await fs4.promises.rename(dest, aside);
|
|
876
|
+
await fs4.promises.rm(aside, { recursive: true, force: true }).catch(() => void 0);
|
|
803
877
|
}
|
|
804
|
-
await
|
|
878
|
+
await fs4.promises.rename(stagingDir, dest);
|
|
805
879
|
} catch (err) {
|
|
806
|
-
await
|
|
880
|
+
await fs4.promises.rm(stagingDir, { recursive: true, force: true }).catch(() => void 0);
|
|
807
881
|
throw err;
|
|
808
882
|
}
|
|
809
883
|
}
|
|
884
|
+
/**
|
|
885
|
+
* Synthetic staging package.json for the dev server-deploy channel:
|
|
886
|
+
* `dependencies` carries the root package as a `file:` ref to its uploaded
|
|
887
|
+
* tgz; `overrides` maps EVERY OTHER uploaded `@camstack/<name>` to its tgz
|
|
888
|
+
* so any transitive occurrence resolves to the uploaded copy, never npm.
|
|
889
|
+
* Fail-closed: a missing/invalid manifest, a manifest for a different
|
|
890
|
+
* version, a missing root package, or a listed-but-absent tgz all throw
|
|
891
|
+
* (surfaced by `applyServerUpdate` as a staging failure).
|
|
892
|
+
*/
|
|
893
|
+
buildDevUploadsPackageJson(devDir, target) {
|
|
894
|
+
const manifest = readDevUploadManifest(devDir);
|
|
895
|
+
if (manifest === null) {
|
|
896
|
+
throw new Error(`dev-uploads manifest missing or invalid in ${devDir}`);
|
|
897
|
+
}
|
|
898
|
+
if (manifest.version !== target) {
|
|
899
|
+
throw new Error(
|
|
900
|
+
`dev-uploads manifest version mismatch: dir is for ${target}, manifest says ${manifest.version}`
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
const rootTgz = manifest.packages[this.spec.packageName];
|
|
904
|
+
if (rootTgz === void 0) {
|
|
905
|
+
throw new Error(
|
|
906
|
+
`dev-uploads for ${target} do not include the root package ${this.spec.packageName}`
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
const fileRef = (filename) => {
|
|
910
|
+
const abs = path5.join(devDir, filename);
|
|
911
|
+
if (!fs4.existsSync(abs)) {
|
|
912
|
+
throw new Error(`dev-uploads tarball listed in the manifest is missing: ${abs}`);
|
|
913
|
+
}
|
|
914
|
+
return `file:${abs}`;
|
|
915
|
+
};
|
|
916
|
+
const overrides = {};
|
|
917
|
+
for (const [pkgName, filename] of Object.entries(manifest.packages)) {
|
|
918
|
+
if (pkgName === this.spec.packageName) continue;
|
|
919
|
+
overrides[pkgName] = fileRef(filename);
|
|
920
|
+
}
|
|
921
|
+
return {
|
|
922
|
+
name: "camstack-node-root",
|
|
923
|
+
private: true,
|
|
924
|
+
dependencies: { [this.spec.packageName]: fileRef(rootTgz) },
|
|
925
|
+
...Object.keys(overrides).length > 0 ? { overrides } : {}
|
|
926
|
+
};
|
|
927
|
+
}
|
|
810
928
|
// ── Rollback ──────────────────────────────────────────────────────────
|
|
811
929
|
async rollbackServerUpdate() {
|
|
812
930
|
if (this.inFlight !== "idle") {
|
|
@@ -936,6 +1054,7 @@ var require_dist = __commonJS({
|
|
|
936
1054
|
(v) => typeof v === "string"
|
|
937
1055
|
)
|
|
938
1056
|
);
|
|
1057
|
+
this.sweepDevUploads(DEV_UPLOADS_KEEP_COUNT);
|
|
939
1058
|
this.logger.info("root package update confirmed healthy", {
|
|
940
1059
|
meta: {
|
|
941
1060
|
version: promoted.currentVersion,
|
|
@@ -959,23 +1078,23 @@ var require_dist = __commonJS({
|
|
|
959
1078
|
const vDir = versionsDir(this.rootDir());
|
|
960
1079
|
let entries;
|
|
961
1080
|
try {
|
|
962
|
-
entries =
|
|
1081
|
+
entries = fs4.readdirSync(vDir);
|
|
963
1082
|
} catch {
|
|
964
1083
|
return;
|
|
965
1084
|
}
|
|
966
1085
|
for (const entry of entries) {
|
|
967
1086
|
if (keep.includes(entry)) continue;
|
|
968
|
-
const full =
|
|
1087
|
+
const full = path5.join(vDir, entry);
|
|
969
1088
|
if (entry.startsWith(".")) {
|
|
970
1089
|
try {
|
|
971
|
-
const ageMs = this.now() -
|
|
1090
|
+
const ageMs = this.now() - fs4.statSync(full).mtimeMs;
|
|
972
1091
|
if (ageMs < _RootUpdateService.STALE_TRANSIENT_MS) continue;
|
|
973
1092
|
} catch {
|
|
974
1093
|
continue;
|
|
975
1094
|
}
|
|
976
1095
|
}
|
|
977
1096
|
try {
|
|
978
|
-
|
|
1097
|
+
fs4.rmSync(full, { recursive: true, force: true });
|
|
979
1098
|
this.logger.debug("pruned server-root version dir", { meta: { entry } });
|
|
980
1099
|
} catch (err) {
|
|
981
1100
|
this.logger.warn("failed to prune server-root version dir", {
|
|
@@ -984,6 +1103,56 @@ var require_dist = __commonJS({
|
|
|
984
1103
|
}
|
|
985
1104
|
}
|
|
986
1105
|
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Promote-time sweep of `server-root/dev-uploads/`: keep only the
|
|
1108
|
+
* `keepCount` most recent entries (ordered by the self-describing
|
|
1109
|
+
* `-dev.<epochSeconds>` suffix; non-dev-shaped residue counts as oldest).
|
|
1110
|
+
* Uses the same rename-aside graveyard pattern as the addon installer —
|
|
1111
|
+
* a rename is a metadata op that succeeds even when a tarball is held
|
|
1112
|
+
* open, and residue in the graveyard is re-swept on the next promote.
|
|
1113
|
+
*/
|
|
1114
|
+
sweepDevUploads(keepCount) {
|
|
1115
|
+
const dir = devUploadsDir(this.rootDir());
|
|
1116
|
+
let entries;
|
|
1117
|
+
try {
|
|
1118
|
+
entries = fs4.readdirSync(dir);
|
|
1119
|
+
} catch {
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
const graveyard = path5.join(dir, ".sweeping");
|
|
1123
|
+
try {
|
|
1124
|
+
for (const residue of fs4.readdirSync(graveyard)) {
|
|
1125
|
+
try {
|
|
1126
|
+
fs4.rmSync(path5.join(graveyard, residue), { recursive: true, force: true });
|
|
1127
|
+
} catch {
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
} catch {
|
|
1131
|
+
}
|
|
1132
|
+
const versions = entries.filter((name) => !name.startsWith("."));
|
|
1133
|
+
const byNewestFirst = [...versions].sort(
|
|
1134
|
+
(a, b) => (devChannelEpoch(b) ?? -1) - (devChannelEpoch(a) ?? -1)
|
|
1135
|
+
);
|
|
1136
|
+
const doomed = byNewestFirst.slice(keepCount);
|
|
1137
|
+
if (doomed.length === 0) return;
|
|
1138
|
+
fs4.mkdirSync(graveyard, { recursive: true });
|
|
1139
|
+
for (const entry of doomed) {
|
|
1140
|
+
const aside = path5.join(graveyard, `${entry}-${this.now()}`);
|
|
1141
|
+
try {
|
|
1142
|
+
fs4.renameSync(path5.join(dir, entry), aside);
|
|
1143
|
+
} catch (err) {
|
|
1144
|
+
this.logger.warn("failed to move dev-uploads entry aside for sweep", {
|
|
1145
|
+
meta: { entry, error: err instanceof Error ? err.message : String(err) }
|
|
1146
|
+
});
|
|
1147
|
+
continue;
|
|
1148
|
+
}
|
|
1149
|
+
try {
|
|
1150
|
+
fs4.rmSync(aside, { recursive: true, force: true });
|
|
1151
|
+
this.logger.debug("swept dev-uploads entry", { meta: { entry } });
|
|
1152
|
+
} catch {
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
987
1156
|
/** Transient (.staging- / .evicted-) dirs younger than this are never pruned. */
|
|
988
1157
|
static STALE_TRANSIENT_MS = 24 * 60 * 60 * 1e3;
|
|
989
1158
|
};
|
|
@@ -995,4 +1164,4 @@ export {
|
|
|
995
1164
|
__toESM,
|
|
996
1165
|
require_dist
|
|
997
1166
|
};
|
|
998
|
-
//# sourceMappingURL=chunk-
|
|
1167
|
+
//# sourceMappingURL=chunk-Y6BUFOWG.mjs.map
|