@kitsy/cnos 1.10.0 → 1.11.1
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 +331 -63
- 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-A5U7EZCJ.js → chunk-2DMCB3PK.js} +1 -1
- package/dist/{chunk-RTHKUGJV.js → chunk-5JGNRADB.js} +1 -1
- package/dist/{chunk-3EZGPQCE.js → chunk-DPC2BV3S.js} +1 -1
- package/dist/{chunk-FHXLOWAB.js → chunk-KJ57PF47.js} +1 -1
- package/dist/{chunk-ESBHCFC6.js → chunk-NU25VFA2.js} +1 -1
- package/dist/{chunk-UGLATJJD.js → chunk-RNTTPI5S.js} +1 -1
- package/dist/{chunk-UKNL2Y4N.js → chunk-T3E57MSQ.js} +1 -1
- package/dist/{chunk-CSA4L64V.js → chunk-V3USPV5U.js} +8 -8
- package/dist/{chunk-MQ4WG3K6.js → chunk-WPB4HB2K.js} +320 -49
- package/dist/{chunk-EIK7OUFP.js → chunk-X4PBPUKL.js} +157 -37
- package/dist/configure/index.cjs +329 -59
- 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-Ud1o2MBn.d.cts → core-CGJObpyy.d.cts} +40 -2
- package/dist/{core-Ud1o2MBn.d.ts → core-CGJObpyy.d.ts} +40 -2
- package/dist/{envNaming-DxxqiGKN.d.cts → envNaming-DIaBgT6E.d.cts} +1 -1
- package/dist/{envNaming-CPwXl4I6.d.ts → envNaming-_WD9sLZI.d.ts} +1 -1
- package/dist/index.cjs +480 -91
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -10
- package/dist/internal.cjs +89 -23
- package/dist/internal.d.cts +3 -3
- package/dist/internal.d.ts +3 -3
- package/dist/internal.js +2 -2
- package/dist/plugin/basic-schema.cjs +4 -1
- 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 +6 -3
- 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 +480 -91
- 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-fUZMRUOz.d.cts → toPublicEnv-C3A8aLjo.d.cts} +1 -1
- package/dist/{toPublicEnv-C9wPSpRo.d.ts → toPublicEnv-DLNNcEso.d.ts} +1 -1
- package/package.json +1 -1
package/dist/build/index.cjs
CHANGED
|
@@ -1601,11 +1601,19 @@ function normalizeVaults(vaults) {
|
|
|
1601
1601
|
throw new CnosManifestError(`Vault "${name}" requires a provider`);
|
|
1602
1602
|
}
|
|
1603
1603
|
const normalizedAuth = normalizeVaultAuth(name, provider, definition.auth);
|
|
1604
|
-
const normalizedMapping =
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1604
|
+
const normalizedMapping = normalizeVaultMapping(definition.mapping);
|
|
1605
|
+
const fallback = (definition.fallback ?? []).map((entry, index) => {
|
|
1606
|
+
const fallbackProvider = entry.provider?.trim();
|
|
1607
|
+
if (!fallbackProvider) {
|
|
1608
|
+
throw new CnosManifestError(`Vault "${name}" fallback ${index + 1} requires a provider`);
|
|
1609
|
+
}
|
|
1610
|
+
const fallbackMapping = normalizeVaultMapping(entry.mapping);
|
|
1611
|
+
return {
|
|
1612
|
+
provider: fallbackProvider,
|
|
1613
|
+
auth: normalizeVaultAuth(name, fallbackProvider, entry.auth),
|
|
1614
|
+
...Object.keys(fallbackMapping).length > 0 ? { mapping: fallbackMapping } : {}
|
|
1615
|
+
};
|
|
1616
|
+
});
|
|
1609
1617
|
return [
|
|
1610
1618
|
name,
|
|
1611
1619
|
{
|
|
@@ -1613,12 +1621,20 @@ function normalizeVaults(vaults) {
|
|
|
1613
1621
|
auth: normalizedAuth,
|
|
1614
1622
|
...Object.keys(normalizedMapping).length > 0 ? {
|
|
1615
1623
|
mapping: normalizedMapping
|
|
1616
|
-
} : {}
|
|
1624
|
+
} : {},
|
|
1625
|
+
...fallback.length > 0 ? { fallback } : {}
|
|
1617
1626
|
}
|
|
1618
1627
|
];
|
|
1619
1628
|
})
|
|
1620
1629
|
);
|
|
1621
1630
|
}
|
|
1631
|
+
function normalizeVaultMapping(mapping) {
|
|
1632
|
+
return Object.fromEntries(
|
|
1633
|
+
Object.entries(mapping ?? {}).filter(
|
|
1634
|
+
(entry) => typeof entry[0] === "string" && typeof entry[1] === "string"
|
|
1635
|
+
).map(([envVar, logicalRef]) => [envVar.trim(), logicalRef.trim()]).filter(([envVar, logicalRef]) => envVar.length > 0 && logicalRef.length > 0)
|
|
1636
|
+
);
|
|
1637
|
+
}
|
|
1622
1638
|
function normalizeAuthSources(value) {
|
|
1623
1639
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1624
1640
|
return void 0;
|
|
@@ -2566,7 +2582,7 @@ function isObject(value) {
|
|
|
2566
2582
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2567
2583
|
}
|
|
2568
2584
|
function isSecretReference(value) {
|
|
2569
|
-
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));
|
|
2585
|
+
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));
|
|
2570
2586
|
}
|
|
2571
2587
|
function resolveSecretStoreRoot(processEnv = process.env) {
|
|
2572
2588
|
return import_node_path11.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
|
|
@@ -2913,6 +2929,23 @@ var SecretCache = class {
|
|
|
2913
2929
|
get(vaultId, ref) {
|
|
2914
2930
|
return this.cache.get(`${vaultId}:${ref}`);
|
|
2915
2931
|
}
|
|
2932
|
+
delete(vaultId, ref) {
|
|
2933
|
+
this.cache.delete(`${vaultId}:${ref}`);
|
|
2934
|
+
}
|
|
2935
|
+
replace(vaultId, secrets) {
|
|
2936
|
+
this.clear(vaultId);
|
|
2937
|
+
this.load(vaultId, secrets);
|
|
2938
|
+
}
|
|
2939
|
+
entriesForVault(vaultId) {
|
|
2940
|
+
const entries = /* @__PURE__ */ new Map();
|
|
2941
|
+
for (const [key, value] of this.cache) {
|
|
2942
|
+
const prefix = `${vaultId}:`;
|
|
2943
|
+
if (key.startsWith(prefix)) {
|
|
2944
|
+
entries.set(key.slice(prefix.length), value);
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
return entries;
|
|
2948
|
+
}
|
|
2916
2949
|
clear(vaultId) {
|
|
2917
2950
|
if (!vaultId) {
|
|
2918
2951
|
this.cache.clear();
|
|
@@ -3078,7 +3111,7 @@ var LocalSecretVaultProvider = class _LocalSecretVaultProvider {
|
|
|
3078
3111
|
};
|
|
3079
3112
|
|
|
3080
3113
|
// ../core/src/secrets/providers/registry.ts
|
|
3081
|
-
function createSecretVaultProvider(vaultId, definition, processEnv) {
|
|
3114
|
+
function createSecretVaultProvider(vaultId, definition, processEnv, factories = []) {
|
|
3082
3115
|
if (definition.provider === "local") {
|
|
3083
3116
|
return new LocalSecretVaultProvider(vaultId, definition, processEnv);
|
|
3084
3117
|
}
|
|
@@ -3088,9 +3121,30 @@ function createSecretVaultProvider(vaultId, definition, processEnv) {
|
|
|
3088
3121
|
if (definition.provider === "github-secrets") {
|
|
3089
3122
|
return new GithubSecretsVaultProvider(vaultId, definition, processEnv);
|
|
3090
3123
|
}
|
|
3124
|
+
const factory = factories.find((candidate) => candidate.provider === definition.provider);
|
|
3125
|
+
if (factory) {
|
|
3126
|
+
return factory.create(vaultId, definition, processEnv);
|
|
3127
|
+
}
|
|
3091
3128
|
throw new CnosManifestError(`Unsupported vault provider: ${definition.provider}`);
|
|
3092
3129
|
}
|
|
3093
3130
|
|
|
3131
|
+
// ../core/src/secrets/providerCompatibility.ts
|
|
3132
|
+
function assertSecretRefVaultProviderCompatible(manifest, ref, logicalKey = "secret ref") {
|
|
3133
|
+
if (!ref.vault || !ref.provider) {
|
|
3134
|
+
return;
|
|
3135
|
+
}
|
|
3136
|
+
const definition = manifest.vaults[ref.vault];
|
|
3137
|
+
if (!definition || definition.provider === ref.provider) {
|
|
3138
|
+
return;
|
|
3139
|
+
}
|
|
3140
|
+
throw new CnosManifestError(
|
|
3141
|
+
`Secret ref "${logicalKey}" declares provider "${ref.provider}" but vault "${ref.vault}" uses provider "${definition.provider}". Remove the ref provider or use a matching vault.`
|
|
3142
|
+
);
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3145
|
+
// ../core/src/secrets/resolveAuth.ts
|
|
3146
|
+
var import_promises12 = require("fs/promises");
|
|
3147
|
+
|
|
3094
3148
|
// ../core/src/secrets/prompt.ts
|
|
3095
3149
|
var import_node_readline = __toESM(require("readline"), 1);
|
|
3096
3150
|
var import_node_stream = require("stream");
|
|
@@ -3131,6 +3185,23 @@ function toAuthError(vaultId, sources) {
|
|
|
3131
3185
|
`Cannot authenticate to vault "${vaultId}". Tried: ${sources.join(", ")}. Set ${getVaultPassphraseEnvVar(vaultId)} or run cnos vault auth ${vaultId}.`
|
|
3132
3186
|
);
|
|
3133
3187
|
}
|
|
3188
|
+
async function resolveTokenFromSource(source, processEnv) {
|
|
3189
|
+
if (source.startsWith("env:")) {
|
|
3190
|
+
return processEnv[source.slice(4)] || void 0;
|
|
3191
|
+
}
|
|
3192
|
+
if (source.startsWith("file:")) {
|
|
3193
|
+
try {
|
|
3194
|
+
const value = await (0, import_promises12.readFile)(expandHomePath(source.slice("file:".length)), "utf8");
|
|
3195
|
+
return value.trim() || void 0;
|
|
3196
|
+
} catch {
|
|
3197
|
+
return void 0;
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
if (source.startsWith("keychain:")) {
|
|
3201
|
+
return readKeychain(source.slice("keychain:".length));
|
|
3202
|
+
}
|
|
3203
|
+
return void 0;
|
|
3204
|
+
}
|
|
3134
3205
|
async function resolveVaultAuth(vaultId, definition, processEnv = process.env) {
|
|
3135
3206
|
const sessionKey = await resolveVaultSessionKey(vaultId, processEnv);
|
|
3136
3207
|
if (sessionKey) {
|
|
@@ -3146,6 +3217,32 @@ async function resolveVaultAuth(vaultId, definition, processEnv = process.env) {
|
|
|
3146
3217
|
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
3147
3218
|
};
|
|
3148
3219
|
}
|
|
3220
|
+
if (definition.auth?.method === "iam") {
|
|
3221
|
+
return {
|
|
3222
|
+
method: "iam",
|
|
3223
|
+
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
3224
|
+
};
|
|
3225
|
+
}
|
|
3226
|
+
if (definition.auth?.method === "environment") {
|
|
3227
|
+
return {
|
|
3228
|
+
method: "environment",
|
|
3229
|
+
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
3230
|
+
};
|
|
3231
|
+
}
|
|
3232
|
+
const tokenSources = definition.auth?.token?.from ?? [];
|
|
3233
|
+
for (const source of tokenSources) {
|
|
3234
|
+
const token = await resolveTokenFromSource(source, processEnv);
|
|
3235
|
+
if (token) {
|
|
3236
|
+
return {
|
|
3237
|
+
token,
|
|
3238
|
+
method: "token",
|
|
3239
|
+
...definition.auth?.config ? { config: definition.auth.config } : {}
|
|
3240
|
+
};
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
if (definition.auth?.method === "token") {
|
|
3244
|
+
throw toAuthError(vaultId, [getVaultSessionKeyEnvVar(vaultId), ...tokenSources]);
|
|
3245
|
+
}
|
|
3149
3246
|
const sources = definition.auth?.passphrase?.from ?? [getVaultPassphraseEnvVar(vaultId)];
|
|
3150
3247
|
for (const source of sources) {
|
|
3151
3248
|
if (source.startsWith("env:")) {
|
|
@@ -3197,22 +3294,76 @@ function collectSecretDescriptors(graph) {
|
|
|
3197
3294
|
ref: entry.value
|
|
3198
3295
|
}));
|
|
3199
3296
|
}
|
|
3200
|
-
|
|
3297
|
+
function secretGroupKey(manifest, descriptor) {
|
|
3298
|
+
assertSecretRefVaultProviderCompatible(manifest, descriptor.ref, descriptor.logicalKey);
|
|
3299
|
+
const vaultId = descriptor.ref.vault ?? "default";
|
|
3300
|
+
const provider = descriptor.ref.provider ?? manifest.vaults[vaultId]?.provider ?? "local";
|
|
3301
|
+
return `${vaultId}\0${provider}`;
|
|
3302
|
+
}
|
|
3303
|
+
function vaultDefinitionForRef(manifest, ref) {
|
|
3304
|
+
assertSecretRefVaultProviderCompatible(manifest, ref);
|
|
3305
|
+
const vaultId = ref.vault ?? "default";
|
|
3306
|
+
const base = manifest.vaults[vaultId] ?? { provider: "local", auth: { passphrase: { from: [] } } };
|
|
3307
|
+
if (!ref.provider || ref.provider === base.provider) {
|
|
3308
|
+
return base;
|
|
3309
|
+
}
|
|
3310
|
+
return {
|
|
3311
|
+
...base,
|
|
3312
|
+
provider: ref.provider
|
|
3313
|
+
};
|
|
3314
|
+
}
|
|
3315
|
+
async function resolveFromDefinition(vaultId, definition, refs, processEnv, factories) {
|
|
3316
|
+
const runtimeDefinition = {
|
|
3317
|
+
provider: definition.provider,
|
|
3318
|
+
...definition.auth ? { auth: definition.auth } : {},
|
|
3319
|
+
...definition.mapping ? { mapping: definition.mapping } : {}
|
|
3320
|
+
};
|
|
3321
|
+
const provider = createSecretVaultProvider(vaultId, runtimeDefinition, processEnv, factories);
|
|
3322
|
+
const auth = await resolveVaultAuth(vaultId, runtimeDefinition, processEnv);
|
|
3323
|
+
await provider.authenticate(auth);
|
|
3324
|
+
return provider.batchGet(refs.map((entry) => entry.ref.ref));
|
|
3325
|
+
}
|
|
3326
|
+
async function batchResolveSecrets(graph, manifest, processEnv = process.env, factories = []) {
|
|
3201
3327
|
const cache = new SecretCache();
|
|
3202
3328
|
const descriptors = collectSecretDescriptors(graph);
|
|
3203
3329
|
const grouped = descriptors.reduce((accumulator, descriptor) => {
|
|
3204
|
-
const
|
|
3205
|
-
const bucket = accumulator.get(
|
|
3330
|
+
const key = secretGroupKey(manifest, descriptor);
|
|
3331
|
+
const bucket = accumulator.get(key) ?? [];
|
|
3206
3332
|
bucket.push(descriptor);
|
|
3207
|
-
accumulator.set(
|
|
3333
|
+
accumulator.set(key, bucket);
|
|
3208
3334
|
return accumulator;
|
|
3209
3335
|
}, /* @__PURE__ */ new Map());
|
|
3210
|
-
for (const
|
|
3211
|
-
const
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
const
|
|
3336
|
+
for (const refs of grouped.values()) {
|
|
3337
|
+
const first = refs[0];
|
|
3338
|
+
if (!first) {
|
|
3339
|
+
continue;
|
|
3340
|
+
}
|
|
3341
|
+
const vaultId = first.ref.vault ?? "default";
|
|
3342
|
+
const definition = vaultDefinitionForRef(manifest, first.ref);
|
|
3343
|
+
const definitions = [definition, ...definition.fallback ?? []];
|
|
3344
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
3345
|
+
let remaining = refs;
|
|
3346
|
+
let lastError;
|
|
3347
|
+
for (const candidate of definitions) {
|
|
3348
|
+
try {
|
|
3349
|
+
const candidateValues = await resolveFromDefinition(vaultId, candidate, remaining, processEnv, factories);
|
|
3350
|
+
for (const descriptor of remaining) {
|
|
3351
|
+
const value = candidateValues.get(descriptor.ref.ref);
|
|
3352
|
+
if (value !== void 0) {
|
|
3353
|
+
resolved.set(descriptor.ref.ref, value);
|
|
3354
|
+
}
|
|
3355
|
+
}
|
|
3356
|
+
remaining = remaining.filter((descriptor) => !resolved.has(descriptor.ref.ref));
|
|
3357
|
+
if (remaining.length === 0) {
|
|
3358
|
+
break;
|
|
3359
|
+
}
|
|
3360
|
+
} catch (error) {
|
|
3361
|
+
lastError = error;
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
if (resolved.size === 0 && lastError) {
|
|
3365
|
+
throw lastError;
|
|
3366
|
+
}
|
|
3216
3367
|
cache.load(vaultId, resolved);
|
|
3217
3368
|
await appendAuditEvent(
|
|
3218
3369
|
{
|
|
@@ -3233,7 +3384,11 @@ function resolveSecretEntryValue(key, value, cache) {
|
|
|
3233
3384
|
return value;
|
|
3234
3385
|
}
|
|
3235
3386
|
const vaultId = value.vault ?? "default";
|
|
3236
|
-
|
|
3387
|
+
const resolved = cache.get(vaultId, value.ref);
|
|
3388
|
+
if (resolved !== void 0 || cache.isVaultAuthenticated(vaultId)) {
|
|
3389
|
+
return resolved;
|
|
3390
|
+
}
|
|
3391
|
+
return value;
|
|
3237
3392
|
}
|
|
3238
3393
|
|
|
3239
3394
|
// ../core/src/runtime/projection.ts
|
|
@@ -3336,19 +3491,117 @@ function configHash(values) {
|
|
|
3336
3491
|
function shouldProjectResolvedValue(sourceId) {
|
|
3337
3492
|
return sourceId !== "process-env";
|
|
3338
3493
|
}
|
|
3494
|
+
var SAFE_PROJECTED_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
3495
|
+
"address",
|
|
3496
|
+
"audience",
|
|
3497
|
+
"clientid",
|
|
3498
|
+
"endpoint",
|
|
3499
|
+
"mount",
|
|
3500
|
+
"namespace",
|
|
3501
|
+
"path",
|
|
3502
|
+
"projectid",
|
|
3503
|
+
"region",
|
|
3504
|
+
"scope",
|
|
3505
|
+
"scopes",
|
|
3506
|
+
"serviceaccountemail",
|
|
3507
|
+
"tenant",
|
|
3508
|
+
"tenantid",
|
|
3509
|
+
"url",
|
|
3510
|
+
"version",
|
|
3511
|
+
"vaulturl"
|
|
3512
|
+
]);
|
|
3513
|
+
function isSafeProjectedConfigKey(key) {
|
|
3514
|
+
return SAFE_PROJECTED_CONFIG_KEYS.has(key.replace(/[^A-Za-z0-9]/g, "").toLowerCase());
|
|
3515
|
+
}
|
|
3516
|
+
function sanitizeProjectedConfigValue(value) {
|
|
3517
|
+
if (Array.isArray(value)) {
|
|
3518
|
+
return value.map((item) => sanitizeProjectedConfigValue(item));
|
|
3519
|
+
}
|
|
3520
|
+
if (!value || typeof value !== "object") {
|
|
3521
|
+
return value;
|
|
3522
|
+
}
|
|
3523
|
+
return stableSortObject(
|
|
3524
|
+
Object.fromEntries(
|
|
3525
|
+
Object.entries(value).map(([key, item]) => [key, sanitizeProjectedConfigValue(item)]).filter(([key, item]) => {
|
|
3526
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
3527
|
+
return Object.keys(item).length > 0;
|
|
3528
|
+
}
|
|
3529
|
+
return isSafeProjectedConfigKey(key);
|
|
3530
|
+
})
|
|
3531
|
+
)
|
|
3532
|
+
);
|
|
3533
|
+
}
|
|
3534
|
+
function sanitizeProjectedConfig(config) {
|
|
3535
|
+
const sanitized = sanitizeProjectedConfigValue(config);
|
|
3536
|
+
if (!sanitized || typeof sanitized !== "object" || Array.isArray(sanitized)) {
|
|
3537
|
+
return void 0;
|
|
3538
|
+
}
|
|
3539
|
+
return Object.keys(sanitized).length > 0 ? sanitized : void 0;
|
|
3540
|
+
}
|
|
3541
|
+
function projectVaultAuth(definition) {
|
|
3542
|
+
const auth = definition.auth;
|
|
3543
|
+
if (!auth) {
|
|
3544
|
+
return void 0;
|
|
3545
|
+
}
|
|
3546
|
+
const config = auth.config ? sanitizeProjectedConfig(auth.config) : void 0;
|
|
3547
|
+
const projected = {
|
|
3548
|
+
...auth.method ? { method: auth.method } : {},
|
|
3549
|
+
...auth.passphrase?.from ? {
|
|
3550
|
+
passphrase: {
|
|
3551
|
+
from: [...auth.passphrase.from]
|
|
3552
|
+
}
|
|
3553
|
+
} : {},
|
|
3554
|
+
...auth.token?.from ? {
|
|
3555
|
+
token: {
|
|
3556
|
+
from: [...auth.token.from]
|
|
3557
|
+
}
|
|
3558
|
+
} : {},
|
|
3559
|
+
...config ? { config } : {}
|
|
3560
|
+
};
|
|
3561
|
+
return Object.keys(projected).length > 0 ? projected : void 0;
|
|
3562
|
+
}
|
|
3563
|
+
function projectVaultDefinition(definition) {
|
|
3564
|
+
const auth = projectVaultAuth(definition);
|
|
3565
|
+
const mapping = definition.mapping ? stableSortObject(definition.mapping) : void 0;
|
|
3566
|
+
const fallback = definition.fallback?.map((entry) => projectVaultDefinition({
|
|
3567
|
+
provider: entry.provider,
|
|
3568
|
+
...entry.auth ? { auth: entry.auth } : {},
|
|
3569
|
+
...entry.mapping ? { mapping: entry.mapping } : {}
|
|
3570
|
+
}));
|
|
3571
|
+
return {
|
|
3572
|
+
provider: definition.provider,
|
|
3573
|
+
...auth ? { auth } : {},
|
|
3574
|
+
...mapping && Object.keys(mapping).length > 0 ? { mapping } : {},
|
|
3575
|
+
...fallback && fallback.length > 0 ? { fallback } : {}
|
|
3576
|
+
};
|
|
3577
|
+
}
|
|
3578
|
+
function projectReferencedVaults(manifest, vaultIds) {
|
|
3579
|
+
const projected = {};
|
|
3580
|
+
for (const vaultId of Array.from(vaultIds).sort((left, right) => left.localeCompare(right))) {
|
|
3581
|
+
const definition = manifest.vaults[vaultId];
|
|
3582
|
+
if (definition) {
|
|
3583
|
+
projected[vaultId] = projectVaultDefinition(definition);
|
|
3584
|
+
}
|
|
3585
|
+
}
|
|
3586
|
+
return Object.keys(projected).length > 0 ? projected : void 0;
|
|
3587
|
+
}
|
|
3339
3588
|
function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev", helpers = {}) {
|
|
3340
3589
|
const values = {};
|
|
3341
3590
|
const derived = {};
|
|
3342
3591
|
const secretRefs = {};
|
|
3592
|
+
const referencedVaultIds = /* @__PURE__ */ new Set();
|
|
3343
3593
|
const namespaces = /* @__PURE__ */ new Set();
|
|
3344
3594
|
const runtimeNamespaces = /* @__PURE__ */ new Set();
|
|
3345
3595
|
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));
|
|
3346
3596
|
for (const [key, entry] of graph.entries) {
|
|
3347
3597
|
if (entry.namespace === "secret" && isSecretReference(entry.value)) {
|
|
3598
|
+
assertSecretRefVaultProviderCompatible(manifest, entry.value, key);
|
|
3348
3599
|
const vaultId = entry.value.vault ?? "default";
|
|
3600
|
+
const provider = entry.value.provider ?? manifest.vaults[vaultId]?.provider ?? "local";
|
|
3349
3601
|
const envVar = resolveProjectedEnvVar(manifest, vaultId, entry.value.ref);
|
|
3602
|
+
referencedVaultIds.add(vaultId);
|
|
3350
3603
|
secretRefs[key.slice("secret.".length)] = {
|
|
3351
|
-
provider
|
|
3604
|
+
provider,
|
|
3352
3605
|
vault: vaultId,
|
|
3353
3606
|
ref: entry.value.ref,
|
|
3354
3607
|
...envVar ? {
|
|
@@ -3394,6 +3647,7 @@ function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev", helpers
|
|
|
3394
3647
|
namespaces.add(entry.namespace);
|
|
3395
3648
|
}
|
|
3396
3649
|
}
|
|
3650
|
+
const vaults = projectReferencedVaults(manifest, referencedVaultIds);
|
|
3397
3651
|
return {
|
|
3398
3652
|
version: 1,
|
|
3399
3653
|
workspace: graph.workspace.workspaceId,
|
|
@@ -3403,6 +3657,7 @@ function toServerProjection(graph, manifest, cnosVersion = "0.0.0-dev", helpers
|
|
|
3403
3657
|
values: stableSortObject(values),
|
|
3404
3658
|
derived: stableSortObject(derived),
|
|
3405
3659
|
secretRefs: stableSortObject(secretRefs),
|
|
3660
|
+
...vaults ? { vaults } : {},
|
|
3406
3661
|
publicKeys,
|
|
3407
3662
|
runtimeNamespaces: Array.from(runtimeNamespaces).sort((left, right) => left.localeCompare(right)),
|
|
3408
3663
|
meta: {
|
|
@@ -3517,9 +3772,10 @@ function toPublicEnv(graph, manifest, options = {}, helpers = {}) {
|
|
|
3517
3772
|
}
|
|
3518
3773
|
|
|
3519
3774
|
// ../core/src/orchestrator/runtime.ts
|
|
3520
|
-
function createRuntime(manifest, graph, plugins = [], secretCache, processEnv = process.env, cnosVersion = "0.0.0-dev") {
|
|
3775
|
+
function createRuntime(manifest, graph, plugins = [], secretCache, processEnv = process.env, cnosVersion = "0.0.0-dev", secretVaultProviders = []) {
|
|
3521
3776
|
const runtimeProviders = createDefaultRuntimeProviders(manifest, processEnv);
|
|
3522
3777
|
const derivedSupport = createDerivedRuntimeSupport(graph, manifest, runtimeProviders);
|
|
3778
|
+
let activeSecretCache = secretCache;
|
|
3523
3779
|
function resolveProjectedSourceKey(key) {
|
|
3524
3780
|
if (!key.startsWith("public.")) {
|
|
3525
3781
|
return key;
|
|
@@ -3536,30 +3792,38 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
3536
3792
|
if (!entry || entry.namespace !== "secret" || !isSecretReference(entry.value)) {
|
|
3537
3793
|
return;
|
|
3538
3794
|
}
|
|
3539
|
-
if (!
|
|
3795
|
+
if (!activeSecretCache) {
|
|
3540
3796
|
return;
|
|
3541
3797
|
}
|
|
3542
3798
|
const vaultId = entry.value.vault ?? "default";
|
|
3543
|
-
const
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3799
|
+
const refreshed = await batchResolveSecrets(
|
|
3800
|
+
{
|
|
3801
|
+
...graph,
|
|
3802
|
+
entries: /* @__PURE__ */ new Map([[key, entry]])
|
|
3803
|
+
},
|
|
3804
|
+
manifest,
|
|
3805
|
+
processEnv,
|
|
3806
|
+
secretVaultProviders
|
|
3807
|
+
);
|
|
3808
|
+
const resolved = refreshed.get(vaultId, entry.value.ref);
|
|
3809
|
+
const existing = activeSecretCache.entriesForVault(vaultId);
|
|
3810
|
+
existing.delete(entry.value.ref);
|
|
3811
|
+
if (resolved !== void 0) {
|
|
3812
|
+
existing.set(entry.value.ref, resolved);
|
|
3553
3813
|
}
|
|
3814
|
+
activeSecretCache.replace(vaultId, existing);
|
|
3554
3815
|
}
|
|
3555
3816
|
async function refreshAllSecrets() {
|
|
3556
|
-
if (!
|
|
3817
|
+
if (!activeSecretCache) {
|
|
3557
3818
|
return;
|
|
3558
3819
|
}
|
|
3559
|
-
const
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3820
|
+
const refreshed = await batchResolveSecrets(
|
|
3821
|
+
graph,
|
|
3822
|
+
manifest,
|
|
3823
|
+
processEnv,
|
|
3824
|
+
secretVaultProviders
|
|
3825
|
+
);
|
|
3826
|
+
activeSecretCache = refreshed;
|
|
3563
3827
|
}
|
|
3564
3828
|
function readLogicalKey(key) {
|
|
3565
3829
|
const resolved = derivedSupport.read(key, (ref) => {
|
|
@@ -3567,10 +3831,10 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
3567
3831
|
if (!entry2) {
|
|
3568
3832
|
return void 0;
|
|
3569
3833
|
}
|
|
3570
|
-
if (!
|
|
3834
|
+
if (!activeSecretCache) {
|
|
3571
3835
|
return entry2.value;
|
|
3572
3836
|
}
|
|
3573
|
-
return resolveSecretEntryValue(ref, entry2.value,
|
|
3837
|
+
return resolveSecretEntryValue(ref, entry2.value, activeSecretCache);
|
|
3574
3838
|
});
|
|
3575
3839
|
if (resolved !== void 0 || graph.entries.has(key) || manifest.runtimeNamespaces[key.split(".")[0] ?? ""]) {
|
|
3576
3840
|
return resolved;
|
|
@@ -3579,10 +3843,10 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
3579
3843
|
if (!entry) {
|
|
3580
3844
|
return void 0;
|
|
3581
3845
|
}
|
|
3582
|
-
if (!
|
|
3846
|
+
if (!activeSecretCache) {
|
|
3583
3847
|
return entry.value;
|
|
3584
3848
|
}
|
|
3585
|
-
return resolveSecretEntryValue(key, entry.value,
|
|
3849
|
+
return resolveSecretEntryValue(key, entry.value, activeSecretCache);
|
|
3586
3850
|
}
|
|
3587
3851
|
return {
|
|
3588
3852
|
manifest,
|
|
@@ -3619,10 +3883,10 @@ function createRuntime(manifest, graph, plugins = [], secretCache, processEnv =
|
|
|
3619
3883
|
if (!entry) {
|
|
3620
3884
|
return void 0;
|
|
3621
3885
|
}
|
|
3622
|
-
if (!
|
|
3886
|
+
if (!activeSecretCache) {
|
|
3623
3887
|
return entry.value;
|
|
3624
3888
|
}
|
|
3625
|
-
return resolveSecretEntryValue(candidate, entry.value,
|
|
3889
|
+
return resolveSecretEntryValue(candidate, entry.value, activeSecretCache);
|
|
3626
3890
|
})
|
|
3627
3891
|
});
|
|
3628
3892
|
},
|
|
@@ -3813,7 +4077,12 @@ async function createCnos(options = {}) {
|
|
|
3813
4077
|
});
|
|
3814
4078
|
const schemaApplied = applySchemaRules(graph, loadedManifest.manifest.schema);
|
|
3815
4079
|
const promotedGraph = promoteToPublic(schemaApplied.graph, loadedManifest.manifest);
|
|
3816
|
-
const secretCache = options.secretResolution === "lazy" ? new SecretCache() : await batchResolveSecrets(
|
|
4080
|
+
const secretCache = options.secretResolution === "lazy" ? new SecretCache() : await batchResolveSecrets(
|
|
4081
|
+
promotedGraph,
|
|
4082
|
+
loadedManifest.manifest,
|
|
4083
|
+
options.processEnv,
|
|
4084
|
+
options.secretVaultProviders
|
|
4085
|
+
);
|
|
3817
4086
|
return createRuntime(
|
|
3818
4087
|
loadedManifest.manifest,
|
|
3819
4088
|
appendMetaEntries({
|
|
@@ -3823,12 +4092,13 @@ async function createCnos(options = {}) {
|
|
|
3823
4092
|
plugins,
|
|
3824
4093
|
secretCache,
|
|
3825
4094
|
options.processEnv,
|
|
3826
|
-
options.cnosVersion
|
|
4095
|
+
options.cnosVersion,
|
|
4096
|
+
options.secretVaultProviders
|
|
3827
4097
|
);
|
|
3828
4098
|
}
|
|
3829
4099
|
|
|
3830
4100
|
// ../core/src/runtime/dump.ts
|
|
3831
|
-
var
|
|
4101
|
+
var import_promises13 = require("fs/promises");
|
|
3832
4102
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
3833
4103
|
|
|
3834
4104
|
// ../core/src/utils/envNaming.ts
|
|
@@ -3866,7 +4136,7 @@ function envVarToLogicalKey(envVar, config = {}) {
|
|
|
3866
4136
|
// package.json
|
|
3867
4137
|
var package_default = {
|
|
3868
4138
|
name: "@kitsy/cnos",
|
|
3869
|
-
version: "1.
|
|
4139
|
+
version: "1.11.1",
|
|
3870
4140
|
description: "Batteries-included CNOS runtime package wired with the official plugins.",
|
|
3871
4141
|
type: "module",
|
|
3872
4142
|
main: "./dist/index.cjs",
|
|
@@ -4065,7 +4335,7 @@ function createCliArgsPlugin() {
|
|
|
4065
4335
|
}
|
|
4066
4336
|
|
|
4067
4337
|
// ../../plugins/dotenv/src/index.ts
|
|
4068
|
-
var
|
|
4338
|
+
var import_promises14 = require("fs/promises");
|
|
4069
4339
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
4070
4340
|
var DOTENV_PLUGIN_ID = "@kitsy/cnos/plugins/dotenv";
|
|
4071
4341
|
function parseDoubleQuoted(value) {
|
|
@@ -4152,7 +4422,7 @@ function dotenvEntriesFromObject(values, mapping = {}, originFile, workspaceId =
|
|
|
4152
4422
|
}
|
|
4153
4423
|
async function readIfPresent(filePath) {
|
|
4154
4424
|
try {
|
|
4155
|
-
return await (0,
|
|
4425
|
+
return await (0, import_promises14.readFile)(filePath, "utf8");
|
|
4156
4426
|
} catch {
|
|
4157
4427
|
return void 0;
|
|
4158
4428
|
}
|
|
@@ -4218,16 +4488,16 @@ function createPublicEnvExportPlugin() {
|
|
|
4218
4488
|
}
|
|
4219
4489
|
|
|
4220
4490
|
// ../../plugins/filesystem/src/filesystemSecretsReader.ts
|
|
4221
|
-
var
|
|
4491
|
+
var import_promises16 = require("fs/promises");
|
|
4222
4492
|
|
|
4223
4493
|
// ../../plugins/filesystem/src/helpers.ts
|
|
4224
|
-
var
|
|
4494
|
+
var import_promises15 = require("fs/promises");
|
|
4225
4495
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
4226
4496
|
var YAML_EXTENSIONS = /* @__PURE__ */ new Set([".yml", ".yaml"]);
|
|
4227
4497
|
var FILESYSTEM_PLUGIN_ID = "@kitsy/cnos/plugins/filesystem";
|
|
4228
4498
|
async function existsDirectory(targetPath) {
|
|
4229
4499
|
try {
|
|
4230
|
-
const stat2 = await (0,
|
|
4500
|
+
const stat2 = await (0, import_promises15.readdir)(targetPath);
|
|
4231
4501
|
void stat2;
|
|
4232
4502
|
return true;
|
|
4233
4503
|
} catch {
|
|
@@ -4235,7 +4505,7 @@ async function existsDirectory(targetPath) {
|
|
|
4235
4505
|
}
|
|
4236
4506
|
}
|
|
4237
4507
|
async function collectYamlFiles(root) {
|
|
4238
|
-
const entries = await (0,
|
|
4508
|
+
const entries = await (0, import_promises15.readdir)(root, { withFileTypes: true });
|
|
4239
4509
|
const results = [];
|
|
4240
4510
|
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
4241
4511
|
const absolutePath = import_node_path15.default.join(root, entry.name);
|
|
@@ -4337,7 +4607,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
4337
4607
|
);
|
|
4338
4608
|
const entries = [];
|
|
4339
4609
|
for (const file of files) {
|
|
4340
|
-
const document = await (0,
|
|
4610
|
+
const document = await (0, import_promises16.readFile)(file.absolutePath, "utf8");
|
|
4341
4611
|
const fileEntries = filesystemSecretsReader(file.relativePath, document, file.workspaceId);
|
|
4342
4612
|
for (const entry of fileEntries) {
|
|
4343
4613
|
const metadata = toSecretReferenceMetadata(entry.value);
|
|
@@ -4353,7 +4623,7 @@ function createFilesystemSecretsPlugin() {
|
|
|
4353
4623
|
}
|
|
4354
4624
|
|
|
4355
4625
|
// ../../plugins/filesystem/src/filesystemValuesReader.ts
|
|
4356
|
-
var
|
|
4626
|
+
var import_promises17 = require("fs/promises");
|
|
4357
4627
|
function filesystemValuesReader(filePath, document, workspaceId = "default") {
|
|
4358
4628
|
return yamlObjectToEntries(document, filePath, "value", "filesystem-values", workspaceId);
|
|
4359
4629
|
}
|
|
@@ -4374,7 +4644,7 @@ function createFilesystemValuesPlugin() {
|
|
|
4374
4644
|
).map(([namespace]) => namespace);
|
|
4375
4645
|
const entries = [];
|
|
4376
4646
|
for (const file of files) {
|
|
4377
|
-
const document = await (0,
|
|
4647
|
+
const document = await (0, import_promises17.readFile)(file.absolutePath, "utf8");
|
|
4378
4648
|
entries.push(...filesystemValuesReader(file.relativePath, document, file.workspaceId));
|
|
4379
4649
|
}
|
|
4380
4650
|
for (const namespace of customNamespaces) {
|
|
@@ -4389,7 +4659,7 @@ function createFilesystemValuesPlugin() {
|
|
|
4389
4659
|
layers
|
|
4390
4660
|
);
|
|
4391
4661
|
for (const file of namespaceFiles) {
|
|
4392
|
-
const document = await (0,
|
|
4662
|
+
const document = await (0, import_promises17.readFile)(file.absolutePath, "utf8");
|
|
4393
4663
|
entries.push(...yamlObjectToEntries(document, file.relativePath, namespace, "filesystem-values", file.workspaceId));
|
|
4394
4664
|
}
|
|
4395
4665
|
}
|
|
@@ -4635,15 +4905,13 @@ function validateServerProjectionSecretRefs(runtime) {
|
|
|
4635
4905
|
}
|
|
4636
4906
|
const vaultId = entry.value.vault ?? "default";
|
|
4637
4907
|
const definition = runtime.manifest.vaults[vaultId];
|
|
4638
|
-
if (!definition) {
|
|
4908
|
+
if (!definition && entry.value.vault) {
|
|
4639
4909
|
throw new CnosManifestError(`Unknown vault "${vaultId}" for secret ref "${entry.key}"`);
|
|
4640
4910
|
}
|
|
4641
|
-
if (entry.value.provider
|
|
4642
|
-
throw new CnosManifestError(
|
|
4643
|
-
`Secret ref "${entry.key}" declares provider "${entry.value.provider}" but vault "${vaultId}" uses provider "${definition.provider}"`
|
|
4644
|
-
);
|
|
4911
|
+
if (!definition && !entry.value.provider) {
|
|
4912
|
+
throw new CnosManifestError(`Secret ref "${entry.key}" must declare a provider or reference a configured vault`);
|
|
4645
4913
|
}
|
|
4646
|
-
|
|
4914
|
+
assertSecretRefVaultProviderCompatible(runtime.manifest, entry.value, entry.key);
|
|
4647
4915
|
}
|
|
4648
4916
|
}
|
|
4649
4917
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/build/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CnosCreateOptions, S as ServerProjection } from '../core-
|
|
1
|
+
import { C as CnosCreateOptions, S as ServerProjection } from '../core-CGJObpyy.cjs';
|
|
2
2
|
|
|
3
3
|
type BrowserDataMap = Record<string, unknown>;
|
|
4
4
|
type FrameworkEnvTarget = 'generic' | 'vite' | 'next' | 'webpack' | (string & {});
|
package/dist/build/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CnosCreateOptions, S as ServerProjection } from '../core-
|
|
1
|
+
import { C as CnosCreateOptions, S as ServerProjection } from '../core-CGJObpyy.js';
|
|
2
2
|
|
|
3
3
|
type BrowserDataMap = Record<string, unknown>;
|
|
4
4
|
type FrameworkEnvTarget = 'generic' | 'vite' | 'next' | 'webpack' | (string & {});
|