@kitsy/cnos 1.5.0 → 1.6.0
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/build/index.cjs +333 -117
- package/dist/build/index.d.cts +3 -2
- package/dist/build/index.d.ts +3 -2
- package/dist/build/index.js +13 -8
- package/dist/{chunk-HMM76UYZ.js → chunk-BMAD24KC.js} +1 -1
- package/dist/{chunk-ZTPSFXWP.js → chunk-JYWQFMW5.js} +1 -1
- package/dist/{chunk-FWJC4Y2D.js → chunk-MW4OVAT3.js} +1 -1
- package/dist/chunk-QU5CXL47.js +577 -0
- package/dist/{chunk-APIU4GTB.js → chunk-S7H2UULC.js} +315 -107
- package/dist/{chunk-WCHX2QFY.js → chunk-UJBQS7CJ.js} +1 -1
- package/dist/{chunk-RYGSG3GR.js → chunk-UOKVLCFL.js} +10 -10
- package/dist/{chunk-T6Y57KTT.js → chunk-UR7CHHNN.js} +1 -1
- package/dist/{chunk-J4K4JUJL.js → chunk-VGZREX5D.js} +1 -1
- package/dist/{chunk-EQSKV3DP.js → chunk-XSUP7JKH.js} +23 -1
- package/dist/configure/index.cjs +332 -122
- package/dist/configure/index.d.cts +3 -3
- package/dist/configure/index.d.ts +3 -3
- package/dist/configure/index.js +8 -8
- package/dist/{envNaming-Dvm_LP2D.d.ts → envNaming-B7Mztkcf.d.ts} +1 -1
- package/dist/{envNaming-S4B-dHUx.d.cts → envNaming-gMVnPOfe.d.cts} +1 -1
- package/dist/index.cjs +754 -143
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -10
- package/dist/internal.cjs +229 -103
- package/dist/internal.d.cts +16 -28
- package/dist/internal.d.ts +16 -28
- package/dist/internal.js +11 -3
- package/dist/plugin/basic-schema.cjs +22 -15
- package/dist/plugin/basic-schema.d.cts +1 -1
- package/dist/plugin/basic-schema.d.ts +1 -1
- package/dist/plugin/basic-schema.js +2 -2
- package/dist/plugin/cli-args.cjs +27 -18
- package/dist/plugin/cli-args.d.cts +1 -1
- package/dist/plugin/cli-args.d.ts +1 -1
- package/dist/plugin/cli-args.js +2 -2
- package/dist/plugin/dotenv.cjs +35 -26
- package/dist/plugin/dotenv.d.cts +2 -2
- package/dist/plugin/dotenv.d.ts +2 -2
- package/dist/plugin/dotenv.js +2 -2
- package/dist/plugin/env-export.cjs +34 -22
- package/dist/plugin/env-export.d.cts +2 -2
- package/dist/plugin/env-export.d.ts +2 -2
- package/dist/plugin/env-export.js +2 -2
- package/dist/plugin/filesystem.cjs +42 -33
- package/dist/plugin/filesystem.d.cts +1 -1
- package/dist/plugin/filesystem.d.ts +1 -1
- package/dist/plugin/filesystem.js +2 -2
- package/dist/plugin/process-env.cjs +24 -17
- package/dist/plugin/process-env.d.cts +2 -2
- package/dist/plugin/process-env.d.ts +2 -2
- package/dist/plugin/process-env.js +2 -2
- package/dist/{plugin-B4xwySxw.d.cts → plugin-CKrBlWGI.d.cts} +52 -3
- package/dist/{plugin-B4xwySxw.d.ts → plugin-CKrBlWGI.d.ts} +52 -3
- package/dist/runtime/index.cjs +752 -143
- package/dist/runtime/index.d.cts +19 -1
- package/dist/runtime/index.d.ts +19 -1
- package/dist/runtime/index.js +10 -10
- package/dist/{toPublicEnv-ggmphZFs.d.cts → toPublicEnv-CmBsy53P.d.cts} +1 -1
- package/dist/{toPublicEnv-CvhGAfsB.d.ts → toPublicEnv-q6VwWxXZ.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-TO76YYS4.js +0 -189
package/dist/runtime/index.cjs
CHANGED
|
@@ -33,6 +33,8 @@ __export(runtime_exports, {
|
|
|
33
33
|
default: () => runtime_default
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(runtime_exports);
|
|
36
|
+
var import_node_fs = require("fs");
|
|
37
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
36
38
|
|
|
37
39
|
// ../core/src/errors.ts
|
|
38
40
|
var CnosError = class extends Error {
|
|
@@ -48,6 +50,11 @@ var CnosManifestError = class extends CnosError {
|
|
|
48
50
|
}
|
|
49
51
|
manifestPath;
|
|
50
52
|
};
|
|
53
|
+
var CnosDiscoveryError = class extends CnosError {
|
|
54
|
+
constructor(message) {
|
|
55
|
+
super(message);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
51
58
|
var CnosSecurityError = class extends CnosError {
|
|
52
59
|
constructor(message) {
|
|
53
60
|
super(message);
|
|
@@ -173,32 +180,110 @@ async function readKeychain(entry) {
|
|
|
173
180
|
}
|
|
174
181
|
|
|
175
182
|
// ../core/src/manifest/loadManifest.ts
|
|
183
|
+
var import_promises3 = require("fs/promises");
|
|
184
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
185
|
+
|
|
186
|
+
// ../core/src/utils/path.ts
|
|
176
187
|
var import_promises2 = require("fs/promises");
|
|
188
|
+
var import_node_os = __toESM(require("os"), 1);
|
|
177
189
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
178
190
|
|
|
179
|
-
// ../core/src/
|
|
191
|
+
// ../core/src/discovery/findCnosrc.ts
|
|
180
192
|
var import_promises = require("fs/promises");
|
|
181
|
-
var import_node_os = __toESM(require("os"), 1);
|
|
182
193
|
var import_node_path = __toESM(require("path"), 1);
|
|
194
|
+
|
|
195
|
+
// ../core/src/utils/yaml.ts
|
|
196
|
+
var import_yaml = require("yaml");
|
|
197
|
+
function parseYaml(source) {
|
|
198
|
+
return (0, import_yaml.parse)(source);
|
|
199
|
+
}
|
|
200
|
+
function stringifyYaml(value) {
|
|
201
|
+
return (0, import_yaml.stringify)(value);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// ../core/src/discovery/findCnosrc.ts
|
|
205
|
+
async function exists(targetPath) {
|
|
206
|
+
try {
|
|
207
|
+
await (0, import_promises.access)(targetPath);
|
|
208
|
+
return true;
|
|
209
|
+
} catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function validateCnosrc(value, filePath) {
|
|
214
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
215
|
+
throw new CnosManifestError(".cnosrc.yml must be a YAML object", filePath);
|
|
216
|
+
}
|
|
217
|
+
const root = typeof value.root === "string" ? value.root.trim() : "";
|
|
218
|
+
const workspace = typeof value.workspace === "string" ? value.workspace.trim() : void 0;
|
|
219
|
+
if (!root) {
|
|
220
|
+
throw new CnosManifestError(".cnosrc.yml requires root", filePath);
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
root,
|
|
224
|
+
...workspace ? { workspace } : {}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
async function findCnosrc(startDir = process.cwd(), maxLevels = 3) {
|
|
228
|
+
let current = import_node_path.default.resolve(startDir);
|
|
229
|
+
for (let depth = 0; depth <= maxLevels; depth += 1) {
|
|
230
|
+
const candidate = import_node_path.default.join(current, ".cnosrc.yml");
|
|
231
|
+
if (await exists(candidate)) {
|
|
232
|
+
return candidate;
|
|
233
|
+
}
|
|
234
|
+
const parent = import_node_path.default.dirname(current);
|
|
235
|
+
if (parent === current) {
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
current = parent;
|
|
239
|
+
}
|
|
240
|
+
return void 0;
|
|
241
|
+
}
|
|
242
|
+
async function discoverCnosAnchor(startDir = process.cwd(), maxLevels = 3) {
|
|
243
|
+
const anchorPath = await findCnosrc(startDir, maxLevels);
|
|
244
|
+
if (!anchorPath) {
|
|
245
|
+
throw new CnosDiscoveryError(
|
|
246
|
+
"No .cnosrc.yml found. Run cnos init or create .cnosrc.yml in your package root."
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
const source = await (0, import_promises.readFile)(anchorPath, "utf8");
|
|
250
|
+
const parsed = validateCnosrc(parseYaml(source), anchorPath);
|
|
251
|
+
const consumerRoot = import_node_path.default.dirname(anchorPath);
|
|
252
|
+
const manifestRoot = import_node_path.default.resolve(consumerRoot, parsed.root);
|
|
253
|
+
const manifestPath = import_node_path.default.join(manifestRoot, "cnos.yml");
|
|
254
|
+
if (!await exists(manifestPath)) {
|
|
255
|
+
throw new CnosDiscoveryError(
|
|
256
|
+
`.cnosrc.yml points to ${manifestRoot} but no cnos.yml found there.`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
anchorPath,
|
|
261
|
+
consumerRoot,
|
|
262
|
+
manifestRoot,
|
|
263
|
+
...parsed.workspace ? { workspace: parsed.workspace } : {}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// ../core/src/utils/path.ts
|
|
183
268
|
var PRIMARY_CNOS_DIR = ".cnos";
|
|
184
269
|
var LEGACY_CNOS_DIR = "cnos";
|
|
185
|
-
async function
|
|
270
|
+
async function exists2(filePath) {
|
|
186
271
|
try {
|
|
187
|
-
await (0,
|
|
272
|
+
await (0, import_promises2.access)(filePath);
|
|
188
273
|
return true;
|
|
189
274
|
} catch {
|
|
190
275
|
return false;
|
|
191
276
|
}
|
|
192
277
|
}
|
|
193
278
|
async function resolveCnosRoot(root = process.cwd()) {
|
|
194
|
-
const basePath =
|
|
279
|
+
const basePath = import_node_path2.default.resolve(root);
|
|
195
280
|
const candidates = [
|
|
196
|
-
|
|
197
|
-
|
|
281
|
+
import_node_path2.default.join(basePath, PRIMARY_CNOS_DIR),
|
|
282
|
+
import_node_path2.default.join(basePath, LEGACY_CNOS_DIR),
|
|
198
283
|
basePath
|
|
199
284
|
];
|
|
200
285
|
for (const candidate of candidates) {
|
|
201
|
-
if (await
|
|
286
|
+
if (await exists2(import_node_path2.default.join(candidate, "cnos.yml"))) {
|
|
202
287
|
return candidate;
|
|
203
288
|
}
|
|
204
289
|
}
|
|
@@ -206,8 +291,23 @@ async function resolveCnosRoot(root = process.cwd()) {
|
|
|
206
291
|
`Could not locate .cnos/cnos.yml or cnos/cnos.yml from root: ${basePath}`
|
|
207
292
|
);
|
|
208
293
|
}
|
|
209
|
-
async function resolveManifestRoot(
|
|
210
|
-
|
|
294
|
+
async function resolveManifestRoot(options = {}) {
|
|
295
|
+
if (options.root) {
|
|
296
|
+
const manifestRoot = await resolveCnosRoot(options.root);
|
|
297
|
+
const resolvedRoot = import_node_path2.default.resolve(options.root);
|
|
298
|
+
const consumerRoot = import_node_path2.default.basename(manifestRoot) === PRIMARY_CNOS_DIR || import_node_path2.default.basename(manifestRoot) === LEGACY_CNOS_DIR ? import_node_path2.default.dirname(manifestRoot) : resolvedRoot;
|
|
299
|
+
return {
|
|
300
|
+
manifestRoot,
|
|
301
|
+
consumerRoot
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const discovered = await discoverCnosAnchor(options.cwd ?? process.cwd());
|
|
305
|
+
return {
|
|
306
|
+
manifestRoot: discovered.manifestRoot,
|
|
307
|
+
consumerRoot: discovered.consumerRoot,
|
|
308
|
+
anchorPath: discovered.anchorPath,
|
|
309
|
+
...discovered.workspace ? { workspace: discovered.workspace } : {}
|
|
310
|
+
};
|
|
211
311
|
}
|
|
212
312
|
function interpolatePathTemplate(template, tokens) {
|
|
213
313
|
return Object.entries(tokens).reduce(
|
|
@@ -220,7 +320,7 @@ function expandHomePath(targetPath) {
|
|
|
220
320
|
return import_node_os.default.homedir();
|
|
221
321
|
}
|
|
222
322
|
if (targetPath.startsWith("~/") || targetPath.startsWith("~\\")) {
|
|
223
|
-
return
|
|
323
|
+
return import_node_path2.default.join(import_node_os.default.homedir(), targetPath.slice(2));
|
|
224
324
|
}
|
|
225
325
|
return targetPath;
|
|
226
326
|
}
|
|
@@ -238,7 +338,7 @@ function stripWorkspaceTemplatePrefix(template) {
|
|
|
238
338
|
function resolveWorkspaceScopedPath(workspaceRoot, template, tokens) {
|
|
239
339
|
const relativeTemplate = stripWorkspaceTemplatePrefix(template);
|
|
240
340
|
const interpolated = interpolatePathTemplate(relativeTemplate, tokens);
|
|
241
|
-
return
|
|
341
|
+
return import_node_path2.default.resolve(workspaceRoot, interpolated);
|
|
242
342
|
}
|
|
243
343
|
function toPortablePath(targetPath) {
|
|
244
344
|
return targetPath.replace(/\\/g, "/");
|
|
@@ -253,15 +353,6 @@ function stripNamespace(key) {
|
|
|
253
353
|
return key.split(".").slice(1).join(".");
|
|
254
354
|
}
|
|
255
355
|
|
|
256
|
-
// ../core/src/utils/yaml.ts
|
|
257
|
-
var import_yaml = require("yaml");
|
|
258
|
-
function parseYaml(source) {
|
|
259
|
-
return (0, import_yaml.parse)(source);
|
|
260
|
-
}
|
|
261
|
-
function stringifyYaml(value) {
|
|
262
|
-
return (0, import_yaml.stringify)(value);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
356
|
// ../core/src/manifest/normalizeManifest.ts
|
|
266
357
|
var DEFAULT_RESOLVE_FROM = ["cli.profile", "env.CNOS_PROFILE", "default"];
|
|
267
358
|
var DEFAULT_LOADERS = [
|
|
@@ -277,7 +368,8 @@ var DEFAULT_INSPECTORS = ["provenance"];
|
|
|
277
368
|
var DEFAULT_FRAMEWORK_PREFIXES = {
|
|
278
369
|
next: "NEXT_PUBLIC_",
|
|
279
370
|
vite: "VITE_",
|
|
280
|
-
nuxt: "NUXT_PUBLIC_"
|
|
371
|
+
nuxt: "NUXT_PUBLIC_",
|
|
372
|
+
webpack: ""
|
|
281
373
|
};
|
|
282
374
|
var DEFAULT_NAMESPACES = {
|
|
283
375
|
value: {
|
|
@@ -530,11 +622,15 @@ function normalizeManifest(manifest) {
|
|
|
530
622
|
|
|
531
623
|
// ../core/src/manifest/loadManifest.ts
|
|
532
624
|
async function loadManifest(options = {}) {
|
|
533
|
-
const
|
|
534
|
-
|
|
625
|
+
const resolved = await resolveManifestRoot({
|
|
626
|
+
...options.root ? { root: options.root } : {},
|
|
627
|
+
...options.cwd ? { cwd: options.cwd } : {}
|
|
628
|
+
});
|
|
629
|
+
const manifestRoot = resolved.manifestRoot;
|
|
630
|
+
const manifestPath = import_node_path3.default.join(manifestRoot, "cnos.yml");
|
|
535
631
|
let source;
|
|
536
632
|
try {
|
|
537
|
-
source = await (0,
|
|
633
|
+
source = await (0, import_promises3.readFile)(manifestPath, "utf8");
|
|
538
634
|
} catch {
|
|
539
635
|
throw new CnosManifestError("Unable to read CNOS manifest", manifestPath);
|
|
540
636
|
}
|
|
@@ -544,7 +640,10 @@ async function loadManifest(options = {}) {
|
|
|
544
640
|
}
|
|
545
641
|
return {
|
|
546
642
|
manifestRoot,
|
|
547
|
-
repoRoot:
|
|
643
|
+
repoRoot: import_node_path3.default.dirname(manifestRoot),
|
|
644
|
+
consumerRoot: resolved.consumerRoot,
|
|
645
|
+
...resolved.anchorPath ? { anchorPath: resolved.anchorPath } : {},
|
|
646
|
+
...resolved.workspace ? { anchoredWorkspace: resolved.workspace } : {},
|
|
548
647
|
manifestPath,
|
|
549
648
|
manifest: normalizeManifest(rawManifest),
|
|
550
649
|
rawManifest
|
|
@@ -552,12 +651,12 @@ async function loadManifest(options = {}) {
|
|
|
552
651
|
}
|
|
553
652
|
|
|
554
653
|
// ../core/src/manifest/loadWorkspaceFile.ts
|
|
555
|
-
var
|
|
556
|
-
var
|
|
654
|
+
var import_promises4 = require("fs/promises");
|
|
655
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
557
656
|
async function loadWorkspaceFile(repoRoot) {
|
|
558
|
-
const workspaceFilePath =
|
|
657
|
+
const workspaceFilePath = import_node_path4.default.join(repoRoot, ".cnos-workspace.yml");
|
|
559
658
|
try {
|
|
560
|
-
const source = await (0,
|
|
659
|
+
const source = await (0, import_promises4.readFile)(workspaceFilePath, "utf8");
|
|
561
660
|
const parsed = parseYaml(source);
|
|
562
661
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
563
662
|
throw new CnosManifestError(".cnos-workspace.yml must be a YAML object", workspaceFilePath);
|
|
@@ -580,11 +679,11 @@ async function loadWorkspaceFile(repoRoot) {
|
|
|
580
679
|
}
|
|
581
680
|
|
|
582
681
|
// ../core/src/profiles/expandProfileChain.ts
|
|
583
|
-
var
|
|
584
|
-
var
|
|
682
|
+
var import_promises5 = require("fs/promises");
|
|
683
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
585
684
|
async function fileExists(targetPath) {
|
|
586
685
|
try {
|
|
587
|
-
await (0,
|
|
686
|
+
await (0, import_promises5.access)(targetPath);
|
|
588
687
|
return true;
|
|
589
688
|
} catch {
|
|
590
689
|
return false;
|
|
@@ -618,11 +717,11 @@ async function loadProfileDefinition(profileName, options) {
|
|
|
618
717
|
return normalizeProfileDefinition(profileName, void 0);
|
|
619
718
|
}
|
|
620
719
|
for (const workspaceRoot of [...workspaceRoots].reverse()) {
|
|
621
|
-
const profilePath =
|
|
720
|
+
const profilePath = import_node_path5.default.join(workspaceRoot.path, "profiles", `${profileName}.yml`);
|
|
622
721
|
if (!await fileExists(profilePath)) {
|
|
623
722
|
continue;
|
|
624
723
|
}
|
|
625
|
-
const document = await (0,
|
|
724
|
+
const document = await (0, import_promises5.readFile)(profilePath, "utf8");
|
|
626
725
|
const parsed = parseYaml(document);
|
|
627
726
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
628
727
|
throw new CnosManifestError("Profile definition must be a YAML object", profilePath);
|
|
@@ -630,7 +729,7 @@ async function loadProfileDefinition(profileName, options) {
|
|
|
630
729
|
const definition = normalizeProfileDefinition(
|
|
631
730
|
profileName,
|
|
632
731
|
parsed,
|
|
633
|
-
options.manifestRoot ? toPortablePath(
|
|
732
|
+
options.manifestRoot ? toPortablePath(import_node_path5.default.relative(import_node_path5.default.dirname(options.manifestRoot), profilePath)) : toPortablePath(profilePath)
|
|
634
733
|
);
|
|
635
734
|
if (definition.name !== profileName) {
|
|
636
735
|
throw new CnosManifestError(
|
|
@@ -912,8 +1011,8 @@ function createProfileAwareResolver() {
|
|
|
912
1011
|
}
|
|
913
1012
|
|
|
914
1013
|
// ../core/src/workspaces/resolveWorkspaceContext.ts
|
|
915
|
-
var
|
|
916
|
-
var
|
|
1014
|
+
var import_promises6 = require("fs/promises");
|
|
1015
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
917
1016
|
|
|
918
1017
|
// ../core/src/workspaces/expandWorkspaceChain.ts
|
|
919
1018
|
function expandWorkspaceChain(workspaceId, items) {
|
|
@@ -950,31 +1049,31 @@ function expandWorkspaceChain(workspaceId, items) {
|
|
|
950
1049
|
}
|
|
951
1050
|
|
|
952
1051
|
// ../core/src/workspaces/resolveWorkspaceContext.ts
|
|
953
|
-
async function
|
|
1052
|
+
async function exists3(targetPath) {
|
|
954
1053
|
try {
|
|
955
|
-
await (0,
|
|
1054
|
+
await (0, import_promises6.access)(targetPath);
|
|
956
1055
|
return true;
|
|
957
1056
|
} catch {
|
|
958
1057
|
return false;
|
|
959
1058
|
}
|
|
960
1059
|
}
|
|
961
1060
|
async function resolveLocalWorkspaceRoot(manifestRoot, workspaceId, manifest) {
|
|
962
|
-
const workspaceRoot =
|
|
963
|
-
if (await
|
|
1061
|
+
const workspaceRoot = import_node_path6.default.join(manifestRoot, "workspaces", workspaceId);
|
|
1062
|
+
if (await exists3(workspaceRoot)) {
|
|
964
1063
|
return workspaceRoot;
|
|
965
1064
|
}
|
|
966
1065
|
const customDataNamespaceRoots = Object.entries(manifest.namespaces).filter(
|
|
967
1066
|
([namespace, definition]) => namespace !== "value" && namespace !== "secret" && definition.kind === "data" && !definition.sensitive
|
|
968
1067
|
).map(([namespace]) => namespace);
|
|
969
1068
|
const legacyMarkers = ["values", "secrets", "env", "profiles", ...customDataNamespaceRoots].map(
|
|
970
|
-
(segment) =>
|
|
1069
|
+
(segment) => import_node_path6.default.join(manifestRoot, segment)
|
|
971
1070
|
);
|
|
972
|
-
if ((await Promise.all(legacyMarkers.map((marker) =>
|
|
1071
|
+
if ((await Promise.all(legacyMarkers.map((marker) => exists3(marker)))).some(Boolean)) {
|
|
973
1072
|
return manifestRoot;
|
|
974
1073
|
}
|
|
975
1074
|
return workspaceRoot;
|
|
976
1075
|
}
|
|
977
|
-
function resolveWorkspaceSelection(manifest, workspaceFile, workspaceOption) {
|
|
1076
|
+
function resolveWorkspaceSelection(manifest, workspaceFile, anchoredWorkspace, workspaceOption) {
|
|
978
1077
|
if (workspaceOption) {
|
|
979
1078
|
return {
|
|
980
1079
|
workspaceId: workspaceOption,
|
|
@@ -987,6 +1086,12 @@ function resolveWorkspaceSelection(manifest, workspaceFile, workspaceOption) {
|
|
|
987
1086
|
source: "workspace-file"
|
|
988
1087
|
};
|
|
989
1088
|
}
|
|
1089
|
+
if (anchoredWorkspace) {
|
|
1090
|
+
return {
|
|
1091
|
+
workspaceId: anchoredWorkspace,
|
|
1092
|
+
source: "anchor-file"
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
990
1095
|
if (manifest.workspaces.default) {
|
|
991
1096
|
return {
|
|
992
1097
|
workspaceId: manifest.workspaces.default,
|
|
@@ -1009,33 +1114,38 @@ function resolveGlobalRoot(manifest, workspaceFile, options) {
|
|
|
1009
1114
|
}
|
|
1010
1115
|
if (options.globalRoot) {
|
|
1011
1116
|
return {
|
|
1012
|
-
value:
|
|
1117
|
+
value: import_node_path6.default.resolve(expandHomePath(options.globalRoot)),
|
|
1013
1118
|
source: "cli"
|
|
1014
1119
|
};
|
|
1015
1120
|
}
|
|
1016
1121
|
if (workspaceFile?.globalRoot) {
|
|
1017
1122
|
return {
|
|
1018
|
-
value:
|
|
1123
|
+
value: import_node_path6.default.resolve(expandHomePath(workspaceFile.globalRoot)),
|
|
1019
1124
|
source: "workspace-file"
|
|
1020
1125
|
};
|
|
1021
1126
|
}
|
|
1022
1127
|
if (manifest.workspaces.global.root) {
|
|
1023
1128
|
return {
|
|
1024
|
-
value:
|
|
1129
|
+
value: import_node_path6.default.resolve(expandHomePath(manifest.workspaces.global.root)),
|
|
1025
1130
|
source: "manifest"
|
|
1026
1131
|
};
|
|
1027
1132
|
}
|
|
1028
1133
|
const cnosHome = options.processEnv?.CNOS_HOME;
|
|
1029
1134
|
if (cnosHome) {
|
|
1030
1135
|
return {
|
|
1031
|
-
value:
|
|
1136
|
+
value: import_node_path6.default.resolve(expandHomePath(cnosHome)),
|
|
1032
1137
|
source: "CNOS_HOME"
|
|
1033
1138
|
};
|
|
1034
1139
|
}
|
|
1035
1140
|
return {};
|
|
1036
1141
|
}
|
|
1037
1142
|
async function resolveWorkspaceContext(manifest, options) {
|
|
1038
|
-
const selectedWorkspace = resolveWorkspaceSelection(
|
|
1143
|
+
const selectedWorkspace = resolveWorkspaceSelection(
|
|
1144
|
+
manifest,
|
|
1145
|
+
options.workspaceFile,
|
|
1146
|
+
options.anchoredWorkspace,
|
|
1147
|
+
options.workspace
|
|
1148
|
+
);
|
|
1039
1149
|
const workspaceChain = expandWorkspaceChain(selectedWorkspace.workspaceId, manifest.workspaces.items);
|
|
1040
1150
|
const globalRoot = resolveGlobalRoot(manifest, options.workspaceFile, options);
|
|
1041
1151
|
const workspaceRoots = [];
|
|
@@ -1045,7 +1155,7 @@ async function resolveWorkspaceContext(manifest, options) {
|
|
|
1045
1155
|
workspaceRoots.push({
|
|
1046
1156
|
scope: "global",
|
|
1047
1157
|
workspaceId: chainWorkspaceId,
|
|
1048
|
-
path:
|
|
1158
|
+
path: import_node_path6.default.join(globalRoot.value, "workspaces", globalWorkspaceId)
|
|
1049
1159
|
});
|
|
1050
1160
|
}
|
|
1051
1161
|
}
|
|
@@ -1237,26 +1347,26 @@ async function runPipeline(options) {
|
|
|
1237
1347
|
}
|
|
1238
1348
|
|
|
1239
1349
|
// ../core/src/secrets/auditLog.ts
|
|
1240
|
-
var
|
|
1241
|
-
var
|
|
1350
|
+
var import_promises9 = require("fs/promises");
|
|
1351
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
1242
1352
|
|
|
1243
1353
|
// ../core/src/utils/secretStore.ts
|
|
1244
1354
|
var import_node_crypto = require("crypto");
|
|
1245
|
-
var
|
|
1246
|
-
var
|
|
1355
|
+
var import_promises8 = require("fs/promises");
|
|
1356
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
1247
1357
|
|
|
1248
1358
|
// ../core/src/secrets/sessionStore.ts
|
|
1249
|
-
var
|
|
1250
|
-
var
|
|
1359
|
+
var import_promises7 = require("fs/promises");
|
|
1360
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
1251
1361
|
function buildSessionRoot(processEnv = process.env) {
|
|
1252
|
-
return
|
|
1362
|
+
return import_node_path7.default.join(import_node_path7.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets")), "sessions");
|
|
1253
1363
|
}
|
|
1254
1364
|
function buildSessionPath(vault, processEnv) {
|
|
1255
|
-
return
|
|
1365
|
+
return import_node_path7.default.join(buildSessionRoot(processEnv), `${vault}.json`);
|
|
1256
1366
|
}
|
|
1257
1367
|
async function readVaultSessionKey(vault, processEnv) {
|
|
1258
1368
|
try {
|
|
1259
|
-
const source = await (0,
|
|
1369
|
+
const source = await (0, import_promises7.readFile)(buildSessionPath(vault, processEnv), "utf8");
|
|
1260
1370
|
const document = JSON.parse(source);
|
|
1261
1371
|
if (document.version !== 1 || typeof document.derivedKey !== "string") {
|
|
1262
1372
|
return void 0;
|
|
@@ -1285,7 +1395,7 @@ function isSecretReference(value) {
|
|
|
1285
1395
|
return isObject(value) && typeof value.provider === "string" && value.provider.trim().length > 0 && typeof value.ref === "string" && value.ref.trim().length > 0 && (value.vault === void 0 && true || typeof value.vault === "string" && value.vault.trim().length > 0) && Object.keys(value).every((key) => ["provider", "ref", "vault"].includes(key));
|
|
1286
1396
|
}
|
|
1287
1397
|
function resolveSecretStoreRoot(processEnv = process.env) {
|
|
1288
|
-
return
|
|
1398
|
+
return import_node_path8.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
|
|
1289
1399
|
}
|
|
1290
1400
|
function normalizeVaultToken(vault = "default") {
|
|
1291
1401
|
return vault.replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
|
|
@@ -1317,16 +1427,16 @@ function deriveVaultKey(passphrase, salt, iterations = PBKDF2_ITERATIONS) {
|
|
|
1317
1427
|
return (0, import_node_crypto.pbkdf2Sync)(passphrase, salt, iterations, KEY_LENGTH, "sha512");
|
|
1318
1428
|
}
|
|
1319
1429
|
function buildMetaPath(storeRoot, vault = "default") {
|
|
1320
|
-
return
|
|
1430
|
+
return import_node_path8.default.join(storeRoot, "vaults", vault, META_FILENAME);
|
|
1321
1431
|
}
|
|
1322
1432
|
function buildKeystorePath(storeRoot, vault = "default") {
|
|
1323
|
-
return
|
|
1433
|
+
return import_node_path8.default.join(storeRoot, "vaults", vault, KEYSTORE_FILENAME);
|
|
1324
1434
|
}
|
|
1325
1435
|
function buildLegacyVaultFile(storeRoot, vault = "default") {
|
|
1326
|
-
return
|
|
1436
|
+
return import_node_path8.default.join(storeRoot, "vaults", `${vault}.json`);
|
|
1327
1437
|
}
|
|
1328
1438
|
function buildLegacyVaultStoreRoot(storeRoot, vault = "default") {
|
|
1329
|
-
return
|
|
1439
|
+
return import_node_path8.default.join(storeRoot, "vaults", vault, "store");
|
|
1330
1440
|
}
|
|
1331
1441
|
function assertVaultMetadata(value, filePath) {
|
|
1332
1442
|
if (!isObject(value)) {
|
|
@@ -1337,9 +1447,9 @@ function assertVaultMetadata(value, filePath) {
|
|
|
1337
1447
|
}
|
|
1338
1448
|
return value;
|
|
1339
1449
|
}
|
|
1340
|
-
async function
|
|
1450
|
+
async function exists4(targetPath) {
|
|
1341
1451
|
try {
|
|
1342
|
-
await (0,
|
|
1452
|
+
await (0, import_promises8.stat)(targetPath);
|
|
1343
1453
|
return true;
|
|
1344
1454
|
} catch {
|
|
1345
1455
|
return false;
|
|
@@ -1348,10 +1458,10 @@ async function exists3(targetPath) {
|
|
|
1348
1458
|
async function detectLegacyVaultFormat(storeRoot, vault = "default") {
|
|
1349
1459
|
const legacyFile = buildLegacyVaultFile(storeRoot, vault);
|
|
1350
1460
|
const legacyStore = buildLegacyVaultStoreRoot(storeRoot, vault);
|
|
1351
|
-
if (await
|
|
1461
|
+
if (await exists4(legacyFile)) {
|
|
1352
1462
|
return legacyFile;
|
|
1353
1463
|
}
|
|
1354
|
-
if (await
|
|
1464
|
+
if (await exists4(legacyStore)) {
|
|
1355
1465
|
return legacyStore;
|
|
1356
1466
|
}
|
|
1357
1467
|
return void 0;
|
|
@@ -1423,15 +1533,15 @@ function buildInitialPayload() {
|
|
|
1423
1533
|
async function writeVaultFiles(storeRoot, vault, meta, payload, key) {
|
|
1424
1534
|
const metaPath = buildMetaPath(storeRoot, vault);
|
|
1425
1535
|
const keystorePath = buildKeystorePath(storeRoot, vault);
|
|
1426
|
-
await (0,
|
|
1427
|
-
await (0,
|
|
1428
|
-
await (0,
|
|
1536
|
+
await (0, import_promises8.mkdir)(import_node_path8.default.dirname(metaPath), { recursive: true });
|
|
1537
|
+
await (0, import_promises8.writeFile)(metaPath, stringifyYaml(meta), "utf8");
|
|
1538
|
+
await (0, import_promises8.writeFile)(keystorePath, encryptPayload(payload, key));
|
|
1429
1539
|
}
|
|
1430
1540
|
async function readVaultMetadata(storeRoot, vault = "default") {
|
|
1431
1541
|
await assertNoLegacyVaultFormat(storeRoot, vault);
|
|
1432
1542
|
const metaPath = buildMetaPath(storeRoot, vault);
|
|
1433
1543
|
try {
|
|
1434
|
-
const source = await (0,
|
|
1544
|
+
const source = await (0, import_promises8.readFile)(metaPath, "utf8");
|
|
1435
1545
|
return assertVaultMetadata(parseYaml(source), metaPath);
|
|
1436
1546
|
} catch (error) {
|
|
1437
1547
|
if (error.code === "ENOENT") {
|
|
@@ -1522,7 +1632,7 @@ async function loadVaultPayload(storeRoot, vault, auth) {
|
|
|
1522
1632
|
if (!key) {
|
|
1523
1633
|
throw new CnosAuthenticationError(`Vault "${vault}" requires authentication before access.`);
|
|
1524
1634
|
}
|
|
1525
|
-
const buffer = await (0,
|
|
1635
|
+
const buffer = await (0, import_promises8.readFile)(buildKeystorePath(storeRoot, vault));
|
|
1526
1636
|
return {
|
|
1527
1637
|
meta,
|
|
1528
1638
|
payload: decryptPayload(buffer, key),
|
|
@@ -1597,9 +1707,9 @@ function resolveVaultDefinition(vaults, vault = "default") {
|
|
|
1597
1707
|
|
|
1598
1708
|
// ../core/src/secrets/auditLog.ts
|
|
1599
1709
|
async function appendAuditEvent(event, processEnv = process.env) {
|
|
1600
|
-
const auditFile = processEnv.CNOS_AUDIT_FILE ??
|
|
1601
|
-
await (0,
|
|
1602
|
-
await (0,
|
|
1710
|
+
const auditFile = processEnv.CNOS_AUDIT_FILE ?? import_node_path9.default.join(resolveSecretStoreRoot(processEnv), "audit", "access.log");
|
|
1711
|
+
await (0, import_promises9.mkdir)(import_node_path9.default.dirname(auditFile), { recursive: true });
|
|
1712
|
+
await (0, import_promises9.appendFile)(
|
|
1603
1713
|
auditFile,
|
|
1604
1714
|
`${JSON.stringify({
|
|
1605
1715
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1992,6 +2102,60 @@ function requireValue(graph, key) {
|
|
|
1992
2102
|
return value;
|
|
1993
2103
|
}
|
|
1994
2104
|
|
|
2105
|
+
// ../core/src/runtime/toServerProjection.ts
|
|
2106
|
+
var import_node_crypto2 = require("crypto");
|
|
2107
|
+
function stableSortObject(value) {
|
|
2108
|
+
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)));
|
|
2109
|
+
}
|
|
2110
|
+
function stripValuePrefix(key) {
|
|
2111
|
+
return key.startsWith("value.") ? key.slice("value.".length) : key;
|
|
2112
|
+
}
|
|
2113
|
+
function configHash(values) {
|
|
2114
|
+
const serialized = JSON.stringify(stableSortObject(values));
|
|
2115
|
+
return (0, import_node_crypto2.createHash)("sha256").update(serialized).digest("hex");
|
|
2116
|
+
}
|
|
2117
|
+
function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev") {
|
|
2118
|
+
const values = {};
|
|
2119
|
+
const secretRefs = {};
|
|
2120
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
2121
|
+
const publicKeys = Array.from(graph.entries.values()).filter((entry) => entry.namespace === "public").map((entry) => entry.key.slice("public.".length)).sort((left, right) => left.localeCompare(right));
|
|
2122
|
+
for (const [key, entry] of graph.entries) {
|
|
2123
|
+
if (entry.namespace === "secret" && isSecretReference(entry.value)) {
|
|
2124
|
+
secretRefs[key.slice("secret.".length)] = {
|
|
2125
|
+
provider: entry.value.provider,
|
|
2126
|
+
vault: entry.value.vault ?? "default",
|
|
2127
|
+
ref: entry.value.ref
|
|
2128
|
+
};
|
|
2129
|
+
continue;
|
|
2130
|
+
}
|
|
2131
|
+
if (entry.namespace === "value") {
|
|
2132
|
+
values[stripValuePrefix(key)] = entry.value;
|
|
2133
|
+
continue;
|
|
2134
|
+
}
|
|
2135
|
+
const namespaceDefinition = manifest.namespaces[entry.namespace];
|
|
2136
|
+
if (namespaceDefinition && namespaceDefinition.kind === "data" && !namespaceDefinition.sensitive && entry.namespace !== "public") {
|
|
2137
|
+
values[key] = entry.value;
|
|
2138
|
+
namespaces.add(entry.namespace);
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
return {
|
|
2142
|
+
version: 1,
|
|
2143
|
+
workspace: graph.workspace.workspaceId,
|
|
2144
|
+
profile: graph.profile,
|
|
2145
|
+
resolvedAt: graph.resolvedAt,
|
|
2146
|
+
configHash: configHash(values),
|
|
2147
|
+
values: stableSortObject(values),
|
|
2148
|
+
secretRefs: stableSortObject(secretRefs),
|
|
2149
|
+
publicKeys,
|
|
2150
|
+
meta: {
|
|
2151
|
+
workspace: graph.workspace.workspaceId,
|
|
2152
|
+
profile: graph.profile,
|
|
2153
|
+
cnos_version: cnosVersion,
|
|
2154
|
+
...namespaces.size > 0 ? { namespaces: Array.from(namespaces).sort((left, right) => left.localeCompare(right)) } : {}
|
|
2155
|
+
}
|
|
2156
|
+
};
|
|
2157
|
+
}
|
|
2158
|
+
|
|
1995
2159
|
// ../core/src/runtime/toEnv.ts
|
|
1996
2160
|
function normalizeEnvValue(value) {
|
|
1997
2161
|
if (value === void 0 || value === null) {
|
|
@@ -2054,11 +2218,14 @@ function resolvePublicPrefix(manifest, options) {
|
|
|
2054
2218
|
if (!options.framework) {
|
|
2055
2219
|
return "";
|
|
2056
2220
|
}
|
|
2057
|
-
const
|
|
2058
|
-
|
|
2221
|
+
const hasConfiguredPrefix = Object.prototype.hasOwnProperty.call(
|
|
2222
|
+
manifest.public.frameworks,
|
|
2223
|
+
options.framework
|
|
2224
|
+
);
|
|
2225
|
+
if (!hasConfiguredPrefix) {
|
|
2059
2226
|
throw new CnosManifestError(`Unknown public framework prefix: ${options.framework}`);
|
|
2060
2227
|
}
|
|
2061
|
-
return
|
|
2228
|
+
return manifest.public.frameworks[options.framework] ?? "";
|
|
2062
2229
|
}
|
|
2063
2230
|
function toPublicEnv(graph, manifest, options = {}) {
|
|
2064
2231
|
const prefix = resolvePublicPrefix(manifest, options);
|
|
@@ -2073,8 +2240,38 @@ function toPublicEnv(graph, manifest, options = {}) {
|
|
|
2073
2240
|
}
|
|
2074
2241
|
|
|
2075
2242
|
// ../core/src/orchestrator/runtime.ts
|
|
2076
|
-
function createRuntime(manifest, graph, plugins = [], secretCache) {
|
|
2077
|
-
function
|
|
2243
|
+
function createRuntime(manifest, graph, plugins = [], secretCache, processEnv = process.env, cnosVersion = "0.0.0-dev") {
|
|
2244
|
+
async function refreshSecretEntry(key) {
|
|
2245
|
+
const entry = graph.entries.get(key);
|
|
2246
|
+
if (!entry || entry.namespace !== "secret" || !isSecretReference(entry.value)) {
|
|
2247
|
+
return;
|
|
2248
|
+
}
|
|
2249
|
+
if (!secretCache) {
|
|
2250
|
+
return;
|
|
2251
|
+
}
|
|
2252
|
+
const vaultId = entry.value.vault ?? "default";
|
|
2253
|
+
const definition = manifest.vaults[vaultId] ?? {
|
|
2254
|
+
provider: entry.value.provider,
|
|
2255
|
+
auth: { passphrase: { from: [] } }
|
|
2256
|
+
};
|
|
2257
|
+
const provider = createSecretVaultProvider(vaultId, definition, processEnv);
|
|
2258
|
+
const auth = await resolveVaultAuth(vaultId, definition, processEnv);
|
|
2259
|
+
await provider.authenticate(auth);
|
|
2260
|
+
const value = await provider.get(entry.value.ref);
|
|
2261
|
+
if (value !== void 0) {
|
|
2262
|
+
secretCache.load(vaultId, /* @__PURE__ */ new Map([[entry.value.ref, value]]));
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
async function refreshAllSecrets() {
|
|
2266
|
+
if (!secretCache) {
|
|
2267
|
+
return;
|
|
2268
|
+
}
|
|
2269
|
+
const secretKeys = Array.from(graph.entries.values()).filter((entry) => entry.namespace === "secret" && isSecretReference(entry.value)).map((entry) => entry.key);
|
|
2270
|
+
for (const key of secretKeys) {
|
|
2271
|
+
await refreshSecretEntry(key);
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
function readLogicalKey2(key) {
|
|
2078
2275
|
const entry = graph.entries.get(key);
|
|
2079
2276
|
if (!entry) {
|
|
2080
2277
|
return void 0;
|
|
@@ -2089,10 +2286,10 @@ function createRuntime(manifest, graph, plugins = [], secretCache) {
|
|
|
2089
2286
|
plugins,
|
|
2090
2287
|
graph,
|
|
2091
2288
|
read(key) {
|
|
2092
|
-
return
|
|
2289
|
+
return readLogicalKey2(key);
|
|
2093
2290
|
},
|
|
2094
2291
|
require(key) {
|
|
2095
|
-
const value =
|
|
2292
|
+
const value = readLogicalKey2(key);
|
|
2096
2293
|
if (value === void 0) {
|
|
2097
2294
|
return requireValue(graph, key);
|
|
2098
2295
|
}
|
|
@@ -2101,14 +2298,14 @@ function createRuntime(manifest, graph, plugins = [], secretCache) {
|
|
|
2101
2298
|
readOr(key, fallback) {
|
|
2102
2299
|
return readOrValue(graph, key, fallback);
|
|
2103
2300
|
},
|
|
2104
|
-
value(
|
|
2105
|
-
return
|
|
2301
|
+
value(path14) {
|
|
2302
|
+
return readLogicalKey2(toLogicalKey("value", path14));
|
|
2106
2303
|
},
|
|
2107
|
-
secret(
|
|
2108
|
-
return
|
|
2304
|
+
secret(path14) {
|
|
2305
|
+
return readLogicalKey2(toLogicalKey("secret", path14));
|
|
2109
2306
|
},
|
|
2110
|
-
meta(
|
|
2111
|
-
return
|
|
2307
|
+
meta(path14) {
|
|
2308
|
+
return readLogicalKey2(toLogicalKey("meta", path14));
|
|
2112
2309
|
},
|
|
2113
2310
|
inspect(key) {
|
|
2114
2311
|
return inspectValue(graph, key);
|
|
@@ -2124,6 +2321,15 @@ function createRuntime(manifest, graph, plugins = [], secretCache) {
|
|
|
2124
2321
|
},
|
|
2125
2322
|
toPublicEnv(options) {
|
|
2126
2323
|
return toPublicEnv(graph, manifest, options);
|
|
2324
|
+
},
|
|
2325
|
+
toServerProjection() {
|
|
2326
|
+
return toServerProjection(graph, manifest, cnosVersion);
|
|
2327
|
+
},
|
|
2328
|
+
async refreshSecrets() {
|
|
2329
|
+
await refreshAllSecrets();
|
|
2330
|
+
},
|
|
2331
|
+
async refreshSecret(key) {
|
|
2332
|
+
await refreshSecretEntry(key);
|
|
2127
2333
|
}
|
|
2128
2334
|
};
|
|
2129
2335
|
}
|
|
@@ -2222,14 +2428,18 @@ function appendMetaEntries(graph, cnosVersion) {
|
|
|
2222
2428
|
};
|
|
2223
2429
|
}
|
|
2224
2430
|
async function createCnos(options = {}) {
|
|
2225
|
-
const loadedManifest = await loadManifest(
|
|
2431
|
+
const loadedManifest = await loadManifest({
|
|
2432
|
+
...options.root ? { root: options.root } : {},
|
|
2433
|
+
...options.cwd ? { cwd: options.cwd } : {}
|
|
2434
|
+
});
|
|
2226
2435
|
for (const key of loadedManifest.manifest.public.promote) {
|
|
2227
2436
|
ensureProjectionAllowed(loadedManifest.manifest, key, "public");
|
|
2228
2437
|
}
|
|
2229
|
-
const workspaceFile = await loadWorkspaceFile(loadedManifest.
|
|
2438
|
+
const workspaceFile = await loadWorkspaceFile(loadedManifest.consumerRoot);
|
|
2230
2439
|
const workspace = await resolveWorkspaceContext(loadedManifest.manifest, {
|
|
2231
2440
|
manifestRoot: loadedManifest.manifestRoot,
|
|
2232
2441
|
...workspaceFile ? { workspaceFile: workspaceFile.config } : {},
|
|
2442
|
+
...loadedManifest.anchoredWorkspace ? { anchoredWorkspace: loadedManifest.anchoredWorkspace } : {},
|
|
2233
2443
|
...options.workspace ? { workspace: options.workspace } : {},
|
|
2234
2444
|
...options.globalRoot ? { globalRoot: options.globalRoot } : {},
|
|
2235
2445
|
...options.processEnv ? { processEnv: options.processEnv } : {}
|
|
@@ -2274,13 +2484,15 @@ async function createCnos(options = {}) {
|
|
|
2274
2484
|
profileSource: activeProfile.source
|
|
2275
2485
|
}, options.cnosVersion),
|
|
2276
2486
|
plugins,
|
|
2277
|
-
secretCache
|
|
2487
|
+
secretCache,
|
|
2488
|
+
options.processEnv,
|
|
2489
|
+
options.cnosVersion
|
|
2278
2490
|
);
|
|
2279
2491
|
}
|
|
2280
2492
|
|
|
2281
2493
|
// ../core/src/runtime/dump.ts
|
|
2282
|
-
var
|
|
2283
|
-
var
|
|
2494
|
+
var import_promises10 = require("fs/promises");
|
|
2495
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
2284
2496
|
|
|
2285
2497
|
// ../core/src/utils/envNaming.ts
|
|
2286
2498
|
function normalizeMappingConfig(config = {}) {
|
|
@@ -2289,8 +2501,8 @@ function normalizeMappingConfig(config = {}) {
|
|
|
2289
2501
|
explicit: config.explicit ?? {}
|
|
2290
2502
|
};
|
|
2291
2503
|
}
|
|
2292
|
-
function fromScreamingSnake(
|
|
2293
|
-
return
|
|
2504
|
+
function fromScreamingSnake(path14) {
|
|
2505
|
+
return path14.split("_").map((segment) => segment.trim().toLowerCase()).filter(Boolean).join(".");
|
|
2294
2506
|
}
|
|
2295
2507
|
function envVarToLogicalKey(envVar, config = {}) {
|
|
2296
2508
|
const normalized = normalizeMappingConfig(config);
|
|
@@ -2317,7 +2529,7 @@ function envVarToLogicalKey(envVar, config = {}) {
|
|
|
2317
2529
|
// package.json
|
|
2318
2530
|
var package_default = {
|
|
2319
2531
|
name: "@kitsy/cnos",
|
|
2320
|
-
version: "1.
|
|
2532
|
+
version: "1.6.0",
|
|
2321
2533
|
description: "Batteries-included CNOS runtime package wired with the official plugins.",
|
|
2322
2534
|
type: "module",
|
|
2323
2535
|
main: "./dist/index.cjs",
|
|
@@ -2516,8 +2728,8 @@ function createCliArgsPlugin() {
|
|
|
2516
2728
|
}
|
|
2517
2729
|
|
|
2518
2730
|
// ../../plugins/dotenv/src/index.ts
|
|
2519
|
-
var
|
|
2520
|
-
var
|
|
2731
|
+
var import_promises11 = require("fs/promises");
|
|
2732
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
2521
2733
|
var DOTENV_PLUGIN_ID = "@kitsy/cnos/plugins/dotenv";
|
|
2522
2734
|
function parseDoubleQuoted(value) {
|
|
2523
2735
|
return value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
@@ -2574,7 +2786,7 @@ function dotenvEntriesFromObject(values, mapping = {}, originFile, workspaceId =
|
|
|
2574
2786
|
}
|
|
2575
2787
|
async function readIfPresent(filePath) {
|
|
2576
2788
|
try {
|
|
2577
|
-
return await (0,
|
|
2789
|
+
return await (0, import_promises11.readFile)(filePath, "utf8");
|
|
2578
2790
|
} catch {
|
|
2579
2791
|
return void 0;
|
|
2580
2792
|
}
|
|
@@ -2593,7 +2805,7 @@ function createDotenvPlugin() {
|
|
|
2593
2805
|
workspace: workspaceRoot.workspaceId
|
|
2594
2806
|
});
|
|
2595
2807
|
for (const fileName of fileNames) {
|
|
2596
|
-
const absolutePath =
|
|
2808
|
+
const absolutePath = import_node_path11.default.join(envRoot, fileName);
|
|
2597
2809
|
const document = await readIfPresent(absolutePath);
|
|
2598
2810
|
if (!document) {
|
|
2599
2811
|
continue;
|
|
@@ -2602,7 +2814,7 @@ function createDotenvPlugin() {
|
|
|
2602
2814
|
...dotenvEntriesFromObject(
|
|
2603
2815
|
parseDotenv(document),
|
|
2604
2816
|
config.envMapping,
|
|
2605
|
-
toPortablePath(
|
|
2817
|
+
toPortablePath(import_node_path11.default.relative(import_node_path11.default.dirname(context.manifestRoot), absolutePath)),
|
|
2606
2818
|
workspaceRoot.workspaceId
|
|
2607
2819
|
)
|
|
2608
2820
|
);
|
|
@@ -2640,16 +2852,16 @@ function createPublicEnvExportPlugin() {
|
|
|
2640
2852
|
}
|
|
2641
2853
|
|
|
2642
2854
|
// ../../plugins/filesystem/src/filesystemSecretsReader.ts
|
|
2643
|
-
var
|
|
2855
|
+
var import_promises13 = require("fs/promises");
|
|
2644
2856
|
|
|
2645
2857
|
// ../../plugins/filesystem/src/helpers.ts
|
|
2646
|
-
var
|
|
2647
|
-
var
|
|
2858
|
+
var import_promises12 = require("fs/promises");
|
|
2859
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
2648
2860
|
var YAML_EXTENSIONS = /* @__PURE__ */ new Set([".yml", ".yaml"]);
|
|
2649
2861
|
var FILESYSTEM_PLUGIN_ID = "@kitsy/cnos/plugins/filesystem";
|
|
2650
2862
|
async function existsDirectory(targetPath) {
|
|
2651
2863
|
try {
|
|
2652
|
-
const stat2 = await (0,
|
|
2864
|
+
const stat2 = await (0, import_promises12.readdir)(targetPath);
|
|
2653
2865
|
void stat2;
|
|
2654
2866
|
return true;
|
|
2655
2867
|
} catch {
|
|
@@ -2657,15 +2869,15 @@ async function existsDirectory(targetPath) {
|
|
|
2657
2869
|
}
|
|
2658
2870
|
}
|
|
2659
2871
|
async function collectYamlFiles(root) {
|
|
2660
|
-
const entries = await (0,
|
|
2872
|
+
const entries = await (0, import_promises12.readdir)(root, { withFileTypes: true });
|
|
2661
2873
|
const results = [];
|
|
2662
2874
|
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
2663
|
-
const absolutePath =
|
|
2875
|
+
const absolutePath = import_node_path12.default.join(root, entry.name);
|
|
2664
2876
|
if (entry.isDirectory()) {
|
|
2665
2877
|
results.push(...await collectYamlFiles(absolutePath));
|
|
2666
2878
|
continue;
|
|
2667
2879
|
}
|
|
2668
|
-
if (entry.isFile() && YAML_EXTENSIONS.has(
|
|
2880
|
+
if (entry.isFile() && YAML_EXTENSIONS.has(import_node_path12.default.extname(entry.name).toLowerCase())) {
|
|
2669
2881
|
results.push(absolutePath);
|
|
2670
2882
|
}
|
|
2671
2883
|
}
|
|
@@ -2673,16 +2885,16 @@ async function collectYamlFiles(root) {
|
|
|
2673
2885
|
}
|
|
2674
2886
|
async function collectFilesystemLayerFiles(manifestRoot, workspaceRoots, sourceRoot, activeLayers) {
|
|
2675
2887
|
const files = [];
|
|
2676
|
-
const repoRoot =
|
|
2888
|
+
const repoRoot = import_node_path12.default.dirname(manifestRoot);
|
|
2677
2889
|
for (const workspaceRoot of workspaceRoots) {
|
|
2678
|
-
const resolvedRoot =
|
|
2890
|
+
const resolvedRoot = import_node_path12.default.resolve(workspaceRoot.path, sourceRoot);
|
|
2679
2891
|
for (const layer of activeLayers) {
|
|
2680
|
-
const layerRoot =
|
|
2892
|
+
const layerRoot = import_node_path12.default.join(resolvedRoot, layer);
|
|
2681
2893
|
if (!await existsDirectory(layerRoot)) {
|
|
2682
2894
|
continue;
|
|
2683
2895
|
}
|
|
2684
2896
|
for (const absolutePath of await collectYamlFiles(layerRoot)) {
|
|
2685
|
-
const relativePath =
|
|
2897
|
+
const relativePath = import_node_path12.default.relative(repoRoot, absolutePath);
|
|
2686
2898
|
files.push({
|
|
2687
2899
|
absolutePath,
|
|
2688
2900
|
relativePath: toPortablePath(relativePath.startsWith("..") ? absolutePath : relativePath),
|
|
@@ -2759,7 +2971,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
2759
2971
|
);
|
|
2760
2972
|
const entries = [];
|
|
2761
2973
|
for (const file of files) {
|
|
2762
|
-
const document = await (0,
|
|
2974
|
+
const document = await (0, import_promises13.readFile)(file.absolutePath, "utf8");
|
|
2763
2975
|
const fileEntries = filesystemSecretsReader(file.relativePath, document, file.workspaceId);
|
|
2764
2976
|
for (const entry of fileEntries) {
|
|
2765
2977
|
const metadata = toSecretReferenceMetadata(entry.value);
|
|
@@ -2775,7 +2987,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
2775
2987
|
}
|
|
2776
2988
|
|
|
2777
2989
|
// ../../plugins/filesystem/src/filesystemValuesReader.ts
|
|
2778
|
-
var
|
|
2990
|
+
var import_promises14 = require("fs/promises");
|
|
2779
2991
|
function filesystemValuesReader(filePath, document, workspaceId = "default") {
|
|
2780
2992
|
return yamlObjectToEntries(document, filePath, "value", "filesystem-values", workspaceId);
|
|
2781
2993
|
}
|
|
@@ -2796,7 +3008,7 @@ function createFilesystemValuesPlugin() {
|
|
|
2796
3008
|
).map(([namespace]) => namespace);
|
|
2797
3009
|
const entries = [];
|
|
2798
3010
|
for (const file of files) {
|
|
2799
|
-
const document = await (0,
|
|
3011
|
+
const document = await (0, import_promises14.readFile)(file.absolutePath, "utf8");
|
|
2800
3012
|
entries.push(...filesystemValuesReader(file.relativePath, document, file.workspaceId));
|
|
2801
3013
|
}
|
|
2802
3014
|
for (const namespace of customNamespaces) {
|
|
@@ -2811,7 +3023,7 @@ function createFilesystemValuesPlugin() {
|
|
|
2811
3023
|
layers
|
|
2812
3024
|
);
|
|
2813
3025
|
for (const file of namespaceFiles) {
|
|
2814
|
-
const document = await (0,
|
|
3026
|
+
const document = await (0, import_promises14.readFile)(file.absolutePath, "utf8");
|
|
2815
3027
|
entries.push(...yamlObjectToEntries(document, file.relativePath, namespace, "filesystem-values", file.workspaceId));
|
|
2816
3028
|
}
|
|
2817
3029
|
}
|
|
@@ -2981,10 +3193,18 @@ async function createCnos2(options = {}) {
|
|
|
2981
3193
|
}
|
|
2982
3194
|
|
|
2983
3195
|
// src/runtime/bootstrap.ts
|
|
2984
|
-
var
|
|
3196
|
+
var import_node_crypto3 = require("crypto");
|
|
2985
3197
|
var CNOS_GRAPH_ENV_VAR = "__CNOS_GRAPH__";
|
|
3198
|
+
var CNOS_PROJECTION_ENV_VAR = "__CNOS_PROJECTION__";
|
|
2986
3199
|
var CNOS_SECRET_PAYLOAD_ENV_VAR = "__CNOS_SECRET_PAYLOAD__";
|
|
2987
3200
|
var CNOS_SESSION_KEY_ENV_VAR = "__CNOS_SESSION_KEY__";
|
|
3201
|
+
function deserializeServerProjection(source) {
|
|
3202
|
+
const payload = JSON.parse(source);
|
|
3203
|
+
if (!payload || payload.version !== 1 || typeof payload.workspace !== "string" || typeof payload.profile !== "string" || typeof payload.resolvedAt !== "string" || typeof payload.configHash !== "string" || !payload.values || typeof payload.values !== "object" || Array.isArray(payload.values) || !payload.secretRefs || typeof payload.secretRefs !== "object" || Array.isArray(payload.secretRefs) || !Array.isArray(payload.publicKeys) || !payload.meta || typeof payload.meta !== "object") {
|
|
3204
|
+
throw new Error("Invalid CNOS server projection payload");
|
|
3205
|
+
}
|
|
3206
|
+
return payload;
|
|
3207
|
+
}
|
|
2988
3208
|
function deserializeRuntimeGraph(source) {
|
|
2989
3209
|
const payload = JSON.parse(source);
|
|
2990
3210
|
if (!payload || !Array.isArray(payload.entries) || typeof payload.profile !== "string" || typeof payload.resolvedAt !== "string" || !payload.profileSource || !payload.workspace || typeof payload.workspace.workspaceId !== "string" || !Array.isArray(payload.workspace.workspaceChain) || !Array.isArray(payload.workspace.workspaceRoots)) {
|
|
@@ -3018,7 +3238,7 @@ function decryptSecretPayload(serialized, sessionKey) {
|
|
|
3018
3238
|
const iv = Buffer.from(payload.iv, "base64");
|
|
3019
3239
|
const tag = Buffer.from(payload.tag, "base64");
|
|
3020
3240
|
const ciphertext = Buffer.from(payload.ciphertext, "base64");
|
|
3021
|
-
const decipher = (0,
|
|
3241
|
+
const decipher = (0, import_node_crypto3.createDecipheriv)("aes-256-gcm", key, iv);
|
|
3022
3242
|
decipher.setAuthTag(tag);
|
|
3023
3243
|
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
3024
3244
|
return JSON.parse(plaintext);
|
|
@@ -3042,6 +3262,13 @@ function readRuntimeGraphFromEnv(processEnv = process.env) {
|
|
|
3042
3262
|
}
|
|
3043
3263
|
return graph;
|
|
3044
3264
|
}
|
|
3265
|
+
function readServerProjectionFromEnv(processEnv = process.env) {
|
|
3266
|
+
const serialized = processEnv[CNOS_PROJECTION_ENV_VAR];
|
|
3267
|
+
if (!serialized) {
|
|
3268
|
+
return void 0;
|
|
3269
|
+
}
|
|
3270
|
+
return deserializeServerProjection(serialized);
|
|
3271
|
+
}
|
|
3045
3272
|
function graphRequiresSecretHydration(graph) {
|
|
3046
3273
|
return Array.from(graph.entries.values()).some((entry) => entry.namespace === "secret" && isSecretReference(entry.value));
|
|
3047
3274
|
}
|
|
@@ -3055,6 +3282,37 @@ function getRuntimeOrThrow() {
|
|
|
3055
3282
|
}
|
|
3056
3283
|
return runtime;
|
|
3057
3284
|
}
|
|
3285
|
+
function requireLogicalKey(runtime, key) {
|
|
3286
|
+
return runtime.require(key);
|
|
3287
|
+
}
|
|
3288
|
+
function readLogicalKey(runtime, key) {
|
|
3289
|
+
return runtime.read(key);
|
|
3290
|
+
}
|
|
3291
|
+
function stringifyLogValue(value) {
|
|
3292
|
+
if (value === void 0) {
|
|
3293
|
+
return "";
|
|
3294
|
+
}
|
|
3295
|
+
if (value === null) {
|
|
3296
|
+
return "null";
|
|
3297
|
+
}
|
|
3298
|
+
if (typeof value === "string") {
|
|
3299
|
+
return value;
|
|
3300
|
+
}
|
|
3301
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
3302
|
+
return String(value);
|
|
3303
|
+
}
|
|
3304
|
+
return JSON.stringify(value);
|
|
3305
|
+
}
|
|
3306
|
+
function formatMessage(runtime, message) {
|
|
3307
|
+
return message.replace(/\$\{([^}]+)\}/g, (match, rawKey) => {
|
|
3308
|
+
const key = String(rawKey).trim();
|
|
3309
|
+
if (!key) {
|
|
3310
|
+
return match;
|
|
3311
|
+
}
|
|
3312
|
+
const value = runtime.read(key);
|
|
3313
|
+
return value === void 0 ? match : stringifyLogValue(value);
|
|
3314
|
+
});
|
|
3315
|
+
}
|
|
3058
3316
|
function attachBootstrappedGraph(graph) {
|
|
3059
3317
|
if (getSingletonRuntime()) {
|
|
3060
3318
|
return;
|
|
@@ -3126,14 +3384,23 @@ function attachBootstrappedGraph(graph) {
|
|
|
3126
3384
|
readOr(key, fallback) {
|
|
3127
3385
|
return readOrValue(graph, key, fallback);
|
|
3128
3386
|
},
|
|
3129
|
-
value(
|
|
3130
|
-
return readValue(graph, toLogicalKey("value",
|
|
3387
|
+
value(path14) {
|
|
3388
|
+
return readValue(graph, toLogicalKey("value", path14));
|
|
3389
|
+
},
|
|
3390
|
+
secret(path14) {
|
|
3391
|
+
return readValue(graph, toLogicalKey("secret", path14));
|
|
3131
3392
|
},
|
|
3132
|
-
|
|
3133
|
-
return readValue(graph, toLogicalKey("
|
|
3393
|
+
meta(path14) {
|
|
3394
|
+
return readValue(graph, toLogicalKey("meta", path14));
|
|
3134
3395
|
},
|
|
3135
|
-
|
|
3136
|
-
return
|
|
3396
|
+
toNamespace(namespace) {
|
|
3397
|
+
return toNamespaceObject(graph, namespace);
|
|
3398
|
+
},
|
|
3399
|
+
toEnv(options) {
|
|
3400
|
+
return toEnv(graph, bootstrappedManifest, options);
|
|
3401
|
+
},
|
|
3402
|
+
toPublicEnv(options) {
|
|
3403
|
+
return toPublicEnv(graph, bootstrappedManifest, options);
|
|
3137
3404
|
},
|
|
3138
3405
|
inspect(key) {
|
|
3139
3406
|
return inspectValue(graph, key);
|
|
@@ -3141,18 +3408,273 @@ function attachBootstrappedGraph(graph) {
|
|
|
3141
3408
|
toObject() {
|
|
3142
3409
|
return toNamespaceObject(graph);
|
|
3143
3410
|
},
|
|
3411
|
+
toServerProjection() {
|
|
3412
|
+
throw new Error("CNOS graph bootstrap payload does not support server projection export.");
|
|
3413
|
+
},
|
|
3414
|
+
async refreshSecrets() {
|
|
3415
|
+
return;
|
|
3416
|
+
},
|
|
3417
|
+
async refreshSecret() {
|
|
3418
|
+
return;
|
|
3419
|
+
}
|
|
3420
|
+
};
|
|
3421
|
+
setSingletonRuntime(runtime);
|
|
3422
|
+
setBootstrappedSecretHydrationRequired(graphRequiresSecretHydration(graph));
|
|
3423
|
+
}
|
|
3424
|
+
function toBootstrappedManifest(graph) {
|
|
3425
|
+
return {
|
|
3426
|
+
version: 1,
|
|
3427
|
+
project: {
|
|
3428
|
+
name: "bootstrapped"
|
|
3429
|
+
},
|
|
3430
|
+
workspaces: {
|
|
3431
|
+
global: {
|
|
3432
|
+
enabled: false,
|
|
3433
|
+
allowWrite: false
|
|
3434
|
+
},
|
|
3435
|
+
items: {},
|
|
3436
|
+
...graph.workspace.workspaceSource === "implicit" ? {} : {
|
|
3437
|
+
default: graph.workspace.workspaceId
|
|
3438
|
+
}
|
|
3439
|
+
},
|
|
3440
|
+
profiles: {
|
|
3441
|
+
default: graph.profile,
|
|
3442
|
+
resolveFrom: ["default"]
|
|
3443
|
+
},
|
|
3444
|
+
plugins: {
|
|
3445
|
+
loaders: [],
|
|
3446
|
+
resolver: "profile-aware",
|
|
3447
|
+
validators: [],
|
|
3448
|
+
exporters: [],
|
|
3449
|
+
inspectors: []
|
|
3450
|
+
},
|
|
3451
|
+
sources: {},
|
|
3452
|
+
resolution: {
|
|
3453
|
+
precedence: [],
|
|
3454
|
+
arrayPolicy: "replace"
|
|
3455
|
+
},
|
|
3456
|
+
envMapping: {
|
|
3457
|
+
explicit: {}
|
|
3458
|
+
},
|
|
3459
|
+
public: {
|
|
3460
|
+
promote: [],
|
|
3461
|
+
frameworks: {}
|
|
3462
|
+
},
|
|
3463
|
+
namespaces: {
|
|
3464
|
+
value: { kind: "data", shareable: true },
|
|
3465
|
+
secret: { kind: "data", shareable: false, sensitive: true },
|
|
3466
|
+
meta: { kind: "system", shareable: false, readonly: true },
|
|
3467
|
+
public: { kind: "projection", shareable: true, readonly: true, source: "promote" }
|
|
3468
|
+
},
|
|
3469
|
+
vaults: {},
|
|
3470
|
+
writePolicy: {
|
|
3471
|
+
define: {
|
|
3472
|
+
defaultProfile: graph.profile,
|
|
3473
|
+
targets: {
|
|
3474
|
+
value: "./values/app.yml",
|
|
3475
|
+
secret: "./secrets/app.yml"
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
},
|
|
3479
|
+
schema: {}
|
|
3480
|
+
};
|
|
3481
|
+
}
|
|
3482
|
+
function graphFromProjection(projection) {
|
|
3483
|
+
const entries = /* @__PURE__ */ new Map();
|
|
3484
|
+
const now = projection.resolvedAt;
|
|
3485
|
+
const explicitNamespaces = /* @__PURE__ */ new Set(["flags", "config", "process", ...projection.meta.namespaces ?? []]);
|
|
3486
|
+
for (const [key, value] of Object.entries(projection.values)) {
|
|
3487
|
+
const firstSegment = key.split(".")[0] ?? "";
|
|
3488
|
+
const logicalKey = key.startsWith("value.") || key.startsWith("public.") || explicitNamespaces.has(firstSegment) ? key : `value.${key}`;
|
|
3489
|
+
const namespace = logicalKey.slice(0, logicalKey.indexOf("."));
|
|
3490
|
+
const winner = {
|
|
3491
|
+
key: logicalKey,
|
|
3492
|
+
value,
|
|
3493
|
+
namespace,
|
|
3494
|
+
sourceId: "server-projection",
|
|
3495
|
+
pluginId: "cnos",
|
|
3496
|
+
workspaceId: projection.workspace,
|
|
3497
|
+
profile: projection.profile
|
|
3498
|
+
};
|
|
3499
|
+
entries.set(logicalKey, {
|
|
3500
|
+
key: logicalKey,
|
|
3501
|
+
value,
|
|
3502
|
+
namespace,
|
|
3503
|
+
winner,
|
|
3504
|
+
overridden: []
|
|
3505
|
+
});
|
|
3506
|
+
}
|
|
3507
|
+
for (const [key, ref] of Object.entries(projection.secretRefs)) {
|
|
3508
|
+
const logicalKey = `secret.${key}`;
|
|
3509
|
+
entries.set(logicalKey, {
|
|
3510
|
+
key: logicalKey,
|
|
3511
|
+
value: ref,
|
|
3512
|
+
namespace: "secret",
|
|
3513
|
+
winner: {
|
|
3514
|
+
key: logicalKey,
|
|
3515
|
+
value: ref,
|
|
3516
|
+
namespace: "secret",
|
|
3517
|
+
sourceId: "server-projection",
|
|
3518
|
+
pluginId: "cnos",
|
|
3519
|
+
workspaceId: projection.workspace,
|
|
3520
|
+
profile: projection.profile
|
|
3521
|
+
},
|
|
3522
|
+
overridden: []
|
|
3523
|
+
});
|
|
3524
|
+
}
|
|
3525
|
+
for (const key of projection.publicKeys) {
|
|
3526
|
+
const valueKey = Object.prototype.hasOwnProperty.call(projection.values, key) ? key : `value.${key}`;
|
|
3527
|
+
const publicKey = `public.${key}`;
|
|
3528
|
+
const sourceEntry = entries.get(valueKey);
|
|
3529
|
+
if (!sourceEntry) {
|
|
3530
|
+
continue;
|
|
3531
|
+
}
|
|
3532
|
+
entries.set(publicKey, {
|
|
3533
|
+
key: publicKey,
|
|
3534
|
+
value: sourceEntry.value,
|
|
3535
|
+
namespace: "public",
|
|
3536
|
+
winner: {
|
|
3537
|
+
key: publicKey,
|
|
3538
|
+
value: sourceEntry.value,
|
|
3539
|
+
namespace: "public",
|
|
3540
|
+
sourceId: "server-projection",
|
|
3541
|
+
pluginId: "cnos",
|
|
3542
|
+
workspaceId: projection.workspace,
|
|
3543
|
+
profile: projection.profile
|
|
3544
|
+
},
|
|
3545
|
+
overridden: []
|
|
3546
|
+
});
|
|
3547
|
+
}
|
|
3548
|
+
entries.set("meta.profile", {
|
|
3549
|
+
key: "meta.profile",
|
|
3550
|
+
value: projection.profile,
|
|
3551
|
+
namespace: "meta",
|
|
3552
|
+
winner: {
|
|
3553
|
+
key: "meta.profile",
|
|
3554
|
+
value: projection.profile,
|
|
3555
|
+
namespace: "meta",
|
|
3556
|
+
sourceId: "server-projection",
|
|
3557
|
+
pluginId: "cnos",
|
|
3558
|
+
workspaceId: projection.workspace,
|
|
3559
|
+
profile: projection.profile
|
|
3560
|
+
},
|
|
3561
|
+
overridden: []
|
|
3562
|
+
});
|
|
3563
|
+
return {
|
|
3564
|
+
entries,
|
|
3565
|
+
profile: projection.profile,
|
|
3566
|
+
resolvedAt: now,
|
|
3567
|
+
profileSource: "manifest-default",
|
|
3568
|
+
workspace: {
|
|
3569
|
+
workspaceId: projection.workspace,
|
|
3570
|
+
workspaceSource: "implicit",
|
|
3571
|
+
workspaceChain: [projection.workspace],
|
|
3572
|
+
workspaceRoots: []
|
|
3573
|
+
}
|
|
3574
|
+
};
|
|
3575
|
+
}
|
|
3576
|
+
function attachBootstrappedProjection(projection, force = false) {
|
|
3577
|
+
if (getSingletonRuntime() && !force) {
|
|
3578
|
+
return;
|
|
3579
|
+
}
|
|
3580
|
+
const graph = graphFromProjection(projection);
|
|
3581
|
+
const manifest = toBootstrappedManifest(graph);
|
|
3582
|
+
const hydratedSecrets = /* @__PURE__ */ new Map();
|
|
3583
|
+
const resolveSecretValue = async (key) => {
|
|
3584
|
+
const entry = graph.entries.get(key);
|
|
3585
|
+
if (!entry || entry.namespace !== "secret") {
|
|
3586
|
+
return entry?.value;
|
|
3587
|
+
}
|
|
3588
|
+
if (hydratedSecrets.has(key)) {
|
|
3589
|
+
return hydratedSecrets.get(key);
|
|
3590
|
+
}
|
|
3591
|
+
const ref = projection.secretRefs[key.slice("secret.".length)];
|
|
3592
|
+
if (!ref) {
|
|
3593
|
+
return void 0;
|
|
3594
|
+
}
|
|
3595
|
+
const definition = { provider: ref.provider };
|
|
3596
|
+
const provider = createSecretVaultProvider(ref.vault ?? "default", definition, process.env);
|
|
3597
|
+
const auth = await resolveVaultAuth(ref.vault ?? "default", definition, process.env);
|
|
3598
|
+
await provider.authenticate(auth);
|
|
3599
|
+
const value = await provider.get(ref.ref);
|
|
3600
|
+
hydratedSecrets.set(key, value);
|
|
3601
|
+
return value;
|
|
3602
|
+
};
|
|
3603
|
+
const runtime = {
|
|
3604
|
+
manifest,
|
|
3605
|
+
plugins: [],
|
|
3606
|
+
graph,
|
|
3607
|
+
read(key) {
|
|
3608
|
+
const entry = graph.entries.get(key);
|
|
3609
|
+
if (!entry) {
|
|
3610
|
+
return void 0;
|
|
3611
|
+
}
|
|
3612
|
+
if (entry.namespace === "secret") {
|
|
3613
|
+
return hydratedSecrets.get(key);
|
|
3614
|
+
}
|
|
3615
|
+
return entry.value;
|
|
3616
|
+
},
|
|
3617
|
+
require(key) {
|
|
3618
|
+
const value = this.read(key);
|
|
3619
|
+
if (value === void 0) {
|
|
3620
|
+
throw new Error(`Missing required CNOS config key: ${key}`);
|
|
3621
|
+
}
|
|
3622
|
+
return value;
|
|
3623
|
+
},
|
|
3624
|
+
readOr(key, fallback) {
|
|
3625
|
+
return this.read(key) ?? fallback;
|
|
3626
|
+
},
|
|
3627
|
+
value(segment) {
|
|
3628
|
+
return this.read(toLogicalKey("value", segment));
|
|
3629
|
+
},
|
|
3630
|
+
secret(segment) {
|
|
3631
|
+
return this.read(toLogicalKey("secret", segment));
|
|
3632
|
+
},
|
|
3633
|
+
meta(segment) {
|
|
3634
|
+
return this.read(toLogicalKey("meta", segment));
|
|
3635
|
+
},
|
|
3636
|
+
inspect(key) {
|
|
3637
|
+
return inspectValue(
|
|
3638
|
+
{
|
|
3639
|
+
...graph,
|
|
3640
|
+
entries: new Map(
|
|
3641
|
+
Array.from(graph.entries.entries()).map(([entryKey, existing]) => [
|
|
3642
|
+
entryKey,
|
|
3643
|
+
entryKey === key && existing.namespace === "secret" && hydratedSecrets.has(entryKey) ? { ...existing, value: hydratedSecrets.get(entryKey) } : existing
|
|
3644
|
+
])
|
|
3645
|
+
)
|
|
3646
|
+
},
|
|
3647
|
+
key
|
|
3648
|
+
);
|
|
3649
|
+
},
|
|
3650
|
+
toObject() {
|
|
3651
|
+
return toNamespaceObject(graph);
|
|
3652
|
+
},
|
|
3144
3653
|
toNamespace(namespace) {
|
|
3145
3654
|
return toNamespaceObject(graph, namespace);
|
|
3146
3655
|
},
|
|
3147
3656
|
toEnv(options) {
|
|
3148
|
-
return toEnv(graph,
|
|
3657
|
+
return toEnv(graph, manifest, options);
|
|
3149
3658
|
},
|
|
3150
3659
|
toPublicEnv(options) {
|
|
3151
|
-
return toPublicEnv(graph,
|
|
3660
|
+
return toPublicEnv(graph, manifest, options);
|
|
3661
|
+
},
|
|
3662
|
+
toServerProjection() {
|
|
3663
|
+
return projection;
|
|
3664
|
+
},
|
|
3665
|
+
async refreshSecrets() {
|
|
3666
|
+
for (const key of Object.keys(projection.secretRefs).map((segment) => `secret.${segment}`)) {
|
|
3667
|
+
hydratedSecrets.delete(key);
|
|
3668
|
+
await resolveSecretValue(key);
|
|
3669
|
+
}
|
|
3670
|
+
},
|
|
3671
|
+
async refreshSecret(key) {
|
|
3672
|
+
hydratedSecrets.delete(key);
|
|
3673
|
+
await resolveSecretValue(key);
|
|
3152
3674
|
}
|
|
3153
3675
|
};
|
|
3154
3676
|
setSingletonRuntime(runtime);
|
|
3155
|
-
setBootstrappedSecretHydrationRequired(
|
|
3677
|
+
setBootstrappedSecretHydrationRequired(Object.keys(projection.secretRefs).length > 0);
|
|
3156
3678
|
}
|
|
3157
3679
|
function bootstrapFromProcessEnv() {
|
|
3158
3680
|
if (typeof process === "undefined") {
|
|
@@ -3162,34 +3684,120 @@ function bootstrapFromProcessEnv() {
|
|
|
3162
3684
|
const graph = readRuntimeGraphFromEnv(process.env);
|
|
3163
3685
|
if (graph) {
|
|
3164
3686
|
attachBootstrappedGraph(graph);
|
|
3687
|
+
return;
|
|
3688
|
+
}
|
|
3689
|
+
const projection = readServerProjectionFromEnv(process.env);
|
|
3690
|
+
if (projection) {
|
|
3691
|
+
attachBootstrappedProjection(projection);
|
|
3692
|
+
}
|
|
3693
|
+
} catch {
|
|
3694
|
+
}
|
|
3695
|
+
}
|
|
3696
|
+
function discoverProjectionPathSync() {
|
|
3697
|
+
const cwd = process.cwd();
|
|
3698
|
+
const directCandidates = [
|
|
3699
|
+
import_node_path13.default.join(cwd, ".cnos-server.json")
|
|
3700
|
+
];
|
|
3701
|
+
for (const candidate of directCandidates) {
|
|
3702
|
+
if ((0, import_node_fs.existsSync)(candidate)) {
|
|
3703
|
+
return candidate;
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
let current = cwd;
|
|
3707
|
+
for (let depth = 0; depth <= 3; depth += 1) {
|
|
3708
|
+
const rcCandidate = import_node_path13.default.join(current, ".cnosrc.yml");
|
|
3709
|
+
if ((0, import_node_fs.existsSync)(rcCandidate)) {
|
|
3710
|
+
const projectionCandidate = import_node_path13.default.join(current, ".cnos-server.json");
|
|
3711
|
+
if ((0, import_node_fs.existsSync)(projectionCandidate)) {
|
|
3712
|
+
return projectionCandidate;
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3715
|
+
const parent = import_node_path13.default.dirname(current);
|
|
3716
|
+
if (parent === current) {
|
|
3717
|
+
break;
|
|
3718
|
+
}
|
|
3719
|
+
current = parent;
|
|
3720
|
+
}
|
|
3721
|
+
return void 0;
|
|
3722
|
+
}
|
|
3723
|
+
function bootstrapFromProjectionFile() {
|
|
3724
|
+
if (getSingletonRuntime()) {
|
|
3725
|
+
return;
|
|
3726
|
+
}
|
|
3727
|
+
try {
|
|
3728
|
+
const projectionPath = discoverProjectionPathSync();
|
|
3729
|
+
if (!projectionPath) {
|
|
3730
|
+
return;
|
|
3165
3731
|
}
|
|
3732
|
+
const projection = deserializeServerProjection((0, import_node_fs.readFileSync)(projectionPath, "utf8"));
|
|
3733
|
+
attachBootstrappedProjection(projection);
|
|
3166
3734
|
} catch {
|
|
3167
3735
|
}
|
|
3168
3736
|
}
|
|
3169
3737
|
bootstrapFromProcessEnv();
|
|
3738
|
+
bootstrapFromProjectionFile();
|
|
3170
3739
|
var cnos = Object.assign(
|
|
3171
|
-
((key) =>
|
|
3740
|
+
((key) => readLogicalKey(getRuntimeOrThrow(), key)),
|
|
3172
3741
|
{
|
|
3173
3742
|
read(key) {
|
|
3174
|
-
return
|
|
3743
|
+
return readLogicalKey(getRuntimeOrThrow(), key);
|
|
3175
3744
|
},
|
|
3176
3745
|
require(key) {
|
|
3177
|
-
return
|
|
3746
|
+
return requireLogicalKey(getRuntimeOrThrow(), key);
|
|
3178
3747
|
},
|
|
3179
3748
|
readOr(key, fallback) {
|
|
3180
|
-
return
|
|
3749
|
+
return getRuntimeOrThrow().readOr(key, fallback);
|
|
3750
|
+
},
|
|
3751
|
+
value(path14) {
|
|
3752
|
+
return getRuntimeOrThrow().value(path14);
|
|
3753
|
+
},
|
|
3754
|
+
secret(path14) {
|
|
3755
|
+
return getRuntimeOrThrow().secret(path14);
|
|
3756
|
+
},
|
|
3757
|
+
meta(path14) {
|
|
3758
|
+
return getRuntimeOrThrow().meta(path14);
|
|
3759
|
+
},
|
|
3760
|
+
inspect(key) {
|
|
3761
|
+
return getRuntimeOrThrow().inspect(key);
|
|
3762
|
+
},
|
|
3763
|
+
toNamespace(namespace) {
|
|
3764
|
+
return getRuntimeOrThrow().toNamespace(namespace);
|
|
3181
3765
|
},
|
|
3182
|
-
|
|
3183
|
-
return
|
|
3766
|
+
toEnv(options) {
|
|
3767
|
+
return getRuntimeOrThrow().toEnv(options);
|
|
3768
|
+
},
|
|
3769
|
+
toPublicEnv(options) {
|
|
3770
|
+
return getRuntimeOrThrow().toPublicEnv(options);
|
|
3184
3771
|
},
|
|
3185
|
-
|
|
3186
|
-
return
|
|
3772
|
+
format(message) {
|
|
3773
|
+
return formatMessage(getRuntimeOrThrow(), message);
|
|
3187
3774
|
},
|
|
3188
|
-
|
|
3189
|
-
|
|
3775
|
+
log(message) {
|
|
3776
|
+
const formatted = formatMessage(getRuntimeOrThrow(), message);
|
|
3777
|
+
console.log(formatted);
|
|
3778
|
+
return formatted;
|
|
3779
|
+
},
|
|
3780
|
+
async loadProjection(source) {
|
|
3781
|
+
const resolvedSource = import_node_path13.default.resolve(source);
|
|
3782
|
+
const projection = deserializeServerProjection((0, import_node_fs.readFileSync)(resolvedSource, "utf8"));
|
|
3783
|
+
attachBootstrappedProjection(projection, true);
|
|
3784
|
+
setBootstrappedSecretHydrationRequired(Object.keys(projection.secretRefs).length > 0);
|
|
3785
|
+
},
|
|
3786
|
+
async refreshSecrets() {
|
|
3787
|
+
await getRuntimeOrThrow().refreshSecrets();
|
|
3788
|
+
setBootstrappedSecretHydrationRequired(false);
|
|
3789
|
+
},
|
|
3790
|
+
async refreshSecret(key) {
|
|
3791
|
+
await getRuntimeOrThrow().refreshSecret(key);
|
|
3190
3792
|
},
|
|
3191
3793
|
async ready() {
|
|
3192
|
-
|
|
3794
|
+
const runtime = getSingletonRuntime();
|
|
3795
|
+
if (runtime && getBootstrappedSecretHydrationRequired()) {
|
|
3796
|
+
await runtime.refreshSecrets();
|
|
3797
|
+
setBootstrappedSecretHydrationRequired(false);
|
|
3798
|
+
return;
|
|
3799
|
+
}
|
|
3800
|
+
if (runtime && !getBootstrappedSecretHydrationRequired()) {
|
|
3193
3801
|
return;
|
|
3194
3802
|
}
|
|
3195
3803
|
const existing = getSingletonReady();
|
|
@@ -3197,9 +3805,10 @@ var cnos = Object.assign(
|
|
|
3197
3805
|
await existing;
|
|
3198
3806
|
return;
|
|
3199
3807
|
}
|
|
3200
|
-
const readyPromise = createCnos2().then((
|
|
3201
|
-
setSingletonRuntime(
|
|
3202
|
-
|
|
3808
|
+
const readyPromise = createCnos2().then((runtime2) => {
|
|
3809
|
+
setSingletonRuntime(runtime2);
|
|
3810
|
+
setBootstrappedSecretHydrationRequired(false);
|
|
3811
|
+
return runtime2;
|
|
3203
3812
|
});
|
|
3204
3813
|
setSingletonReady(readyPromise);
|
|
3205
3814
|
await readyPromise;
|