@kitsy/cnos 1.9.1 → 1.10.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 +193 -18
- package/dist/build/index.d.cts +1 -1
- package/dist/build/index.d.ts +1 -1
- package/dist/build/index.js +8 -8
- package/dist/{chunk-2JBA2LXU.js → chunk-3EZGPQCE.js} +35 -6
- package/dist/{chunk-6QQPHDUI.js → chunk-A5U7EZCJ.js} +1 -1
- package/dist/{chunk-MYG6EPUX.js → chunk-CSA4L64V.js} +10 -10
- package/dist/{chunk-L6ZMJPA6.js → chunk-EIK7OUFP.js} +3 -3
- package/dist/{chunk-A2WG3ZKW.js → chunk-ESBHCFC6.js} +1 -1
- package/dist/{chunk-7JZO6XN3.js → chunk-FHXLOWAB.js} +1 -1
- package/dist/{chunk-7KVM5PUW.js → chunk-MQ4WG3K6.js} +158 -12
- package/dist/{chunk-LURQ4LAK.js → chunk-RTHKUGJV.js} +1 -1
- package/dist/{chunk-L7JVECPE.js → chunk-UGLATJJD.js} +1 -1
- package/dist/{chunk-NVFACB64.js → chunk-UKNL2Y4N.js} +1 -1
- package/dist/configure/index.cjs +193 -18
- 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/{core-zDTUSVx9.d.cts → core-Ud1o2MBn.d.cts} +12 -5
- package/dist/{core-zDTUSVx9.d.ts → core-Ud1o2MBn.d.ts} +12 -5
- package/dist/{envNaming-BkorOKW_.d.ts → envNaming-CPwXl4I6.d.ts} +1 -1
- package/dist/{envNaming-EFzezmB3.d.cts → envNaming-DxxqiGKN.d.cts} +1 -1
- package/dist/index.cjs +193 -18
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -10
- package/dist/internal.cjs +289 -31
- package/dist/internal.d.cts +31 -3
- package/dist/internal.d.ts +31 -3
- package/dist/internal.js +141 -23
- package/dist/plugin/basic-schema.cjs +9 -2
- 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.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 +34 -5
- 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.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.d.cts +1 -1
- package/dist/plugin/filesystem.d.ts +1 -1
- package/dist/plugin/filesystem.js +2 -2
- 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 +193 -18
- package/dist/runtime/index.d.cts +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +10 -10
- package/dist/{toPublicEnv-CT265rzS.d.ts → toPublicEnv-C9wPSpRo.d.ts} +1 -1
- package/dist/{toPublicEnv-Ds1DRwCX.d.cts → toPublicEnv-fUZMRUOz.d.cts} +1 -1
- package/package.json +1 -1
|
@@ -1355,6 +1355,134 @@ function resolveRemoteRootCachePaths(uri, processEnv = process.env) {
|
|
|
1355
1355
|
import { readFile as readFile3 } from "fs/promises";
|
|
1356
1356
|
import path6 from "path";
|
|
1357
1357
|
|
|
1358
|
+
// ../core/src/spec/normalizeSpecRule.ts
|
|
1359
|
+
var ALLOWED_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "object", "array"]);
|
|
1360
|
+
var SECRET_FORBIDDEN_FIELDS = ["default", "examples", "enum"];
|
|
1361
|
+
function hasOwn(target, key) {
|
|
1362
|
+
return Object.prototype.hasOwnProperty.call(target, key);
|
|
1363
|
+
}
|
|
1364
|
+
function normalizeOptionalString(value, fieldName, logicalKey) {
|
|
1365
|
+
if (value === void 0) {
|
|
1366
|
+
return void 0;
|
|
1367
|
+
}
|
|
1368
|
+
if (typeof value !== "string") {
|
|
1369
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "${fieldName}" must be a string.`);
|
|
1370
|
+
}
|
|
1371
|
+
const nextValue = value.trim();
|
|
1372
|
+
return nextValue.length > 0 ? nextValue : void 0;
|
|
1373
|
+
}
|
|
1374
|
+
function normalizeStringArray(value, fieldName, logicalKey) {
|
|
1375
|
+
if (value === void 0) {
|
|
1376
|
+
return void 0;
|
|
1377
|
+
}
|
|
1378
|
+
if (!Array.isArray(value)) {
|
|
1379
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "${fieldName}" must be an array.`);
|
|
1380
|
+
}
|
|
1381
|
+
const nextValue = value.map((entry) => {
|
|
1382
|
+
if (typeof entry !== "string") {
|
|
1383
|
+
throw new CnosManifestError(
|
|
1384
|
+
`Invalid schema rule for ${logicalKey}: "${fieldName}" entries must be strings.`
|
|
1385
|
+
);
|
|
1386
|
+
}
|
|
1387
|
+
return entry.trim();
|
|
1388
|
+
}).filter(Boolean);
|
|
1389
|
+
return nextValue.length > 0 ? nextValue : void 0;
|
|
1390
|
+
}
|
|
1391
|
+
function normalizeUnknownArray(value, fieldName, logicalKey) {
|
|
1392
|
+
if (value === void 0) {
|
|
1393
|
+
return void 0;
|
|
1394
|
+
}
|
|
1395
|
+
if (!Array.isArray(value)) {
|
|
1396
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "${fieldName}" must be an array.`);
|
|
1397
|
+
}
|
|
1398
|
+
return value.length > 0 ? value : void 0;
|
|
1399
|
+
}
|
|
1400
|
+
function assertValidPatternRegex(pattern, logicalKey) {
|
|
1401
|
+
try {
|
|
1402
|
+
void new RegExp(pattern);
|
|
1403
|
+
} catch (error) {
|
|
1404
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
1405
|
+
throw new CnosManifestError(
|
|
1406
|
+
`Invalid schema rule for ${logicalKey}: "pattern" must be a valid regex (${reason}).`
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
function assertSecretRuleSafety(logicalKey, rule) {
|
|
1411
|
+
if (!logicalKey.startsWith("secret.")) {
|
|
1412
|
+
return;
|
|
1413
|
+
}
|
|
1414
|
+
const offendingFields = SECRET_FORBIDDEN_FIELDS.filter((field) => hasOwn(rule, field));
|
|
1415
|
+
if (offendingFields.length === 0) {
|
|
1416
|
+
return;
|
|
1417
|
+
}
|
|
1418
|
+
throw new CnosManifestError(
|
|
1419
|
+
`Invalid schema rule for ${logicalKey}: secret specs cannot include ${offendingFields.join(", ")}. Store secret values in the vault, not schema metadata. Remove ${offendingFields.map((field) => `schema.${logicalKey}.${field}`).join(", ")} to continue.`
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
function normalizeSpecRule(logicalKey, rule) {
|
|
1423
|
+
if (!rule || typeof rule !== "object" || Array.isArray(rule)) {
|
|
1424
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: expected an object.`);
|
|
1425
|
+
}
|
|
1426
|
+
const candidate = rule;
|
|
1427
|
+
assertSecretRuleSafety(logicalKey, candidate);
|
|
1428
|
+
const normalized = {};
|
|
1429
|
+
if (candidate.type !== void 0) {
|
|
1430
|
+
if (typeof candidate.type !== "string" || !ALLOWED_TYPES.has(candidate.type)) {
|
|
1431
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: unsupported type "${String(candidate.type)}".`);
|
|
1432
|
+
}
|
|
1433
|
+
normalized.type = candidate.type;
|
|
1434
|
+
}
|
|
1435
|
+
if (candidate.required !== void 0) {
|
|
1436
|
+
if (typeof candidate.required !== "boolean") {
|
|
1437
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "required" must be a boolean.`);
|
|
1438
|
+
}
|
|
1439
|
+
normalized.required = candidate.required;
|
|
1440
|
+
}
|
|
1441
|
+
if (hasOwn(candidate, "default")) {
|
|
1442
|
+
normalized.default = candidate.default;
|
|
1443
|
+
}
|
|
1444
|
+
const normalizedEnum = normalizeUnknownArray(candidate.enum, "enum", logicalKey);
|
|
1445
|
+
if (normalizedEnum !== void 0) {
|
|
1446
|
+
normalized.enum = normalizedEnum;
|
|
1447
|
+
}
|
|
1448
|
+
const normalizedPattern = normalizeOptionalString(candidate.pattern, "pattern", logicalKey);
|
|
1449
|
+
if (normalizedPattern !== void 0) {
|
|
1450
|
+
assertValidPatternRegex(normalizedPattern, logicalKey);
|
|
1451
|
+
normalized.pattern = normalizedPattern;
|
|
1452
|
+
}
|
|
1453
|
+
const normalizedSummary = normalizeOptionalString(candidate.summary, "summary", logicalKey);
|
|
1454
|
+
if (normalizedSummary !== void 0) {
|
|
1455
|
+
normalized.summary = normalizedSummary;
|
|
1456
|
+
}
|
|
1457
|
+
const normalizedDescription = normalizeOptionalString(candidate.description, "description", logicalKey);
|
|
1458
|
+
if (normalizedDescription !== void 0) {
|
|
1459
|
+
normalized.description = normalizedDescription;
|
|
1460
|
+
}
|
|
1461
|
+
const normalizedExamples = normalizeUnknownArray(candidate.examples, "examples", logicalKey);
|
|
1462
|
+
if (normalizedExamples !== void 0) {
|
|
1463
|
+
normalized.examples = normalizedExamples;
|
|
1464
|
+
}
|
|
1465
|
+
const normalizedUsedBy = normalizeStringArray(candidate.usedBy, "usedBy", logicalKey);
|
|
1466
|
+
if (normalizedUsedBy !== void 0) {
|
|
1467
|
+
normalized.usedBy = normalizedUsedBy;
|
|
1468
|
+
}
|
|
1469
|
+
if (candidate.deprecated !== void 0) {
|
|
1470
|
+
if (typeof candidate.deprecated !== "boolean") {
|
|
1471
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "deprecated" must be a boolean.`);
|
|
1472
|
+
}
|
|
1473
|
+
normalized.deprecated = candidate.deprecated;
|
|
1474
|
+
}
|
|
1475
|
+
const normalizedDeprecationMessage = normalizeOptionalString(
|
|
1476
|
+
candidate.deprecationMessage,
|
|
1477
|
+
"deprecationMessage",
|
|
1478
|
+
logicalKey
|
|
1479
|
+
);
|
|
1480
|
+
if (normalizedDeprecationMessage !== void 0) {
|
|
1481
|
+
normalized.deprecationMessage = normalizedDeprecationMessage;
|
|
1482
|
+
}
|
|
1483
|
+
return normalized;
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1358
1486
|
// ../core/src/manifest/normalizeManifest.ts
|
|
1359
1487
|
var DEFAULT_RESOLVE_FROM = ["cli.profile", "env.CNOS_PROFILE", "default"];
|
|
1360
1488
|
var DEFAULT_LOADERS = [
|
|
@@ -1553,6 +1681,14 @@ function normalizeVaultAuth(vaultName, provider, auth) {
|
|
|
1553
1681
|
...auth?.config ? { config: auth.config } : {}
|
|
1554
1682
|
};
|
|
1555
1683
|
}
|
|
1684
|
+
function normalizeSchema(schema) {
|
|
1685
|
+
return Object.fromEntries(
|
|
1686
|
+
Object.entries(schema ?? {}).map(([logicalKey, rule]) => [
|
|
1687
|
+
logicalKey,
|
|
1688
|
+
normalizeSpecRule(logicalKey, rule)
|
|
1689
|
+
])
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1556
1692
|
function normalizeManifest(manifest) {
|
|
1557
1693
|
const version = manifest.version ?? 1;
|
|
1558
1694
|
if (version !== 1) {
|
|
@@ -1650,7 +1786,7 @@ function normalizeManifest(manifest) {
|
|
|
1650
1786
|
}
|
|
1651
1787
|
}
|
|
1652
1788
|
},
|
|
1653
|
-
schema: manifest.schema
|
|
1789
|
+
schema: normalizeSchema(manifest.schema)
|
|
1654
1790
|
};
|
|
1655
1791
|
}
|
|
1656
1792
|
|
|
@@ -2201,16 +2337,19 @@ import { appendFile, mkdir as mkdir5 } from "fs/promises";
|
|
|
2201
2337
|
import path9 from "path";
|
|
2202
2338
|
async function appendAuditEvent(event, processEnv = process.env) {
|
|
2203
2339
|
const auditFile = processEnv.CNOS_AUDIT_FILE ?? path9.join(resolveSecretStoreRoot(processEnv), "audit", "access.log");
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2340
|
+
try {
|
|
2341
|
+
await mkdir5(path9.dirname(auditFile), { recursive: true });
|
|
2342
|
+
await appendFile(
|
|
2343
|
+
auditFile,
|
|
2344
|
+
`${JSON.stringify({
|
|
2345
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2346
|
+
...event
|
|
2347
|
+
})}
|
|
2211
2348
|
`,
|
|
2212
|
-
|
|
2213
|
-
|
|
2349
|
+
"utf8"
|
|
2350
|
+
);
|
|
2351
|
+
} catch {
|
|
2352
|
+
}
|
|
2214
2353
|
}
|
|
2215
2354
|
|
|
2216
2355
|
// ../core/src/secrets/providers/local.ts
|
|
@@ -3380,6 +3519,13 @@ function enumMatches(value, allowed) {
|
|
|
3380
3519
|
const serialized = JSON.stringify(value);
|
|
3381
3520
|
return allowed.some((candidate) => JSON.stringify(candidate) === serialized);
|
|
3382
3521
|
}
|
|
3522
|
+
function testPattern(pattern, value) {
|
|
3523
|
+
try {
|
|
3524
|
+
return new RegExp(pattern).test(value);
|
|
3525
|
+
} catch {
|
|
3526
|
+
return false;
|
|
3527
|
+
}
|
|
3528
|
+
}
|
|
3383
3529
|
function applySchemaRules(graph, schema) {
|
|
3384
3530
|
const nextEntries = new Map(graph.entries);
|
|
3385
3531
|
const issues = [];
|
|
@@ -3446,11 +3592,11 @@ function applySchemaRules(graph, schema) {
|
|
|
3446
3592
|
key,
|
|
3447
3593
|
message: `Config key ${key} must be a string to match pattern ${rule.pattern}`
|
|
3448
3594
|
});
|
|
3449
|
-
} else if (!
|
|
3595
|
+
} else if (!testPattern(rule.pattern, coercedValue)) {
|
|
3450
3596
|
issues.push({
|
|
3451
3597
|
code: "schema.pattern",
|
|
3452
3598
|
key,
|
|
3453
|
-
message: `Config key ${key} does not match pattern ${rule.pattern}
|
|
3599
|
+
message: `Config key ${key} does not match pattern ${rule.pattern} (or the pattern is invalid).`
|
|
3454
3600
|
});
|
|
3455
3601
|
}
|
|
3456
3602
|
}
|
package/dist/configure/index.cjs
CHANGED
|
@@ -1342,6 +1342,134 @@ function stripNamespace(key) {
|
|
|
1342
1342
|
return key.split(".").slice(1).join(".");
|
|
1343
1343
|
}
|
|
1344
1344
|
|
|
1345
|
+
// ../core/src/spec/normalizeSpecRule.ts
|
|
1346
|
+
var ALLOWED_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "object", "array"]);
|
|
1347
|
+
var SECRET_FORBIDDEN_FIELDS = ["default", "examples", "enum"];
|
|
1348
|
+
function hasOwn(target, key) {
|
|
1349
|
+
return Object.prototype.hasOwnProperty.call(target, key);
|
|
1350
|
+
}
|
|
1351
|
+
function normalizeOptionalString(value, fieldName, logicalKey) {
|
|
1352
|
+
if (value === void 0) {
|
|
1353
|
+
return void 0;
|
|
1354
|
+
}
|
|
1355
|
+
if (typeof value !== "string") {
|
|
1356
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "${fieldName}" must be a string.`);
|
|
1357
|
+
}
|
|
1358
|
+
const nextValue = value.trim();
|
|
1359
|
+
return nextValue.length > 0 ? nextValue : void 0;
|
|
1360
|
+
}
|
|
1361
|
+
function normalizeStringArray(value, fieldName, logicalKey) {
|
|
1362
|
+
if (value === void 0) {
|
|
1363
|
+
return void 0;
|
|
1364
|
+
}
|
|
1365
|
+
if (!Array.isArray(value)) {
|
|
1366
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "${fieldName}" must be an array.`);
|
|
1367
|
+
}
|
|
1368
|
+
const nextValue = value.map((entry) => {
|
|
1369
|
+
if (typeof entry !== "string") {
|
|
1370
|
+
throw new CnosManifestError(
|
|
1371
|
+
`Invalid schema rule for ${logicalKey}: "${fieldName}" entries must be strings.`
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
return entry.trim();
|
|
1375
|
+
}).filter(Boolean);
|
|
1376
|
+
return nextValue.length > 0 ? nextValue : void 0;
|
|
1377
|
+
}
|
|
1378
|
+
function normalizeUnknownArray(value, fieldName, logicalKey) {
|
|
1379
|
+
if (value === void 0) {
|
|
1380
|
+
return void 0;
|
|
1381
|
+
}
|
|
1382
|
+
if (!Array.isArray(value)) {
|
|
1383
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "${fieldName}" must be an array.`);
|
|
1384
|
+
}
|
|
1385
|
+
return value.length > 0 ? value : void 0;
|
|
1386
|
+
}
|
|
1387
|
+
function assertValidPatternRegex(pattern, logicalKey) {
|
|
1388
|
+
try {
|
|
1389
|
+
void new RegExp(pattern);
|
|
1390
|
+
} catch (error) {
|
|
1391
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
1392
|
+
throw new CnosManifestError(
|
|
1393
|
+
`Invalid schema rule for ${logicalKey}: "pattern" must be a valid regex (${reason}).`
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
function assertSecretRuleSafety(logicalKey, rule) {
|
|
1398
|
+
if (!logicalKey.startsWith("secret.")) {
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
const offendingFields = SECRET_FORBIDDEN_FIELDS.filter((field) => hasOwn(rule, field));
|
|
1402
|
+
if (offendingFields.length === 0) {
|
|
1403
|
+
return;
|
|
1404
|
+
}
|
|
1405
|
+
throw new CnosManifestError(
|
|
1406
|
+
`Invalid schema rule for ${logicalKey}: secret specs cannot include ${offendingFields.join(", ")}. Store secret values in the vault, not schema metadata. Remove ${offendingFields.map((field) => `schema.${logicalKey}.${field}`).join(", ")} to continue.`
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
function normalizeSpecRule(logicalKey, rule) {
|
|
1410
|
+
if (!rule || typeof rule !== "object" || Array.isArray(rule)) {
|
|
1411
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: expected an object.`);
|
|
1412
|
+
}
|
|
1413
|
+
const candidate = rule;
|
|
1414
|
+
assertSecretRuleSafety(logicalKey, candidate);
|
|
1415
|
+
const normalized = {};
|
|
1416
|
+
if (candidate.type !== void 0) {
|
|
1417
|
+
if (typeof candidate.type !== "string" || !ALLOWED_TYPES.has(candidate.type)) {
|
|
1418
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: unsupported type "${String(candidate.type)}".`);
|
|
1419
|
+
}
|
|
1420
|
+
normalized.type = candidate.type;
|
|
1421
|
+
}
|
|
1422
|
+
if (candidate.required !== void 0) {
|
|
1423
|
+
if (typeof candidate.required !== "boolean") {
|
|
1424
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "required" must be a boolean.`);
|
|
1425
|
+
}
|
|
1426
|
+
normalized.required = candidate.required;
|
|
1427
|
+
}
|
|
1428
|
+
if (hasOwn(candidate, "default")) {
|
|
1429
|
+
normalized.default = candidate.default;
|
|
1430
|
+
}
|
|
1431
|
+
const normalizedEnum = normalizeUnknownArray(candidate.enum, "enum", logicalKey);
|
|
1432
|
+
if (normalizedEnum !== void 0) {
|
|
1433
|
+
normalized.enum = normalizedEnum;
|
|
1434
|
+
}
|
|
1435
|
+
const normalizedPattern = normalizeOptionalString(candidate.pattern, "pattern", logicalKey);
|
|
1436
|
+
if (normalizedPattern !== void 0) {
|
|
1437
|
+
assertValidPatternRegex(normalizedPattern, logicalKey);
|
|
1438
|
+
normalized.pattern = normalizedPattern;
|
|
1439
|
+
}
|
|
1440
|
+
const normalizedSummary = normalizeOptionalString(candidate.summary, "summary", logicalKey);
|
|
1441
|
+
if (normalizedSummary !== void 0) {
|
|
1442
|
+
normalized.summary = normalizedSummary;
|
|
1443
|
+
}
|
|
1444
|
+
const normalizedDescription = normalizeOptionalString(candidate.description, "description", logicalKey);
|
|
1445
|
+
if (normalizedDescription !== void 0) {
|
|
1446
|
+
normalized.description = normalizedDescription;
|
|
1447
|
+
}
|
|
1448
|
+
const normalizedExamples = normalizeUnknownArray(candidate.examples, "examples", logicalKey);
|
|
1449
|
+
if (normalizedExamples !== void 0) {
|
|
1450
|
+
normalized.examples = normalizedExamples;
|
|
1451
|
+
}
|
|
1452
|
+
const normalizedUsedBy = normalizeStringArray(candidate.usedBy, "usedBy", logicalKey);
|
|
1453
|
+
if (normalizedUsedBy !== void 0) {
|
|
1454
|
+
normalized.usedBy = normalizedUsedBy;
|
|
1455
|
+
}
|
|
1456
|
+
if (candidate.deprecated !== void 0) {
|
|
1457
|
+
if (typeof candidate.deprecated !== "boolean") {
|
|
1458
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "deprecated" must be a boolean.`);
|
|
1459
|
+
}
|
|
1460
|
+
normalized.deprecated = candidate.deprecated;
|
|
1461
|
+
}
|
|
1462
|
+
const normalizedDeprecationMessage = normalizeOptionalString(
|
|
1463
|
+
candidate.deprecationMessage,
|
|
1464
|
+
"deprecationMessage",
|
|
1465
|
+
logicalKey
|
|
1466
|
+
);
|
|
1467
|
+
if (normalizedDeprecationMessage !== void 0) {
|
|
1468
|
+
normalized.deprecationMessage = normalizedDeprecationMessage;
|
|
1469
|
+
}
|
|
1470
|
+
return normalized;
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1345
1473
|
// ../core/src/manifest/normalizeManifest.ts
|
|
1346
1474
|
var DEFAULT_RESOLVE_FROM = ["cli.profile", "env.CNOS_PROFILE", "default"];
|
|
1347
1475
|
var DEFAULT_LOADERS = [
|
|
@@ -1540,6 +1668,14 @@ function normalizeVaultAuth(vaultName, provider, auth) {
|
|
|
1540
1668
|
...auth?.config ? { config: auth.config } : {}
|
|
1541
1669
|
};
|
|
1542
1670
|
}
|
|
1671
|
+
function normalizeSchema(schema) {
|
|
1672
|
+
return Object.fromEntries(
|
|
1673
|
+
Object.entries(schema ?? {}).map(([logicalKey, rule]) => [
|
|
1674
|
+
logicalKey,
|
|
1675
|
+
normalizeSpecRule(logicalKey, rule)
|
|
1676
|
+
])
|
|
1677
|
+
);
|
|
1678
|
+
}
|
|
1543
1679
|
function normalizeManifest(manifest) {
|
|
1544
1680
|
const version = manifest.version ?? 1;
|
|
1545
1681
|
if (version !== 1) {
|
|
@@ -1637,7 +1773,7 @@ function normalizeManifest(manifest) {
|
|
|
1637
1773
|
}
|
|
1638
1774
|
}
|
|
1639
1775
|
},
|
|
1640
|
-
schema: manifest.schema
|
|
1776
|
+
schema: normalizeSchema(manifest.schema)
|
|
1641
1777
|
};
|
|
1642
1778
|
}
|
|
1643
1779
|
|
|
@@ -2271,6 +2407,13 @@ function enumMatches(value, allowed) {
|
|
|
2271
2407
|
const serialized = JSON.stringify(value);
|
|
2272
2408
|
return allowed.some((candidate) => JSON.stringify(candidate) === serialized);
|
|
2273
2409
|
}
|
|
2410
|
+
function testPattern(pattern, value) {
|
|
2411
|
+
try {
|
|
2412
|
+
return new RegExp(pattern).test(value);
|
|
2413
|
+
} catch {
|
|
2414
|
+
return false;
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2274
2417
|
function applySchemaRules(graph, schema) {
|
|
2275
2418
|
const nextEntries = new Map(graph.entries);
|
|
2276
2419
|
const issues = [];
|
|
@@ -2337,11 +2480,11 @@ function applySchemaRules(graph, schema) {
|
|
|
2337
2480
|
key,
|
|
2338
2481
|
message: `Config key ${key} must be a string to match pattern ${rule.pattern}`
|
|
2339
2482
|
});
|
|
2340
|
-
} else if (!
|
|
2483
|
+
} else if (!testPattern(rule.pattern, coercedValue)) {
|
|
2341
2484
|
issues.push({
|
|
2342
2485
|
code: "schema.pattern",
|
|
2343
2486
|
key,
|
|
2344
|
-
message: `Config key ${key} does not match pattern ${rule.pattern}
|
|
2487
|
+
message: `Config key ${key} does not match pattern ${rule.pattern} (or the pattern is invalid).`
|
|
2345
2488
|
});
|
|
2346
2489
|
}
|
|
2347
2490
|
}
|
|
@@ -2741,16 +2884,19 @@ function resolveVaultDefinition(vaults, vault = "default") {
|
|
|
2741
2884
|
// ../core/src/secrets/auditLog.ts
|
|
2742
2885
|
async function appendAuditEvent(event, processEnv = process.env) {
|
|
2743
2886
|
const auditFile = processEnv.CNOS_AUDIT_FILE ?? import_node_path12.default.join(resolveSecretStoreRoot(processEnv), "audit", "access.log");
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2887
|
+
try {
|
|
2888
|
+
await (0, import_promises11.mkdir)(import_node_path12.default.dirname(auditFile), { recursive: true });
|
|
2889
|
+
await (0, import_promises11.appendFile)(
|
|
2890
|
+
auditFile,
|
|
2891
|
+
`${JSON.stringify({
|
|
2892
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2893
|
+
...event
|
|
2894
|
+
})}
|
|
2751
2895
|
`,
|
|
2752
|
-
|
|
2753
|
-
|
|
2896
|
+
"utf8"
|
|
2897
|
+
);
|
|
2898
|
+
} catch {
|
|
2899
|
+
}
|
|
2754
2900
|
}
|
|
2755
2901
|
|
|
2756
2902
|
// ../core/src/secrets/secretCache.ts
|
|
@@ -3764,7 +3910,7 @@ function envVarToLogicalKey(envVar, config = {}) {
|
|
|
3764
3910
|
// package.json
|
|
3765
3911
|
var package_default = {
|
|
3766
3912
|
name: "@kitsy/cnos",
|
|
3767
|
-
version: "1.
|
|
3913
|
+
version: "1.10.0",
|
|
3768
3914
|
description: "Batteries-included CNOS runtime package wired with the official plugins.",
|
|
3769
3915
|
type: "module",
|
|
3770
3916
|
main: "./dist/index.cjs",
|
|
@@ -3969,9 +4115,30 @@ var DOTENV_PLUGIN_ID = "@kitsy/cnos/plugins/dotenv";
|
|
|
3969
4115
|
function parseDoubleQuoted(value) {
|
|
3970
4116
|
return value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
3971
4117
|
}
|
|
4118
|
+
function isEscapedCharacter(value, index) {
|
|
4119
|
+
let slashCount = 0;
|
|
4120
|
+
for (let cursor = index - 1; cursor >= 0 && value[cursor] === "\\"; cursor -= 1) {
|
|
4121
|
+
slashCount += 1;
|
|
4122
|
+
}
|
|
4123
|
+
return slashCount % 2 === 1;
|
|
4124
|
+
}
|
|
4125
|
+
function findClosingQuote(value, quote) {
|
|
4126
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
4127
|
+
if (value[index] !== quote) {
|
|
4128
|
+
continue;
|
|
4129
|
+
}
|
|
4130
|
+
if (quote === '"' && isEscapedCharacter(value, index)) {
|
|
4131
|
+
continue;
|
|
4132
|
+
}
|
|
4133
|
+
return index;
|
|
4134
|
+
}
|
|
4135
|
+
return -1;
|
|
4136
|
+
}
|
|
3972
4137
|
function parseDotenv(document) {
|
|
3973
4138
|
const parsed = {};
|
|
3974
|
-
|
|
4139
|
+
const lines = document.split(/\r?\n/);
|
|
4140
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
|
|
4141
|
+
const rawLine = lines[lineIndex] ?? "";
|
|
3975
4142
|
const line = rawLine.trim();
|
|
3976
4143
|
if (!line || line.startsWith("#")) {
|
|
3977
4144
|
continue;
|
|
@@ -3986,10 +4153,18 @@ function parseDotenv(document) {
|
|
|
3986
4153
|
if (!envVar) {
|
|
3987
4154
|
continue;
|
|
3988
4155
|
}
|
|
3989
|
-
if (value.startsWith('"')
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
4156
|
+
if (value.startsWith('"') || value.startsWith("'")) {
|
|
4157
|
+
const quote = value.startsWith('"') ? '"' : "'";
|
|
4158
|
+
let quotedContent = value.slice(1);
|
|
4159
|
+
let closingIndex = findClosingQuote(quotedContent, quote);
|
|
4160
|
+
while (closingIndex === -1 && lineIndex < lines.length - 1) {
|
|
4161
|
+
lineIndex += 1;
|
|
4162
|
+
quotedContent = `${quotedContent}
|
|
4163
|
+
${lines[lineIndex] ?? ""}`;
|
|
4164
|
+
closingIndex = findClosingQuote(quotedContent, quote);
|
|
4165
|
+
}
|
|
4166
|
+
const rawQuotedValue = closingIndex === -1 ? quotedContent : quotedContent.slice(0, closingIndex);
|
|
4167
|
+
value = quote === '"' ? parseDoubleQuoted(rawQuotedValue) : rawQuotedValue;
|
|
3993
4168
|
} else {
|
|
3994
4169
|
value = value.replace(/\s+#.*$/, "").trim();
|
|
3995
4170
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as ResolvedGraph, D as DumpPlanOptions, d as DumpPlan, e as DumpOptions, f as DumpResult, C as CnosCreateOptions, g as CnosRuntime, h as CnosPlugin } from '../core-
|
|
2
|
-
export { a as ConfigEntry, i as DerivedFormula, j as DerivedValue, k as ExprNode, I as InspectResult, L as LoaderPlugin, b as LogicalKey, M as ManifestFile, N as NormalizedManifest, P as ParsedDerivation, l as RuntimeProvider, T as ToEnvOptions, c as ToPublicEnvOptions } from '../core-
|
|
3
|
-
export { t as toEnv, a as toPublicEnv } from '../toPublicEnv-
|
|
1
|
+
import { R as ResolvedGraph, D as DumpPlanOptions, d as DumpPlan, e as DumpOptions, f as DumpResult, C as CnosCreateOptions, g as CnosRuntime, h as CnosPlugin } from '../core-Ud1o2MBn.cjs';
|
|
2
|
+
export { a as ConfigEntry, i as DerivedFormula, j as DerivedValue, k as ExprNode, I as InspectResult, L as LoaderPlugin, b as LogicalKey, M as ManifestFile, N as NormalizedManifest, P as ParsedDerivation, l as RuntimeProvider, T as ToEnvOptions, c as ToPublicEnvOptions } from '../core-Ud1o2MBn.cjs';
|
|
3
|
+
export { t as toEnv, a as toPublicEnv } from '../toPublicEnv-fUZMRUOz.cjs';
|
|
4
4
|
|
|
5
5
|
declare function planDump(graph: ResolvedGraph, options?: DumpPlanOptions): DumpPlan;
|
|
6
6
|
declare function writeDump(graph: ResolvedGraph, options: DumpOptions): Promise<DumpResult>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as ResolvedGraph, D as DumpPlanOptions, d as DumpPlan, e as DumpOptions, f as DumpResult, C as CnosCreateOptions, g as CnosRuntime, h as CnosPlugin } from '../core-
|
|
2
|
-
export { a as ConfigEntry, i as DerivedFormula, j as DerivedValue, k as ExprNode, I as InspectResult, L as LoaderPlugin, b as LogicalKey, M as ManifestFile, N as NormalizedManifest, P as ParsedDerivation, l as RuntimeProvider, T as ToEnvOptions, c as ToPublicEnvOptions } from '../core-
|
|
3
|
-
export { t as toEnv, a as toPublicEnv } from '../toPublicEnv-
|
|
1
|
+
import { R as ResolvedGraph, D as DumpPlanOptions, d as DumpPlan, e as DumpOptions, f as DumpResult, C as CnosCreateOptions, g as CnosRuntime, h as CnosPlugin } from '../core-Ud1o2MBn.js';
|
|
2
|
+
export { a as ConfigEntry, i as DerivedFormula, j as DerivedValue, k as ExprNode, I as InspectResult, L as LoaderPlugin, b as LogicalKey, M as ManifestFile, N as NormalizedManifest, P as ParsedDerivation, l as RuntimeProvider, T as ToEnvOptions, c as ToPublicEnvOptions } from '../core-Ud1o2MBn.js';
|
|
3
|
+
export { t as toEnv, a as toPublicEnv } from '../toPublicEnv-C9wPSpRo.js';
|
|
4
4
|
|
|
5
5
|
declare function planDump(graph: ResolvedGraph, options?: DumpPlanOptions): DumpPlan;
|
|
6
6
|
declare function writeDump(graph: ResolvedGraph, options: DumpOptions): Promise<DumpResult>;
|
package/dist/configure/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createCnos,
|
|
3
3
|
defaultPlugins
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-CSA4L64V.js";
|
|
5
|
+
import "../chunk-3EZGPQCE.js";
|
|
6
|
+
import "../chunk-RTHKUGJV.js";
|
|
7
|
+
import "../chunk-ESBHCFC6.js";
|
|
8
|
+
import "../chunk-UGLATJJD.js";
|
|
9
|
+
import "../chunk-A5U7EZCJ.js";
|
|
10
|
+
import "../chunk-FHXLOWAB.js";
|
|
11
11
|
import {
|
|
12
12
|
planDump,
|
|
13
13
|
toEnv,
|
|
14
14
|
toPublicEnv,
|
|
15
15
|
writeDump
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-MQ4WG3K6.js";
|
|
17
17
|
export {
|
|
18
18
|
createCnos,
|
|
19
19
|
defaultPlugins,
|
|
@@ -6,12 +6,19 @@ interface ProfileActivation {
|
|
|
6
6
|
envFiles: string[];
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
type ConfigSpecValueType = 'string' | 'number' | 'boolean' | 'object' | 'array';
|
|
10
|
+
interface ConfigSpecRule {
|
|
11
|
+
type?: ConfigSpecValueType;
|
|
11
12
|
required?: boolean;
|
|
12
13
|
enum?: unknown[];
|
|
13
14
|
pattern?: string;
|
|
14
15
|
default?: unknown;
|
|
16
|
+
summary?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
examples?: unknown[];
|
|
19
|
+
usedBy?: string[];
|
|
20
|
+
deprecated?: boolean;
|
|
21
|
+
deprecationMessage?: string;
|
|
15
22
|
}
|
|
16
23
|
|
|
17
24
|
type WorkspaceSource = 'cli' | 'workspace-file' | 'anchor-file' | 'manifest-default' | 'implicit' | 'directory-inferred';
|
|
@@ -143,7 +150,7 @@ interface ManifestFile {
|
|
|
143
150
|
targets?: Partial<Record<'value' | 'secret', string>>;
|
|
144
151
|
};
|
|
145
152
|
};
|
|
146
|
-
schema?: Record<LogicalKey,
|
|
153
|
+
schema?: Record<LogicalKey, ConfigSpecRule>;
|
|
147
154
|
}
|
|
148
155
|
interface NormalizedManifest {
|
|
149
156
|
version: 1;
|
|
@@ -192,7 +199,7 @@ interface NormalizedManifest {
|
|
|
192
199
|
targets: Record<'value' | 'secret', string>;
|
|
193
200
|
};
|
|
194
201
|
};
|
|
195
|
-
schema: Record<LogicalKey,
|
|
202
|
+
schema: Record<LogicalKey, ConfigSpecRule>;
|
|
196
203
|
}
|
|
197
204
|
interface LoadManifestOptions {
|
|
198
205
|
root?: string;
|
|
@@ -232,7 +239,7 @@ interface LoaderContext {
|
|
|
232
239
|
}
|
|
233
240
|
interface ValidationContext {
|
|
234
241
|
manifest: NormalizedManifest;
|
|
235
|
-
schema?: Record<LogicalKey,
|
|
242
|
+
schema?: Record<LogicalKey, ConfigSpecRule>;
|
|
236
243
|
}
|
|
237
244
|
interface ExportContext {
|
|
238
245
|
manifest: NormalizedManifest;
|
|
@@ -6,12 +6,19 @@ interface ProfileActivation {
|
|
|
6
6
|
envFiles: string[];
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
type ConfigSpecValueType = 'string' | 'number' | 'boolean' | 'object' | 'array';
|
|
10
|
+
interface ConfigSpecRule {
|
|
11
|
+
type?: ConfigSpecValueType;
|
|
11
12
|
required?: boolean;
|
|
12
13
|
enum?: unknown[];
|
|
13
14
|
pattern?: string;
|
|
14
15
|
default?: unknown;
|
|
16
|
+
summary?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
examples?: unknown[];
|
|
19
|
+
usedBy?: string[];
|
|
20
|
+
deprecated?: boolean;
|
|
21
|
+
deprecationMessage?: string;
|
|
15
22
|
}
|
|
16
23
|
|
|
17
24
|
type WorkspaceSource = 'cli' | 'workspace-file' | 'anchor-file' | 'manifest-default' | 'implicit' | 'directory-inferred';
|
|
@@ -143,7 +150,7 @@ interface ManifestFile {
|
|
|
143
150
|
targets?: Partial<Record<'value' | 'secret', string>>;
|
|
144
151
|
};
|
|
145
152
|
};
|
|
146
|
-
schema?: Record<LogicalKey,
|
|
153
|
+
schema?: Record<LogicalKey, ConfigSpecRule>;
|
|
147
154
|
}
|
|
148
155
|
interface NormalizedManifest {
|
|
149
156
|
version: 1;
|
|
@@ -192,7 +199,7 @@ interface NormalizedManifest {
|
|
|
192
199
|
targets: Record<'value' | 'secret', string>;
|
|
193
200
|
};
|
|
194
201
|
};
|
|
195
|
-
schema: Record<LogicalKey,
|
|
202
|
+
schema: Record<LogicalKey, ConfigSpecRule>;
|
|
196
203
|
}
|
|
197
204
|
interface LoadManifestOptions {
|
|
198
205
|
root?: string;
|
|
@@ -232,7 +239,7 @@ interface LoaderContext {
|
|
|
232
239
|
}
|
|
233
240
|
interface ValidationContext {
|
|
234
241
|
manifest: NormalizedManifest;
|
|
235
|
-
schema?: Record<LogicalKey,
|
|
242
|
+
schema?: Record<LogicalKey, ConfigSpecRule>;
|
|
236
243
|
}
|
|
237
244
|
interface ExportContext {
|
|
238
245
|
manifest: NormalizedManifest;
|