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