@kitsy/cnos 1.6.0 → 1.7.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 +1332 -156
- package/dist/build/index.d.cts +1 -1
- package/dist/build/index.d.ts +1 -1
- package/dist/build/index.js +36 -14
- package/dist/{chunk-JYWQFMW5.js → chunk-2DGT7N7E.js} +1 -1
- package/dist/{chunk-S7H2UULC.js → chunk-2TL42I6M.js} +1323 -139
- package/dist/{chunk-MW4OVAT3.js → chunk-5KIQCYFH.js} +1 -1
- package/dist/{chunk-UOKVLCFL.js → chunk-CV3SLBYZ.js} +10 -10
- package/dist/{chunk-XSUP7JKH.js → chunk-GHGJFRDL.js} +6 -2
- package/dist/{chunk-BMAD24KC.js → chunk-OA7FQGAG.js} +1 -1
- package/dist/{chunk-QU5CXL47.js → chunk-PFT56ID2.js} +195 -28
- package/dist/{chunk-VGZREX5D.js → chunk-RYIARE4M.js} +1 -1
- package/dist/{chunk-UR7CHHNN.js → chunk-TT4NV56Z.js} +3 -2
- package/dist/{chunk-UJBQS7CJ.js → chunk-UL63DFLS.js} +1 -1
- package/dist/configure/index.cjs +1309 -155
- 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/{plugin-CKrBlWGI.d.cts → core-BJ8xewez.d.cts} +142 -60
- package/dist/{plugin-CKrBlWGI.d.ts → core-BJ8xewez.d.ts} +142 -60
- package/dist/{envNaming-B7Mztkcf.d.ts → envNaming-BRyiuPoI.d.ts} +1 -1
- package/dist/{envNaming-gMVnPOfe.d.cts → envNaming-rx71gpi0.d.cts} +1 -1
- package/dist/index.cjs +1548 -227
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -10
- package/dist/internal.cjs +831 -122
- package/dist/internal.d.cts +56 -3
- package/dist/internal.d.ts +56 -3
- package/dist/internal.js +30 -3
- package/dist/plugin/basic-schema.cjs +49 -23
- 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 +38 -23
- 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 +46 -31
- 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 +56 -27
- 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 +61 -39
- 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 +40 -25
- 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/runtime/index.cjs +1548 -227
- package/dist/runtime/index.d.cts +3 -1
- package/dist/runtime/index.d.ts +3 -1
- package/dist/runtime/index.js +10 -10
- package/dist/toPublicEnv-CCSgdvI9.d.ts +13 -0
- package/dist/toPublicEnv-ivRtLjcw.d.cts +13 -0
- package/package.json +1 -1
- package/dist/toPublicEnv-CmBsy53P.d.cts +0 -7
- package/dist/toPublicEnv-q6VwWxXZ.d.ts +0 -7
package/dist/configure/index.cjs
CHANGED
|
@@ -75,16 +75,673 @@ var CnosKeyNotFoundError = class extends CnosError {
|
|
|
75
75
|
}
|
|
76
76
|
key;
|
|
77
77
|
};
|
|
78
|
+
var CnosDerivedExpressionError = class extends CnosError {
|
|
79
|
+
constructor(message, expression) {
|
|
80
|
+
super(expression ? `${message} (${expression})` : message);
|
|
81
|
+
this.expression = expression;
|
|
82
|
+
}
|
|
83
|
+
expression;
|
|
84
|
+
};
|
|
85
|
+
var CnosDerivedCycleError = class extends CnosError {
|
|
86
|
+
constructor(message) {
|
|
87
|
+
super(message);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var CnosDerivedResolutionError = class extends CnosError {
|
|
91
|
+
constructor(key, message) {
|
|
92
|
+
super(message);
|
|
93
|
+
this.key = key;
|
|
94
|
+
}
|
|
95
|
+
key;
|
|
96
|
+
};
|
|
97
|
+
var CnosRuntimeProviderError = class extends CnosError {
|
|
98
|
+
constructor(message) {
|
|
99
|
+
super(message);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// ../core/src/derive/builtins.ts
|
|
104
|
+
function stringify(value) {
|
|
105
|
+
if (value === void 0 || value === null) {
|
|
106
|
+
return "";
|
|
107
|
+
}
|
|
108
|
+
if (typeof value === "string") {
|
|
109
|
+
return value;
|
|
110
|
+
}
|
|
111
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
112
|
+
return String(value);
|
|
113
|
+
}
|
|
114
|
+
return JSON.stringify(value);
|
|
115
|
+
}
|
|
116
|
+
var DERIVE_BUILTINS = {
|
|
117
|
+
concat: (...args) => args.map((value) => stringify(value)).join(""),
|
|
118
|
+
coalesce: (...args) => args.find((value) => value !== void 0 && value !== null),
|
|
119
|
+
when: (condition, whenTrue, whenFalse) => condition ? whenTrue : whenFalse,
|
|
120
|
+
exists: (value) => value !== void 0 && value !== null,
|
|
121
|
+
eq: (left, right) => left === right,
|
|
122
|
+
ne: (left, right) => left !== right
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// ../core/src/derive/depGraph.ts
|
|
126
|
+
function detectDerivationCycles(dependencyMap) {
|
|
127
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
128
|
+
const visited = /* @__PURE__ */ new Set();
|
|
129
|
+
const stack = [];
|
|
130
|
+
const visit = (key) => {
|
|
131
|
+
if (visited.has(key)) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (visiting.has(key)) {
|
|
135
|
+
const start = stack.indexOf(key);
|
|
136
|
+
const cycle = [...stack.slice(start), key].join(" -> ");
|
|
137
|
+
throw new CnosDerivedCycleError(`Derivation cycle detected: ${cycle}`);
|
|
138
|
+
}
|
|
139
|
+
visiting.add(key);
|
|
140
|
+
stack.push(key);
|
|
141
|
+
for (const dependency of dependencyMap.get(key) ?? []) {
|
|
142
|
+
visit(dependency);
|
|
143
|
+
}
|
|
144
|
+
stack.pop();
|
|
145
|
+
visiting.delete(key);
|
|
146
|
+
visited.add(key);
|
|
147
|
+
};
|
|
148
|
+
for (const key of dependencyMap.keys()) {
|
|
149
|
+
visit(key);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ../core/src/derive/parser.ts
|
|
154
|
+
function isWhitespace(value) {
|
|
155
|
+
return value === " " || value === "\n" || value === "\r" || value === " ";
|
|
156
|
+
}
|
|
157
|
+
function skipWhitespace(state) {
|
|
158
|
+
while (isWhitespace(state.source[state.index])) {
|
|
159
|
+
state.index += 1;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function isIdentifierStart(value) {
|
|
163
|
+
return typeof value === "string" && /[A-Za-z_]/.test(value);
|
|
164
|
+
}
|
|
165
|
+
function isIdentifierPart(value) {
|
|
166
|
+
return typeof value === "string" && /[A-Za-z0-9_.-]/.test(value);
|
|
167
|
+
}
|
|
168
|
+
function errorAt(state, message) {
|
|
169
|
+
throw new CnosDerivedExpressionError(`${message} at position ${state.index + 1}`, state.source);
|
|
170
|
+
}
|
|
171
|
+
function parseStringLiteral(state) {
|
|
172
|
+
const quote = state.source[state.index];
|
|
173
|
+
if (quote !== "'") {
|
|
174
|
+
errorAt(state, "Expected string literal");
|
|
175
|
+
}
|
|
176
|
+
state.index += 1;
|
|
177
|
+
let value = "";
|
|
178
|
+
while (state.index < state.source.length) {
|
|
179
|
+
const current = state.source[state.index];
|
|
180
|
+
if (current === "\\") {
|
|
181
|
+
const next = state.source[state.index + 1];
|
|
182
|
+
if (next === void 0) {
|
|
183
|
+
errorAt(state, "Unterminated escape sequence");
|
|
184
|
+
}
|
|
185
|
+
value += next;
|
|
186
|
+
state.index += 2;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (current === "'") {
|
|
190
|
+
state.index += 1;
|
|
191
|
+
return {
|
|
192
|
+
type: "literal",
|
|
193
|
+
value
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
value += current;
|
|
197
|
+
state.index += 1;
|
|
198
|
+
}
|
|
199
|
+
errorAt(state, "Unterminated string literal");
|
|
200
|
+
}
|
|
201
|
+
function parseNumberLiteral(state) {
|
|
202
|
+
const start = state.index;
|
|
203
|
+
while (/[0-9]/.test(state.source[state.index] ?? "")) {
|
|
204
|
+
state.index += 1;
|
|
205
|
+
}
|
|
206
|
+
if (state.source[state.index] === ".") {
|
|
207
|
+
state.index += 1;
|
|
208
|
+
while (/[0-9]/.test(state.source[state.index] ?? "")) {
|
|
209
|
+
state.index += 1;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
type: "literal",
|
|
214
|
+
value: Number(state.source.slice(start, state.index))
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function parseIdentifier(state) {
|
|
218
|
+
if (!isIdentifierStart(state.source[state.index])) {
|
|
219
|
+
errorAt(state, "Expected identifier");
|
|
220
|
+
}
|
|
221
|
+
const start = state.index;
|
|
222
|
+
state.index += 1;
|
|
223
|
+
while (isIdentifierPart(state.source[state.index])) {
|
|
224
|
+
state.index += 1;
|
|
225
|
+
}
|
|
226
|
+
return state.source.slice(start, state.index);
|
|
227
|
+
}
|
|
228
|
+
function parseArguments(state) {
|
|
229
|
+
const args = [];
|
|
230
|
+
skipWhitespace(state);
|
|
231
|
+
if (state.source[state.index] === ")") {
|
|
232
|
+
state.index += 1;
|
|
233
|
+
return args;
|
|
234
|
+
}
|
|
235
|
+
while (state.index < state.source.length) {
|
|
236
|
+
args.push(parseExpressionNode(state));
|
|
237
|
+
skipWhitespace(state);
|
|
238
|
+
const current = state.source[state.index];
|
|
239
|
+
if (current === ",") {
|
|
240
|
+
state.index += 1;
|
|
241
|
+
skipWhitespace(state);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (current === ")") {
|
|
245
|
+
state.index += 1;
|
|
246
|
+
return args;
|
|
247
|
+
}
|
|
248
|
+
errorAt(state, 'Expected "," or ")"');
|
|
249
|
+
}
|
|
250
|
+
errorAt(state, "Unterminated function call");
|
|
251
|
+
}
|
|
252
|
+
function parseIdentifierOrCall(state) {
|
|
253
|
+
const identifier = parseIdentifier(state);
|
|
254
|
+
skipWhitespace(state);
|
|
255
|
+
if (state.source[state.index] === "(") {
|
|
256
|
+
if (!(identifier in DERIVE_BUILTINS)) {
|
|
257
|
+
throw new CnosDerivedExpressionError(`Unknown derive function: ${identifier}`, state.source);
|
|
258
|
+
}
|
|
259
|
+
state.index += 1;
|
|
260
|
+
return {
|
|
261
|
+
type: "call",
|
|
262
|
+
name: identifier,
|
|
263
|
+
args: parseArguments(state)
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
if (identifier === "true" || identifier === "false") {
|
|
267
|
+
return {
|
|
268
|
+
type: "literal",
|
|
269
|
+
value: identifier === "true"
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
if (identifier === "null") {
|
|
273
|
+
return {
|
|
274
|
+
type: "literal",
|
|
275
|
+
value: null
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
type: "ref",
|
|
280
|
+
path: identifier
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
function parseExpressionNode(state) {
|
|
284
|
+
skipWhitespace(state);
|
|
285
|
+
const current = state.source[state.index];
|
|
286
|
+
if (current === "'") {
|
|
287
|
+
return parseStringLiteral(state);
|
|
288
|
+
}
|
|
289
|
+
if (/[0-9]/.test(current ?? "")) {
|
|
290
|
+
return parseNumberLiteral(state);
|
|
291
|
+
}
|
|
292
|
+
if (isIdentifierStart(current)) {
|
|
293
|
+
return parseIdentifierOrCall(state);
|
|
294
|
+
}
|
|
295
|
+
errorAt(state, "Unexpected token");
|
|
296
|
+
}
|
|
297
|
+
function parseExpression(source) {
|
|
298
|
+
const state = {
|
|
299
|
+
source,
|
|
300
|
+
index: 0
|
|
301
|
+
};
|
|
302
|
+
const ast = parseExpressionNode(state);
|
|
303
|
+
skipWhitespace(state);
|
|
304
|
+
if (state.index !== source.length) {
|
|
305
|
+
errorAt(state, "Unexpected trailing input");
|
|
306
|
+
}
|
|
307
|
+
return ast;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// ../core/src/derive/templateParser.ts
|
|
311
|
+
function toLiteral(value) {
|
|
312
|
+
return {
|
|
313
|
+
type: "literal",
|
|
314
|
+
value
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function toRef(path16) {
|
|
318
|
+
return {
|
|
319
|
+
type: "ref",
|
|
320
|
+
path: path16
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function parseTemplate(source) {
|
|
324
|
+
const parts = [];
|
|
325
|
+
let cursor = 0;
|
|
326
|
+
while (cursor < source.length) {
|
|
327
|
+
const start = source.indexOf("${", cursor);
|
|
328
|
+
if (start < 0) {
|
|
329
|
+
if (cursor < source.length) {
|
|
330
|
+
parts.push(toLiteral(source.slice(cursor)));
|
|
331
|
+
}
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
if (start > cursor) {
|
|
335
|
+
parts.push(toLiteral(source.slice(cursor, start)));
|
|
336
|
+
}
|
|
337
|
+
const end = source.indexOf("}", start + 2);
|
|
338
|
+
if (end < 0) {
|
|
339
|
+
throw new CnosDerivedExpressionError(`Invalid derivation template: unclosed \${...} at position ${start + 1}`, source);
|
|
340
|
+
}
|
|
341
|
+
const ref = source.slice(start + 2, end).trim();
|
|
342
|
+
if (!ref) {
|
|
343
|
+
throw new CnosDerivedExpressionError(`Invalid derivation template: empty reference at position ${start + 1}`, source);
|
|
344
|
+
}
|
|
345
|
+
if (!/^[A-Za-z_][A-Za-z0-9_.-]*$/.test(ref)) {
|
|
346
|
+
throw new CnosDerivedExpressionError(`Invalid derivation template reference "${ref}"`, source);
|
|
347
|
+
}
|
|
348
|
+
parts.push(toRef(ref));
|
|
349
|
+
cursor = end + 1;
|
|
350
|
+
}
|
|
351
|
+
if (parts.length === 0) {
|
|
352
|
+
return toLiteral("");
|
|
353
|
+
}
|
|
354
|
+
if (parts.length === 1) {
|
|
355
|
+
return parts[0];
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
type: "call",
|
|
359
|
+
name: "concat",
|
|
360
|
+
args: parts
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// ../core/src/derive/evaluator.ts
|
|
365
|
+
function isDerivedValue(value) {
|
|
366
|
+
return Boolean(
|
|
367
|
+
value && typeof value === "object" && !Array.isArray(value) && "$derive" in value
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
function extractRefs(node, refs = /* @__PURE__ */ new Set()) {
|
|
371
|
+
if (node.type === "ref") {
|
|
372
|
+
refs.add(node.path);
|
|
373
|
+
return refs;
|
|
374
|
+
}
|
|
375
|
+
if (node.type === "call") {
|
|
376
|
+
for (const arg of node.args) {
|
|
377
|
+
extractRefs(arg, refs);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return refs;
|
|
381
|
+
}
|
|
382
|
+
function parseDerivation(value) {
|
|
383
|
+
const source = typeof value.$derive === "string" ? value.$derive : value.$derive?.expr;
|
|
384
|
+
if (typeof source !== "string") {
|
|
385
|
+
throw new CnosDerivedExpressionError("Derived value requires either a template string or { expr } object");
|
|
386
|
+
}
|
|
387
|
+
const type = typeof value.$derive === "string" ? "template" : "expression";
|
|
388
|
+
const ast = type === "template" ? parseTemplate(source) : parseExpression(source);
|
|
389
|
+
const refs = Array.from(extractRefs(ast)).sort((left, right) => left.localeCompare(right));
|
|
390
|
+
return {
|
|
391
|
+
type,
|
|
392
|
+
raw: source,
|
|
393
|
+
ast,
|
|
394
|
+
refs,
|
|
395
|
+
runtimeRefs: [],
|
|
396
|
+
isRuntimeDependent: false
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function normalizeConcatValue(value) {
|
|
400
|
+
if (value === void 0 || value === null) {
|
|
401
|
+
return "";
|
|
402
|
+
}
|
|
403
|
+
if (typeof value === "string") {
|
|
404
|
+
return value;
|
|
405
|
+
}
|
|
406
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
407
|
+
return String(value);
|
|
408
|
+
}
|
|
409
|
+
return JSON.stringify(value);
|
|
410
|
+
}
|
|
411
|
+
function evaluateNode(node, resolveRef) {
|
|
412
|
+
switch (node.type) {
|
|
413
|
+
case "literal":
|
|
414
|
+
return node.value;
|
|
415
|
+
case "ref":
|
|
416
|
+
return resolveRef(node.path);
|
|
417
|
+
case "call": {
|
|
418
|
+
const args = node.args.map((arg) => evaluateNode(arg, resolveRef));
|
|
419
|
+
switch (node.name) {
|
|
420
|
+
case "concat":
|
|
421
|
+
return args.map((value) => normalizeConcatValue(value)).join("");
|
|
422
|
+
case "coalesce":
|
|
423
|
+
return DERIVE_BUILTINS.coalesce(...args);
|
|
424
|
+
case "when":
|
|
425
|
+
return DERIVE_BUILTINS.when(args[0], args[1], args[2]);
|
|
426
|
+
case "exists":
|
|
427
|
+
return DERIVE_BUILTINS.exists(args[0]);
|
|
428
|
+
case "eq":
|
|
429
|
+
return DERIVE_BUILTINS.eq(args[0], args[1]);
|
|
430
|
+
case "ne":
|
|
431
|
+
return DERIVE_BUILTINS.ne(args[0], args[1]);
|
|
432
|
+
default:
|
|
433
|
+
throw new CnosDerivedExpressionError(`Unknown derive function: ${String(node.name)}`);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
default:
|
|
437
|
+
throw new CnosDerivedExpressionError(`Unsupported derive AST node ${node.type ?? "unknown"}`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
function evaluateDerivation(options) {
|
|
441
|
+
const missingRefs = /* @__PURE__ */ new Set();
|
|
442
|
+
const value = evaluateNode(options.parsed.ast, (ref) => {
|
|
443
|
+
const resolved = options.resolveRef(ref);
|
|
444
|
+
if (resolved === void 0) {
|
|
445
|
+
missingRefs.add(ref);
|
|
446
|
+
options.onMissing?.(ref);
|
|
447
|
+
}
|
|
448
|
+
return resolved;
|
|
449
|
+
});
|
|
450
|
+
if (missingRefs.size > 0 && options.parsed.ast.type === "ref") {
|
|
451
|
+
throw new CnosDerivedResolutionError(
|
|
452
|
+
options.key,
|
|
453
|
+
`Unable to resolve derived config key ${options.key} because ${Array.from(missingRefs).join(", ")} is missing.`
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
return value;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// ../core/src/derive/validate.ts
|
|
460
|
+
var FORBIDDEN_TARGET_NAMESPACES = /* @__PURE__ */ new Set(["public", "meta", "secret"]);
|
|
461
|
+
var FORBIDDEN_REF_NAMESPACES = /* @__PURE__ */ new Set(["public", "secret"]);
|
|
462
|
+
function validateDerivedTargetNamespace(manifest, namespace) {
|
|
463
|
+
if (FORBIDDEN_TARGET_NAMESPACES.has(namespace)) {
|
|
464
|
+
throw new CnosManifestError(`Cannot define derived values under namespace "${namespace}".`);
|
|
465
|
+
}
|
|
466
|
+
if (manifest.runtimeNamespaces[namespace]) {
|
|
467
|
+
throw new CnosManifestError(`Cannot define derived values under runtime namespace "${namespace}".`);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
function validateParsedDerivation(manifest, parsed) {
|
|
471
|
+
for (const ref of parsed.refs) {
|
|
472
|
+
const namespace = ref.split(".")[0] ?? "";
|
|
473
|
+
if (FORBIDDEN_REF_NAMESPACES.has(namespace)) {
|
|
474
|
+
throw new CnosDerivedExpressionError(`Derived expressions cannot reference ${namespace}.* keys.`, parsed.raw);
|
|
475
|
+
}
|
|
476
|
+
if (manifest.runtimeNamespaces[namespace]) {
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
if (!manifest.namespaces[namespace] && namespace !== "value" && namespace !== "meta") {
|
|
480
|
+
throw new CnosDerivedExpressionError(`Unknown derive reference namespace: ${namespace}`, parsed.raw);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// ../core/src/derive/runtime.ts
|
|
486
|
+
function namespaceForKey(key) {
|
|
487
|
+
return key.split(".")[0] ?? "";
|
|
488
|
+
}
|
|
489
|
+
function dependencyNamespaces(key, entries, memo) {
|
|
490
|
+
if (memo.has(key)) {
|
|
491
|
+
return memo.get(key);
|
|
492
|
+
}
|
|
493
|
+
const entry = entries.get(key);
|
|
494
|
+
if (!entry) {
|
|
495
|
+
memo.set(key, []);
|
|
496
|
+
return [];
|
|
497
|
+
}
|
|
498
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
499
|
+
for (const ref of entry.parsed.refs) {
|
|
500
|
+
const namespace = namespaceForKey(ref);
|
|
501
|
+
if (!entries.has(ref)) {
|
|
502
|
+
namespaces.add(namespace);
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
for (const dependencyNamespace of dependencyNamespaces(ref, entries, memo)) {
|
|
506
|
+
namespaces.add(dependencyNamespace);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
const result = Array.from(namespaces).sort((left, right) => left.localeCompare(right));
|
|
510
|
+
memo.set(key, result);
|
|
511
|
+
return result;
|
|
512
|
+
}
|
|
513
|
+
function isRuntimeDependentKey(key, entries, manifest, memo) {
|
|
514
|
+
if (memo.has(key)) {
|
|
515
|
+
return memo.get(key);
|
|
516
|
+
}
|
|
517
|
+
const entry = entries.get(key);
|
|
518
|
+
if (!entry) {
|
|
519
|
+
memo.set(key, false);
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
for (const ref of entry.parsed.refs) {
|
|
523
|
+
const namespace = namespaceForKey(ref);
|
|
524
|
+
if (manifest.runtimeNamespaces[namespace]) {
|
|
525
|
+
memo.set(key, true);
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
if (entries.has(ref) && isRuntimeDependentKey(ref, entries, manifest, memo)) {
|
|
529
|
+
memo.set(key, true);
|
|
530
|
+
return true;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
memo.set(key, false);
|
|
534
|
+
return false;
|
|
535
|
+
}
|
|
536
|
+
function prepareEntries(graph, manifest) {
|
|
537
|
+
const entries = /* @__PURE__ */ new Map();
|
|
538
|
+
for (const [key, entry] of graph.entries) {
|
|
539
|
+
if (!isDerivedValue(entry.value)) {
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
const namespaceDefinition = manifest.namespaces[entry.namespace];
|
|
543
|
+
if (!namespaceDefinition || namespaceDefinition.kind === "data") {
|
|
544
|
+
validateDerivedTargetNamespace(manifest, entry.namespace);
|
|
545
|
+
}
|
|
546
|
+
const parsed = parseDerivation(entry.value);
|
|
547
|
+
validateParsedDerivation(manifest, parsed);
|
|
548
|
+
entries.set(key, {
|
|
549
|
+
key,
|
|
550
|
+
namespace: entry.namespace,
|
|
551
|
+
value: entry.value,
|
|
552
|
+
parsed
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
detectDerivationCycles(
|
|
556
|
+
new Map(
|
|
557
|
+
Array.from(entries.values()).map((entry) => [
|
|
558
|
+
entry.key,
|
|
559
|
+
entry.parsed.refs.filter((ref) => entries.has(ref))
|
|
560
|
+
])
|
|
561
|
+
)
|
|
562
|
+
);
|
|
563
|
+
const runtimeMemo = /* @__PURE__ */ new Map();
|
|
564
|
+
const namespaceMemo = /* @__PURE__ */ new Map();
|
|
565
|
+
for (const entry of entries.values()) {
|
|
566
|
+
entry.parsed.isRuntimeDependent = isRuntimeDependentKey(entry.key, entries, manifest, runtimeMemo);
|
|
567
|
+
entry.parsed.runtimeRefs = entry.parsed.refs.filter((ref) => manifest.runtimeNamespaces[namespaceForKey(ref)]);
|
|
568
|
+
if (entry.parsed.runtimeRefs.length === 0 && entry.parsed.isRuntimeDependent) {
|
|
569
|
+
entry.parsed.runtimeRefs = dependencyNamespaces(entry.key, entries, namespaceMemo).filter((namespace) => manifest.runtimeNamespaces[namespace]).map((namespace) => `${namespace}.*`);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return entries;
|
|
573
|
+
}
|
|
574
|
+
function createDerivedRuntimeSupport(graph, manifest, runtimeProviders) {
|
|
575
|
+
const entries = prepareEntries(graph, manifest);
|
|
576
|
+
const configCache = /* @__PURE__ */ new Map();
|
|
577
|
+
const runtimeDependencyMemo = /* @__PURE__ */ new Map();
|
|
578
|
+
const support = {};
|
|
579
|
+
Object.assign(support, {
|
|
580
|
+
runtimeProviders,
|
|
581
|
+
read(key, readBase) {
|
|
582
|
+
const namespace = namespaceForKey(key);
|
|
583
|
+
if (runtimeProviders.has(namespace)) {
|
|
584
|
+
const provider = runtimeProviders.get(namespace);
|
|
585
|
+
return provider(key.slice(namespace.length + 1));
|
|
586
|
+
}
|
|
587
|
+
if (entries.has(key)) {
|
|
588
|
+
return readDerived(key, readBase);
|
|
589
|
+
}
|
|
590
|
+
return readBase(key);
|
|
591
|
+
},
|
|
592
|
+
describe(key, readBase) {
|
|
593
|
+
const entry = entries.get(key);
|
|
594
|
+
if (!entry) {
|
|
595
|
+
return void 0;
|
|
596
|
+
}
|
|
597
|
+
const runtimeNamespaces = Array.from(
|
|
598
|
+
new Set(
|
|
599
|
+
entry.parsed.refs.map((ref) => namespaceForKey(ref)).filter((namespace) => manifest.runtimeNamespaces[namespace])
|
|
600
|
+
)
|
|
601
|
+
).sort((left, right) => left.localeCompare(right));
|
|
602
|
+
return {
|
|
603
|
+
key,
|
|
604
|
+
type: entry.parsed.type,
|
|
605
|
+
expression: entry.parsed.raw,
|
|
606
|
+
dependencies: entry.parsed.refs.map((ref) => {
|
|
607
|
+
const namespace = namespaceForKey(ref);
|
|
608
|
+
return {
|
|
609
|
+
key: ref,
|
|
610
|
+
value: support.read(ref, readBase),
|
|
611
|
+
...manifest.runtimeNamespaces[namespace] ? {
|
|
612
|
+
runtimeNamespace: namespace
|
|
613
|
+
} : {}
|
|
614
|
+
};
|
|
615
|
+
}),
|
|
616
|
+
runtimeDependent: entry.parsed.isRuntimeDependent,
|
|
617
|
+
runtimeNamespaces,
|
|
618
|
+
...entry.parsed.isRuntimeDependent ? {
|
|
619
|
+
promotionWarning: "Cannot be promoted to browser/public."
|
|
620
|
+
} : {}
|
|
621
|
+
};
|
|
622
|
+
},
|
|
623
|
+
isDerivedKey(key) {
|
|
624
|
+
return entries.has(key);
|
|
625
|
+
},
|
|
626
|
+
isRuntimeDependentKey(key) {
|
|
627
|
+
if (runtimeDependencyMemo.has(key)) {
|
|
628
|
+
return runtimeDependencyMemo.get(key);
|
|
629
|
+
}
|
|
630
|
+
const value = entries.get(key)?.parsed.isRuntimeDependent ?? false;
|
|
631
|
+
runtimeDependencyMemo.set(key, value);
|
|
632
|
+
return value;
|
|
633
|
+
},
|
|
634
|
+
toConcreteValue(key, readBase, mode) {
|
|
635
|
+
const entry = entries.get(key);
|
|
636
|
+
if (!entry) {
|
|
637
|
+
return support.read(key, readBase);
|
|
638
|
+
}
|
|
639
|
+
if (!entry.parsed.isRuntimeDependent) {
|
|
640
|
+
return support.read(key, readBase);
|
|
641
|
+
}
|
|
642
|
+
if (mode === "server" || mode === "runtime") {
|
|
643
|
+
return support.read(key, readBase);
|
|
644
|
+
}
|
|
645
|
+
for (const ref of entry.parsed.refs) {
|
|
646
|
+
const namespace = namespaceForKey(ref);
|
|
647
|
+
const runtimeNamespace = manifest.runtimeNamespaces[namespace];
|
|
648
|
+
if (!runtimeNamespace) {
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
if (runtimeNamespace.serverOnly) {
|
|
652
|
+
throw new CnosDerivedResolutionError(
|
|
653
|
+
key,
|
|
654
|
+
`Cannot resolve ${key} for ${mode} output because it depends on runtime namespace ${namespace}.`
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
if (!runtimeProviders.has(namespace)) {
|
|
658
|
+
if (mode === "env") {
|
|
659
|
+
return void 0;
|
|
660
|
+
}
|
|
661
|
+
throw new CnosDerivedResolutionError(
|
|
662
|
+
key,
|
|
663
|
+
`Cannot resolve ${key} for ${mode} output because runtime namespace ${namespace} has no registered provider.`
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return support.read(key, readBase);
|
|
668
|
+
},
|
|
669
|
+
toServerFormula(key) {
|
|
670
|
+
const entry = entries.get(key);
|
|
671
|
+
if (!entry || !entry.parsed.isRuntimeDependent) {
|
|
672
|
+
return void 0;
|
|
673
|
+
}
|
|
674
|
+
return {
|
|
675
|
+
expr: entry.parsed.raw,
|
|
676
|
+
deps: entry.parsed.refs.filter((ref) => !manifest.runtimeNamespaces[namespaceForKey(ref)]),
|
|
677
|
+
runtimeRefs: entry.parsed.refs.filter((ref) => manifest.runtimeNamespaces[namespaceForKey(ref)])
|
|
678
|
+
};
|
|
679
|
+
},
|
|
680
|
+
derivedKeys: Array.from(entries.keys()).sort((left, right) => left.localeCompare(right))
|
|
681
|
+
});
|
|
682
|
+
const readDerived = (key, readBase, evaluationStack = /* @__PURE__ */ new Set()) => {
|
|
683
|
+
const entry = entries.get(key);
|
|
684
|
+
if (!entry) {
|
|
685
|
+
return readBase(key);
|
|
686
|
+
}
|
|
687
|
+
if (!entry.parsed.isRuntimeDependent && configCache.has(key)) {
|
|
688
|
+
return configCache.get(key);
|
|
689
|
+
}
|
|
690
|
+
const value = evaluateDerivation({
|
|
691
|
+
key,
|
|
692
|
+
parsed: entry.parsed,
|
|
693
|
+
resolveRef: (ref) => {
|
|
694
|
+
const namespace = namespaceForKey(ref);
|
|
695
|
+
if (runtimeProviders.has(namespace)) {
|
|
696
|
+
const provider = runtimeProviders.get(namespace);
|
|
697
|
+
return provider(ref.slice(namespace.length + 1));
|
|
698
|
+
}
|
|
699
|
+
if (entries.has(ref)) {
|
|
700
|
+
if (evaluationStack.has(ref)) {
|
|
701
|
+
throw new CnosDerivedResolutionError(key, `Unable to resolve derived config key ${key} because of a recursive dependency on ${ref}.`);
|
|
702
|
+
}
|
|
703
|
+
evaluationStack.add(ref);
|
|
704
|
+
const resolved = readDerived(ref, readBase, evaluationStack);
|
|
705
|
+
evaluationStack.delete(ref);
|
|
706
|
+
return resolved;
|
|
707
|
+
}
|
|
708
|
+
return readBase(ref);
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
if (!entry.parsed.isRuntimeDependent) {
|
|
712
|
+
configCache.set(key, value);
|
|
713
|
+
}
|
|
714
|
+
return value;
|
|
715
|
+
};
|
|
716
|
+
for (const key of Array.from(entries.keys()).sort((left, right) => left.localeCompare(right))) {
|
|
717
|
+
const entry = entries.get(key);
|
|
718
|
+
if (!entry.parsed.isRuntimeDependent) {
|
|
719
|
+
readDerived(key, (ref) => graph.entries.get(ref)?.value);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
return support;
|
|
723
|
+
}
|
|
724
|
+
function registerRuntimeProvider(manifest, runtimeProviders, namespace, provider) {
|
|
725
|
+
const definition = manifest.runtimeNamespaces[namespace];
|
|
726
|
+
if (!definition) {
|
|
727
|
+
throw new CnosRuntimeProviderError(`Cannot register runtime provider for undeclared namespace "${namespace}".`);
|
|
728
|
+
}
|
|
729
|
+
if (definition.builtIn) {
|
|
730
|
+
throw new CnosRuntimeProviderError(`Cannot override built-in runtime namespace "${namespace}".`);
|
|
731
|
+
}
|
|
732
|
+
runtimeProviders.set(namespace, provider);
|
|
733
|
+
}
|
|
78
734
|
|
|
79
735
|
// ../core/src/runtime/inspect.ts
|
|
80
|
-
function inspectValue(graph, key) {
|
|
736
|
+
function inspectValue(graph, key, helpers = {}) {
|
|
81
737
|
const entry = graph.entries.get(key);
|
|
82
738
|
if (!entry) {
|
|
83
739
|
throw new CnosKeyNotFoundError(key);
|
|
84
740
|
}
|
|
741
|
+
const derived = helpers.describeDerived?.(key);
|
|
85
742
|
return {
|
|
86
743
|
key: entry.key,
|
|
87
|
-
value: entry.value,
|
|
744
|
+
value: helpers.read ? helpers.read(entry.key) : entry.value,
|
|
88
745
|
namespace: entry.namespace,
|
|
89
746
|
profile: graph.profile,
|
|
90
747
|
profileSource: graph.profileSource,
|
|
@@ -105,7 +762,10 @@ function inspectValue(graph, key) {
|
|
|
105
762
|
workspaceId: override.workspaceId,
|
|
106
763
|
value: override.value,
|
|
107
764
|
...override.origin ? { origin: override.origin } : {}
|
|
108
|
-
}))
|
|
765
|
+
})),
|
|
766
|
+
...derived ? {
|
|
767
|
+
derived
|
|
768
|
+
} : {}
|
|
109
769
|
};
|
|
110
770
|
}
|
|
111
771
|
|
|
@@ -183,17 +843,17 @@ async function readKeychain(entry) {
|
|
|
183
843
|
}
|
|
184
844
|
|
|
185
845
|
// ../core/src/manifest/loadManifest.ts
|
|
186
|
-
var
|
|
187
|
-
var
|
|
846
|
+
var import_promises5 = require("fs/promises");
|
|
847
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
188
848
|
|
|
189
849
|
// ../core/src/utils/path.ts
|
|
190
|
-
var
|
|
191
|
-
var
|
|
192
|
-
var
|
|
850
|
+
var import_promises4 = require("fs/promises");
|
|
851
|
+
var import_node_os3 = __toESM(require("os"), 1);
|
|
852
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
193
853
|
|
|
194
854
|
// ../core/src/discovery/findCnosrc.ts
|
|
195
|
-
var
|
|
196
|
-
var
|
|
855
|
+
var import_promises3 = require("fs/promises");
|
|
856
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
197
857
|
|
|
198
858
|
// ../core/src/utils/yaml.ts
|
|
199
859
|
var import_yaml = require("yaml");
|
|
@@ -204,10 +864,315 @@ function stringifyYaml(value) {
|
|
|
204
864
|
return (0, import_yaml.stringify)(value);
|
|
205
865
|
}
|
|
206
866
|
|
|
867
|
+
// ../core/src/discovery/resolveRoot.ts
|
|
868
|
+
var import_promises2 = require("fs/promises");
|
|
869
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
870
|
+
var import_node_child_process4 = require("child_process");
|
|
871
|
+
var import_node_os2 = __toESM(require("os"), 1);
|
|
872
|
+
|
|
873
|
+
// ../core/src/discovery/parseGitUri.ts
|
|
874
|
+
function isGitRootUri(uri) {
|
|
875
|
+
return /^git\+[a-z]+:\/\//i.test(uri);
|
|
876
|
+
}
|
|
877
|
+
function parseGitUri(uri) {
|
|
878
|
+
if (!isGitRootUri(uri)) {
|
|
879
|
+
throw new CnosDiscoveryError(`Unsupported git root URI: ${uri}`);
|
|
880
|
+
}
|
|
881
|
+
const withoutPrefix = uri.slice("git+".length);
|
|
882
|
+
const hashIndex = withoutPrefix.indexOf("#");
|
|
883
|
+
if (hashIndex < 0) {
|
|
884
|
+
throw new CnosDiscoveryError(
|
|
885
|
+
`Git root URI must include a #ref (tag, branch, or commit). Got: ${uri}`
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
const cloneUrl = withoutPrefix.slice(0, hashIndex);
|
|
889
|
+
const fragment = withoutPrefix.slice(hashIndex + 1);
|
|
890
|
+
const separatorIndex = fragment.indexOf(":");
|
|
891
|
+
const ref = (separatorIndex >= 0 ? fragment.slice(0, separatorIndex) : fragment).trim();
|
|
892
|
+
const subpath = (separatorIndex >= 0 ? fragment.slice(separatorIndex + 1) : ".cnos").trim() || ".cnos";
|
|
893
|
+
const protocol = cloneUrl.slice(0, cloneUrl.indexOf("://"));
|
|
894
|
+
if (!cloneUrl || !ref) {
|
|
895
|
+
throw new CnosDiscoveryError(
|
|
896
|
+
`Git root URI must include both a clone URL and #ref. Got: ${uri}`
|
|
897
|
+
);
|
|
898
|
+
}
|
|
899
|
+
return {
|
|
900
|
+
uri,
|
|
901
|
+
cloneUrl,
|
|
902
|
+
ref,
|
|
903
|
+
subpath,
|
|
904
|
+
transport: protocol === "https" ? "https" : protocol === "ssh" ? "ssh" : protocol === "file" ? "file" : "custom"
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
// ../core/src/discovery/cache/cacheManager.ts
|
|
909
|
+
var SEMVER_TAG_RE = /^v?\d+\.\d+(?:\.\d+)?(?:[-+][A-Za-z0-9.-]+)?$/;
|
|
910
|
+
var COMMIT_SHA_RE = /^[0-9a-f]{40}$/i;
|
|
911
|
+
function isImmutableGitRef(ref) {
|
|
912
|
+
return SEMVER_TAG_RE.test(ref) || COMMIT_SHA_RE.test(ref);
|
|
913
|
+
}
|
|
914
|
+
function resolveRemoteRootCacheTtlSeconds(mode = "runtime", processEnv = process.env, override) {
|
|
915
|
+
if (typeof override === "number" && Number.isFinite(override) && override >= 0) {
|
|
916
|
+
return override;
|
|
917
|
+
}
|
|
918
|
+
const fromEnv = Number(processEnv.CNOS_CACHE_TTL ?? "");
|
|
919
|
+
if (Number.isFinite(fromEnv) && fromEnv >= 0) {
|
|
920
|
+
return fromEnv;
|
|
921
|
+
}
|
|
922
|
+
switch (mode) {
|
|
923
|
+
case "build":
|
|
924
|
+
return 0;
|
|
925
|
+
case "dev":
|
|
926
|
+
return 30;
|
|
927
|
+
case "runtime":
|
|
928
|
+
default:
|
|
929
|
+
return 300;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
function isRemoteRootCacheFresh(metadata, options) {
|
|
933
|
+
if (!metadata || options.forceRefresh) {
|
|
934
|
+
return false;
|
|
935
|
+
}
|
|
936
|
+
if (metadata.uri !== options.uri || metadata.ref !== options.ref) {
|
|
937
|
+
return false;
|
|
938
|
+
}
|
|
939
|
+
if (metadata.isImmutable) {
|
|
940
|
+
return true;
|
|
941
|
+
}
|
|
942
|
+
const ttlSeconds = resolveRemoteRootCacheTtlSeconds(
|
|
943
|
+
options.mode,
|
|
944
|
+
options.processEnv,
|
|
945
|
+
options.ttlSeconds
|
|
946
|
+
);
|
|
947
|
+
if (ttlSeconds <= 0) {
|
|
948
|
+
return false;
|
|
949
|
+
}
|
|
950
|
+
const cachedAtMs = Date.parse(metadata.cachedAt);
|
|
951
|
+
if (Number.isNaN(cachedAtMs)) {
|
|
952
|
+
return false;
|
|
953
|
+
}
|
|
954
|
+
return Date.now() - cachedAtMs <= ttlSeconds * 1e3;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// ../core/src/discovery/cache/cacheMetadata.ts
|
|
958
|
+
var import_promises = require("fs/promises");
|
|
959
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
960
|
+
async function readRemoteRootCacheMetadata(metaPath) {
|
|
961
|
+
try {
|
|
962
|
+
const source = await (0, import_promises.readFile)(metaPath, "utf8");
|
|
963
|
+
const parsed = JSON.parse(source);
|
|
964
|
+
if (!parsed || typeof parsed.uri !== "string" || typeof parsed.cloneUrl !== "string" || typeof parsed.ref !== "string" || typeof parsed.subpath !== "string" || typeof parsed.resolvedCommit !== "string" || typeof parsed.cachedAt !== "string" || typeof parsed.isImmutable !== "boolean") {
|
|
965
|
+
return void 0;
|
|
966
|
+
}
|
|
967
|
+
return parsed;
|
|
968
|
+
} catch {
|
|
969
|
+
return void 0;
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
async function writeRemoteRootCacheMetadata(metaPath, metadata) {
|
|
973
|
+
await (0, import_promises.mkdir)(import_node_path.default.dirname(metaPath), { recursive: true });
|
|
974
|
+
await (0, import_promises.writeFile)(metaPath, `${JSON.stringify(metadata, null, 2)}
|
|
975
|
+
`, "utf8");
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
// ../core/src/discovery/cache/cachePaths.ts
|
|
979
|
+
var import_node_crypto = require("crypto");
|
|
980
|
+
var import_node_os = __toESM(require("os"), 1);
|
|
981
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
982
|
+
function resolveCnosCacheRoot(processEnv = process.env) {
|
|
983
|
+
return import_node_path2.default.resolve(
|
|
984
|
+
expandHomePath(processEnv.CNOS_CACHE_DIR ?? import_node_path2.default.join(import_node_os.default.homedir(), ".cnos", "cache"))
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
function createRemoteRootCacheKey(uri) {
|
|
988
|
+
return (0, import_node_crypto.createHash)("sha256").update(uri).digest("hex");
|
|
989
|
+
}
|
|
990
|
+
function resolveRemoteRootCachePaths(uri, processEnv = process.env) {
|
|
991
|
+
const cacheRoot = resolveCnosCacheRoot(processEnv);
|
|
992
|
+
const cacheDir = import_node_path2.default.join(cacheRoot, "roots", createRemoteRootCacheKey(uri));
|
|
993
|
+
return {
|
|
994
|
+
cacheRoot,
|
|
995
|
+
cacheDir,
|
|
996
|
+
repoDir: import_node_path2.default.join(cacheDir, "repo"),
|
|
997
|
+
metaPath: import_node_path2.default.join(cacheDir, ".cnos-cache-meta.json")
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// ../core/src/discovery/resolveRoot.ts
|
|
1002
|
+
async function pathExists(targetPath) {
|
|
1003
|
+
try {
|
|
1004
|
+
await (0, import_promises2.access)(targetPath);
|
|
1005
|
+
return true;
|
|
1006
|
+
} catch {
|
|
1007
|
+
return false;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
function expandHomePath2(targetPath) {
|
|
1011
|
+
if (targetPath === "~") {
|
|
1012
|
+
return import_node_os2.default.homedir();
|
|
1013
|
+
}
|
|
1014
|
+
if (targetPath.startsWith("~/") || targetPath.startsWith("~\\")) {
|
|
1015
|
+
return import_node_path3.default.join(import_node_os2.default.homedir(), targetPath.slice(2));
|
|
1016
|
+
}
|
|
1017
|
+
return targetPath;
|
|
1018
|
+
}
|
|
1019
|
+
function isLocalRootUri(rootUri) {
|
|
1020
|
+
return !isGitRootUri2(rootUri) && !isCnosHostedRootUri(rootUri);
|
|
1021
|
+
}
|
|
1022
|
+
function isCnosHostedRootUri(rootUri) {
|
|
1023
|
+
return rootUri.startsWith("cnos://");
|
|
1024
|
+
}
|
|
1025
|
+
function isGitRootUri2(rootUri) {
|
|
1026
|
+
return rootUri.startsWith("git+");
|
|
1027
|
+
}
|
|
1028
|
+
async function runGitCommand(args, options = {}) {
|
|
1029
|
+
return new Promise((resolve, reject) => {
|
|
1030
|
+
const child = (0, import_node_child_process4.spawn)("git", args, {
|
|
1031
|
+
cwd: options.cwd,
|
|
1032
|
+
env: options.processEnv ?? process.env,
|
|
1033
|
+
shell: process.platform === "win32",
|
|
1034
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
1035
|
+
});
|
|
1036
|
+
let stdout = "";
|
|
1037
|
+
let stderr = "";
|
|
1038
|
+
child.stdout.on("data", (chunk) => {
|
|
1039
|
+
stdout += chunk.toString();
|
|
1040
|
+
});
|
|
1041
|
+
child.stderr.on("data", (chunk) => {
|
|
1042
|
+
stderr += chunk.toString();
|
|
1043
|
+
});
|
|
1044
|
+
child.on("error", (error) => {
|
|
1045
|
+
reject(
|
|
1046
|
+
new CnosDiscoveryError(
|
|
1047
|
+
`Failed to run git. Make sure git is installed and available on PATH. ${error.message}`
|
|
1048
|
+
)
|
|
1049
|
+
);
|
|
1050
|
+
});
|
|
1051
|
+
child.on("close", (code) => {
|
|
1052
|
+
if (code === 0) {
|
|
1053
|
+
resolve(stdout.trim());
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
const details = stderr.trim() || stdout.trim();
|
|
1057
|
+
reject(
|
|
1058
|
+
new CnosDiscoveryError(
|
|
1059
|
+
details ? `Git command failed: ${details}` : `Git command failed with exit code ${code ?? 1}`
|
|
1060
|
+
)
|
|
1061
|
+
);
|
|
1062
|
+
});
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
async function resolveLocalRoot(rootUri, cnosrcDir) {
|
|
1066
|
+
const candidateRoot = rootUri.startsWith("~") ? expandHomePath2(rootUri) : rootUri;
|
|
1067
|
+
const manifestRoot = import_node_path3.default.resolve(cnosrcDir, candidateRoot);
|
|
1068
|
+
const manifestPath = import_node_path3.default.join(manifestRoot, "cnos.yml");
|
|
1069
|
+
if (!await pathExists(manifestPath)) {
|
|
1070
|
+
throw new CnosDiscoveryError(`.cnosrc.yml points to ${manifestRoot} but no cnos.yml found there.`);
|
|
1071
|
+
}
|
|
1072
|
+
return {
|
|
1073
|
+
manifestRoot,
|
|
1074
|
+
resolution: {
|
|
1075
|
+
rootUri,
|
|
1076
|
+
protocol: "local",
|
|
1077
|
+
remote: false,
|
|
1078
|
+
readOnly: false
|
|
1079
|
+
}
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
async function ensureGitCheckout(parsed, repoDir, processEnv) {
|
|
1083
|
+
const hasRepo = await pathExists(import_node_path3.default.join(repoDir, ".git"));
|
|
1084
|
+
if (!hasRepo) {
|
|
1085
|
+
await (0, import_promises2.mkdir)(import_node_path3.default.dirname(repoDir), { recursive: true });
|
|
1086
|
+
await runGitCommand(["clone", "--no-checkout", parsed.cloneUrl, repoDir], { processEnv });
|
|
1087
|
+
} else {
|
|
1088
|
+
await runGitCommand(["-C", repoDir, "remote", "set-url", "origin", parsed.cloneUrl], {
|
|
1089
|
+
processEnv
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
await runGitCommand(["-C", repoDir, "fetch", "--tags", "--force", "origin"], { processEnv });
|
|
1093
|
+
await runGitCommand(["-C", repoDir, "checkout", "--force", parsed.ref], { processEnv });
|
|
1094
|
+
await runGitCommand(["-C", repoDir, "clean", "-fdx"], { processEnv });
|
|
1095
|
+
}
|
|
1096
|
+
async function resolveGitRoot(rootUri, options = {}) {
|
|
1097
|
+
const processEnv = options.processEnv ?? process.env;
|
|
1098
|
+
const parsed = parseGitUri(rootUri);
|
|
1099
|
+
const cachePaths = resolveRemoteRootCachePaths(rootUri, processEnv);
|
|
1100
|
+
const metadata = await readRemoteRootCacheMetadata(cachePaths.metaPath);
|
|
1101
|
+
const immutable = isImmutableGitRef(parsed.ref);
|
|
1102
|
+
const cacheFresh = isRemoteRootCacheFresh(metadata, {
|
|
1103
|
+
uri: rootUri,
|
|
1104
|
+
ref: parsed.ref,
|
|
1105
|
+
...options.cacheMode ? { mode: options.cacheMode } : {},
|
|
1106
|
+
processEnv,
|
|
1107
|
+
...typeof options.cacheTtlSeconds === "number" ? { ttlSeconds: options.cacheTtlSeconds } : {},
|
|
1108
|
+
...options.forceRefresh ? { forceRefresh: true } : {}
|
|
1109
|
+
});
|
|
1110
|
+
if (!cacheFresh) {
|
|
1111
|
+
try {
|
|
1112
|
+
await ensureGitCheckout(parsed, cachePaths.repoDir, processEnv);
|
|
1113
|
+
} catch (error) {
|
|
1114
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1115
|
+
const authHint = parsed.transport === "ssh" ? " Check your SSH key and git access." : " Check the URL and your git credential helper or token setup.";
|
|
1116
|
+
throw new CnosDiscoveryError(`Failed to resolve remote git root ${rootUri}. ${message}${authHint}`);
|
|
1117
|
+
}
|
|
1118
|
+
const resolvedCommit = await runGitCommand(["-C", cachePaths.repoDir, "rev-parse", "HEAD"], {
|
|
1119
|
+
processEnv
|
|
1120
|
+
});
|
|
1121
|
+
await writeRemoteRootCacheMetadata(cachePaths.metaPath, {
|
|
1122
|
+
uri: rootUri,
|
|
1123
|
+
cloneUrl: parsed.cloneUrl,
|
|
1124
|
+
ref: parsed.ref,
|
|
1125
|
+
subpath: parsed.subpath,
|
|
1126
|
+
resolvedCommit,
|
|
1127
|
+
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1128
|
+
isImmutable: immutable
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
const nextMetadata = metadata && cacheFresh ? metadata : await readRemoteRootCacheMetadata(cachePaths.metaPath);
|
|
1132
|
+
const manifestRoot = import_node_path3.default.join(cachePaths.repoDir, parsed.subpath);
|
|
1133
|
+
if (!await pathExists(import_node_path3.default.join(manifestRoot, "cnos.yml"))) {
|
|
1134
|
+
throw new CnosDiscoveryError(
|
|
1135
|
+
`Git root ${rootUri} resolved to ${manifestRoot} but no cnos.yml was found there. Check the :subpath segment.`
|
|
1136
|
+
);
|
|
1137
|
+
}
|
|
1138
|
+
return {
|
|
1139
|
+
manifestRoot,
|
|
1140
|
+
resolution: {
|
|
1141
|
+
rootUri,
|
|
1142
|
+
protocol: "git",
|
|
1143
|
+
remote: true,
|
|
1144
|
+
readOnly: true,
|
|
1145
|
+
cacheDir: cachePaths.cacheDir,
|
|
1146
|
+
cacheMetaPath: cachePaths.metaPath,
|
|
1147
|
+
ref: parsed.ref,
|
|
1148
|
+
subpath: parsed.subpath,
|
|
1149
|
+
immutable,
|
|
1150
|
+
...nextMetadata?.resolvedCommit ? { resolvedCommit: nextMetadata.resolvedCommit } : {},
|
|
1151
|
+
...nextMetadata?.cachedAt ? { cachedAt: nextMetadata.cachedAt } : {}
|
|
1152
|
+
}
|
|
1153
|
+
};
|
|
1154
|
+
}
|
|
1155
|
+
async function resolveRootUri(rootUri, cnosrcDir, options = {}) {
|
|
1156
|
+
if (isLocalRootUri(rootUri)) {
|
|
1157
|
+
return resolveLocalRoot(rootUri, cnosrcDir);
|
|
1158
|
+
}
|
|
1159
|
+
if (isGitRootUri2(rootUri)) {
|
|
1160
|
+
return resolveGitRoot(rootUri, options);
|
|
1161
|
+
}
|
|
1162
|
+
if (isCnosHostedRootUri(rootUri)) {
|
|
1163
|
+
throw new CnosDiscoveryError(
|
|
1164
|
+
`The cnos:// remote root protocol is reserved but not implemented yet. Use git+https:// or git+ssh:// for now.`
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
throw new CnosDiscoveryError(
|
|
1168
|
+
`Unknown root protocol: ${rootUri}. Supported root protocols are local paths, git+https://..., and git+ssh://....`
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
207
1172
|
// ../core/src/discovery/findCnosrc.ts
|
|
208
1173
|
async function exists(targetPath) {
|
|
209
1174
|
try {
|
|
210
|
-
await (0,
|
|
1175
|
+
await (0, import_promises3.access)(targetPath);
|
|
211
1176
|
return true;
|
|
212
1177
|
} catch {
|
|
213
1178
|
return false;
|
|
@@ -228,13 +1193,13 @@ function validateCnosrc(value, filePath) {
|
|
|
228
1193
|
};
|
|
229
1194
|
}
|
|
230
1195
|
async function findCnosrc(startDir = process.cwd(), maxLevels = 3) {
|
|
231
|
-
let current =
|
|
1196
|
+
let current = import_node_path4.default.resolve(startDir);
|
|
232
1197
|
for (let depth = 0; depth <= maxLevels; depth += 1) {
|
|
233
|
-
const candidate =
|
|
1198
|
+
const candidate = import_node_path4.default.join(current, ".cnosrc.yml");
|
|
234
1199
|
if (await exists(candidate)) {
|
|
235
1200
|
return candidate;
|
|
236
1201
|
}
|
|
237
|
-
const parent =
|
|
1202
|
+
const parent = import_node_path4.default.dirname(current);
|
|
238
1203
|
if (parent === current) {
|
|
239
1204
|
break;
|
|
240
1205
|
}
|
|
@@ -242,27 +1207,22 @@ async function findCnosrc(startDir = process.cwd(), maxLevels = 3) {
|
|
|
242
1207
|
}
|
|
243
1208
|
return void 0;
|
|
244
1209
|
}
|
|
245
|
-
async function discoverCnosAnchor(startDir = process.cwd(), maxLevels = 3) {
|
|
1210
|
+
async function discoverCnosAnchor(startDir = process.cwd(), maxLevels = 3, options = {}) {
|
|
246
1211
|
const anchorPath = await findCnosrc(startDir, maxLevels);
|
|
247
1212
|
if (!anchorPath) {
|
|
248
1213
|
throw new CnosDiscoveryError(
|
|
249
1214
|
"No .cnosrc.yml found. Run cnos init or create .cnosrc.yml in your package root."
|
|
250
1215
|
);
|
|
251
1216
|
}
|
|
252
|
-
const source = await (0,
|
|
1217
|
+
const source = await (0, import_promises3.readFile)(anchorPath, "utf8");
|
|
253
1218
|
const parsed = validateCnosrc(parseYaml(source), anchorPath);
|
|
254
|
-
const consumerRoot =
|
|
255
|
-
const
|
|
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
|
-
}
|
|
1219
|
+
const consumerRoot = import_node_path4.default.dirname(anchorPath);
|
|
1220
|
+
const resolvedRoot = await resolveRootUri(parsed.root, consumerRoot, options);
|
|
262
1221
|
return {
|
|
263
1222
|
anchorPath,
|
|
264
1223
|
consumerRoot,
|
|
265
|
-
manifestRoot,
|
|
1224
|
+
manifestRoot: resolvedRoot.manifestRoot,
|
|
1225
|
+
rootResolution: resolvedRoot.resolution,
|
|
266
1226
|
...parsed.workspace ? { workspace: parsed.workspace } : {}
|
|
267
1227
|
};
|
|
268
1228
|
}
|
|
@@ -272,21 +1232,21 @@ var PRIMARY_CNOS_DIR = ".cnos";
|
|
|
272
1232
|
var LEGACY_CNOS_DIR = "cnos";
|
|
273
1233
|
async function exists2(filePath) {
|
|
274
1234
|
try {
|
|
275
|
-
await (0,
|
|
1235
|
+
await (0, import_promises4.access)(filePath);
|
|
276
1236
|
return true;
|
|
277
1237
|
} catch {
|
|
278
1238
|
return false;
|
|
279
1239
|
}
|
|
280
1240
|
}
|
|
281
1241
|
async function resolveCnosRoot(root = process.cwd()) {
|
|
282
|
-
const basePath =
|
|
1242
|
+
const basePath = import_node_path5.default.resolve(root);
|
|
283
1243
|
const candidates = [
|
|
284
|
-
|
|
285
|
-
|
|
1244
|
+
import_node_path5.default.join(basePath, PRIMARY_CNOS_DIR),
|
|
1245
|
+
import_node_path5.default.join(basePath, LEGACY_CNOS_DIR),
|
|
286
1246
|
basePath
|
|
287
1247
|
];
|
|
288
1248
|
for (const candidate of candidates) {
|
|
289
|
-
if (await exists2(
|
|
1249
|
+
if (await exists2(import_node_path5.default.join(candidate, "cnos.yml"))) {
|
|
290
1250
|
return candidate;
|
|
291
1251
|
}
|
|
292
1252
|
}
|
|
@@ -296,18 +1256,44 @@ async function resolveCnosRoot(root = process.cwd()) {
|
|
|
296
1256
|
}
|
|
297
1257
|
async function resolveManifestRoot(options = {}) {
|
|
298
1258
|
if (options.root) {
|
|
1259
|
+
if (options.root.startsWith("git+") || options.root.startsWith("cnos://")) {
|
|
1260
|
+
const consumerRoot2 = import_node_path5.default.resolve(options.cwd ?? process.cwd());
|
|
1261
|
+
const resolvedRoot2 = await resolveRootUri(options.root, consumerRoot2, {
|
|
1262
|
+
...options.processEnv ? { processEnv: options.processEnv } : {},
|
|
1263
|
+
...options.cacheMode ? { cacheMode: options.cacheMode } : {},
|
|
1264
|
+
...typeof options.cacheTtlSeconds === "number" ? { cacheTtlSeconds: options.cacheTtlSeconds } : {},
|
|
1265
|
+
...options.forceRefresh ? { forceRefresh: true } : {}
|
|
1266
|
+
});
|
|
1267
|
+
return {
|
|
1268
|
+
manifestRoot: resolvedRoot2.manifestRoot,
|
|
1269
|
+
consumerRoot: consumerRoot2,
|
|
1270
|
+
rootResolution: resolvedRoot2.resolution
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
299
1273
|
const manifestRoot = await resolveCnosRoot(options.root);
|
|
300
|
-
const resolvedRoot =
|
|
301
|
-
const consumerRoot =
|
|
1274
|
+
const resolvedRoot = import_node_path5.default.resolve(options.root);
|
|
1275
|
+
const consumerRoot = import_node_path5.default.basename(manifestRoot) === PRIMARY_CNOS_DIR || import_node_path5.default.basename(manifestRoot) === LEGACY_CNOS_DIR ? import_node_path5.default.dirname(manifestRoot) : resolvedRoot;
|
|
302
1276
|
return {
|
|
303
1277
|
manifestRoot,
|
|
304
|
-
consumerRoot
|
|
1278
|
+
consumerRoot,
|
|
1279
|
+
rootResolution: {
|
|
1280
|
+
rootUri: manifestRoot,
|
|
1281
|
+
protocol: "local",
|
|
1282
|
+
remote: false,
|
|
1283
|
+
readOnly: false
|
|
1284
|
+
}
|
|
305
1285
|
};
|
|
306
1286
|
}
|
|
307
|
-
const discovered = await discoverCnosAnchor(options.cwd ?? process.cwd()
|
|
1287
|
+
const discovered = await discoverCnosAnchor(options.cwd ?? process.cwd(), 3, {
|
|
1288
|
+
...options.processEnv ? { processEnv: options.processEnv } : {},
|
|
1289
|
+
...options.cacheMode ? { cacheMode: options.cacheMode } : {},
|
|
1290
|
+
...typeof options.cacheTtlSeconds === "number" ? { cacheTtlSeconds: options.cacheTtlSeconds } : {},
|
|
1291
|
+
...options.forceRefresh ? { forceRefresh: true } : {}
|
|
1292
|
+
});
|
|
308
1293
|
return {
|
|
309
1294
|
manifestRoot: discovered.manifestRoot,
|
|
310
1295
|
consumerRoot: discovered.consumerRoot,
|
|
1296
|
+
rootResolution: discovered.rootResolution,
|
|
311
1297
|
anchorPath: discovered.anchorPath,
|
|
312
1298
|
...discovered.workspace ? { workspace: discovered.workspace } : {}
|
|
313
1299
|
};
|
|
@@ -320,10 +1306,10 @@ function interpolatePathTemplate(template, tokens) {
|
|
|
320
1306
|
}
|
|
321
1307
|
function expandHomePath(targetPath) {
|
|
322
1308
|
if (targetPath === "~") {
|
|
323
|
-
return
|
|
1309
|
+
return import_node_os3.default.homedir();
|
|
324
1310
|
}
|
|
325
1311
|
if (targetPath.startsWith("~/") || targetPath.startsWith("~\\")) {
|
|
326
|
-
return
|
|
1312
|
+
return import_node_path5.default.join(import_node_os3.default.homedir(), targetPath.slice(2));
|
|
327
1313
|
}
|
|
328
1314
|
return targetPath;
|
|
329
1315
|
}
|
|
@@ -341,7 +1327,7 @@ function stripWorkspaceTemplatePrefix(template) {
|
|
|
341
1327
|
function resolveWorkspaceScopedPath(workspaceRoot, template, tokens) {
|
|
342
1328
|
const relativeTemplate = stripWorkspaceTemplatePrefix(template);
|
|
343
1329
|
const interpolated = interpolatePathTemplate(relativeTemplate, tokens);
|
|
344
|
-
return
|
|
1330
|
+
return import_node_path5.default.resolve(workspaceRoot, interpolated);
|
|
345
1331
|
}
|
|
346
1332
|
function toPortablePath(targetPath) {
|
|
347
1333
|
return targetPath.replace(/\\/g, "/");
|
|
@@ -407,6 +1393,13 @@ var DEFAULT_NAMESPACES = {
|
|
|
407
1393
|
readonly: true
|
|
408
1394
|
}
|
|
409
1395
|
};
|
|
1396
|
+
var DEFAULT_RUNTIME_NAMESPACES = {
|
|
1397
|
+
process: {
|
|
1398
|
+
description: "Live process runtime values.",
|
|
1399
|
+
serverOnly: true,
|
|
1400
|
+
builtIn: true
|
|
1401
|
+
}
|
|
1402
|
+
};
|
|
410
1403
|
function validateResolveFrom(resolveFrom) {
|
|
411
1404
|
const validValues = ["cli.profile", "env.CNOS_PROFILE", "default"];
|
|
412
1405
|
for (const entry of resolveFrom) {
|
|
@@ -429,7 +1422,7 @@ function normalizeWorkspaceItems(items) {
|
|
|
429
1422
|
}
|
|
430
1423
|
function normalizeNamespaces(namespaces) {
|
|
431
1424
|
const normalized = Object.fromEntries(
|
|
432
|
-
Object.entries(namespaces ?? {}).map(([namespace, definition]) => [
|
|
1425
|
+
Object.entries(namespaces ?? {}).filter(([namespace]) => namespace !== "runtime").map(([namespace, definition]) => [
|
|
433
1426
|
namespace,
|
|
434
1427
|
{
|
|
435
1428
|
kind: definition.kind ?? "data",
|
|
@@ -445,6 +1438,29 @@ function normalizeNamespaces(namespaces) {
|
|
|
445
1438
|
...normalized
|
|
446
1439
|
};
|
|
447
1440
|
}
|
|
1441
|
+
function normalizeRuntimeNamespaces(namespaces) {
|
|
1442
|
+
const runtimeEntries = namespaces?.runtime ?? {};
|
|
1443
|
+
const normalized = Object.fromEntries(
|
|
1444
|
+
Object.entries(runtimeEntries).map(([namespace, definition]) => [
|
|
1445
|
+
namespace,
|
|
1446
|
+
{
|
|
1447
|
+
...definition.description?.trim() ? {
|
|
1448
|
+
description: definition.description.trim()
|
|
1449
|
+
} : {},
|
|
1450
|
+
serverOnly: definition.server_only ?? true
|
|
1451
|
+
}
|
|
1452
|
+
])
|
|
1453
|
+
);
|
|
1454
|
+
for (const namespace of Object.keys(normalized)) {
|
|
1455
|
+
if (DEFAULT_NAMESPACES[namespace] || namespace === "runtime") {
|
|
1456
|
+
throw new CnosManifestError(`Runtime namespace "${namespace}" conflicts with a built-in or reserved namespace.`);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
return {
|
|
1460
|
+
...DEFAULT_RUNTIME_NAMESPACES,
|
|
1461
|
+
...normalized
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
448
1464
|
function normalizeVaults(vaults) {
|
|
449
1465
|
return Object.fromEntries(
|
|
450
1466
|
Object.entries(vaults ?? {}).map(([name, definition]) => {
|
|
@@ -536,6 +1552,7 @@ function normalizeManifest(manifest) {
|
|
|
536
1552
|
const defaultProfile = manifest.profiles?.default?.trim() || "base";
|
|
537
1553
|
const workspaceItems = normalizeWorkspaceItems(manifest.workspaces?.items);
|
|
538
1554
|
const resolveFrom = validateResolveFrom(manifest.profiles?.resolveFrom ?? DEFAULT_RESOLVE_FROM);
|
|
1555
|
+
const runtimeNamespaces = normalizeRuntimeNamespaces(manifest.namespaces);
|
|
539
1556
|
const filesystemValues = {
|
|
540
1557
|
root: "./",
|
|
541
1558
|
format: "yaml",
|
|
@@ -609,6 +1626,7 @@ function normalizeManifest(manifest) {
|
|
|
609
1626
|
}
|
|
610
1627
|
},
|
|
611
1628
|
namespaces: normalizeNamespaces(manifest.namespaces),
|
|
1629
|
+
runtimeNamespaces,
|
|
612
1630
|
vaults: normalizeVaults(manifest.vaults),
|
|
613
1631
|
writePolicy: {
|
|
614
1632
|
define: {
|
|
@@ -627,13 +1645,17 @@ function normalizeManifest(manifest) {
|
|
|
627
1645
|
async function loadManifest(options = {}) {
|
|
628
1646
|
const resolved = await resolveManifestRoot({
|
|
629
1647
|
...options.root ? { root: options.root } : {},
|
|
630
|
-
...options.cwd ? { cwd: options.cwd } : {}
|
|
1648
|
+
...options.cwd ? { cwd: options.cwd } : {},
|
|
1649
|
+
...options.processEnv ? { processEnv: options.processEnv } : {},
|
|
1650
|
+
...options.cacheMode ? { cacheMode: options.cacheMode } : {},
|
|
1651
|
+
...typeof options.cacheTtlSeconds === "number" ? { cacheTtlSeconds: options.cacheTtlSeconds } : {},
|
|
1652
|
+
...options.forceRefresh ? { forceRefresh: true } : {}
|
|
631
1653
|
});
|
|
632
1654
|
const manifestRoot = resolved.manifestRoot;
|
|
633
|
-
const manifestPath =
|
|
1655
|
+
const manifestPath = import_node_path6.default.join(manifestRoot, "cnos.yml");
|
|
634
1656
|
let source;
|
|
635
1657
|
try {
|
|
636
|
-
source = await (0,
|
|
1658
|
+
source = await (0, import_promises5.readFile)(manifestPath, "utf8");
|
|
637
1659
|
} catch {
|
|
638
1660
|
throw new CnosManifestError("Unable to read CNOS manifest", manifestPath);
|
|
639
1661
|
}
|
|
@@ -643,10 +1665,11 @@ async function loadManifest(options = {}) {
|
|
|
643
1665
|
}
|
|
644
1666
|
return {
|
|
645
1667
|
manifestRoot,
|
|
646
|
-
repoRoot:
|
|
1668
|
+
repoRoot: import_node_path6.default.dirname(manifestRoot),
|
|
647
1669
|
consumerRoot: resolved.consumerRoot,
|
|
648
1670
|
...resolved.anchorPath ? { anchorPath: resolved.anchorPath } : {},
|
|
649
1671
|
...resolved.workspace ? { anchoredWorkspace: resolved.workspace } : {},
|
|
1672
|
+
rootResolution: resolved.rootResolution,
|
|
650
1673
|
manifestPath,
|
|
651
1674
|
manifest: normalizeManifest(rawManifest),
|
|
652
1675
|
rawManifest
|
|
@@ -654,12 +1677,12 @@ async function loadManifest(options = {}) {
|
|
|
654
1677
|
}
|
|
655
1678
|
|
|
656
1679
|
// ../core/src/manifest/loadWorkspaceFile.ts
|
|
657
|
-
var
|
|
658
|
-
var
|
|
1680
|
+
var import_promises6 = require("fs/promises");
|
|
1681
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
659
1682
|
async function loadWorkspaceFile(repoRoot) {
|
|
660
|
-
const workspaceFilePath =
|
|
1683
|
+
const workspaceFilePath = import_node_path7.default.join(repoRoot, ".cnos-workspace.yml");
|
|
661
1684
|
try {
|
|
662
|
-
const source = await (0,
|
|
1685
|
+
const source = await (0, import_promises6.readFile)(workspaceFilePath, "utf8");
|
|
663
1686
|
const parsed = parseYaml(source);
|
|
664
1687
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
665
1688
|
throw new CnosManifestError(".cnos-workspace.yml must be a YAML object", workspaceFilePath);
|
|
@@ -682,11 +1705,11 @@ async function loadWorkspaceFile(repoRoot) {
|
|
|
682
1705
|
}
|
|
683
1706
|
|
|
684
1707
|
// ../core/src/profiles/expandProfileChain.ts
|
|
685
|
-
var
|
|
686
|
-
var
|
|
1708
|
+
var import_promises7 = require("fs/promises");
|
|
1709
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
687
1710
|
async function fileExists(targetPath) {
|
|
688
1711
|
try {
|
|
689
|
-
await (0,
|
|
1712
|
+
await (0, import_promises7.access)(targetPath);
|
|
690
1713
|
return true;
|
|
691
1714
|
} catch {
|
|
692
1715
|
return false;
|
|
@@ -720,11 +1743,11 @@ async function loadProfileDefinition(profileName, options) {
|
|
|
720
1743
|
return normalizeProfileDefinition(profileName, void 0);
|
|
721
1744
|
}
|
|
722
1745
|
for (const workspaceRoot of [...workspaceRoots].reverse()) {
|
|
723
|
-
const profilePath =
|
|
1746
|
+
const profilePath = import_node_path8.default.join(workspaceRoot.path, "profiles", `${profileName}.yml`);
|
|
724
1747
|
if (!await fileExists(profilePath)) {
|
|
725
1748
|
continue;
|
|
726
1749
|
}
|
|
727
|
-
const document = await (0,
|
|
1750
|
+
const document = await (0, import_promises7.readFile)(profilePath, "utf8");
|
|
728
1751
|
const parsed = parseYaml(document);
|
|
729
1752
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
730
1753
|
throw new CnosManifestError("Profile definition must be a YAML object", profilePath);
|
|
@@ -732,7 +1755,7 @@ async function loadProfileDefinition(profileName, options) {
|
|
|
732
1755
|
const definition = normalizeProfileDefinition(
|
|
733
1756
|
profileName,
|
|
734
1757
|
parsed,
|
|
735
|
-
options.manifestRoot ? toPortablePath(
|
|
1758
|
+
options.manifestRoot ? toPortablePath(import_node_path8.default.relative(import_node_path8.default.dirname(options.manifestRoot), profilePath)) : toPortablePath(profilePath)
|
|
736
1759
|
);
|
|
737
1760
|
if (definition.name !== profileName) {
|
|
738
1761
|
throw new CnosManifestError(
|
|
@@ -1014,8 +2037,8 @@ function createProfileAwareResolver() {
|
|
|
1014
2037
|
}
|
|
1015
2038
|
|
|
1016
2039
|
// ../core/src/workspaces/resolveWorkspaceContext.ts
|
|
1017
|
-
var
|
|
1018
|
-
var
|
|
2040
|
+
var import_promises8 = require("fs/promises");
|
|
2041
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
1019
2042
|
|
|
1020
2043
|
// ../core/src/workspaces/expandWorkspaceChain.ts
|
|
1021
2044
|
function expandWorkspaceChain(workspaceId, items) {
|
|
@@ -1054,14 +2077,14 @@ function expandWorkspaceChain(workspaceId, items) {
|
|
|
1054
2077
|
// ../core/src/workspaces/resolveWorkspaceContext.ts
|
|
1055
2078
|
async function exists3(targetPath) {
|
|
1056
2079
|
try {
|
|
1057
|
-
await (0,
|
|
2080
|
+
await (0, import_promises8.access)(targetPath);
|
|
1058
2081
|
return true;
|
|
1059
2082
|
} catch {
|
|
1060
2083
|
return false;
|
|
1061
2084
|
}
|
|
1062
2085
|
}
|
|
1063
2086
|
async function resolveLocalWorkspaceRoot(manifestRoot, workspaceId, manifest) {
|
|
1064
|
-
const workspaceRoot =
|
|
2087
|
+
const workspaceRoot = import_node_path9.default.join(manifestRoot, "workspaces", workspaceId);
|
|
1065
2088
|
if (await exists3(workspaceRoot)) {
|
|
1066
2089
|
return workspaceRoot;
|
|
1067
2090
|
}
|
|
@@ -1069,7 +2092,7 @@ async function resolveLocalWorkspaceRoot(manifestRoot, workspaceId, manifest) {
|
|
|
1069
2092
|
([namespace, definition]) => namespace !== "value" && namespace !== "secret" && definition.kind === "data" && !definition.sensitive
|
|
1070
2093
|
).map(([namespace]) => namespace);
|
|
1071
2094
|
const legacyMarkers = ["values", "secrets", "env", "profiles", ...customDataNamespaceRoots].map(
|
|
1072
|
-
(segment) =>
|
|
2095
|
+
(segment) => import_node_path9.default.join(manifestRoot, segment)
|
|
1073
2096
|
);
|
|
1074
2097
|
if ((await Promise.all(legacyMarkers.map((marker) => exists3(marker)))).some(Boolean)) {
|
|
1075
2098
|
return manifestRoot;
|
|
@@ -1117,26 +2140,26 @@ function resolveGlobalRoot(manifest, workspaceFile, options) {
|
|
|
1117
2140
|
}
|
|
1118
2141
|
if (options.globalRoot) {
|
|
1119
2142
|
return {
|
|
1120
|
-
value:
|
|
2143
|
+
value: import_node_path9.default.resolve(expandHomePath(options.globalRoot)),
|
|
1121
2144
|
source: "cli"
|
|
1122
2145
|
};
|
|
1123
2146
|
}
|
|
1124
2147
|
if (workspaceFile?.globalRoot) {
|
|
1125
2148
|
return {
|
|
1126
|
-
value:
|
|
2149
|
+
value: import_node_path9.default.resolve(expandHomePath(workspaceFile.globalRoot)),
|
|
1127
2150
|
source: "workspace-file"
|
|
1128
2151
|
};
|
|
1129
2152
|
}
|
|
1130
2153
|
if (manifest.workspaces.global.root) {
|
|
1131
2154
|
return {
|
|
1132
|
-
value:
|
|
2155
|
+
value: import_node_path9.default.resolve(expandHomePath(manifest.workspaces.global.root)),
|
|
1133
2156
|
source: "manifest"
|
|
1134
2157
|
};
|
|
1135
2158
|
}
|
|
1136
2159
|
const cnosHome = options.processEnv?.CNOS_HOME;
|
|
1137
2160
|
if (cnosHome) {
|
|
1138
2161
|
return {
|
|
1139
|
-
value:
|
|
2162
|
+
value: import_node_path9.default.resolve(expandHomePath(cnosHome)),
|
|
1140
2163
|
source: "CNOS_HOME"
|
|
1141
2164
|
};
|
|
1142
2165
|
}
|
|
@@ -1158,7 +2181,7 @@ async function resolveWorkspaceContext(manifest, options) {
|
|
|
1158
2181
|
workspaceRoots.push({
|
|
1159
2182
|
scope: "global",
|
|
1160
2183
|
workspaceId: chainWorkspaceId,
|
|
1161
|
-
path:
|
|
2184
|
+
path: import_node_path9.default.join(globalRoot.value, "workspaces", globalWorkspaceId)
|
|
1162
2185
|
});
|
|
1163
2186
|
}
|
|
1164
2187
|
}
|
|
@@ -1281,6 +2304,10 @@ function applySchemaRules(graph, schema) {
|
|
|
1281
2304
|
}
|
|
1282
2305
|
continue;
|
|
1283
2306
|
}
|
|
2307
|
+
if (isDerivedValue(resolvedEntry.value)) {
|
|
2308
|
+
nextEntries.set(key, resolvedEntry);
|
|
2309
|
+
continue;
|
|
2310
|
+
}
|
|
1284
2311
|
const coercedValue = coerceValue(resolvedEntry.value, rule);
|
|
1285
2312
|
const nextResolvedEntry = coercedValue === resolvedEntry.value ? resolvedEntry : {
|
|
1286
2313
|
...resolvedEntry,
|
|
@@ -1350,26 +2377,26 @@ async function runPipeline(options) {
|
|
|
1350
2377
|
}
|
|
1351
2378
|
|
|
1352
2379
|
// ../core/src/secrets/auditLog.ts
|
|
1353
|
-
var
|
|
1354
|
-
var
|
|
2380
|
+
var import_promises11 = require("fs/promises");
|
|
2381
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
1355
2382
|
|
|
1356
2383
|
// ../core/src/utils/secretStore.ts
|
|
1357
|
-
var
|
|
1358
|
-
var
|
|
1359
|
-
var
|
|
2384
|
+
var import_node_crypto2 = require("crypto");
|
|
2385
|
+
var import_promises10 = require("fs/promises");
|
|
2386
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
1360
2387
|
|
|
1361
2388
|
// ../core/src/secrets/sessionStore.ts
|
|
1362
|
-
var
|
|
1363
|
-
var
|
|
2389
|
+
var import_promises9 = require("fs/promises");
|
|
2390
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
1364
2391
|
function buildSessionRoot(processEnv = process.env) {
|
|
1365
|
-
return
|
|
2392
|
+
return import_node_path10.default.join(import_node_path10.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets")), "sessions");
|
|
1366
2393
|
}
|
|
1367
2394
|
function buildSessionPath(vault, processEnv) {
|
|
1368
|
-
return
|
|
2395
|
+
return import_node_path10.default.join(buildSessionRoot(processEnv), `${vault}.json`);
|
|
1369
2396
|
}
|
|
1370
2397
|
async function readVaultSessionKey(vault, processEnv) {
|
|
1371
2398
|
try {
|
|
1372
|
-
const source = await (0,
|
|
2399
|
+
const source = await (0, import_promises9.readFile)(buildSessionPath(vault, processEnv), "utf8");
|
|
1373
2400
|
const document = JSON.parse(source);
|
|
1374
2401
|
if (document.version !== 1 || typeof document.derivedKey !== "string") {
|
|
1375
2402
|
return void 0;
|
|
@@ -1398,7 +2425,7 @@ function isSecretReference(value) {
|
|
|
1398
2425
|
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));
|
|
1399
2426
|
}
|
|
1400
2427
|
function resolveSecretStoreRoot(processEnv = process.env) {
|
|
1401
|
-
return
|
|
2428
|
+
return import_node_path11.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
|
|
1402
2429
|
}
|
|
1403
2430
|
function normalizeVaultToken(vault = "default") {
|
|
1404
2431
|
return vault.replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
|
|
@@ -1427,19 +2454,19 @@ function resolveVaultSessionKey(vault = "default", processEnv = process.env) {
|
|
|
1427
2454
|
}
|
|
1428
2455
|
}
|
|
1429
2456
|
function deriveVaultKey(passphrase, salt, iterations = PBKDF2_ITERATIONS) {
|
|
1430
|
-
return (0,
|
|
2457
|
+
return (0, import_node_crypto2.pbkdf2Sync)(passphrase, salt, iterations, KEY_LENGTH, "sha512");
|
|
1431
2458
|
}
|
|
1432
2459
|
function buildMetaPath(storeRoot, vault = "default") {
|
|
1433
|
-
return
|
|
2460
|
+
return import_node_path11.default.join(storeRoot, "vaults", vault, META_FILENAME);
|
|
1434
2461
|
}
|
|
1435
2462
|
function buildKeystorePath(storeRoot, vault = "default") {
|
|
1436
|
-
return
|
|
2463
|
+
return import_node_path11.default.join(storeRoot, "vaults", vault, KEYSTORE_FILENAME);
|
|
1437
2464
|
}
|
|
1438
2465
|
function buildLegacyVaultFile(storeRoot, vault = "default") {
|
|
1439
|
-
return
|
|
2466
|
+
return import_node_path11.default.join(storeRoot, "vaults", `${vault}.json`);
|
|
1440
2467
|
}
|
|
1441
2468
|
function buildLegacyVaultStoreRoot(storeRoot, vault = "default") {
|
|
1442
|
-
return
|
|
2469
|
+
return import_node_path11.default.join(storeRoot, "vaults", vault, "store");
|
|
1443
2470
|
}
|
|
1444
2471
|
function assertVaultMetadata(value, filePath) {
|
|
1445
2472
|
if (!isObject(value)) {
|
|
@@ -1452,7 +2479,7 @@ function assertVaultMetadata(value, filePath) {
|
|
|
1452
2479
|
}
|
|
1453
2480
|
async function exists4(targetPath) {
|
|
1454
2481
|
try {
|
|
1455
|
-
await (0,
|
|
2482
|
+
await (0, import_promises10.stat)(targetPath);
|
|
1456
2483
|
return true;
|
|
1457
2484
|
} catch {
|
|
1458
2485
|
return false;
|
|
@@ -1479,8 +2506,8 @@ async function assertNoLegacyVaultFormat(storeRoot, vault = "default") {
|
|
|
1479
2506
|
);
|
|
1480
2507
|
}
|
|
1481
2508
|
function encryptPayload(payload, key) {
|
|
1482
|
-
const iv = (0,
|
|
1483
|
-
const cipher = (0,
|
|
2509
|
+
const iv = (0, import_node_crypto2.randomBytes)(IV_LENGTH);
|
|
2510
|
+
const cipher = (0, import_node_crypto2.createCipheriv)("aes-256-gcm", key, iv);
|
|
1484
2511
|
const plaintext = Buffer.from(JSON.stringify(payload), "utf8");
|
|
1485
2512
|
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
1486
2513
|
const tag = cipher.getAuthTag();
|
|
@@ -1505,7 +2532,7 @@ function decryptPayload(buffer, key) {
|
|
|
1505
2532
|
const iv = buffer.subarray(ivOffset, tagOffset);
|
|
1506
2533
|
const tag = buffer.subarray(tagOffset, cipherOffset);
|
|
1507
2534
|
const ciphertext = buffer.subarray(cipherOffset);
|
|
1508
|
-
const decipher = (0,
|
|
2535
|
+
const decipher = (0, import_node_crypto2.createDecipheriv)("aes-256-gcm", key, iv);
|
|
1509
2536
|
decipher.setAuthTag(tag);
|
|
1510
2537
|
try {
|
|
1511
2538
|
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
@@ -1536,15 +2563,15 @@ function buildInitialPayload() {
|
|
|
1536
2563
|
async function writeVaultFiles(storeRoot, vault, meta, payload, key) {
|
|
1537
2564
|
const metaPath = buildMetaPath(storeRoot, vault);
|
|
1538
2565
|
const keystorePath = buildKeystorePath(storeRoot, vault);
|
|
1539
|
-
await (0,
|
|
1540
|
-
await (0,
|
|
1541
|
-
await (0,
|
|
2566
|
+
await (0, import_promises10.mkdir)(import_node_path11.default.dirname(metaPath), { recursive: true });
|
|
2567
|
+
await (0, import_promises10.writeFile)(metaPath, stringifyYaml(meta), "utf8");
|
|
2568
|
+
await (0, import_promises10.writeFile)(keystorePath, encryptPayload(payload, key));
|
|
1542
2569
|
}
|
|
1543
2570
|
async function readVaultMetadata(storeRoot, vault = "default") {
|
|
1544
2571
|
await assertNoLegacyVaultFormat(storeRoot, vault);
|
|
1545
2572
|
const metaPath = buildMetaPath(storeRoot, vault);
|
|
1546
2573
|
try {
|
|
1547
|
-
const source = await (0,
|
|
2574
|
+
const source = await (0, import_promises10.readFile)(metaPath, "utf8");
|
|
1548
2575
|
return assertVaultMetadata(parseYaml(source), metaPath);
|
|
1549
2576
|
} catch (error) {
|
|
1550
2577
|
if (error.code === "ENOENT") {
|
|
@@ -1556,7 +2583,7 @@ async function readVaultMetadata(storeRoot, vault = "default") {
|
|
|
1556
2583
|
async function createSecretVault(storeRoot, vault, passphrase) {
|
|
1557
2584
|
const normalizedVault = vault.trim() || "default";
|
|
1558
2585
|
await assertNoLegacyVaultFormat(storeRoot, normalizedVault);
|
|
1559
|
-
const salt = (0,
|
|
2586
|
+
const salt = (0, import_node_crypto2.randomBytes)(SALT_LENGTH);
|
|
1560
2587
|
const key = deriveVaultKey(passphrase, salt, PBKDF2_ITERATIONS);
|
|
1561
2588
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1562
2589
|
const meta = {
|
|
@@ -1635,7 +2662,7 @@ async function loadVaultPayload(storeRoot, vault, auth) {
|
|
|
1635
2662
|
if (!key) {
|
|
1636
2663
|
throw new CnosAuthenticationError(`Vault "${vault}" requires authentication before access.`);
|
|
1637
2664
|
}
|
|
1638
|
-
const buffer = await (0,
|
|
2665
|
+
const buffer = await (0, import_promises10.readFile)(buildKeystorePath(storeRoot, vault));
|
|
1639
2666
|
return {
|
|
1640
2667
|
meta,
|
|
1641
2668
|
payload: decryptPayload(buffer, key),
|
|
@@ -1710,9 +2737,9 @@ function resolveVaultDefinition(vaults, vault = "default") {
|
|
|
1710
2737
|
|
|
1711
2738
|
// ../core/src/secrets/auditLog.ts
|
|
1712
2739
|
async function appendAuditEvent(event, processEnv = process.env) {
|
|
1713
|
-
const auditFile = processEnv.CNOS_AUDIT_FILE ??
|
|
1714
|
-
await (0,
|
|
1715
|
-
await (0,
|
|
2740
|
+
const auditFile = processEnv.CNOS_AUDIT_FILE ?? import_node_path12.default.join(resolveSecretStoreRoot(processEnv), "audit", "access.log");
|
|
2741
|
+
await (0, import_promises11.mkdir)(import_node_path12.default.dirname(auditFile), { recursive: true });
|
|
2742
|
+
await (0, import_promises11.appendFile)(
|
|
1716
2743
|
auditFile,
|
|
1717
2744
|
`${JSON.stringify({
|
|
1718
2745
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -2070,7 +3097,7 @@ function setNestedValue(target, pathSegments, value) {
|
|
|
2070
3097
|
target[head] = nextTarget;
|
|
2071
3098
|
setNestedValue(nextTarget, tail, value);
|
|
2072
3099
|
}
|
|
2073
|
-
function toNamespaceObject(graph, namespace) {
|
|
3100
|
+
function toNamespaceObject(graph, namespace, readValueForKey = (key) => graph.entries.get(key)?.value) {
|
|
2074
3101
|
const output = {};
|
|
2075
3102
|
const resolvedEntries = Array.from(graph.entries.values()).sort(
|
|
2076
3103
|
(left, right) => left.key.localeCompare(right.key)
|
|
@@ -2080,7 +3107,11 @@ function toNamespaceObject(graph, namespace) {
|
|
|
2080
3107
|
continue;
|
|
2081
3108
|
}
|
|
2082
3109
|
const valuePath = namespace ? stripNamespace(entry.key) : entry.key;
|
|
2083
|
-
|
|
3110
|
+
const value = readValueForKey(entry.key);
|
|
3111
|
+
if (value === void 0) {
|
|
3112
|
+
continue;
|
|
3113
|
+
}
|
|
3114
|
+
setNestedValue(output, valuePath.split("."), value);
|
|
2084
3115
|
}
|
|
2085
3116
|
return output;
|
|
2086
3117
|
}
|
|
@@ -2090,12 +3121,6 @@ function readValue(graph, key) {
|
|
|
2090
3121
|
return graph.entries.get(key)?.value;
|
|
2091
3122
|
}
|
|
2092
3123
|
|
|
2093
|
-
// ../core/src/runtime/readOr.ts
|
|
2094
|
-
function readOrValue(graph, key, fallback) {
|
|
2095
|
-
const value = readValue(graph, key);
|
|
2096
|
-
return value === void 0 ? fallback : value;
|
|
2097
|
-
}
|
|
2098
|
-
|
|
2099
3124
|
// ../core/src/runtime/require.ts
|
|
2100
3125
|
function requireValue(graph, key) {
|
|
2101
3126
|
const value = readValue(graph, key);
|
|
@@ -2105,8 +3130,38 @@ function requireValue(graph, key) {
|
|
|
2105
3130
|
return value;
|
|
2106
3131
|
}
|
|
2107
3132
|
|
|
3133
|
+
// ../core/src/runtime/runtimeProviders.ts
|
|
3134
|
+
function createDefaultRuntimeProviders(manifest, processEnv) {
|
|
3135
|
+
const providers = /* @__PURE__ */ new Map();
|
|
3136
|
+
if (manifest.runtimeNamespaces.process) {
|
|
3137
|
+
providers.set("process", (key) => {
|
|
3138
|
+
const segments = key.split(".");
|
|
3139
|
+
if (segments[0] === "env") {
|
|
3140
|
+
return processEnv[segments.slice(1).join(".")];
|
|
3141
|
+
}
|
|
3142
|
+
if (key === "cwd") {
|
|
3143
|
+
return process.cwd();
|
|
3144
|
+
}
|
|
3145
|
+
if (key === "platform") {
|
|
3146
|
+
return process.platform;
|
|
3147
|
+
}
|
|
3148
|
+
if (key === "arch") {
|
|
3149
|
+
return process.arch;
|
|
3150
|
+
}
|
|
3151
|
+
if (key === "pid") {
|
|
3152
|
+
return process.pid;
|
|
3153
|
+
}
|
|
3154
|
+
if (key === "node.version") {
|
|
3155
|
+
return process.version;
|
|
3156
|
+
}
|
|
3157
|
+
return void 0;
|
|
3158
|
+
});
|
|
3159
|
+
}
|
|
3160
|
+
return providers;
|
|
3161
|
+
}
|
|
3162
|
+
|
|
2108
3163
|
// ../core/src/runtime/toServerProjection.ts
|
|
2109
|
-
var
|
|
3164
|
+
var import_node_crypto3 = require("crypto");
|
|
2110
3165
|
function stableSortObject(value) {
|
|
2111
3166
|
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)));
|
|
2112
3167
|
}
|
|
@@ -2115,12 +3170,14 @@ function stripValuePrefix(key) {
|
|
|
2115
3170
|
}
|
|
2116
3171
|
function configHash(values) {
|
|
2117
3172
|
const serialized = JSON.stringify(stableSortObject(values));
|
|
2118
|
-
return (0,
|
|
3173
|
+
return (0, import_node_crypto3.createHash)("sha256").update(serialized).digest("hex");
|
|
2119
3174
|
}
|
|
2120
|
-
function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev") {
|
|
3175
|
+
function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev", helpers = {}) {
|
|
2121
3176
|
const values = {};
|
|
3177
|
+
const derived = {};
|
|
2122
3178
|
const secretRefs = {};
|
|
2123
3179
|
const namespaces = /* @__PURE__ */ new Set();
|
|
3180
|
+
const runtimeNamespaces = /* @__PURE__ */ new Set();
|
|
2124
3181
|
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
3182
|
for (const [key, entry] of graph.entries) {
|
|
2126
3183
|
if (entry.namespace === "secret" && isSecretReference(entry.value)) {
|
|
@@ -2132,12 +3189,33 @@ function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev") {
|
|
|
2132
3189
|
continue;
|
|
2133
3190
|
}
|
|
2134
3191
|
if (entry.namespace === "value") {
|
|
2135
|
-
|
|
3192
|
+
if (helpers.isRuntimeDependent?.(key)) {
|
|
3193
|
+
const formula = helpers.toServerFormula?.(key);
|
|
3194
|
+
if (formula) {
|
|
3195
|
+
derived[stripValuePrefix(key)] = formula;
|
|
3196
|
+
for (const ref of formula.runtimeRefs) {
|
|
3197
|
+
runtimeNamespaces.add(ref.split(".")[0] ?? "");
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
continue;
|
|
3201
|
+
}
|
|
3202
|
+
const value = helpers.read ? helpers.read(key) : entry.value;
|
|
3203
|
+
values[stripValuePrefix(key)] = value;
|
|
2136
3204
|
continue;
|
|
2137
3205
|
}
|
|
2138
3206
|
const namespaceDefinition = manifest.namespaces[entry.namespace];
|
|
2139
3207
|
if (namespaceDefinition && namespaceDefinition.kind === "data" && !namespaceDefinition.sensitive && entry.namespace !== "public") {
|
|
2140
|
-
|
|
3208
|
+
if (helpers.isRuntimeDependent?.(key)) {
|
|
3209
|
+
const formula = helpers.toServerFormula?.(key);
|
|
3210
|
+
if (formula) {
|
|
3211
|
+
derived[key] = formula;
|
|
3212
|
+
for (const ref of formula.runtimeRefs) {
|
|
3213
|
+
runtimeNamespaces.add(ref.split(".")[0] ?? "");
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
continue;
|
|
3217
|
+
}
|
|
3218
|
+
values[key] = helpers.read ? helpers.read(key) : entry.value;
|
|
2141
3219
|
namespaces.add(entry.namespace);
|
|
2142
3220
|
}
|
|
2143
3221
|
}
|
|
@@ -2148,8 +3226,10 @@ function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev") {
|
|
|
2148
3226
|
resolvedAt: graph.resolvedAt,
|
|
2149
3227
|
configHash: configHash(values),
|
|
2150
3228
|
values: stableSortObject(values),
|
|
3229
|
+
derived: stableSortObject(derived),
|
|
2151
3230
|
secretRefs: stableSortObject(secretRefs),
|
|
2152
3231
|
publicKeys,
|
|
3232
|
+
runtimeNamespaces: Array.from(runtimeNamespaces).sort((left, right) => left.localeCompare(right)),
|
|
2153
3233
|
meta: {
|
|
2154
3234
|
workspace: graph.workspace.workspaceId,
|
|
2155
3235
|
profile: graph.profile,
|
|
@@ -2172,7 +3252,7 @@ function normalizeEnvValue(value) {
|
|
|
2172
3252
|
}
|
|
2173
3253
|
return JSON.stringify(value);
|
|
2174
3254
|
}
|
|
2175
|
-
function toEnv(graph, manifest, options = {}) {
|
|
3255
|
+
function toEnv(graph, manifest, options = {}, helpers = {}) {
|
|
2176
3256
|
const includeSecrets = options.includeSecrets ?? true;
|
|
2177
3257
|
const output = {};
|
|
2178
3258
|
const mappedEntries = Object.entries(manifest.envMapping.explicit).sort(
|
|
@@ -2193,7 +3273,11 @@ function toEnv(graph, manifest, options = {}) {
|
|
|
2193
3273
|
if (isSecretReference(entry.value)) {
|
|
2194
3274
|
continue;
|
|
2195
3275
|
}
|
|
2196
|
-
|
|
3276
|
+
const value = helpers.read ? helpers.read(logicalKey) : entry.value;
|
|
3277
|
+
if (value === void 0) {
|
|
3278
|
+
continue;
|
|
3279
|
+
}
|
|
3280
|
+
output[envVar] = normalizeEnvValue(value);
|
|
2197
3281
|
}
|
|
2198
3282
|
return output;
|
|
2199
3283
|
}
|
|
@@ -2230,20 +3314,43 @@ function resolvePublicPrefix(manifest, options) {
|
|
|
2230
3314
|
}
|
|
2231
3315
|
return manifest.public.frameworks[options.framework] ?? "";
|
|
2232
3316
|
}
|
|
2233
|
-
function toPublicEnv(graph, manifest, options = {}) {
|
|
3317
|
+
function toPublicEnv(graph, manifest, options = {}, helpers = {}) {
|
|
2234
3318
|
const prefix = resolvePublicPrefix(manifest, options);
|
|
2235
3319
|
const output = {};
|
|
2236
3320
|
const promotions = Array.from(graph.entries.values()).filter((entry) => entry.namespace === "public").sort((left, right) => left.key.localeCompare(right.key));
|
|
2237
3321
|
for (const resolved of promotions) {
|
|
3322
|
+
if (helpers.isRuntimeDependent?.(resolved.key)) {
|
|
3323
|
+
const value2 = helpers.read?.(resolved.key);
|
|
3324
|
+
if (value2 === void 0) {
|
|
3325
|
+
throw new CnosManifestError(`Cannot build public output for ${resolved.key} because it depends on runtime-only values.`);
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
2238
3328
|
const baseEnvVar = fallbackPublicEnvVar(stripNamespace(resolved.key));
|
|
2239
3329
|
const envVar = prefix && !baseEnvVar.startsWith(prefix) ? `${prefix}${baseEnvVar}` : baseEnvVar;
|
|
2240
|
-
|
|
3330
|
+
const value = helpers.read ? helpers.read(resolved.key) : resolved.value;
|
|
3331
|
+
if (value === void 0) {
|
|
3332
|
+
continue;
|
|
3333
|
+
}
|
|
3334
|
+
output[envVar] = normalizeEnvValue2(value);
|
|
2241
3335
|
}
|
|
2242
3336
|
return output;
|
|
2243
3337
|
}
|
|
2244
3338
|
|
|
2245
3339
|
// ../core/src/orchestrator/runtime.ts
|
|
2246
3340
|
function createRuntime(manifest, graph, plugins = [], secretCache, processEnv = process.env, cnosVersion = "0.0.0-dev") {
|
|
3341
|
+
const runtimeProviders = createDefaultRuntimeProviders(manifest, processEnv);
|
|
3342
|
+
const derivedSupport = createDerivedRuntimeSupport(graph, manifest, runtimeProviders);
|
|
3343
|
+
function resolveProjectedSourceKey(key) {
|
|
3344
|
+
if (!key.startsWith("public.")) {
|
|
3345
|
+
return key;
|
|
3346
|
+
}
|
|
3347
|
+
const promotedFrom = graph.entries.get(key)?.winner.metadata?.promotedFrom;
|
|
3348
|
+
if (typeof promotedFrom === "string") {
|
|
3349
|
+
return promotedFrom;
|
|
3350
|
+
}
|
|
3351
|
+
const fallback = `value.${key.slice("public.".length)}`;
|
|
3352
|
+
return graph.entries.has(fallback) ? fallback : key;
|
|
3353
|
+
}
|
|
2247
3354
|
async function refreshSecretEntry(key) {
|
|
2248
3355
|
const entry = graph.entries.get(key);
|
|
2249
3356
|
if (!entry || entry.namespace !== "secret" || !isSecretReference(entry.value)) {
|
|
@@ -2275,6 +3382,19 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
2275
3382
|
}
|
|
2276
3383
|
}
|
|
2277
3384
|
function readLogicalKey(key) {
|
|
3385
|
+
const resolved = derivedSupport.read(key, (ref) => {
|
|
3386
|
+
const entry2 = graph.entries.get(ref);
|
|
3387
|
+
if (!entry2) {
|
|
3388
|
+
return void 0;
|
|
3389
|
+
}
|
|
3390
|
+
if (!secretCache) {
|
|
3391
|
+
return entry2.value;
|
|
3392
|
+
}
|
|
3393
|
+
return resolveSecretEntryValue(ref, entry2.value, secretCache);
|
|
3394
|
+
});
|
|
3395
|
+
if (resolved !== void 0 || graph.entries.has(key) || manifest.runtimeNamespaces[key.split(".")[0] ?? ""]) {
|
|
3396
|
+
return resolved;
|
|
3397
|
+
}
|
|
2278
3398
|
const entry = graph.entries.get(key);
|
|
2279
3399
|
if (!entry) {
|
|
2280
3400
|
return void 0;
|
|
@@ -2299,34 +3419,64 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
2299
3419
|
return value;
|
|
2300
3420
|
},
|
|
2301
3421
|
readOr(key, fallback) {
|
|
2302
|
-
|
|
3422
|
+
const value = readLogicalKey(key);
|
|
3423
|
+
return value === void 0 ? fallback : value;
|
|
2303
3424
|
},
|
|
2304
|
-
value(
|
|
2305
|
-
return readLogicalKey(toLogicalKey("value",
|
|
3425
|
+
value(path16) {
|
|
3426
|
+
return readLogicalKey(toLogicalKey("value", path16));
|
|
2306
3427
|
},
|
|
2307
|
-
secret(
|
|
2308
|
-
return readLogicalKey(toLogicalKey("secret",
|
|
3428
|
+
secret(path16) {
|
|
3429
|
+
return readLogicalKey(toLogicalKey("secret", path16));
|
|
2309
3430
|
},
|
|
2310
|
-
meta(
|
|
2311
|
-
return readLogicalKey(toLogicalKey("meta",
|
|
3431
|
+
meta(path16) {
|
|
3432
|
+
return readLogicalKey(toLogicalKey("meta", path16));
|
|
2312
3433
|
},
|
|
2313
3434
|
inspect(key) {
|
|
2314
|
-
return inspectValue(graph, key
|
|
3435
|
+
return inspectValue(graph, key, {
|
|
3436
|
+
read: (ref) => readLogicalKey(ref),
|
|
3437
|
+
describeDerived: (ref) => derivedSupport.describe(ref, (candidate) => {
|
|
3438
|
+
const entry = graph.entries.get(candidate);
|
|
3439
|
+
if (!entry) {
|
|
3440
|
+
return void 0;
|
|
3441
|
+
}
|
|
3442
|
+
if (!secretCache) {
|
|
3443
|
+
return entry.value;
|
|
3444
|
+
}
|
|
3445
|
+
return resolveSecretEntryValue(candidate, entry.value, secretCache);
|
|
3446
|
+
})
|
|
3447
|
+
});
|
|
2315
3448
|
},
|
|
2316
3449
|
toObject() {
|
|
2317
|
-
return toNamespaceObject(graph);
|
|
3450
|
+
return toNamespaceObject(graph, void 0, (key) => readLogicalKey(key));
|
|
2318
3451
|
},
|
|
2319
3452
|
toNamespace(namespace) {
|
|
2320
|
-
return toNamespaceObject(graph, namespace);
|
|
3453
|
+
return toNamespaceObject(graph, namespace, (key) => readLogicalKey(key));
|
|
2321
3454
|
},
|
|
2322
3455
|
toEnv(options) {
|
|
2323
|
-
return toEnv(graph, manifest, options
|
|
3456
|
+
return toEnv(graph, manifest, options, {
|
|
3457
|
+
read: (key) => readLogicalKey(key),
|
|
3458
|
+
isRuntimeDependent: (key) => derivedSupport.isRuntimeDependentKey(key)
|
|
3459
|
+
});
|
|
2324
3460
|
},
|
|
2325
3461
|
toPublicEnv(options) {
|
|
2326
|
-
return toPublicEnv(graph, manifest, options
|
|
3462
|
+
return toPublicEnv(graph, manifest, options, {
|
|
3463
|
+
read: (key) => derivedSupport.toConcreteValue(
|
|
3464
|
+
resolveProjectedSourceKey(key),
|
|
3465
|
+
(candidate) => readLogicalKey(candidate),
|
|
3466
|
+
"public"
|
|
3467
|
+
),
|
|
3468
|
+
isRuntimeDependent: (key) => derivedSupport.isRuntimeDependentKey(resolveProjectedSourceKey(key))
|
|
3469
|
+
});
|
|
2327
3470
|
},
|
|
2328
3471
|
toServerProjection() {
|
|
2329
|
-
return toServerProjection(graph, manifest, cnosVersion
|
|
3472
|
+
return toServerProjection(graph, manifest, cnosVersion, {
|
|
3473
|
+
read: (key) => derivedSupport.toConcreteValue(key, (candidate) => readLogicalKey(candidate), "server"),
|
|
3474
|
+
isRuntimeDependent: (key) => derivedSupport.isRuntimeDependentKey(key),
|
|
3475
|
+
toServerFormula: (key) => derivedSupport.toServerFormula(key)
|
|
3476
|
+
});
|
|
3477
|
+
},
|
|
3478
|
+
registerRuntimeProvider(namespace, provider) {
|
|
3479
|
+
registerRuntimeProvider(manifest, runtimeProviders, namespace, provider);
|
|
2330
3480
|
},
|
|
2331
3481
|
async refreshSecrets() {
|
|
2332
3482
|
await refreshAllSecrets();
|
|
@@ -2433,7 +3583,11 @@ function appendMetaEntries(graph, cnosVersion) {
|
|
|
2433
3583
|
async function createCnos(options = {}) {
|
|
2434
3584
|
const loadedManifest = await loadManifest({
|
|
2435
3585
|
...options.root ? { root: options.root } : {},
|
|
2436
|
-
...options.cwd ? { cwd: options.cwd } : {}
|
|
3586
|
+
...options.cwd ? { cwd: options.cwd } : {},
|
|
3587
|
+
...options.processEnv ? { processEnv: options.processEnv } : {},
|
|
3588
|
+
...options.cacheMode ? { cacheMode: options.cacheMode } : {},
|
|
3589
|
+
...typeof options.cacheTtlSeconds === "number" ? { cacheTtlSeconds: options.cacheTtlSeconds } : {},
|
|
3590
|
+
...options.forceRefresh ? { forceRefresh: true } : {}
|
|
2437
3591
|
});
|
|
2438
3592
|
for (const key of loadedManifest.manifest.public.promote) {
|
|
2439
3593
|
ensureProjectionAllowed(loadedManifest.manifest, key, "public");
|
|
@@ -2494,23 +3648,23 @@ async function createCnos(options = {}) {
|
|
|
2494
3648
|
}
|
|
2495
3649
|
|
|
2496
3650
|
// ../core/src/runtime/dump.ts
|
|
2497
|
-
var
|
|
2498
|
-
var
|
|
3651
|
+
var import_promises12 = require("fs/promises");
|
|
3652
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
2499
3653
|
function buildDumpFiles(graph, options = {}) {
|
|
2500
|
-
const basePath = options.flatten ? "" :
|
|
3654
|
+
const basePath = options.flatten ? "" : import_node_path13.default.posix.join("workspaces", graph.workspace.workspaceId);
|
|
2501
3655
|
const values = toNamespaceObject(graph, "value");
|
|
2502
3656
|
const secrets = toNamespaceObject(graph, "secret");
|
|
2503
3657
|
const files = [];
|
|
2504
3658
|
if (Object.keys(values).length > 0) {
|
|
2505
3659
|
files.push({
|
|
2506
|
-
path:
|
|
3660
|
+
path: import_node_path13.default.posix.join(basePath, "values", graph.profile, "app.yml"),
|
|
2507
3661
|
namespace: "value",
|
|
2508
3662
|
content: stringifyYaml(values)
|
|
2509
3663
|
});
|
|
2510
3664
|
}
|
|
2511
3665
|
if (Object.keys(secrets).length > 0) {
|
|
2512
3666
|
files.push({
|
|
2513
|
-
path:
|
|
3667
|
+
path: import_node_path13.default.posix.join(basePath, "secrets", graph.profile, "app.yml"),
|
|
2514
3668
|
namespace: "secret",
|
|
2515
3669
|
content: stringifyYaml(secrets)
|
|
2516
3670
|
});
|
|
@@ -2526,12 +3680,12 @@ function planDump(graph, options = {}) {
|
|
|
2526
3680
|
};
|
|
2527
3681
|
}
|
|
2528
3682
|
async function writeDump(graph, options) {
|
|
2529
|
-
const root =
|
|
3683
|
+
const root = import_node_path13.default.resolve(options.to);
|
|
2530
3684
|
const plan = planDump(graph, options);
|
|
2531
3685
|
for (const file of plan.files) {
|
|
2532
|
-
const destination =
|
|
2533
|
-
await (0,
|
|
2534
|
-
await (0,
|
|
3686
|
+
const destination = import_node_path13.default.join(root, file.path);
|
|
3687
|
+
await (0, import_promises12.mkdir)(import_node_path13.default.dirname(destination), { recursive: true });
|
|
3688
|
+
await (0, import_promises12.writeFile)(destination, file.content, "utf8");
|
|
2535
3689
|
}
|
|
2536
3690
|
return {
|
|
2537
3691
|
...plan,
|
|
@@ -2546,8 +3700,8 @@ function normalizeMappingConfig(config = {}) {
|
|
|
2546
3700
|
explicit: config.explicit ?? {}
|
|
2547
3701
|
};
|
|
2548
3702
|
}
|
|
2549
|
-
function fromScreamingSnake(
|
|
2550
|
-
return
|
|
3703
|
+
function fromScreamingSnake(path16) {
|
|
3704
|
+
return path16.split("_").map((segment) => segment.trim().toLowerCase()).filter(Boolean).join(".");
|
|
2551
3705
|
}
|
|
2552
3706
|
function envVarToLogicalKey(envVar, config = {}) {
|
|
2553
3707
|
const normalized = normalizeMappingConfig(config);
|
|
@@ -2574,7 +3728,7 @@ function envVarToLogicalKey(envVar, config = {}) {
|
|
|
2574
3728
|
// package.json
|
|
2575
3729
|
var package_default = {
|
|
2576
3730
|
name: "@kitsy/cnos",
|
|
2577
|
-
version: "1.
|
|
3731
|
+
version: "1.7.0",
|
|
2578
3732
|
description: "Batteries-included CNOS runtime package wired with the official plugins.",
|
|
2579
3733
|
type: "module",
|
|
2580
3734
|
main: "./dist/index.cjs",
|
|
@@ -2773,8 +3927,8 @@ function createCliArgsPlugin() {
|
|
|
2773
3927
|
}
|
|
2774
3928
|
|
|
2775
3929
|
// ../../plugins/dotenv/src/index.ts
|
|
2776
|
-
var
|
|
2777
|
-
var
|
|
3930
|
+
var import_promises13 = require("fs/promises");
|
|
3931
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
2778
3932
|
var DOTENV_PLUGIN_ID = "@kitsy/cnos/plugins/dotenv";
|
|
2779
3933
|
function parseDoubleQuoted(value) {
|
|
2780
3934
|
return value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
@@ -2831,7 +3985,7 @@ function dotenvEntriesFromObject(values, mapping = {}, originFile, workspaceId =
|
|
|
2831
3985
|
}
|
|
2832
3986
|
async function readIfPresent(filePath) {
|
|
2833
3987
|
try {
|
|
2834
|
-
return await (0,
|
|
3988
|
+
return await (0, import_promises13.readFile)(filePath, "utf8");
|
|
2835
3989
|
} catch {
|
|
2836
3990
|
return void 0;
|
|
2837
3991
|
}
|
|
@@ -2850,7 +4004,7 @@ function createDotenvPlugin() {
|
|
|
2850
4004
|
workspace: workspaceRoot.workspaceId
|
|
2851
4005
|
});
|
|
2852
4006
|
for (const fileName of fileNames) {
|
|
2853
|
-
const absolutePath =
|
|
4007
|
+
const absolutePath = import_node_path14.default.join(envRoot, fileName);
|
|
2854
4008
|
const document = await readIfPresent(absolutePath);
|
|
2855
4009
|
if (!document) {
|
|
2856
4010
|
continue;
|
|
@@ -2859,7 +4013,7 @@ function createDotenvPlugin() {
|
|
|
2859
4013
|
...dotenvEntriesFromObject(
|
|
2860
4014
|
parseDotenv(document),
|
|
2861
4015
|
config.envMapping,
|
|
2862
|
-
toPortablePath(
|
|
4016
|
+
toPortablePath(import_node_path14.default.relative(import_node_path14.default.dirname(context.manifestRoot), absolutePath)),
|
|
2863
4017
|
workspaceRoot.workspaceId
|
|
2864
4018
|
)
|
|
2865
4019
|
);
|
|
@@ -2897,16 +4051,16 @@ function createPublicEnvExportPlugin() {
|
|
|
2897
4051
|
}
|
|
2898
4052
|
|
|
2899
4053
|
// ../../plugins/filesystem/src/filesystemSecretsReader.ts
|
|
2900
|
-
var
|
|
4054
|
+
var import_promises15 = require("fs/promises");
|
|
2901
4055
|
|
|
2902
4056
|
// ../../plugins/filesystem/src/helpers.ts
|
|
2903
|
-
var
|
|
2904
|
-
var
|
|
4057
|
+
var import_promises14 = require("fs/promises");
|
|
4058
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
2905
4059
|
var YAML_EXTENSIONS = /* @__PURE__ */ new Set([".yml", ".yaml"]);
|
|
2906
4060
|
var FILESYSTEM_PLUGIN_ID = "@kitsy/cnos/plugins/filesystem";
|
|
2907
4061
|
async function existsDirectory(targetPath) {
|
|
2908
4062
|
try {
|
|
2909
|
-
const stat2 = await (0,
|
|
4063
|
+
const stat2 = await (0, import_promises14.readdir)(targetPath);
|
|
2910
4064
|
void stat2;
|
|
2911
4065
|
return true;
|
|
2912
4066
|
} catch {
|
|
@@ -2914,15 +4068,15 @@ async function existsDirectory(targetPath) {
|
|
|
2914
4068
|
}
|
|
2915
4069
|
}
|
|
2916
4070
|
async function collectYamlFiles(root) {
|
|
2917
|
-
const entries = await (0,
|
|
4071
|
+
const entries = await (0, import_promises14.readdir)(root, { withFileTypes: true });
|
|
2918
4072
|
const results = [];
|
|
2919
4073
|
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
2920
|
-
const absolutePath =
|
|
4074
|
+
const absolutePath = import_node_path15.default.join(root, entry.name);
|
|
2921
4075
|
if (entry.isDirectory()) {
|
|
2922
4076
|
results.push(...await collectYamlFiles(absolutePath));
|
|
2923
4077
|
continue;
|
|
2924
4078
|
}
|
|
2925
|
-
if (entry.isFile() && YAML_EXTENSIONS.has(
|
|
4079
|
+
if (entry.isFile() && YAML_EXTENSIONS.has(import_node_path15.default.extname(entry.name).toLowerCase())) {
|
|
2926
4080
|
results.push(absolutePath);
|
|
2927
4081
|
}
|
|
2928
4082
|
}
|
|
@@ -2930,16 +4084,16 @@ async function collectYamlFiles(root) {
|
|
|
2930
4084
|
}
|
|
2931
4085
|
async function collectFilesystemLayerFiles(manifestRoot, workspaceRoots, sourceRoot, activeLayers) {
|
|
2932
4086
|
const files = [];
|
|
2933
|
-
const repoRoot =
|
|
4087
|
+
const repoRoot = import_node_path15.default.dirname(manifestRoot);
|
|
2934
4088
|
for (const workspaceRoot of workspaceRoots) {
|
|
2935
|
-
const resolvedRoot =
|
|
4089
|
+
const resolvedRoot = import_node_path15.default.resolve(workspaceRoot.path, sourceRoot);
|
|
2936
4090
|
for (const layer of activeLayers) {
|
|
2937
|
-
const layerRoot =
|
|
4091
|
+
const layerRoot = import_node_path15.default.join(resolvedRoot, layer);
|
|
2938
4092
|
if (!await existsDirectory(layerRoot)) {
|
|
2939
4093
|
continue;
|
|
2940
4094
|
}
|
|
2941
4095
|
for (const absolutePath of await collectYamlFiles(layerRoot)) {
|
|
2942
|
-
const relativePath =
|
|
4096
|
+
const relativePath = import_node_path15.default.relative(repoRoot, absolutePath);
|
|
2943
4097
|
files.push({
|
|
2944
4098
|
absolutePath,
|
|
2945
4099
|
relativePath: toPortablePath(relativePath.startsWith("..") ? absolutePath : relativePath),
|
|
@@ -2959,7 +4113,7 @@ function assertObjectDocument(value, filePath) {
|
|
|
2959
4113
|
function flattenConfigObject(value, options = {}, prefix = "") {
|
|
2960
4114
|
return Object.entries(value).reduce((accumulator, [key, nestedValue]) => {
|
|
2961
4115
|
const nextKey = prefix ? `${prefix}.${key}` : key;
|
|
2962
|
-
if (nestedValue && typeof nestedValue === "object" && !Array.isArray(nestedValue) && !options.stopAtLeaf?.(nestedValue)) {
|
|
4116
|
+
if (nestedValue && typeof nestedValue === "object" && !Array.isArray(nestedValue) && !isDerivedValue(nestedValue) && !options.stopAtLeaf?.(nestedValue)) {
|
|
2963
4117
|
Object.assign(
|
|
2964
4118
|
accumulator,
|
|
2965
4119
|
flattenConfigObject(nestedValue, options, nextKey)
|
|
@@ -3016,7 +4170,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
3016
4170
|
);
|
|
3017
4171
|
const entries = [];
|
|
3018
4172
|
for (const file of files) {
|
|
3019
|
-
const document = await (0,
|
|
4173
|
+
const document = await (0, import_promises15.readFile)(file.absolutePath, "utf8");
|
|
3020
4174
|
const fileEntries = filesystemSecretsReader(file.relativePath, document, file.workspaceId);
|
|
3021
4175
|
for (const entry of fileEntries) {
|
|
3022
4176
|
const metadata = toSecretReferenceMetadata(entry.value);
|
|
@@ -3032,7 +4186,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
3032
4186
|
}
|
|
3033
4187
|
|
|
3034
4188
|
// ../../plugins/filesystem/src/filesystemValuesReader.ts
|
|
3035
|
-
var
|
|
4189
|
+
var import_promises16 = require("fs/promises");
|
|
3036
4190
|
function filesystemValuesReader(filePath, document, workspaceId = "default") {
|
|
3037
4191
|
return yamlObjectToEntries(document, filePath, "value", "filesystem-values", workspaceId);
|
|
3038
4192
|
}
|
|
@@ -3053,7 +4207,7 @@ function createFilesystemValuesPlugin() {
|
|
|
3053
4207
|
).map(([namespace]) => namespace);
|
|
3054
4208
|
const entries = [];
|
|
3055
4209
|
for (const file of files) {
|
|
3056
|
-
const document = await (0,
|
|
4210
|
+
const document = await (0, import_promises16.readFile)(file.absolutePath, "utf8");
|
|
3057
4211
|
entries.push(...filesystemValuesReader(file.relativePath, document, file.workspaceId));
|
|
3058
4212
|
}
|
|
3059
4213
|
for (const namespace of customNamespaces) {
|
|
@@ -3068,7 +4222,7 @@ function createFilesystemValuesPlugin() {
|
|
|
3068
4222
|
layers
|
|
3069
4223
|
);
|
|
3070
4224
|
for (const file of namespaceFiles) {
|
|
3071
|
-
const document = await (0,
|
|
4225
|
+
const document = await (0, import_promises16.readFile)(file.absolutePath, "utf8");
|
|
3072
4226
|
entries.push(...yamlObjectToEntries(document, file.relativePath, namespace, "filesystem-values", file.workspaceId));
|
|
3073
4227
|
}
|
|
3074
4228
|
}
|