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