@kitsy/cnos 1.9.2 → 1.11.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 +523 -80
- package/dist/build/index.d.cts +1 -1
- package/dist/build/index.d.ts +1 -1
- package/dist/build/index.js +13 -15
- package/dist/{chunk-6QQPHDUI.js → chunk-2DMCB3PK.js} +1 -1
- package/dist/{chunk-LURQ4LAK.js → chunk-5JGNRADB.js} +1 -1
- package/dist/{chunk-2JBA2LXU.js → chunk-DPC2BV3S.js} +35 -6
- package/dist/{chunk-7JZO6XN3.js → chunk-KJ57PF47.js} +1 -1
- package/dist/{chunk-CPGRRZLP.js → chunk-NFGPS7VJ.js} +8 -8
- package/dist/{chunk-A2WG3ZKW.js → chunk-NU25VFA2.js} +1 -1
- package/dist/{chunk-L7JVECPE.js → chunk-RNTTPI5S.js} +1 -1
- package/dist/{chunk-NVFACB64.js → chunk-T3E57MSQ.js} +1 -1
- package/dist/{chunk-7KVM5PUW.js → chunk-WPB4HB2K.js} +478 -61
- package/dist/{chunk-QK7BMU47.js → chunk-XGK6DXQL.js} +157 -37
- package/dist/configure/index.cjs +521 -76
- 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-BW8SLnRx.d.cts} +46 -7
- package/dist/{core-zDTUSVx9.d.ts → core-BW8SLnRx.d.ts} +46 -7
- package/dist/{envNaming-EFzezmB3.d.cts → envNaming-1rk7BR0e.d.cts} +1 -1
- package/dist/{envNaming-BkorOKW_.d.ts → envNaming-CjL28IeH.d.ts} +1 -1
- package/dist/index.cjs +672 -108
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -10
- package/dist/internal.cjs +378 -54
- package/dist/internal.d.cts +32 -4
- package/dist/internal.d.ts +32 -4
- package/dist/internal.js +141 -23
- package/dist/plugin/basic-schema.cjs +13 -3
- 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 +4 -1
- 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 +40 -8
- 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 +5 -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.cjs +13 -10
- 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 +4 -1
- 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 +672 -108
- package/dist/runtime/index.d.cts +13 -6
- package/dist/runtime/index.d.ts +13 -6
- package/dist/runtime/index.js +10 -10
- package/dist/{toPublicEnv-Ds1DRwCX.d.cts → toPublicEnv-CZzpvhGg.d.cts} +1 -1
- package/dist/{toPublicEnv-CT265rzS.d.ts → toPublicEnv-CmydGcxg.d.ts} +1 -1
- package/package.json +1 -1
package/dist/internal.cjs
CHANGED
|
@@ -40,6 +40,7 @@ __export(internal_exports, {
|
|
|
40
40
|
clearAllVaultSessionKeys: () => clearAllVaultSessionKeys,
|
|
41
41
|
clearVaultSessionKey: () => clearVaultSessionKey,
|
|
42
42
|
compareSchemaToGraph: () => compareSchemaToGraph,
|
|
43
|
+
compareSpecToGraph: () => compareSpecToGraph,
|
|
43
44
|
createRemoteRootCacheKey: () => createRemoteRootCacheKey,
|
|
44
45
|
createSecretVault: () => createSecretVault,
|
|
45
46
|
createSecretVaultProvider: () => createSecretVaultProvider,
|
|
@@ -1033,6 +1034,134 @@ function resolveConfigDocumentPath(workspaceRoot, namespace, configPath, profile
|
|
|
1033
1034
|
return import_node_path5.default.resolve(namespaceRoot, fileName);
|
|
1034
1035
|
}
|
|
1035
1036
|
|
|
1037
|
+
// ../core/src/spec/normalizeSpecRule.ts
|
|
1038
|
+
var ALLOWED_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "object", "array"]);
|
|
1039
|
+
var SECRET_FORBIDDEN_FIELDS = ["default", "examples", "enum"];
|
|
1040
|
+
function hasOwn(target, key) {
|
|
1041
|
+
return Object.prototype.hasOwnProperty.call(target, key);
|
|
1042
|
+
}
|
|
1043
|
+
function normalizeOptionalString(value, fieldName, logicalKey) {
|
|
1044
|
+
if (value === void 0) {
|
|
1045
|
+
return void 0;
|
|
1046
|
+
}
|
|
1047
|
+
if (typeof value !== "string") {
|
|
1048
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "${fieldName}" must be a string.`);
|
|
1049
|
+
}
|
|
1050
|
+
const nextValue = value.trim();
|
|
1051
|
+
return nextValue.length > 0 ? nextValue : void 0;
|
|
1052
|
+
}
|
|
1053
|
+
function normalizeStringArray(value, fieldName, logicalKey) {
|
|
1054
|
+
if (value === void 0) {
|
|
1055
|
+
return void 0;
|
|
1056
|
+
}
|
|
1057
|
+
if (!Array.isArray(value)) {
|
|
1058
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "${fieldName}" must be an array.`);
|
|
1059
|
+
}
|
|
1060
|
+
const nextValue = value.map((entry) => {
|
|
1061
|
+
if (typeof entry !== "string") {
|
|
1062
|
+
throw new CnosManifestError(
|
|
1063
|
+
`Invalid schema rule for ${logicalKey}: "${fieldName}" entries must be strings.`
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
return entry.trim();
|
|
1067
|
+
}).filter(Boolean);
|
|
1068
|
+
return nextValue.length > 0 ? nextValue : void 0;
|
|
1069
|
+
}
|
|
1070
|
+
function normalizeUnknownArray(value, fieldName, logicalKey) {
|
|
1071
|
+
if (value === void 0) {
|
|
1072
|
+
return void 0;
|
|
1073
|
+
}
|
|
1074
|
+
if (!Array.isArray(value)) {
|
|
1075
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "${fieldName}" must be an array.`);
|
|
1076
|
+
}
|
|
1077
|
+
return value.length > 0 ? value : void 0;
|
|
1078
|
+
}
|
|
1079
|
+
function assertValidPatternRegex(pattern, logicalKey) {
|
|
1080
|
+
try {
|
|
1081
|
+
void new RegExp(pattern);
|
|
1082
|
+
} catch (error) {
|
|
1083
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
1084
|
+
throw new CnosManifestError(
|
|
1085
|
+
`Invalid schema rule for ${logicalKey}: "pattern" must be a valid regex (${reason}).`
|
|
1086
|
+
);
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
function assertSecretRuleSafety(logicalKey, rule) {
|
|
1090
|
+
if (!logicalKey.startsWith("secret.")) {
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
const offendingFields = SECRET_FORBIDDEN_FIELDS.filter((field) => hasOwn(rule, field));
|
|
1094
|
+
if (offendingFields.length === 0) {
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
throw new CnosManifestError(
|
|
1098
|
+
`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.`
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
function normalizeSpecRule(logicalKey, rule) {
|
|
1102
|
+
if (!rule || typeof rule !== "object" || Array.isArray(rule)) {
|
|
1103
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: expected an object.`);
|
|
1104
|
+
}
|
|
1105
|
+
const candidate = rule;
|
|
1106
|
+
assertSecretRuleSafety(logicalKey, candidate);
|
|
1107
|
+
const normalized = {};
|
|
1108
|
+
if (candidate.type !== void 0) {
|
|
1109
|
+
if (typeof candidate.type !== "string" || !ALLOWED_TYPES.has(candidate.type)) {
|
|
1110
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: unsupported type "${String(candidate.type)}".`);
|
|
1111
|
+
}
|
|
1112
|
+
normalized.type = candidate.type;
|
|
1113
|
+
}
|
|
1114
|
+
if (candidate.required !== void 0) {
|
|
1115
|
+
if (typeof candidate.required !== "boolean") {
|
|
1116
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "required" must be a boolean.`);
|
|
1117
|
+
}
|
|
1118
|
+
normalized.required = candidate.required;
|
|
1119
|
+
}
|
|
1120
|
+
if (hasOwn(candidate, "default")) {
|
|
1121
|
+
normalized.default = candidate.default;
|
|
1122
|
+
}
|
|
1123
|
+
const normalizedEnum = normalizeUnknownArray(candidate.enum, "enum", logicalKey);
|
|
1124
|
+
if (normalizedEnum !== void 0) {
|
|
1125
|
+
normalized.enum = normalizedEnum;
|
|
1126
|
+
}
|
|
1127
|
+
const normalizedPattern = normalizeOptionalString(candidate.pattern, "pattern", logicalKey);
|
|
1128
|
+
if (normalizedPattern !== void 0) {
|
|
1129
|
+
assertValidPatternRegex(normalizedPattern, logicalKey);
|
|
1130
|
+
normalized.pattern = normalizedPattern;
|
|
1131
|
+
}
|
|
1132
|
+
const normalizedSummary = normalizeOptionalString(candidate.summary, "summary", logicalKey);
|
|
1133
|
+
if (normalizedSummary !== void 0) {
|
|
1134
|
+
normalized.summary = normalizedSummary;
|
|
1135
|
+
}
|
|
1136
|
+
const normalizedDescription = normalizeOptionalString(candidate.description, "description", logicalKey);
|
|
1137
|
+
if (normalizedDescription !== void 0) {
|
|
1138
|
+
normalized.description = normalizedDescription;
|
|
1139
|
+
}
|
|
1140
|
+
const normalizedExamples = normalizeUnknownArray(candidate.examples, "examples", logicalKey);
|
|
1141
|
+
if (normalizedExamples !== void 0) {
|
|
1142
|
+
normalized.examples = normalizedExamples;
|
|
1143
|
+
}
|
|
1144
|
+
const normalizedUsedBy = normalizeStringArray(candidate.usedBy, "usedBy", logicalKey);
|
|
1145
|
+
if (normalizedUsedBy !== void 0) {
|
|
1146
|
+
normalized.usedBy = normalizedUsedBy;
|
|
1147
|
+
}
|
|
1148
|
+
if (candidate.deprecated !== void 0) {
|
|
1149
|
+
if (typeof candidate.deprecated !== "boolean") {
|
|
1150
|
+
throw new CnosManifestError(`Invalid schema rule for ${logicalKey}: "deprecated" must be a boolean.`);
|
|
1151
|
+
}
|
|
1152
|
+
normalized.deprecated = candidate.deprecated;
|
|
1153
|
+
}
|
|
1154
|
+
const normalizedDeprecationMessage = normalizeOptionalString(
|
|
1155
|
+
candidate.deprecationMessage,
|
|
1156
|
+
"deprecationMessage",
|
|
1157
|
+
logicalKey
|
|
1158
|
+
);
|
|
1159
|
+
if (normalizedDeprecationMessage !== void 0) {
|
|
1160
|
+
normalized.deprecationMessage = normalizedDeprecationMessage;
|
|
1161
|
+
}
|
|
1162
|
+
return normalized;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1036
1165
|
// ../core/src/manifest/normalizeManifest.ts
|
|
1037
1166
|
var DEFAULT_RESOLVE_FROM = ["cli.profile", "env.CNOS_PROFILE", "default"];
|
|
1038
1167
|
var DEFAULT_LOADERS = [
|
|
@@ -1166,11 +1295,19 @@ function normalizeVaults(vaults) {
|
|
|
1166
1295
|
throw new CnosManifestError(`Vault "${name}" requires a provider`);
|
|
1167
1296
|
}
|
|
1168
1297
|
const normalizedAuth = normalizeVaultAuth(name, provider, definition.auth);
|
|
1169
|
-
const normalizedMapping =
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1298
|
+
const normalizedMapping = normalizeVaultMapping(definition.mapping);
|
|
1299
|
+
const fallback = (definition.fallback ?? []).map((entry, index) => {
|
|
1300
|
+
const fallbackProvider = entry.provider?.trim();
|
|
1301
|
+
if (!fallbackProvider) {
|
|
1302
|
+
throw new CnosManifestError(`Vault "${name}" fallback ${index + 1} requires a provider`);
|
|
1303
|
+
}
|
|
1304
|
+
const fallbackMapping = normalizeVaultMapping(entry.mapping);
|
|
1305
|
+
return {
|
|
1306
|
+
provider: fallbackProvider,
|
|
1307
|
+
auth: normalizeVaultAuth(name, fallbackProvider, entry.auth),
|
|
1308
|
+
...Object.keys(fallbackMapping).length > 0 ? { mapping: fallbackMapping } : {}
|
|
1309
|
+
};
|
|
1310
|
+
});
|
|
1174
1311
|
return [
|
|
1175
1312
|
name,
|
|
1176
1313
|
{
|
|
@@ -1178,12 +1315,20 @@ function normalizeVaults(vaults) {
|
|
|
1178
1315
|
auth: normalizedAuth,
|
|
1179
1316
|
...Object.keys(normalizedMapping).length > 0 ? {
|
|
1180
1317
|
mapping: normalizedMapping
|
|
1181
|
-
} : {}
|
|
1318
|
+
} : {},
|
|
1319
|
+
...fallback.length > 0 ? { fallback } : {}
|
|
1182
1320
|
}
|
|
1183
1321
|
];
|
|
1184
1322
|
})
|
|
1185
1323
|
);
|
|
1186
1324
|
}
|
|
1325
|
+
function normalizeVaultMapping(mapping) {
|
|
1326
|
+
return Object.fromEntries(
|
|
1327
|
+
Object.entries(mapping ?? {}).filter(
|
|
1328
|
+
(entry) => typeof entry[0] === "string" && typeof entry[1] === "string"
|
|
1329
|
+
).map(([envVar, logicalRef]) => [envVar.trim(), logicalRef.trim()]).filter(([envVar, logicalRef]) => envVar.length > 0 && logicalRef.length > 0)
|
|
1330
|
+
);
|
|
1331
|
+
}
|
|
1187
1332
|
function normalizeAuthSources(value) {
|
|
1188
1333
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1189
1334
|
return void 0;
|
|
@@ -1231,6 +1376,14 @@ function normalizeVaultAuth(vaultName, provider, auth) {
|
|
|
1231
1376
|
...auth?.config ? { config: auth.config } : {}
|
|
1232
1377
|
};
|
|
1233
1378
|
}
|
|
1379
|
+
function normalizeSchema(schema) {
|
|
1380
|
+
return Object.fromEntries(
|
|
1381
|
+
Object.entries(schema ?? {}).map(([logicalKey, rule]) => [
|
|
1382
|
+
logicalKey,
|
|
1383
|
+
normalizeSpecRule(logicalKey, rule)
|
|
1384
|
+
])
|
|
1385
|
+
);
|
|
1386
|
+
}
|
|
1234
1387
|
function normalizeManifest(manifest) {
|
|
1235
1388
|
const version = manifest.version ?? 1;
|
|
1236
1389
|
if (version !== 1) {
|
|
@@ -1328,7 +1481,7 @@ function normalizeManifest(manifest) {
|
|
|
1328
1481
|
}
|
|
1329
1482
|
}
|
|
1330
1483
|
},
|
|
1331
|
-
schema: manifest.schema
|
|
1484
|
+
schema: normalizeSchema(manifest.schema)
|
|
1332
1485
|
};
|
|
1333
1486
|
}
|
|
1334
1487
|
|
|
@@ -1499,7 +1652,7 @@ function isObject(value) {
|
|
|
1499
1652
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1500
1653
|
}
|
|
1501
1654
|
function isSecretReference(value) {
|
|
1502
|
-
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));
|
|
1655
|
+
return isObject(value) && (value.provider === void 0 || 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));
|
|
1503
1656
|
}
|
|
1504
1657
|
function resolveSecretStoreRoot(processEnv = process.env) {
|
|
1505
1658
|
return import_node_path11.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
|
|
@@ -1836,16 +1989,19 @@ async function removeLocalVaultFiles(storeRoot, vault = "default") {
|
|
|
1836
1989
|
// ../core/src/secrets/auditLog.ts
|
|
1837
1990
|
async function appendAuditEvent(event, processEnv = process.env) {
|
|
1838
1991
|
const auditFile = processEnv.CNOS_AUDIT_FILE ?? import_node_path12.default.join(resolveSecretStoreRoot(processEnv), "audit", "access.log");
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1992
|
+
try {
|
|
1993
|
+
await (0, import_promises11.mkdir)(import_node_path12.default.dirname(auditFile), { recursive: true });
|
|
1994
|
+
await (0, import_promises11.appendFile)(
|
|
1995
|
+
auditFile,
|
|
1996
|
+
`${JSON.stringify({
|
|
1997
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1998
|
+
...event
|
|
1999
|
+
})}
|
|
1846
2000
|
`,
|
|
1847
|
-
|
|
1848
|
-
|
|
2001
|
+
"utf8"
|
|
2002
|
+
);
|
|
2003
|
+
} catch {
|
|
2004
|
+
}
|
|
1849
2005
|
}
|
|
1850
2006
|
|
|
1851
2007
|
// ../core/src/secrets/providers/environment.ts
|
|
@@ -1998,7 +2154,7 @@ var LocalSecretVaultProvider = class _LocalSecretVaultProvider {
|
|
|
1998
2154
|
};
|
|
1999
2155
|
|
|
2000
2156
|
// ../core/src/secrets/providers/registry.ts
|
|
2001
|
-
function createSecretVaultProvider(vaultId, definition, processEnv) {
|
|
2157
|
+
function createSecretVaultProvider(vaultId, definition, processEnv, factories = []) {
|
|
2002
2158
|
if (definition.provider === "local") {
|
|
2003
2159
|
return new LocalSecretVaultProvider(vaultId, definition, processEnv);
|
|
2004
2160
|
}
|
|
@@ -2008,9 +2164,16 @@ function createSecretVaultProvider(vaultId, definition, processEnv) {
|
|
|
2008
2164
|
if (definition.provider === "github-secrets") {
|
|
2009
2165
|
return new GithubSecretsVaultProvider(vaultId, definition, processEnv);
|
|
2010
2166
|
}
|
|
2167
|
+
const factory = factories.find((candidate) => candidate.provider === definition.provider);
|
|
2168
|
+
if (factory) {
|
|
2169
|
+
return factory.create(vaultId, definition, processEnv);
|
|
2170
|
+
}
|
|
2011
2171
|
throw new CnosManifestError(`Unsupported vault provider: ${definition.provider}`);
|
|
2012
2172
|
}
|
|
2013
2173
|
|
|
2174
|
+
// ../core/src/secrets/resolveAuth.ts
|
|
2175
|
+
var import_promises12 = require("fs/promises");
|
|
2176
|
+
|
|
2014
2177
|
// ../core/src/secrets/prompt.ts
|
|
2015
2178
|
var import_node_readline = __toESM(require("readline"), 1);
|
|
2016
2179
|
var import_node_stream = require("stream");
|
|
@@ -2051,6 +2214,23 @@ function toAuthError(vaultId, sources) {
|
|
|
2051
2214
|
`Cannot authenticate to vault "${vaultId}". Tried: ${sources.join(", ")}. Set ${getVaultPassphraseEnvVar(vaultId)} or run cnos vault auth ${vaultId}.`
|
|
2052
2215
|
);
|
|
2053
2216
|
}
|
|
2217
|
+
async function resolveTokenFromSource(source, processEnv) {
|
|
2218
|
+
if (source.startsWith("env:")) {
|
|
2219
|
+
return processEnv[source.slice(4)] || void 0;
|
|
2220
|
+
}
|
|
2221
|
+
if (source.startsWith("file:")) {
|
|
2222
|
+
try {
|
|
2223
|
+
const value = await (0, import_promises12.readFile)(expandHomePath(source.slice("file:".length)), "utf8");
|
|
2224
|
+
return value.trim() || void 0;
|
|
2225
|
+
} catch {
|
|
2226
|
+
return void 0;
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
if (source.startsWith("keychain:")) {
|
|
2230
|
+
return readKeychain(source.slice("keychain:".length));
|
|
2231
|
+
}
|
|
2232
|
+
return void 0;
|
|
2233
|
+
}
|
|
2054
2234
|
async function resolveVaultAuth(vaultId, definition, processEnv = process.env) {
|
|
2055
2235
|
const sessionKey = await resolveVaultSessionKey(vaultId, processEnv);
|
|
2056
2236
|
if (sessionKey) {
|
|
@@ -2066,6 +2246,32 @@ async function resolveVaultAuth(vaultId, definition, processEnv = process.env) {
|
|
|
2066
2246
|
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
2067
2247
|
};
|
|
2068
2248
|
}
|
|
2249
|
+
if (definition.auth?.method === "iam") {
|
|
2250
|
+
return {
|
|
2251
|
+
method: "iam",
|
|
2252
|
+
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
if (definition.auth?.method === "environment") {
|
|
2256
|
+
return {
|
|
2257
|
+
method: "environment",
|
|
2258
|
+
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
2259
|
+
};
|
|
2260
|
+
}
|
|
2261
|
+
const tokenSources = definition.auth?.token?.from ?? [];
|
|
2262
|
+
for (const source of tokenSources) {
|
|
2263
|
+
const token = await resolveTokenFromSource(source, processEnv);
|
|
2264
|
+
if (token) {
|
|
2265
|
+
return {
|
|
2266
|
+
token,
|
|
2267
|
+
method: "token",
|
|
2268
|
+
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
2269
|
+
};
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
if (definition.auth?.method === "token") {
|
|
2273
|
+
throw toAuthError(vaultId, [getVaultSessionKeyEnvVar(vaultId), ...tokenSources]);
|
|
2274
|
+
}
|
|
2069
2275
|
const sources = definition.auth?.passphrase?.from ?? [getVaultPassphraseEnvVar(vaultId)];
|
|
2070
2276
|
for (const source of sources) {
|
|
2071
2277
|
if (source.startsWith("env:")) {
|
|
@@ -2114,7 +2320,7 @@ async function resolveVaultAuth(vaultId, definition, processEnv = process.env) {
|
|
|
2114
2320
|
var import_node_crypto3 = require("crypto");
|
|
2115
2321
|
|
|
2116
2322
|
// ../core/src/runtime/dump.ts
|
|
2117
|
-
var
|
|
2323
|
+
var import_promises13 = require("fs/promises");
|
|
2118
2324
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
2119
2325
|
|
|
2120
2326
|
// ../core/src/utils/envNaming.ts
|
|
@@ -2516,7 +2722,7 @@ function generateCodegenContent(manifest, sourcePath, typeModuleImport = "./cnos
|
|
|
2516
2722
|
}
|
|
2517
2723
|
|
|
2518
2724
|
// src/codegen/writeOutput.ts
|
|
2519
|
-
var
|
|
2725
|
+
var import_promises14 = require("fs/promises");
|
|
2520
2726
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
2521
2727
|
function stripTsExtension(filePath) {
|
|
2522
2728
|
return filePath.replace(/(\.d)?\.[cm]?tsx?$/i, "").replace(/\.[cm]?jsx?$/i, "");
|
|
@@ -2536,10 +2742,10 @@ async function writeCodegenOutput(options = {}) {
|
|
|
2536
2742
|
const outputRoot = loadedManifest.rootResolution.remote ? loadedManifest.consumerRoot : loadedManifest.repoRoot;
|
|
2537
2743
|
const paths = resolveCodegenPaths(outputRoot, options.out);
|
|
2538
2744
|
const generated = generateCodegenContent(loadedManifest.manifest, loadedManifest.manifestPath, paths.typeImportPath);
|
|
2539
|
-
await (0,
|
|
2540
|
-
await (0,
|
|
2541
|
-
await (0,
|
|
2542
|
-
await (0,
|
|
2745
|
+
await (0, import_promises14.mkdir)(import_node_path14.default.dirname(paths.typesPath), { recursive: true });
|
|
2746
|
+
await (0, import_promises14.mkdir)(import_node_path14.default.dirname(paths.runtimePath), { recursive: true });
|
|
2747
|
+
await (0, import_promises14.writeFile)(paths.typesPath, generated.typesContent, "utf8");
|
|
2748
|
+
await (0, import_promises14.writeFile)(paths.runtimePath, generated.runtimeContent, "utf8");
|
|
2543
2749
|
return {
|
|
2544
2750
|
manifestPath: loadedManifest.manifestPath,
|
|
2545
2751
|
typesPath: paths.typesPath,
|
|
@@ -2580,7 +2786,7 @@ async function watchSchema(options = {}) {
|
|
|
2580
2786
|
return watcher;
|
|
2581
2787
|
}
|
|
2582
2788
|
|
|
2583
|
-
// src/
|
|
2789
|
+
// src/spec/compareSpecToGraph.ts
|
|
2584
2790
|
function describeValueType(value) {
|
|
2585
2791
|
if (Array.isArray(value)) {
|
|
2586
2792
|
return "array";
|
|
@@ -2603,6 +2809,17 @@ function matchesType(value, type) {
|
|
|
2603
2809
|
return typeof value === type;
|
|
2604
2810
|
}
|
|
2605
2811
|
}
|
|
2812
|
+
function enumMatches(value, allowed) {
|
|
2813
|
+
const serialized = JSON.stringify(value);
|
|
2814
|
+
return allowed.some((candidate) => JSON.stringify(candidate) === serialized);
|
|
2815
|
+
}
|
|
2816
|
+
function matchesPattern(pattern, value) {
|
|
2817
|
+
try {
|
|
2818
|
+
return new RegExp(pattern).test(value);
|
|
2819
|
+
} catch {
|
|
2820
|
+
return false;
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2606
2823
|
function isSchemaDefault(entry) {
|
|
2607
2824
|
return entry.winner.metadata?.schemaDefault === true;
|
|
2608
2825
|
}
|
|
@@ -2612,34 +2829,53 @@ function shouldTrackKey(key) {
|
|
|
2612
2829
|
function isTransientRuntimeSource(entry) {
|
|
2613
2830
|
return entry.winner.sourceId === "process-env" || entry.winner.sourceId === "cli-args";
|
|
2614
2831
|
}
|
|
2615
|
-
function
|
|
2832
|
+
function buildSummary(issues) {
|
|
2833
|
+
return {
|
|
2834
|
+
missingRequired: issues.filter((issue) => issue.status === "missing_required").length,
|
|
2835
|
+
undeclared: issues.filter((issue) => issue.status === "undeclared").length,
|
|
2836
|
+
typeMismatch: issues.filter((issue) => issue.status === "type_mismatch").length,
|
|
2837
|
+
enumMismatch: issues.filter((issue) => issue.status === "enum_mismatch").length,
|
|
2838
|
+
patternMismatch: issues.filter((issue) => issue.status === "pattern_mismatch").length,
|
|
2839
|
+
defaultApplied: issues.filter((issue) => issue.status === "default_applied").length,
|
|
2840
|
+
deprecatedInUse: issues.filter((issue) => issue.status === "deprecated_in_use").length
|
|
2841
|
+
};
|
|
2842
|
+
}
|
|
2843
|
+
function compareSpecToGraph(runtime) {
|
|
2616
2844
|
const schema = runtime.manifest.schema;
|
|
2617
|
-
const
|
|
2618
|
-
const mismatches = [];
|
|
2619
|
-
const defaultsApplied = [];
|
|
2845
|
+
const issues = [];
|
|
2620
2846
|
for (const [key, rule] of Object.entries(schema).sort(([left], [right]) => left.localeCompare(right))) {
|
|
2621
2847
|
const entry = runtime.graph.entries.get(key);
|
|
2848
|
+
const summary = rule.summary;
|
|
2622
2849
|
if (!entry) {
|
|
2623
2850
|
if (rule.required && rule.default === void 0) {
|
|
2624
|
-
|
|
2851
|
+
issues.push({
|
|
2625
2852
|
key,
|
|
2853
|
+
status: "missing_required",
|
|
2626
2854
|
...rule.type ? {
|
|
2627
2855
|
expectedType: rule.type
|
|
2856
|
+
} : {},
|
|
2857
|
+
...summary ? {
|
|
2858
|
+
summary
|
|
2628
2859
|
} : {}
|
|
2629
2860
|
});
|
|
2630
2861
|
}
|
|
2631
2862
|
continue;
|
|
2632
2863
|
}
|
|
2633
2864
|
if (isSchemaDefault(entry)) {
|
|
2634
|
-
|
|
2865
|
+
issues.push({
|
|
2635
2866
|
key,
|
|
2636
|
-
|
|
2867
|
+
status: "default_applied",
|
|
2868
|
+
value: entry.value,
|
|
2869
|
+
...summary ? {
|
|
2870
|
+
summary
|
|
2871
|
+
} : {}
|
|
2637
2872
|
});
|
|
2638
2873
|
}
|
|
2639
2874
|
const actualValue = entry.winner.value;
|
|
2640
2875
|
if (!matchesType(actualValue, rule.type)) {
|
|
2641
|
-
|
|
2876
|
+
issues.push({
|
|
2642
2877
|
key,
|
|
2878
|
+
status: "type_mismatch",
|
|
2643
2879
|
...rule.type ? {
|
|
2644
2880
|
expectedType: rule.type
|
|
2645
2881
|
} : {},
|
|
@@ -2647,26 +2883,113 @@ function compareSchemaToGraph(runtime) {
|
|
|
2647
2883
|
value: actualValue,
|
|
2648
2884
|
...entry.winner.origin?.file ? {
|
|
2649
2885
|
sourceFile: entry.winner.origin.file
|
|
2886
|
+
} : {},
|
|
2887
|
+
...summary ? {
|
|
2888
|
+
summary
|
|
2889
|
+
} : {}
|
|
2890
|
+
});
|
|
2891
|
+
}
|
|
2892
|
+
if (rule.enum && !enumMatches(actualValue, rule.enum)) {
|
|
2893
|
+
issues.push({
|
|
2894
|
+
key,
|
|
2895
|
+
status: "enum_mismatch",
|
|
2896
|
+
value: actualValue,
|
|
2897
|
+
...summary ? {
|
|
2898
|
+
summary
|
|
2899
|
+
} : {}
|
|
2900
|
+
});
|
|
2901
|
+
}
|
|
2902
|
+
if (rule.pattern) {
|
|
2903
|
+
if (typeof actualValue !== "string" || !matchesPattern(rule.pattern, actualValue)) {
|
|
2904
|
+
issues.push({
|
|
2905
|
+
key,
|
|
2906
|
+
status: "pattern_mismatch",
|
|
2907
|
+
value: actualValue,
|
|
2908
|
+
pattern: rule.pattern,
|
|
2909
|
+
...summary ? {
|
|
2910
|
+
summary
|
|
2911
|
+
} : {}
|
|
2912
|
+
});
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2915
|
+
if (rule.deprecated) {
|
|
2916
|
+
issues.push({
|
|
2917
|
+
key,
|
|
2918
|
+
status: "deprecated_in_use",
|
|
2919
|
+
value: actualValue,
|
|
2920
|
+
...summary ? {
|
|
2921
|
+
summary
|
|
2650
2922
|
} : {}
|
|
2651
2923
|
});
|
|
2652
2924
|
}
|
|
2653
2925
|
}
|
|
2654
|
-
const
|
|
2926
|
+
const undeclaredIssues = Array.from(runtime.graph.entries.values()).filter(
|
|
2655
2927
|
(entry) => shouldTrackKey(entry.key) && !schema[entry.key] && !isSchemaDefault(entry) && !isTransientRuntimeSource(entry)
|
|
2656
|
-
).map((entry) => {
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
}).sort((left, right) => left.key.localeCompare(right.key));
|
|
2928
|
+
).map((entry) => ({
|
|
2929
|
+
key: entry.key,
|
|
2930
|
+
status: "undeclared",
|
|
2931
|
+
value: entry.winner.value,
|
|
2932
|
+
actualType: describeValueType(entry.winner.value),
|
|
2933
|
+
...entry.winner.origin?.file ? {
|
|
2934
|
+
sourceFile: entry.winner.origin.file
|
|
2935
|
+
} : {}
|
|
2936
|
+
})).sort((left, right) => left.key.localeCompare(right.key));
|
|
2937
|
+
const allIssues = [...issues, ...undeclaredIssues].sort((left, right) => left.key.localeCompare(right.key));
|
|
2667
2938
|
return {
|
|
2668
2939
|
profile: runtime.graph.profile,
|
|
2669
2940
|
workspace: runtime.graph.workspace.workspaceId,
|
|
2941
|
+
summary: buildSummary(allIssues),
|
|
2942
|
+
issues: allIssues
|
|
2943
|
+
};
|
|
2944
|
+
}
|
|
2945
|
+
|
|
2946
|
+
// src/drift/compareSchemaToGraph.ts
|
|
2947
|
+
function compareSchemaToGraph(runtime) {
|
|
2948
|
+
const report = compareSpecToGraph(runtime);
|
|
2949
|
+
const missing = report.issues.filter((issue) => issue.status === "missing_required").map(
|
|
2950
|
+
(issue) => ({
|
|
2951
|
+
key: issue.key,
|
|
2952
|
+
...issue.expectedType ? {
|
|
2953
|
+
expectedType: issue.expectedType
|
|
2954
|
+
} : {}
|
|
2955
|
+
})
|
|
2956
|
+
);
|
|
2957
|
+
const undeclared = report.issues.filter((issue) => issue.status === "undeclared").map(
|
|
2958
|
+
(issue) => ({
|
|
2959
|
+
key: issue.key,
|
|
2960
|
+
value: issue.value,
|
|
2961
|
+
...issue.actualType ? {
|
|
2962
|
+
actualType: issue.actualType
|
|
2963
|
+
} : {},
|
|
2964
|
+
...issue.sourceFile ? {
|
|
2965
|
+
sourceFile: issue.sourceFile
|
|
2966
|
+
} : {}
|
|
2967
|
+
})
|
|
2968
|
+
);
|
|
2969
|
+
const mismatches = report.issues.filter((issue) => issue.status === "type_mismatch").map(
|
|
2970
|
+
(issue) => ({
|
|
2971
|
+
key: issue.key,
|
|
2972
|
+
...issue.expectedType ? {
|
|
2973
|
+
expectedType: issue.expectedType
|
|
2974
|
+
} : {},
|
|
2975
|
+
...issue.actualType ? {
|
|
2976
|
+
actualType: issue.actualType
|
|
2977
|
+
} : {},
|
|
2978
|
+
value: issue.value,
|
|
2979
|
+
...issue.sourceFile ? {
|
|
2980
|
+
sourceFile: issue.sourceFile
|
|
2981
|
+
} : {}
|
|
2982
|
+
})
|
|
2983
|
+
);
|
|
2984
|
+
const defaultsApplied = report.issues.filter((issue) => issue.status === "default_applied").map(
|
|
2985
|
+
(issue) => ({
|
|
2986
|
+
key: issue.key,
|
|
2987
|
+
value: issue.value
|
|
2988
|
+
})
|
|
2989
|
+
);
|
|
2990
|
+
return {
|
|
2991
|
+
profile: report.profile,
|
|
2992
|
+
workspace: report.workspace,
|
|
2670
2993
|
missing,
|
|
2671
2994
|
undeclared,
|
|
2672
2995
|
mismatches,
|
|
@@ -2725,7 +3048,7 @@ function formatDriftReport(report) {
|
|
|
2725
3048
|
}
|
|
2726
3049
|
|
|
2727
3050
|
// src/migrate/applyManifest.ts
|
|
2728
|
-
var
|
|
3051
|
+
var import_promises15 = require("fs/promises");
|
|
2729
3052
|
function sortRecord(record) {
|
|
2730
3053
|
return Object.fromEntries(Object.entries(record).sort(([left], [right]) => left.localeCompare(right)));
|
|
2731
3054
|
}
|
|
@@ -2760,7 +3083,7 @@ async function applyManifestMappings(proposals, root) {
|
|
|
2760
3083
|
promote: Array.from(promoted).sort((left, right) => left.localeCompare(right))
|
|
2761
3084
|
};
|
|
2762
3085
|
}
|
|
2763
|
-
await (0,
|
|
3086
|
+
await (0, import_promises15.writeFile)(loadedManifest.manifestPath, stringifyYaml(rawManifest), "utf8");
|
|
2764
3087
|
return {
|
|
2765
3088
|
manifestPath: loadedManifest.manifestPath,
|
|
2766
3089
|
appliedMappings,
|
|
@@ -2795,7 +3118,7 @@ function proposeMapping(envVar) {
|
|
|
2795
3118
|
}
|
|
2796
3119
|
|
|
2797
3120
|
// src/migrate/rewriteSource.ts
|
|
2798
|
-
var
|
|
3121
|
+
var import_promises16 = require("fs/promises");
|
|
2799
3122
|
function importStatementFor(kind) {
|
|
2800
3123
|
return kind === "import-meta-env" ? "import cnos from '@kitsy/cnos/browser';" : "import cnos from '@kitsy/cnos';";
|
|
2801
3124
|
}
|
|
@@ -2816,7 +3139,7 @@ async function rewriteSourceFiles(usages, proposals) {
|
|
|
2816
3139
|
const backupFiles = [];
|
|
2817
3140
|
const skippedUsages = [];
|
|
2818
3141
|
for (const [filePath, fileUsages] of fileGroups.entries()) {
|
|
2819
|
-
const original = await (0,
|
|
3142
|
+
const original = await (0, import_promises16.readFile)(filePath, "utf8");
|
|
2820
3143
|
let nextSource = original;
|
|
2821
3144
|
let changed = false;
|
|
2822
3145
|
const importKinds = /* @__PURE__ */ new Set();
|
|
@@ -2843,7 +3166,7 @@ async function rewriteSourceFiles(usages, proposals) {
|
|
|
2843
3166
|
continue;
|
|
2844
3167
|
}
|
|
2845
3168
|
const backupPath = `${filePath}.bak`;
|
|
2846
|
-
await (0,
|
|
3169
|
+
await (0, import_promises16.copyFile)(filePath, backupPath);
|
|
2847
3170
|
backupFiles.push(backupPath);
|
|
2848
3171
|
for (const kind of Array.from(importKinds)) {
|
|
2849
3172
|
const importStatement = importStatementFor(kind);
|
|
@@ -2852,7 +3175,7 @@ async function rewriteSourceFiles(usages, proposals) {
|
|
|
2852
3175
|
${nextSource}`;
|
|
2853
3176
|
}
|
|
2854
3177
|
}
|
|
2855
|
-
await (0,
|
|
3178
|
+
await (0, import_promises16.writeFile)(filePath, nextSource, "utf8");
|
|
2856
3179
|
rewrittenFiles.push(filePath);
|
|
2857
3180
|
}
|
|
2858
3181
|
return {
|
|
@@ -2863,7 +3186,7 @@ ${nextSource}`;
|
|
|
2863
3186
|
}
|
|
2864
3187
|
|
|
2865
3188
|
// src/migrate/scanEnvUsage.ts
|
|
2866
|
-
var
|
|
3189
|
+
var import_promises17 = require("fs/promises");
|
|
2867
3190
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
2868
3191
|
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mts", ".cts", ".mjs", ".cjs"]);
|
|
2869
3192
|
var PROCESS_ENV_DOT = /process\.env\.([A-Z][A-Z0-9_]*)/g;
|
|
@@ -2871,7 +3194,7 @@ var PROCESS_ENV_BRACKET = /process\.env\[['"]([A-Z][A-Z0-9_]*)['"]\]/g;
|
|
|
2871
3194
|
var IMPORT_META_ENV_DOT = /import\.meta\.env\.([A-Z][A-Z0-9_]*)/g;
|
|
2872
3195
|
var IMPORT_META_ENV_BRACKET = /import\.meta\.env\[['"]([A-Z][A-Z0-9_]*)['"]\]/g;
|
|
2873
3196
|
async function collectFiles(root) {
|
|
2874
|
-
const entries = await (0,
|
|
3197
|
+
const entries = await (0, import_promises17.readdir)(root, { withFileTypes: true });
|
|
2875
3198
|
const files = [];
|
|
2876
3199
|
for (const entry of entries) {
|
|
2877
3200
|
const filePath = import_node_path15.default.join(root, entry.name);
|
|
@@ -2908,7 +3231,7 @@ async function scanEnvUsage(scanRoot) {
|
|
|
2908
3231
|
const files = await collectFiles(scanRoot);
|
|
2909
3232
|
const usages = [];
|
|
2910
3233
|
for (const filePath of files) {
|
|
2911
|
-
const source = await (0,
|
|
3234
|
+
const source = await (0, import_promises17.readFile)(filePath, "utf8");
|
|
2912
3235
|
usages.push(...collectMatches(filePath, source, PROCESS_ENV_DOT, "process-env"));
|
|
2913
3236
|
usages.push(...collectMatches(filePath, source, PROCESS_ENV_BRACKET, "process-env"));
|
|
2914
3237
|
usages.push(...collectMatches(filePath, source, IMPORT_META_ENV_DOT, "import-meta-env"));
|
|
@@ -2978,6 +3301,7 @@ async function watchFiles(runtime, root) {
|
|
|
2978
3301
|
clearAllVaultSessionKeys,
|
|
2979
3302
|
clearVaultSessionKey,
|
|
2980
3303
|
compareSchemaToGraph,
|
|
3304
|
+
compareSpecToGraph,
|
|
2981
3305
|
createRemoteRootCacheKey,
|
|
2982
3306
|
createSecretVault,
|
|
2983
3307
|
createSecretVaultProvider,
|