@kitsy/cnos 1.5.1 → 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 +325 -113
- 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-UWFE4JE2.js → chunk-BMAD24KC.js} +1 -1
- package/dist/{chunk-7EI3RFUE.js → chunk-JYWQFMW5.js} +1 -1
- package/dist/{chunk-F2ZAIZNH.js → chunk-MW4OVAT3.js} +1 -1
- package/dist/chunk-QU5CXL47.js +577 -0
- package/dist/{chunk-BS33AW4Y.js → chunk-S7H2UULC.js} +307 -103
- package/dist/{chunk-H53ZRQLX.js → chunk-UJBQS7CJ.js} +1 -1
- package/dist/{chunk-CMQK2AEF.js → chunk-UOKVLCFL.js} +10 -10
- package/dist/{chunk-EJAXWFNT.js → chunk-UR7CHHNN.js} +1 -1
- package/dist/{chunk-SZKQVA2M.js → chunk-VGZREX5D.js} +1 -1
- package/dist/{chunk-5F2OFKND.js → chunk-XSUP7JKH.js} +23 -1
- package/dist/configure/index.cjs +324 -118
- 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 +698 -136
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -10
- package/dist/internal.cjs +227 -102
- 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 +28 -19
- 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 +696 -136
- package/dist/runtime/index.d.cts +7 -1
- package/dist/runtime/index.d.ts +7 -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-TUMR7JA3.js +0 -234
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 = [
|
|
@@ -532,11 +625,15 @@ function normalizeManifest(manifest) {
|
|
|
532
625
|
|
|
533
626
|
// ../core/src/manifest/loadManifest.ts
|
|
534
627
|
async function loadManifest(options = {}) {
|
|
535
|
-
const
|
|
536
|
-
|
|
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");
|
|
537
634
|
let source;
|
|
538
635
|
try {
|
|
539
|
-
source = await (0,
|
|
636
|
+
source = await (0, import_promises3.readFile)(manifestPath, "utf8");
|
|
540
637
|
} catch {
|
|
541
638
|
throw new CnosManifestError("Unable to read CNOS manifest", manifestPath);
|
|
542
639
|
}
|
|
@@ -546,7 +643,10 @@ async function loadManifest(options = {}) {
|
|
|
546
643
|
}
|
|
547
644
|
return {
|
|
548
645
|
manifestRoot,
|
|
549
|
-
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 } : {},
|
|
550
650
|
manifestPath,
|
|
551
651
|
manifest: normalizeManifest(rawManifest),
|
|
552
652
|
rawManifest
|
|
@@ -554,12 +654,12 @@ async function loadManifest(options = {}) {
|
|
|
554
654
|
}
|
|
555
655
|
|
|
556
656
|
// ../core/src/manifest/loadWorkspaceFile.ts
|
|
557
|
-
var
|
|
558
|
-
var
|
|
657
|
+
var import_promises4 = require("fs/promises");
|
|
658
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
559
659
|
async function loadWorkspaceFile(repoRoot) {
|
|
560
|
-
const workspaceFilePath =
|
|
660
|
+
const workspaceFilePath = import_node_path4.default.join(repoRoot, ".cnos-workspace.yml");
|
|
561
661
|
try {
|
|
562
|
-
const source = await (0,
|
|
662
|
+
const source = await (0, import_promises4.readFile)(workspaceFilePath, "utf8");
|
|
563
663
|
const parsed = parseYaml(source);
|
|
564
664
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
565
665
|
throw new CnosManifestError(".cnos-workspace.yml must be a YAML object", workspaceFilePath);
|
|
@@ -582,11 +682,11 @@ async function loadWorkspaceFile(repoRoot) {
|
|
|
582
682
|
}
|
|
583
683
|
|
|
584
684
|
// ../core/src/profiles/expandProfileChain.ts
|
|
585
|
-
var
|
|
586
|
-
var
|
|
685
|
+
var import_promises5 = require("fs/promises");
|
|
686
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
587
687
|
async function fileExists(targetPath) {
|
|
588
688
|
try {
|
|
589
|
-
await (0,
|
|
689
|
+
await (0, import_promises5.access)(targetPath);
|
|
590
690
|
return true;
|
|
591
691
|
} catch {
|
|
592
692
|
return false;
|
|
@@ -620,11 +720,11 @@ async function loadProfileDefinition(profileName, options) {
|
|
|
620
720
|
return normalizeProfileDefinition(profileName, void 0);
|
|
621
721
|
}
|
|
622
722
|
for (const workspaceRoot of [...workspaceRoots].reverse()) {
|
|
623
|
-
const profilePath =
|
|
723
|
+
const profilePath = import_node_path5.default.join(workspaceRoot.path, "profiles", `${profileName}.yml`);
|
|
624
724
|
if (!await fileExists(profilePath)) {
|
|
625
725
|
continue;
|
|
626
726
|
}
|
|
627
|
-
const document = await (0,
|
|
727
|
+
const document = await (0, import_promises5.readFile)(profilePath, "utf8");
|
|
628
728
|
const parsed = parseYaml(document);
|
|
629
729
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
630
730
|
throw new CnosManifestError("Profile definition must be a YAML object", profilePath);
|
|
@@ -632,7 +732,7 @@ async function loadProfileDefinition(profileName, options) {
|
|
|
632
732
|
const definition = normalizeProfileDefinition(
|
|
633
733
|
profileName,
|
|
634
734
|
parsed,
|
|
635
|
-
options.manifestRoot ? toPortablePath(
|
|
735
|
+
options.manifestRoot ? toPortablePath(import_node_path5.default.relative(import_node_path5.default.dirname(options.manifestRoot), profilePath)) : toPortablePath(profilePath)
|
|
636
736
|
);
|
|
637
737
|
if (definition.name !== profileName) {
|
|
638
738
|
throw new CnosManifestError(
|
|
@@ -914,8 +1014,8 @@ function createProfileAwareResolver() {
|
|
|
914
1014
|
}
|
|
915
1015
|
|
|
916
1016
|
// ../core/src/workspaces/resolveWorkspaceContext.ts
|
|
917
|
-
var
|
|
918
|
-
var
|
|
1017
|
+
var import_promises6 = require("fs/promises");
|
|
1018
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
919
1019
|
|
|
920
1020
|
// ../core/src/workspaces/expandWorkspaceChain.ts
|
|
921
1021
|
function expandWorkspaceChain(workspaceId, items) {
|
|
@@ -952,31 +1052,31 @@ function expandWorkspaceChain(workspaceId, items) {
|
|
|
952
1052
|
}
|
|
953
1053
|
|
|
954
1054
|
// ../core/src/workspaces/resolveWorkspaceContext.ts
|
|
955
|
-
async function
|
|
1055
|
+
async function exists3(targetPath) {
|
|
956
1056
|
try {
|
|
957
|
-
await (0,
|
|
1057
|
+
await (0, import_promises6.access)(targetPath);
|
|
958
1058
|
return true;
|
|
959
1059
|
} catch {
|
|
960
1060
|
return false;
|
|
961
1061
|
}
|
|
962
1062
|
}
|
|
963
1063
|
async function resolveLocalWorkspaceRoot(manifestRoot, workspaceId, manifest) {
|
|
964
|
-
const workspaceRoot =
|
|
965
|
-
if (await
|
|
1064
|
+
const workspaceRoot = import_node_path6.default.join(manifestRoot, "workspaces", workspaceId);
|
|
1065
|
+
if (await exists3(workspaceRoot)) {
|
|
966
1066
|
return workspaceRoot;
|
|
967
1067
|
}
|
|
968
1068
|
const customDataNamespaceRoots = Object.entries(manifest.namespaces).filter(
|
|
969
1069
|
([namespace, definition]) => namespace !== "value" && namespace !== "secret" && definition.kind === "data" && !definition.sensitive
|
|
970
1070
|
).map(([namespace]) => namespace);
|
|
971
1071
|
const legacyMarkers = ["values", "secrets", "env", "profiles", ...customDataNamespaceRoots].map(
|
|
972
|
-
(segment) =>
|
|
1072
|
+
(segment) => import_node_path6.default.join(manifestRoot, segment)
|
|
973
1073
|
);
|
|
974
|
-
if ((await Promise.all(legacyMarkers.map((marker) =>
|
|
1074
|
+
if ((await Promise.all(legacyMarkers.map((marker) => exists3(marker)))).some(Boolean)) {
|
|
975
1075
|
return manifestRoot;
|
|
976
1076
|
}
|
|
977
1077
|
return workspaceRoot;
|
|
978
1078
|
}
|
|
979
|
-
function resolveWorkspaceSelection(manifest, workspaceFile, workspaceOption) {
|
|
1079
|
+
function resolveWorkspaceSelection(manifest, workspaceFile, anchoredWorkspace, workspaceOption) {
|
|
980
1080
|
if (workspaceOption) {
|
|
981
1081
|
return {
|
|
982
1082
|
workspaceId: workspaceOption,
|
|
@@ -989,6 +1089,12 @@ function resolveWorkspaceSelection(manifest, workspaceFile, workspaceOption) {
|
|
|
989
1089
|
source: "workspace-file"
|
|
990
1090
|
};
|
|
991
1091
|
}
|
|
1092
|
+
if (anchoredWorkspace) {
|
|
1093
|
+
return {
|
|
1094
|
+
workspaceId: anchoredWorkspace,
|
|
1095
|
+
source: "anchor-file"
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
992
1098
|
if (manifest.workspaces.default) {
|
|
993
1099
|
return {
|
|
994
1100
|
workspaceId: manifest.workspaces.default,
|
|
@@ -1011,33 +1117,38 @@ function resolveGlobalRoot(manifest, workspaceFile, options) {
|
|
|
1011
1117
|
}
|
|
1012
1118
|
if (options.globalRoot) {
|
|
1013
1119
|
return {
|
|
1014
|
-
value:
|
|
1120
|
+
value: import_node_path6.default.resolve(expandHomePath(options.globalRoot)),
|
|
1015
1121
|
source: "cli"
|
|
1016
1122
|
};
|
|
1017
1123
|
}
|
|
1018
1124
|
if (workspaceFile?.globalRoot) {
|
|
1019
1125
|
return {
|
|
1020
|
-
value:
|
|
1126
|
+
value: import_node_path6.default.resolve(expandHomePath(workspaceFile.globalRoot)),
|
|
1021
1127
|
source: "workspace-file"
|
|
1022
1128
|
};
|
|
1023
1129
|
}
|
|
1024
1130
|
if (manifest.workspaces.global.root) {
|
|
1025
1131
|
return {
|
|
1026
|
-
value:
|
|
1132
|
+
value: import_node_path6.default.resolve(expandHomePath(manifest.workspaces.global.root)),
|
|
1027
1133
|
source: "manifest"
|
|
1028
1134
|
};
|
|
1029
1135
|
}
|
|
1030
1136
|
const cnosHome = options.processEnv?.CNOS_HOME;
|
|
1031
1137
|
if (cnosHome) {
|
|
1032
1138
|
return {
|
|
1033
|
-
value:
|
|
1139
|
+
value: import_node_path6.default.resolve(expandHomePath(cnosHome)),
|
|
1034
1140
|
source: "CNOS_HOME"
|
|
1035
1141
|
};
|
|
1036
1142
|
}
|
|
1037
1143
|
return {};
|
|
1038
1144
|
}
|
|
1039
1145
|
async function resolveWorkspaceContext(manifest, options) {
|
|
1040
|
-
const selectedWorkspace = resolveWorkspaceSelection(
|
|
1146
|
+
const selectedWorkspace = resolveWorkspaceSelection(
|
|
1147
|
+
manifest,
|
|
1148
|
+
options.workspaceFile,
|
|
1149
|
+
options.anchoredWorkspace,
|
|
1150
|
+
options.workspace
|
|
1151
|
+
);
|
|
1041
1152
|
const workspaceChain = expandWorkspaceChain(selectedWorkspace.workspaceId, manifest.workspaces.items);
|
|
1042
1153
|
const globalRoot = resolveGlobalRoot(manifest, options.workspaceFile, options);
|
|
1043
1154
|
const workspaceRoots = [];
|
|
@@ -1047,7 +1158,7 @@ async function resolveWorkspaceContext(manifest, options) {
|
|
|
1047
1158
|
workspaceRoots.push({
|
|
1048
1159
|
scope: "global",
|
|
1049
1160
|
workspaceId: chainWorkspaceId,
|
|
1050
|
-
path:
|
|
1161
|
+
path: import_node_path6.default.join(globalRoot.value, "workspaces", globalWorkspaceId)
|
|
1051
1162
|
});
|
|
1052
1163
|
}
|
|
1053
1164
|
}
|
|
@@ -1239,26 +1350,26 @@ async function runPipeline(options) {
|
|
|
1239
1350
|
}
|
|
1240
1351
|
|
|
1241
1352
|
// ../core/src/secrets/auditLog.ts
|
|
1242
|
-
var
|
|
1243
|
-
var
|
|
1353
|
+
var import_promises9 = require("fs/promises");
|
|
1354
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
1244
1355
|
|
|
1245
1356
|
// ../core/src/utils/secretStore.ts
|
|
1246
1357
|
var import_node_crypto = require("crypto");
|
|
1247
|
-
var
|
|
1248
|
-
var
|
|
1358
|
+
var import_promises8 = require("fs/promises");
|
|
1359
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
1249
1360
|
|
|
1250
1361
|
// ../core/src/secrets/sessionStore.ts
|
|
1251
|
-
var
|
|
1252
|
-
var
|
|
1362
|
+
var import_promises7 = require("fs/promises");
|
|
1363
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
1253
1364
|
function buildSessionRoot(processEnv = process.env) {
|
|
1254
|
-
return
|
|
1365
|
+
return import_node_path7.default.join(import_node_path7.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets")), "sessions");
|
|
1255
1366
|
}
|
|
1256
1367
|
function buildSessionPath(vault, processEnv) {
|
|
1257
|
-
return
|
|
1368
|
+
return import_node_path7.default.join(buildSessionRoot(processEnv), `${vault}.json`);
|
|
1258
1369
|
}
|
|
1259
1370
|
async function readVaultSessionKey(vault, processEnv) {
|
|
1260
1371
|
try {
|
|
1261
|
-
const source = await (0,
|
|
1372
|
+
const source = await (0, import_promises7.readFile)(buildSessionPath(vault, processEnv), "utf8");
|
|
1262
1373
|
const document = JSON.parse(source);
|
|
1263
1374
|
if (document.version !== 1 || typeof document.derivedKey !== "string") {
|
|
1264
1375
|
return void 0;
|
|
@@ -1287,7 +1398,7 @@ function isSecretReference(value) {
|
|
|
1287
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));
|
|
1288
1399
|
}
|
|
1289
1400
|
function resolveSecretStoreRoot(processEnv = process.env) {
|
|
1290
|
-
return
|
|
1401
|
+
return import_node_path8.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
|
|
1291
1402
|
}
|
|
1292
1403
|
function normalizeVaultToken(vault = "default") {
|
|
1293
1404
|
return vault.replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
|
|
@@ -1319,16 +1430,16 @@ function deriveVaultKey(passphrase, salt, iterations = PBKDF2_ITERATIONS) {
|
|
|
1319
1430
|
return (0, import_node_crypto.pbkdf2Sync)(passphrase, salt, iterations, KEY_LENGTH, "sha512");
|
|
1320
1431
|
}
|
|
1321
1432
|
function buildMetaPath(storeRoot, vault = "default") {
|
|
1322
|
-
return
|
|
1433
|
+
return import_node_path8.default.join(storeRoot, "vaults", vault, META_FILENAME);
|
|
1323
1434
|
}
|
|
1324
1435
|
function buildKeystorePath(storeRoot, vault = "default") {
|
|
1325
|
-
return
|
|
1436
|
+
return import_node_path8.default.join(storeRoot, "vaults", vault, KEYSTORE_FILENAME);
|
|
1326
1437
|
}
|
|
1327
1438
|
function buildLegacyVaultFile(storeRoot, vault = "default") {
|
|
1328
|
-
return
|
|
1439
|
+
return import_node_path8.default.join(storeRoot, "vaults", `${vault}.json`);
|
|
1329
1440
|
}
|
|
1330
1441
|
function buildLegacyVaultStoreRoot(storeRoot, vault = "default") {
|
|
1331
|
-
return
|
|
1442
|
+
return import_node_path8.default.join(storeRoot, "vaults", vault, "store");
|
|
1332
1443
|
}
|
|
1333
1444
|
function assertVaultMetadata(value, filePath) {
|
|
1334
1445
|
if (!isObject(value)) {
|
|
@@ -1339,9 +1450,9 @@ function assertVaultMetadata(value, filePath) {
|
|
|
1339
1450
|
}
|
|
1340
1451
|
return value;
|
|
1341
1452
|
}
|
|
1342
|
-
async function
|
|
1453
|
+
async function exists4(targetPath) {
|
|
1343
1454
|
try {
|
|
1344
|
-
await (0,
|
|
1455
|
+
await (0, import_promises8.stat)(targetPath);
|
|
1345
1456
|
return true;
|
|
1346
1457
|
} catch {
|
|
1347
1458
|
return false;
|
|
@@ -1350,10 +1461,10 @@ async function exists3(targetPath) {
|
|
|
1350
1461
|
async function detectLegacyVaultFormat(storeRoot, vault = "default") {
|
|
1351
1462
|
const legacyFile = buildLegacyVaultFile(storeRoot, vault);
|
|
1352
1463
|
const legacyStore = buildLegacyVaultStoreRoot(storeRoot, vault);
|
|
1353
|
-
if (await
|
|
1464
|
+
if (await exists4(legacyFile)) {
|
|
1354
1465
|
return legacyFile;
|
|
1355
1466
|
}
|
|
1356
|
-
if (await
|
|
1467
|
+
if (await exists4(legacyStore)) {
|
|
1357
1468
|
return legacyStore;
|
|
1358
1469
|
}
|
|
1359
1470
|
return void 0;
|
|
@@ -1425,15 +1536,15 @@ function buildInitialPayload() {
|
|
|
1425
1536
|
async function writeVaultFiles(storeRoot, vault, meta, payload, key) {
|
|
1426
1537
|
const metaPath = buildMetaPath(storeRoot, vault);
|
|
1427
1538
|
const keystorePath = buildKeystorePath(storeRoot, vault);
|
|
1428
|
-
await (0,
|
|
1429
|
-
await (0,
|
|
1430
|
-
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));
|
|
1431
1542
|
}
|
|
1432
1543
|
async function readVaultMetadata(storeRoot, vault = "default") {
|
|
1433
1544
|
await assertNoLegacyVaultFormat(storeRoot, vault);
|
|
1434
1545
|
const metaPath = buildMetaPath(storeRoot, vault);
|
|
1435
1546
|
try {
|
|
1436
|
-
const source = await (0,
|
|
1547
|
+
const source = await (0, import_promises8.readFile)(metaPath, "utf8");
|
|
1437
1548
|
return assertVaultMetadata(parseYaml(source), metaPath);
|
|
1438
1549
|
} catch (error) {
|
|
1439
1550
|
if (error.code === "ENOENT") {
|
|
@@ -1524,7 +1635,7 @@ async function loadVaultPayload(storeRoot, vault, auth) {
|
|
|
1524
1635
|
if (!key) {
|
|
1525
1636
|
throw new CnosAuthenticationError(`Vault "${vault}" requires authentication before access.`);
|
|
1526
1637
|
}
|
|
1527
|
-
const buffer = await (0,
|
|
1638
|
+
const buffer = await (0, import_promises8.readFile)(buildKeystorePath(storeRoot, vault));
|
|
1528
1639
|
return {
|
|
1529
1640
|
meta,
|
|
1530
1641
|
payload: decryptPayload(buffer, key),
|
|
@@ -1599,9 +1710,9 @@ function resolveVaultDefinition(vaults, vault = "default") {
|
|
|
1599
1710
|
|
|
1600
1711
|
// ../core/src/secrets/auditLog.ts
|
|
1601
1712
|
async function appendAuditEvent(event, processEnv = process.env) {
|
|
1602
|
-
const auditFile = processEnv.CNOS_AUDIT_FILE ??
|
|
1603
|
-
await (0,
|
|
1604
|
-
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)(
|
|
1605
1716
|
auditFile,
|
|
1606
1717
|
`${JSON.stringify({
|
|
1607
1718
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1994,6 +2105,60 @@ function requireValue(graph, key) {
|
|
|
1994
2105
|
return value;
|
|
1995
2106
|
}
|
|
1996
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
|
+
|
|
1997
2162
|
// ../core/src/runtime/toEnv.ts
|
|
1998
2163
|
function normalizeEnvValue(value) {
|
|
1999
2164
|
if (value === void 0 || value === null) {
|
|
@@ -2078,8 +2243,38 @@ function toPublicEnv(graph, manifest, options = {}) {
|
|
|
2078
2243
|
}
|
|
2079
2244
|
|
|
2080
2245
|
// ../core/src/orchestrator/runtime.ts
|
|
2081
|
-
function createRuntime(manifest, graph, plugins = [], secretCache) {
|
|
2082
|
-
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) {
|
|
2083
2278
|
const entry = graph.entries.get(key);
|
|
2084
2279
|
if (!entry) {
|
|
2085
2280
|
return void 0;
|
|
@@ -2094,10 +2289,10 @@ function createRuntime(manifest, graph, plugins = [], secretCache) {
|
|
|
2094
2289
|
plugins,
|
|
2095
2290
|
graph,
|
|
2096
2291
|
read(key) {
|
|
2097
|
-
return
|
|
2292
|
+
return readLogicalKey2(key);
|
|
2098
2293
|
},
|
|
2099
2294
|
require(key) {
|
|
2100
|
-
const value =
|
|
2295
|
+
const value = readLogicalKey2(key);
|
|
2101
2296
|
if (value === void 0) {
|
|
2102
2297
|
return requireValue(graph, key);
|
|
2103
2298
|
}
|
|
@@ -2106,14 +2301,14 @@ function createRuntime(manifest, graph, plugins = [], secretCache) {
|
|
|
2106
2301
|
readOr(key, fallback) {
|
|
2107
2302
|
return readOrValue(graph, key, fallback);
|
|
2108
2303
|
},
|
|
2109
|
-
value(
|
|
2110
|
-
return
|
|
2304
|
+
value(path14) {
|
|
2305
|
+
return readLogicalKey2(toLogicalKey("value", path14));
|
|
2111
2306
|
},
|
|
2112
|
-
secret(
|
|
2113
|
-
return
|
|
2307
|
+
secret(path14) {
|
|
2308
|
+
return readLogicalKey2(toLogicalKey("secret", path14));
|
|
2114
2309
|
},
|
|
2115
|
-
meta(
|
|
2116
|
-
return
|
|
2310
|
+
meta(path14) {
|
|
2311
|
+
return readLogicalKey2(toLogicalKey("meta", path14));
|
|
2117
2312
|
},
|
|
2118
2313
|
inspect(key) {
|
|
2119
2314
|
return inspectValue(graph, key);
|
|
@@ -2129,6 +2324,15 @@ function createRuntime(manifest, graph, plugins = [], secretCache) {
|
|
|
2129
2324
|
},
|
|
2130
2325
|
toPublicEnv(options) {
|
|
2131
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);
|
|
2132
2336
|
}
|
|
2133
2337
|
};
|
|
2134
2338
|
}
|
|
@@ -2227,14 +2431,18 @@ function appendMetaEntries(graph, cnosVersion) {
|
|
|
2227
2431
|
};
|
|
2228
2432
|
}
|
|
2229
2433
|
async function createCnos(options = {}) {
|
|
2230
|
-
const loadedManifest = await loadManifest(
|
|
2434
|
+
const loadedManifest = await loadManifest({
|
|
2435
|
+
...options.root ? { root: options.root } : {},
|
|
2436
|
+
...options.cwd ? { cwd: options.cwd } : {}
|
|
2437
|
+
});
|
|
2231
2438
|
for (const key of loadedManifest.manifest.public.promote) {
|
|
2232
2439
|
ensureProjectionAllowed(loadedManifest.manifest, key, "public");
|
|
2233
2440
|
}
|
|
2234
|
-
const workspaceFile = await loadWorkspaceFile(loadedManifest.
|
|
2441
|
+
const workspaceFile = await loadWorkspaceFile(loadedManifest.consumerRoot);
|
|
2235
2442
|
const workspace = await resolveWorkspaceContext(loadedManifest.manifest, {
|
|
2236
2443
|
manifestRoot: loadedManifest.manifestRoot,
|
|
2237
2444
|
...workspaceFile ? { workspaceFile: workspaceFile.config } : {},
|
|
2445
|
+
...loadedManifest.anchoredWorkspace ? { anchoredWorkspace: loadedManifest.anchoredWorkspace } : {},
|
|
2238
2446
|
...options.workspace ? { workspace: options.workspace } : {},
|
|
2239
2447
|
...options.globalRoot ? { globalRoot: options.globalRoot } : {},
|
|
2240
2448
|
...options.processEnv ? { processEnv: options.processEnv } : {}
|
|
@@ -2279,13 +2487,15 @@ async function createCnos(options = {}) {
|
|
|
2279
2487
|
profileSource: activeProfile.source
|
|
2280
2488
|
}, options.cnosVersion),
|
|
2281
2489
|
plugins,
|
|
2282
|
-
secretCache
|
|
2490
|
+
secretCache,
|
|
2491
|
+
options.processEnv,
|
|
2492
|
+
options.cnosVersion
|
|
2283
2493
|
);
|
|
2284
2494
|
}
|
|
2285
2495
|
|
|
2286
2496
|
// ../core/src/runtime/dump.ts
|
|
2287
|
-
var
|
|
2288
|
-
var
|
|
2497
|
+
var import_promises10 = require("fs/promises");
|
|
2498
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
2289
2499
|
|
|
2290
2500
|
// ../core/src/utils/envNaming.ts
|
|
2291
2501
|
function normalizeMappingConfig(config = {}) {
|
|
@@ -2294,8 +2504,8 @@ function normalizeMappingConfig(config = {}) {
|
|
|
2294
2504
|
explicit: config.explicit ?? {}
|
|
2295
2505
|
};
|
|
2296
2506
|
}
|
|
2297
|
-
function fromScreamingSnake(
|
|
2298
|
-
return
|
|
2507
|
+
function fromScreamingSnake(path14) {
|
|
2508
|
+
return path14.split("_").map((segment) => segment.trim().toLowerCase()).filter(Boolean).join(".");
|
|
2299
2509
|
}
|
|
2300
2510
|
function envVarToLogicalKey(envVar, config = {}) {
|
|
2301
2511
|
const normalized = normalizeMappingConfig(config);
|
|
@@ -2322,7 +2532,7 @@ function envVarToLogicalKey(envVar, config = {}) {
|
|
|
2322
2532
|
// package.json
|
|
2323
2533
|
var package_default = {
|
|
2324
2534
|
name: "@kitsy/cnos",
|
|
2325
|
-
version: "1.
|
|
2535
|
+
version: "1.6.0",
|
|
2326
2536
|
description: "Batteries-included CNOS runtime package wired with the official plugins.",
|
|
2327
2537
|
type: "module",
|
|
2328
2538
|
main: "./dist/index.cjs",
|
|
@@ -2521,8 +2731,8 @@ function createCliArgsPlugin() {
|
|
|
2521
2731
|
}
|
|
2522
2732
|
|
|
2523
2733
|
// ../../plugins/dotenv/src/index.ts
|
|
2524
|
-
var
|
|
2525
|
-
var
|
|
2734
|
+
var import_promises11 = require("fs/promises");
|
|
2735
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
2526
2736
|
var DOTENV_PLUGIN_ID = "@kitsy/cnos/plugins/dotenv";
|
|
2527
2737
|
function parseDoubleQuoted(value) {
|
|
2528
2738
|
return value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
@@ -2579,7 +2789,7 @@ function dotenvEntriesFromObject(values, mapping = {}, originFile, workspaceId =
|
|
|
2579
2789
|
}
|
|
2580
2790
|
async function readIfPresent(filePath) {
|
|
2581
2791
|
try {
|
|
2582
|
-
return await (0,
|
|
2792
|
+
return await (0, import_promises11.readFile)(filePath, "utf8");
|
|
2583
2793
|
} catch {
|
|
2584
2794
|
return void 0;
|
|
2585
2795
|
}
|
|
@@ -2598,7 +2808,7 @@ function createDotenvPlugin() {
|
|
|
2598
2808
|
workspace: workspaceRoot.workspaceId
|
|
2599
2809
|
});
|
|
2600
2810
|
for (const fileName of fileNames) {
|
|
2601
|
-
const absolutePath =
|
|
2811
|
+
const absolutePath = import_node_path11.default.join(envRoot, fileName);
|
|
2602
2812
|
const document = await readIfPresent(absolutePath);
|
|
2603
2813
|
if (!document) {
|
|
2604
2814
|
continue;
|
|
@@ -2607,7 +2817,7 @@ function createDotenvPlugin() {
|
|
|
2607
2817
|
...dotenvEntriesFromObject(
|
|
2608
2818
|
parseDotenv(document),
|
|
2609
2819
|
config.envMapping,
|
|
2610
|
-
toPortablePath(
|
|
2820
|
+
toPortablePath(import_node_path11.default.relative(import_node_path11.default.dirname(context.manifestRoot), absolutePath)),
|
|
2611
2821
|
workspaceRoot.workspaceId
|
|
2612
2822
|
)
|
|
2613
2823
|
);
|
|
@@ -2645,16 +2855,16 @@ function createPublicEnvExportPlugin() {
|
|
|
2645
2855
|
}
|
|
2646
2856
|
|
|
2647
2857
|
// ../../plugins/filesystem/src/filesystemSecretsReader.ts
|
|
2648
|
-
var
|
|
2858
|
+
var import_promises13 = require("fs/promises");
|
|
2649
2859
|
|
|
2650
2860
|
// ../../plugins/filesystem/src/helpers.ts
|
|
2651
|
-
var
|
|
2652
|
-
var
|
|
2861
|
+
var import_promises12 = require("fs/promises");
|
|
2862
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
2653
2863
|
var YAML_EXTENSIONS = /* @__PURE__ */ new Set([".yml", ".yaml"]);
|
|
2654
2864
|
var FILESYSTEM_PLUGIN_ID = "@kitsy/cnos/plugins/filesystem";
|
|
2655
2865
|
async function existsDirectory(targetPath) {
|
|
2656
2866
|
try {
|
|
2657
|
-
const stat2 = await (0,
|
|
2867
|
+
const stat2 = await (0, import_promises12.readdir)(targetPath);
|
|
2658
2868
|
void stat2;
|
|
2659
2869
|
return true;
|
|
2660
2870
|
} catch {
|
|
@@ -2662,15 +2872,15 @@ async function existsDirectory(targetPath) {
|
|
|
2662
2872
|
}
|
|
2663
2873
|
}
|
|
2664
2874
|
async function collectYamlFiles(root) {
|
|
2665
|
-
const entries = await (0,
|
|
2875
|
+
const entries = await (0, import_promises12.readdir)(root, { withFileTypes: true });
|
|
2666
2876
|
const results = [];
|
|
2667
2877
|
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
2668
|
-
const absolutePath =
|
|
2878
|
+
const absolutePath = import_node_path12.default.join(root, entry.name);
|
|
2669
2879
|
if (entry.isDirectory()) {
|
|
2670
2880
|
results.push(...await collectYamlFiles(absolutePath));
|
|
2671
2881
|
continue;
|
|
2672
2882
|
}
|
|
2673
|
-
if (entry.isFile() && YAML_EXTENSIONS.has(
|
|
2883
|
+
if (entry.isFile() && YAML_EXTENSIONS.has(import_node_path12.default.extname(entry.name).toLowerCase())) {
|
|
2674
2884
|
results.push(absolutePath);
|
|
2675
2885
|
}
|
|
2676
2886
|
}
|
|
@@ -2678,16 +2888,16 @@ async function collectYamlFiles(root) {
|
|
|
2678
2888
|
}
|
|
2679
2889
|
async function collectFilesystemLayerFiles(manifestRoot, workspaceRoots, sourceRoot, activeLayers) {
|
|
2680
2890
|
const files = [];
|
|
2681
|
-
const repoRoot =
|
|
2891
|
+
const repoRoot = import_node_path12.default.dirname(manifestRoot);
|
|
2682
2892
|
for (const workspaceRoot of workspaceRoots) {
|
|
2683
|
-
const resolvedRoot =
|
|
2893
|
+
const resolvedRoot = import_node_path12.default.resolve(workspaceRoot.path, sourceRoot);
|
|
2684
2894
|
for (const layer of activeLayers) {
|
|
2685
|
-
const layerRoot =
|
|
2895
|
+
const layerRoot = import_node_path12.default.join(resolvedRoot, layer);
|
|
2686
2896
|
if (!await existsDirectory(layerRoot)) {
|
|
2687
2897
|
continue;
|
|
2688
2898
|
}
|
|
2689
2899
|
for (const absolutePath of await collectYamlFiles(layerRoot)) {
|
|
2690
|
-
const relativePath =
|
|
2900
|
+
const relativePath = import_node_path12.default.relative(repoRoot, absolutePath);
|
|
2691
2901
|
files.push({
|
|
2692
2902
|
absolutePath,
|
|
2693
2903
|
relativePath: toPortablePath(relativePath.startsWith("..") ? absolutePath : relativePath),
|
|
@@ -2764,7 +2974,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
2764
2974
|
);
|
|
2765
2975
|
const entries = [];
|
|
2766
2976
|
for (const file of files) {
|
|
2767
|
-
const document = await (0,
|
|
2977
|
+
const document = await (0, import_promises13.readFile)(file.absolutePath, "utf8");
|
|
2768
2978
|
const fileEntries = filesystemSecretsReader(file.relativePath, document, file.workspaceId);
|
|
2769
2979
|
for (const entry of fileEntries) {
|
|
2770
2980
|
const metadata = toSecretReferenceMetadata(entry.value);
|
|
@@ -2780,7 +2990,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
2780
2990
|
}
|
|
2781
2991
|
|
|
2782
2992
|
// ../../plugins/filesystem/src/filesystemValuesReader.ts
|
|
2783
|
-
var
|
|
2993
|
+
var import_promises14 = require("fs/promises");
|
|
2784
2994
|
function filesystemValuesReader(filePath, document, workspaceId = "default") {
|
|
2785
2995
|
return yamlObjectToEntries(document, filePath, "value", "filesystem-values", workspaceId);
|
|
2786
2996
|
}
|
|
@@ -2801,7 +3011,7 @@ function createFilesystemValuesPlugin() {
|
|
|
2801
3011
|
).map(([namespace]) => namespace);
|
|
2802
3012
|
const entries = [];
|
|
2803
3013
|
for (const file of files) {
|
|
2804
|
-
const document = await (0,
|
|
3014
|
+
const document = await (0, import_promises14.readFile)(file.absolutePath, "utf8");
|
|
2805
3015
|
entries.push(...filesystemValuesReader(file.relativePath, document, file.workspaceId));
|
|
2806
3016
|
}
|
|
2807
3017
|
for (const namespace of customNamespaces) {
|
|
@@ -2816,7 +3026,7 @@ function createFilesystemValuesPlugin() {
|
|
|
2816
3026
|
layers
|
|
2817
3027
|
);
|
|
2818
3028
|
for (const file of namespaceFiles) {
|
|
2819
|
-
const document = await (0,
|
|
3029
|
+
const document = await (0, import_promises14.readFile)(file.absolutePath, "utf8");
|
|
2820
3030
|
entries.push(...yamlObjectToEntries(document, file.relativePath, namespace, "filesystem-values", file.workspaceId));
|
|
2821
3031
|
}
|
|
2822
3032
|
}
|
|
@@ -2986,10 +3196,18 @@ async function createCnos2(options = {}) {
|
|
|
2986
3196
|
}
|
|
2987
3197
|
|
|
2988
3198
|
// src/runtime/bootstrap.ts
|
|
2989
|
-
var
|
|
3199
|
+
var import_node_crypto3 = require("crypto");
|
|
2990
3200
|
var CNOS_GRAPH_ENV_VAR = "__CNOS_GRAPH__";
|
|
3201
|
+
var CNOS_PROJECTION_ENV_VAR = "__CNOS_PROJECTION__";
|
|
2991
3202
|
var CNOS_SECRET_PAYLOAD_ENV_VAR = "__CNOS_SECRET_PAYLOAD__";
|
|
2992
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
|
+
}
|
|
2993
3211
|
function deserializeRuntimeGraph(source) {
|
|
2994
3212
|
const payload = JSON.parse(source);
|
|
2995
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)) {
|
|
@@ -3023,7 +3241,7 @@ function decryptSecretPayload(serialized, sessionKey) {
|
|
|
3023
3241
|
const iv = Buffer.from(payload.iv, "base64");
|
|
3024
3242
|
const tag = Buffer.from(payload.tag, "base64");
|
|
3025
3243
|
const ciphertext = Buffer.from(payload.ciphertext, "base64");
|
|
3026
|
-
const decipher = (0,
|
|
3244
|
+
const decipher = (0, import_node_crypto3.createDecipheriv)("aes-256-gcm", key, iv);
|
|
3027
3245
|
decipher.setAuthTag(tag);
|
|
3028
3246
|
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
3029
3247
|
return JSON.parse(plaintext);
|
|
@@ -3047,6 +3265,13 @@ function readRuntimeGraphFromEnv(processEnv = process.env) {
|
|
|
3047
3265
|
}
|
|
3048
3266
|
return graph;
|
|
3049
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
|
+
}
|
|
3050
3275
|
function graphRequiresSecretHydration(graph) {
|
|
3051
3276
|
return Array.from(graph.entries.values()).some((entry) => entry.namespace === "secret" && isSecretReference(entry.value));
|
|
3052
3277
|
}
|
|
@@ -3060,6 +3285,12 @@ function getRuntimeOrThrow() {
|
|
|
3060
3285
|
}
|
|
3061
3286
|
return runtime;
|
|
3062
3287
|
}
|
|
3288
|
+
function requireLogicalKey(runtime, key) {
|
|
3289
|
+
return runtime.require(key);
|
|
3290
|
+
}
|
|
3291
|
+
function readLogicalKey(runtime, key) {
|
|
3292
|
+
return runtime.read(key);
|
|
3293
|
+
}
|
|
3063
3294
|
function stringifyLogValue(value) {
|
|
3064
3295
|
if (value === void 0) {
|
|
3065
3296
|
return "";
|
|
@@ -3156,14 +3387,14 @@ function attachBootstrappedGraph(graph) {
|
|
|
3156
3387
|
readOr(key, fallback) {
|
|
3157
3388
|
return readOrValue(graph, key, fallback);
|
|
3158
3389
|
},
|
|
3159
|
-
value(
|
|
3160
|
-
return readValue(graph, toLogicalKey("value",
|
|
3390
|
+
value(path14) {
|
|
3391
|
+
return readValue(graph, toLogicalKey("value", path14));
|
|
3161
3392
|
},
|
|
3162
|
-
secret(
|
|
3163
|
-
return readValue(graph, toLogicalKey("secret",
|
|
3393
|
+
secret(path14) {
|
|
3394
|
+
return readValue(graph, toLogicalKey("secret", path14));
|
|
3164
3395
|
},
|
|
3165
|
-
meta(
|
|
3166
|
-
return readValue(graph, toLogicalKey("meta",
|
|
3396
|
+
meta(path14) {
|
|
3397
|
+
return readValue(graph, toLogicalKey("meta", path14));
|
|
3167
3398
|
},
|
|
3168
3399
|
toNamespace(namespace) {
|
|
3169
3400
|
return toNamespaceObject(graph, namespace);
|
|
@@ -3179,11 +3410,275 @@ function attachBootstrappedGraph(graph) {
|
|
|
3179
3410
|
},
|
|
3180
3411
|
toObject() {
|
|
3181
3412
|
return toNamespaceObject(graph);
|
|
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;
|
|
3182
3422
|
}
|
|
3183
3423
|
};
|
|
3184
3424
|
setSingletonRuntime(runtime);
|
|
3185
3425
|
setBootstrappedSecretHydrationRequired(graphRequiresSecretHydration(graph));
|
|
3186
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
|
+
},
|
|
3656
|
+
toNamespace(namespace) {
|
|
3657
|
+
return toNamespaceObject(graph, namespace);
|
|
3658
|
+
},
|
|
3659
|
+
toEnv(options) {
|
|
3660
|
+
return toEnv(graph, manifest, options);
|
|
3661
|
+
},
|
|
3662
|
+
toPublicEnv(options) {
|
|
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);
|
|
3677
|
+
}
|
|
3678
|
+
};
|
|
3679
|
+
setSingletonRuntime(runtime);
|
|
3680
|
+
setBootstrappedSecretHydrationRequired(Object.keys(projection.secretRefs).length > 0);
|
|
3681
|
+
}
|
|
3187
3682
|
function bootstrapFromProcessEnv() {
|
|
3188
3683
|
if (typeof process === "undefined") {
|
|
3189
3684
|
return;
|
|
@@ -3192,31 +3687,78 @@ function bootstrapFromProcessEnv() {
|
|
|
3192
3687
|
const graph = readRuntimeGraphFromEnv(process.env);
|
|
3193
3688
|
if (graph) {
|
|
3194
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;
|
|
3195
3734
|
}
|
|
3735
|
+
const projection = deserializeServerProjection((0, import_node_fs.readFileSync)(projectionPath, "utf8"));
|
|
3736
|
+
attachBootstrappedProjection(projection);
|
|
3196
3737
|
} catch {
|
|
3197
3738
|
}
|
|
3198
3739
|
}
|
|
3199
3740
|
bootstrapFromProcessEnv();
|
|
3741
|
+
bootstrapFromProjectionFile();
|
|
3200
3742
|
var cnos = Object.assign(
|
|
3201
|
-
((key) =>
|
|
3743
|
+
((key) => readLogicalKey(getRuntimeOrThrow(), key)),
|
|
3202
3744
|
{
|
|
3203
3745
|
read(key) {
|
|
3204
|
-
return
|
|
3746
|
+
return readLogicalKey(getRuntimeOrThrow(), key);
|
|
3205
3747
|
},
|
|
3206
3748
|
require(key) {
|
|
3207
|
-
return
|
|
3749
|
+
return requireLogicalKey(getRuntimeOrThrow(), key);
|
|
3208
3750
|
},
|
|
3209
3751
|
readOr(key, fallback) {
|
|
3210
|
-
return
|
|
3752
|
+
return getRuntimeOrThrow().readOr(key, fallback);
|
|
3211
3753
|
},
|
|
3212
|
-
value(
|
|
3213
|
-
return
|
|
3754
|
+
value(path14) {
|
|
3755
|
+
return getRuntimeOrThrow().value(path14);
|
|
3214
3756
|
},
|
|
3215
|
-
secret(
|
|
3216
|
-
return
|
|
3757
|
+
secret(path14) {
|
|
3758
|
+
return getRuntimeOrThrow().secret(path14);
|
|
3217
3759
|
},
|
|
3218
|
-
meta(
|
|
3219
|
-
return
|
|
3760
|
+
meta(path14) {
|
|
3761
|
+
return getRuntimeOrThrow().meta(path14);
|
|
3220
3762
|
},
|
|
3221
3763
|
inspect(key) {
|
|
3222
3764
|
return getRuntimeOrThrow().inspect(key);
|
|
@@ -3238,8 +3780,27 @@ var cnos = Object.assign(
|
|
|
3238
3780
|
console.log(formatted);
|
|
3239
3781
|
return formatted;
|
|
3240
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);
|
|
3795
|
+
},
|
|
3241
3796
|
async ready() {
|
|
3242
|
-
|
|
3797
|
+
const runtime = getSingletonRuntime();
|
|
3798
|
+
if (runtime && getBootstrappedSecretHydrationRequired()) {
|
|
3799
|
+
await runtime.refreshSecrets();
|
|
3800
|
+
setBootstrappedSecretHydrationRequired(false);
|
|
3801
|
+
return;
|
|
3802
|
+
}
|
|
3803
|
+
if (runtime && !getBootstrappedSecretHydrationRequired()) {
|
|
3243
3804
|
return;
|
|
3244
3805
|
}
|
|
3245
3806
|
const existing = getSingletonReady();
|
|
@@ -3247,9 +3808,10 @@ var cnos = Object.assign(
|
|
|
3247
3808
|
await existing;
|
|
3248
3809
|
return;
|
|
3249
3810
|
}
|
|
3250
|
-
const readyPromise = createCnos2().then((
|
|
3251
|
-
setSingletonRuntime(
|
|
3252
|
-
|
|
3811
|
+
const readyPromise = createCnos2().then((runtime2) => {
|
|
3812
|
+
setSingletonRuntime(runtime2);
|
|
3813
|
+
setBootstrappedSecretHydrationRequired(false);
|
|
3814
|
+
return runtime2;
|
|
3253
3815
|
});
|
|
3254
3816
|
setSingletonReady(readyPromise);
|
|
3255
3817
|
await readyPromise;
|