@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.
Files changed (57) hide show
  1. package/dist/build/index.cjs +193 -18
  2. package/dist/build/index.d.cts +1 -1
  3. package/dist/build/index.d.ts +1 -1
  4. package/dist/build/index.js +8 -8
  5. package/dist/{chunk-2JBA2LXU.js → chunk-3EZGPQCE.js} +35 -6
  6. package/dist/{chunk-6QQPHDUI.js → chunk-A5U7EZCJ.js} +1 -1
  7. package/dist/{chunk-MYG6EPUX.js → chunk-CSA4L64V.js} +10 -10
  8. package/dist/{chunk-L6ZMJPA6.js → chunk-EIK7OUFP.js} +3 -3
  9. package/dist/{chunk-A2WG3ZKW.js → chunk-ESBHCFC6.js} +1 -1
  10. package/dist/{chunk-7JZO6XN3.js → chunk-FHXLOWAB.js} +1 -1
  11. package/dist/{chunk-7KVM5PUW.js → chunk-MQ4WG3K6.js} +158 -12
  12. package/dist/{chunk-LURQ4LAK.js → chunk-RTHKUGJV.js} +1 -1
  13. package/dist/{chunk-L7JVECPE.js → chunk-UGLATJJD.js} +1 -1
  14. package/dist/{chunk-NVFACB64.js → chunk-UKNL2Y4N.js} +1 -1
  15. package/dist/configure/index.cjs +193 -18
  16. package/dist/configure/index.d.cts +3 -3
  17. package/dist/configure/index.d.ts +3 -3
  18. package/dist/configure/index.js +8 -8
  19. package/dist/{core-zDTUSVx9.d.cts → core-Ud1o2MBn.d.cts} +12 -5
  20. package/dist/{core-zDTUSVx9.d.ts → core-Ud1o2MBn.d.ts} +12 -5
  21. package/dist/{envNaming-BkorOKW_.d.ts → envNaming-CPwXl4I6.d.ts} +1 -1
  22. package/dist/{envNaming-EFzezmB3.d.cts → envNaming-DxxqiGKN.d.cts} +1 -1
  23. package/dist/index.cjs +193 -18
  24. package/dist/index.d.cts +1 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.js +10 -10
  27. package/dist/internal.cjs +289 -31
  28. package/dist/internal.d.cts +31 -3
  29. package/dist/internal.d.ts +31 -3
  30. package/dist/internal.js +141 -23
  31. package/dist/plugin/basic-schema.cjs +9 -2
  32. package/dist/plugin/basic-schema.d.cts +1 -1
  33. package/dist/plugin/basic-schema.d.ts +1 -1
  34. package/dist/plugin/basic-schema.js +2 -2
  35. package/dist/plugin/cli-args.d.cts +1 -1
  36. package/dist/plugin/cli-args.d.ts +1 -1
  37. package/dist/plugin/cli-args.js +2 -2
  38. package/dist/plugin/dotenv.cjs +34 -5
  39. package/dist/plugin/dotenv.d.cts +2 -2
  40. package/dist/plugin/dotenv.d.ts +2 -2
  41. package/dist/plugin/dotenv.js +2 -2
  42. package/dist/plugin/env-export.d.cts +2 -2
  43. package/dist/plugin/env-export.d.ts +2 -2
  44. package/dist/plugin/env-export.js +2 -2
  45. package/dist/plugin/filesystem.d.cts +1 -1
  46. package/dist/plugin/filesystem.d.ts +1 -1
  47. package/dist/plugin/filesystem.js +2 -2
  48. package/dist/plugin/process-env.d.cts +2 -2
  49. package/dist/plugin/process-env.d.ts +2 -2
  50. package/dist/plugin/process-env.js +2 -2
  51. package/dist/runtime/index.cjs +193 -18
  52. package/dist/runtime/index.d.cts +1 -1
  53. package/dist/runtime/index.d.ts +1 -1
  54. package/dist/runtime/index.js +10 -10
  55. package/dist/{toPublicEnv-CT265rzS.d.ts → toPublicEnv-C9wPSpRo.d.ts} +1 -1
  56. package/dist/{toPublicEnv-Ds1DRwCX.d.cts → toPublicEnv-fUZMRUOz.d.cts} +1 -1
  57. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { N as NormalizedManifest, b as LogicalKey } from './core-zDTUSVx9.cjs';
1
+ import { N as NormalizedManifest, b as LogicalKey } from './core-Ud1o2MBn.cjs';
2
2
 
3
3
  interface EnvMappingConfig {
4
4
  convention?: NormalizedManifest['envMapping']['convention'];
package/dist/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 (!new RegExp(rule.pattern).test(coercedValue)) {
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
- await (0, import_promises11.mkdir)(import_node_path12.default.dirname(auditFile), { recursive: true });
2745
- await (0, import_promises11.appendFile)(
2746
- auditFile,
2747
- `${JSON.stringify({
2748
- ts: (/* @__PURE__ */ new Date()).toISOString(),
2749
- ...event
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
- "utf8"
2753
- );
2896
+ "utf8"
2897
+ );
2898
+ } catch {
2899
+ }
2754
2900
  }
2755
2901
 
2756
2902
  // ../core/src/secrets/secretCache.ts
@@ -3722,7 +3868,7 @@ function envVarToLogicalKey(envVar, config = {}) {
3722
3868
  // package.json
3723
3869
  var package_default = {
3724
3870
  name: "@kitsy/cnos",
3725
- version: "1.9.1",
3871
+ version: "1.10.0",
3726
3872
  description: "Batteries-included CNOS runtime package wired with the official plugins.",
3727
3873
  type: "module",
3728
3874
  main: "./dist/index.cjs",
@@ -3927,9 +4073,30 @@ var DOTENV_PLUGIN_ID = "@kitsy/cnos/plugins/dotenv";
3927
4073
  function parseDoubleQuoted(value) {
3928
4074
  return value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
3929
4075
  }
4076
+ function isEscapedCharacter(value, index) {
4077
+ let slashCount = 0;
4078
+ for (let cursor = index - 1; cursor >= 0 && value[cursor] === "\\"; cursor -= 1) {
4079
+ slashCount += 1;
4080
+ }
4081
+ return slashCount % 2 === 1;
4082
+ }
4083
+ function findClosingQuote(value, quote) {
4084
+ for (let index = 0; index < value.length; index += 1) {
4085
+ if (value[index] !== quote) {
4086
+ continue;
4087
+ }
4088
+ if (quote === '"' && isEscapedCharacter(value, index)) {
4089
+ continue;
4090
+ }
4091
+ return index;
4092
+ }
4093
+ return -1;
4094
+ }
3930
4095
  function parseDotenv(document) {
3931
4096
  const parsed = {};
3932
- for (const rawLine of document.split(/\r?\n/)) {
4097
+ const lines = document.split(/\r?\n/);
4098
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
4099
+ const rawLine = lines[lineIndex] ?? "";
3933
4100
  const line = rawLine.trim();
3934
4101
  if (!line || line.startsWith("#")) {
3935
4102
  continue;
@@ -3944,10 +4111,18 @@ function parseDotenv(document) {
3944
4111
  if (!envVar) {
3945
4112
  continue;
3946
4113
  }
3947
- if (value.startsWith('"') && value.endsWith('"')) {
3948
- value = parseDoubleQuoted(value.slice(1, -1));
3949
- } else if (value.startsWith("'") && value.endsWith("'")) {
3950
- value = value.slice(1, -1);
4114
+ if (value.startsWith('"') || value.startsWith("'")) {
4115
+ const quote = value.startsWith('"') ? '"' : "'";
4116
+ let quotedContent = value.slice(1);
4117
+ let closingIndex = findClosingQuote(quotedContent, quote);
4118
+ while (closingIndex === -1 && lineIndex < lines.length - 1) {
4119
+ lineIndex += 1;
4120
+ quotedContent = `${quotedContent}
4121
+ ${lines[lineIndex] ?? ""}`;
4122
+ closingIndex = findClosingQuote(quotedContent, quote);
4123
+ }
4124
+ const rawQuotedValue = closingIndex === -1 ? quotedContent : quotedContent.slice(0, closingIndex);
4125
+ value = quote === '"' ? parseDoubleQuoted(rawQuotedValue) : rawQuotedValue;
3951
4126
  } else {
3952
4127
  value = value.replace(/\s+#.*$/, "").trim();
3953
4128
  }
package/dist/index.d.cts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { CnosSingleton, default as cnos, default } from './runtime/index.cjs';
2
- export { h as CnosPlugin, g as CnosRuntime, 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 } from './core-zDTUSVx9.cjs';
2
+ export { h as CnosPlugin, g as CnosRuntime, 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 } from './core-Ud1o2MBn.cjs';
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { CnosSingleton, default as cnos, default } from './runtime/index.js';
2
- export { h as CnosPlugin, g as CnosRuntime, 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 } from './core-zDTUSVx9.js';
2
+ export { h as CnosPlugin, g as CnosRuntime, 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 } from './core-Ud1o2MBn.js';
package/dist/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  runtime_default
3
- } from "./chunk-L6ZMJPA6.js";
4
- import "./chunk-NVFACB64.js";
5
- import "./chunk-MYG6EPUX.js";
6
- import "./chunk-LURQ4LAK.js";
7
- import "./chunk-A2WG3ZKW.js";
8
- import "./chunk-L7JVECPE.js";
9
- import "./chunk-6QQPHDUI.js";
10
- import "./chunk-7JZO6XN3.js";
11
- import "./chunk-2JBA2LXU.js";
12
- import "./chunk-7KVM5PUW.js";
3
+ } from "./chunk-EIK7OUFP.js";
4
+ import "./chunk-UKNL2Y4N.js";
5
+ import "./chunk-CSA4L64V.js";
6
+ import "./chunk-3EZGPQCE.js";
7
+ import "./chunk-RTHKUGJV.js";
8
+ import "./chunk-ESBHCFC6.js";
9
+ import "./chunk-UGLATJJD.js";
10
+ import "./chunk-A5U7EZCJ.js";
11
+ import "./chunk-FHXLOWAB.js";
12
+ import "./chunk-MQ4WG3K6.js";
13
13
  export {
14
14
  runtime_default as cnos,
15
15
  runtime_default as default