@penvhq/cli 0.14.0 → 0.15.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/bin.cjs +249 -270
- package/dist/bin.cjs.map +1 -1
- package/dist/index.cjs +105 -131
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -7
- package/dist/index.d.ts +1 -7
- package/dist/index.js +119 -134
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/bin.cjs
CHANGED
|
@@ -47771,6 +47771,16 @@ function assertNever2(value2, context) {
|
|
|
47771
47771
|
function own(record3, key) {
|
|
47772
47772
|
return record3 !== void 0 && Object.hasOwn(record3, key) ? record3[key] : void 0;
|
|
47773
47773
|
}
|
|
47774
|
+
function environmentNames(config2) {
|
|
47775
|
+
return Object.keys(config2.environments);
|
|
47776
|
+
}
|
|
47777
|
+
function environmentEntry(config2, environment) {
|
|
47778
|
+
const declared = own(config2.environments, environment);
|
|
47779
|
+
if (declared === void 0) {
|
|
47780
|
+
return void 0;
|
|
47781
|
+
}
|
|
47782
|
+
return typeof declared === "string" ? { provider: declared } : declared;
|
|
47783
|
+
}
|
|
47774
47784
|
function retainsPrevious(provider) {
|
|
47775
47785
|
return typeof provider.readPrevious === "function";
|
|
47776
47786
|
}
|
|
@@ -47787,11 +47797,11 @@ var CODE_FILE_EXTENSIONS = /* @__PURE__ */ new Set(["ts", "tsx", "js", "jsx", "m
|
|
|
47787
47797
|
function isCodeModule(filename, config2) {
|
|
47788
47798
|
const segments = filename.split(".");
|
|
47789
47799
|
const extension = segments[segments.length - 1];
|
|
47790
|
-
return extension !== void 0 && CODE_FILE_EXTENSIONS.has(extension) && !config2.
|
|
47800
|
+
return extension !== void 0 && CODE_FILE_EXTENSIONS.has(extension) && !environmentNames(config2).includes(extension);
|
|
47791
47801
|
}
|
|
47792
47802
|
var SUPPORTED_META_FORMAT = "json";
|
|
47793
47803
|
function reservedTokensFor(config2) {
|
|
47794
|
-
return [.../* @__PURE__ */ new Set([...RESERVED_TOKENS, ...config2
|
|
47804
|
+
return [.../* @__PURE__ */ new Set([...RESERVED_TOKENS, ...environmentNames(config2)])];
|
|
47795
47805
|
}
|
|
47796
47806
|
function isReservedToken(token, config2) {
|
|
47797
47807
|
return reservedTokensFor(config2).includes(token);
|
|
@@ -47831,17 +47841,19 @@ function formatMetaFile(ref) {
|
|
|
47831
47841
|
return `${refPath(ref)}.${ref.format}`;
|
|
47832
47842
|
}
|
|
47833
47843
|
function declaredList(config2) {
|
|
47834
|
-
|
|
47844
|
+
const names = environmentNames(config2);
|
|
47845
|
+
if (names.length === 0) {
|
|
47835
47846
|
return "no environments are declared in penv.config.ts";
|
|
47836
47847
|
}
|
|
47837
|
-
return `declared environments are ${
|
|
47848
|
+
return `declared environments are ${names.map((e) => `\`${e}\``).join(", ")}`;
|
|
47838
47849
|
}
|
|
47839
47850
|
function asEnvironment(segment, relativePath, config2) {
|
|
47840
|
-
|
|
47851
|
+
const names = environmentNames(config2);
|
|
47852
|
+
if (names.includes(segment)) {
|
|
47841
47853
|
return segment;
|
|
47842
47854
|
}
|
|
47843
47855
|
if (BARE_WORD.test(segment)) {
|
|
47844
|
-
throw new UnknownEnvironmentError(segment,
|
|
47856
|
+
throw new UnknownEnvironmentError(segment, names);
|
|
47845
47857
|
}
|
|
47846
47858
|
throw new FilenameGrammarError(
|
|
47847
47859
|
relativePath,
|
|
@@ -47996,12 +48008,12 @@ function isLegalEnvironmentName(name) {
|
|
|
47996
48008
|
}
|
|
47997
48009
|
function validateEnvironmentNames(config2) {
|
|
47998
48010
|
const errors = [];
|
|
47999
|
-
for (const environment of config2
|
|
48011
|
+
for (const environment of environmentNames(config2)) {
|
|
48000
48012
|
if (RESERVED_TOKENS.includes(environment)) {
|
|
48001
48013
|
errors.push(new ReservedTokenError("environment", environment, "penv.config.ts"));
|
|
48002
48014
|
continue;
|
|
48003
48015
|
}
|
|
48004
|
-
if (
|
|
48016
|
+
if (!isLegalEnvironmentName(environment)) {
|
|
48005
48017
|
errors.push(new IllegalEnvironmentNameError(environment));
|
|
48006
48018
|
}
|
|
48007
48019
|
}
|
|
@@ -48111,15 +48123,25 @@ function createKeychainKeySource(config2, keychain) {
|
|
|
48111
48123
|
};
|
|
48112
48124
|
}
|
|
48113
48125
|
function nullKeySource(environment) {
|
|
48114
|
-
const detail = `environment ${environment} declares no \`
|
|
48126
|
+
const detail = `environment ${environment} declares no \`keySource\` in penv.config.ts, so penv was never told where its keys live`;
|
|
48115
48127
|
return {
|
|
48116
48128
|
type: "none",
|
|
48117
48129
|
lookup: () => ({ kind: "unavailable", detail }),
|
|
48118
48130
|
current: () => ({ kind: "unavailable", detail })
|
|
48119
48131
|
};
|
|
48120
48132
|
}
|
|
48133
|
+
function keyConfigFor(config2, environment) {
|
|
48134
|
+
const declared = environmentEntry(config2, environment)?.keySource;
|
|
48135
|
+
if (declared === void 0) {
|
|
48136
|
+
return void 0;
|
|
48137
|
+
}
|
|
48138
|
+
if (typeof declared === "string") {
|
|
48139
|
+
return { source: declared, id: environment };
|
|
48140
|
+
}
|
|
48141
|
+
return { source: declared.source, id: declared.id ?? environment };
|
|
48142
|
+
}
|
|
48121
48143
|
function resolveKeySource(config2, environment) {
|
|
48122
|
-
const declared =
|
|
48144
|
+
const declared = keyConfigFor(config2, environment);
|
|
48123
48145
|
if (declared === void 0) {
|
|
48124
48146
|
return nullKeySource(environment);
|
|
48125
48147
|
}
|
|
@@ -48132,13 +48154,13 @@ function resolveKeySource(config2, environment) {
|
|
|
48132
48154
|
throw new PenvError(
|
|
48133
48155
|
"KEY_SOURCE_UNSUPPORTED",
|
|
48134
48156
|
`Environment ${environment} declares key source \`${String(declared.source)}\`, which penv cannot read`,
|
|
48135
|
-
`\`${String(declared.source)}\` is not a key source penv knows. Declare \`
|
|
48157
|
+
`\`${String(declared.source)}\` is not a key source penv knows. Declare \`keySource: "env"\` (exported as \`${envVarFor(declared.id)}\`) or \`keySource: "keychain"\`.`
|
|
48136
48158
|
);
|
|
48137
48159
|
}
|
|
48138
48160
|
var NO_KEY_SOURCE = "none";
|
|
48139
48161
|
function keySourceIdentifier(config2, environment) {
|
|
48140
48162
|
const source = resolveKeySource(config2, environment);
|
|
48141
|
-
const declared =
|
|
48163
|
+
const declared = keyConfigFor(config2, environment);
|
|
48142
48164
|
if (declared === void 0) {
|
|
48143
48165
|
return NO_KEY_SOURCE;
|
|
48144
48166
|
}
|
|
@@ -48168,60 +48190,47 @@ var KEY_ID = /^[A-Za-z0-9._-]+$/;
|
|
|
48168
48190
|
var SOURCES = ["env", "keychain"];
|
|
48169
48191
|
function validateKeys(config2, declared) {
|
|
48170
48192
|
const errors = [];
|
|
48171
|
-
const
|
|
48172
|
-
|
|
48173
|
-
|
|
48174
|
-
}
|
|
48175
|
-
if (keys === null || typeof keys !== "object" || Array.isArray(keys)) {
|
|
48176
|
-
errors.push(
|
|
48177
|
-
new ConfigError(
|
|
48178
|
-
"`keys` in penv.config.ts is not an object",
|
|
48179
|
-
'Declare one key source per environment, e.g. `keys: { production: { source: "env", id: "prod" } }`, or remove the block.'
|
|
48180
|
-
)
|
|
48181
|
-
);
|
|
48182
|
-
return errors;
|
|
48183
|
-
}
|
|
48184
|
-
const entries = keys;
|
|
48185
|
-
for (const environment of Object.keys(entries)) {
|
|
48186
|
-
if (!declared.has(environment)) {
|
|
48187
|
-
errors.push(
|
|
48188
|
-
new ConfigError(
|
|
48189
|
-
`The \`keys\` block in penv.config.ts names environment ${environment}, which is not declared`,
|
|
48190
|
-
`Add \`${environment}\` to the \`environments\` list, or remove its \`keys\` entry. Environments are a whitelist \u2014 penv never infers one.`
|
|
48191
|
-
)
|
|
48192
|
-
);
|
|
48193
|
+
for (const environment of declared) {
|
|
48194
|
+
const keySource = environmentEntry(config2, environment)?.keySource;
|
|
48195
|
+
if (keySource === void 0) {
|
|
48193
48196
|
continue;
|
|
48194
48197
|
}
|
|
48195
|
-
|
|
48196
|
-
|
|
48198
|
+
if (typeof keySource === "string") {
|
|
48199
|
+
if (!SOURCES.includes(keySource)) {
|
|
48200
|
+
errors.push(unknownSource(environment, keySource));
|
|
48201
|
+
}
|
|
48202
|
+
continue;
|
|
48203
|
+
}
|
|
48204
|
+
if (keySource === null || typeof keySource !== "object" || Array.isArray(keySource)) {
|
|
48197
48205
|
errors.push(
|
|
48198
48206
|
new ConfigError(
|
|
48199
|
-
`The \`
|
|
48200
|
-
`Declare it as
|
|
48207
|
+
`The \`keySource\` for environment ${environment} is not a key source`,
|
|
48208
|
+
`Declare it as \`keySource: "env"\` \u2014 the key named after the environment \u2014 or as \`keySource: { source: "env", id: "prod" }\` to name a different key.`
|
|
48201
48209
|
)
|
|
48202
48210
|
);
|
|
48203
48211
|
continue;
|
|
48204
48212
|
}
|
|
48205
|
-
const { source, id } =
|
|
48213
|
+
const { source, id } = keySource;
|
|
48206
48214
|
if (typeof source !== "string" || !SOURCES.includes(source)) {
|
|
48207
|
-
errors.push(
|
|
48208
|
-
new ConfigError(
|
|
48209
|
-
`The \`keys\` entry for environment ${environment} declares source \`${String(source)}\``,
|
|
48210
|
-
`A key source is ${SOURCES.map((s) => `\`${s}\``).join(" or ")}.`
|
|
48211
|
-
)
|
|
48212
|
-
);
|
|
48215
|
+
errors.push(unknownSource(environment, String(source)));
|
|
48213
48216
|
}
|
|
48214
|
-
if (typeof id !== "string" || !KEY_ID.test(id)) {
|
|
48217
|
+
if (id !== void 0 && (typeof id !== "string" || !KEY_ID.test(id))) {
|
|
48215
48218
|
errors.push(
|
|
48216
48219
|
new ConfigError(
|
|
48217
|
-
`The \`
|
|
48218
|
-
"A key id is one or more of `A-Za-z0-9._-`. It is written into every value file sealed under it, where `:` separates the fields, so `:` cannot appear in one."
|
|
48220
|
+
`The \`keySource\` for environment ${environment} declares id \`${String(id)}\``,
|
|
48221
|
+
"A key id is one or more of `A-Za-z0-9._-`. It is written into every value file sealed under it, where `:` separates the fields, so `:` cannot appear in one. Omit `id` to use the environment's own name."
|
|
48219
48222
|
)
|
|
48220
48223
|
);
|
|
48221
48224
|
}
|
|
48222
48225
|
}
|
|
48223
48226
|
return errors;
|
|
48224
48227
|
}
|
|
48228
|
+
function unknownSource(environment, source) {
|
|
48229
|
+
return new ConfigError(
|
|
48230
|
+
`The \`keySource\` for environment ${environment} declares source \`${source}\``,
|
|
48231
|
+
`A key source is ${SOURCES.map((s) => `\`${s}\``).join(" or ")}.`
|
|
48232
|
+
);
|
|
48233
|
+
}
|
|
48225
48234
|
var CONFIG_FILENAMES = ["penv.config.ts", "penv.config.js", "penv.config.mjs"];
|
|
48226
48235
|
var jitiModule;
|
|
48227
48236
|
function setJitiApi(api) {
|
|
@@ -48250,7 +48259,7 @@ function jitiFor(file2) {
|
|
|
48250
48259
|
...alias === void 0 ? {} : { alias }
|
|
48251
48260
|
});
|
|
48252
48261
|
}
|
|
48253
|
-
var EXPORT_REMEDY =
|
|
48262
|
+
var EXPORT_REMEDY = 'penv reads its configuration from the default export: `export default defineConfig({ environments: { development: "@penvhq/provider-filesystem" } })`.';
|
|
48254
48263
|
function describeValue(value2) {
|
|
48255
48264
|
if (value2 === null) {
|
|
48256
48265
|
return "`null`";
|
|
@@ -48353,6 +48362,11 @@ function loadConfigFrom(file2) {
|
|
|
48353
48362
|
EXPORT_REMEDY
|
|
48354
48363
|
);
|
|
48355
48364
|
}
|
|
48365
|
+
const merged = mergedEnvironmentsBlock(config2);
|
|
48366
|
+
const first = merged[0];
|
|
48367
|
+
if (first !== void 0) {
|
|
48368
|
+
throw first;
|
|
48369
|
+
}
|
|
48356
48370
|
return config2;
|
|
48357
48371
|
}
|
|
48358
48372
|
function loadConfig(cwd = process.cwd()) {
|
|
@@ -48374,20 +48388,20 @@ var LEGACY_PROVIDER_TYPES = {
|
|
|
48374
48388
|
github: "@penvhq/provider-github"
|
|
48375
48389
|
};
|
|
48376
48390
|
var PACKAGE_NAME = /^(@[a-z0-9~-][a-z0-9._~-]*\/)?[a-z0-9~-][a-z0-9._~-]*$/;
|
|
48377
|
-
function
|
|
48378
|
-
const legacy = own(LEGACY_PROVIDER_TYPES,
|
|
48391
|
+
function validateProviderName(environment, provider) {
|
|
48392
|
+
const legacy = own(LEGACY_PROVIDER_TYPES, provider);
|
|
48379
48393
|
if (legacy !== void 0) {
|
|
48380
48394
|
return new PenvError(
|
|
48381
|
-
"
|
|
48382
|
-
`The provider
|
|
48383
|
-
`Write \`${environment}: {
|
|
48395
|
+
"PROVIDER_LEGACY",
|
|
48396
|
+
`The provider \`${provider}\` for environment ${environment} is a short name, and a provider is a package name`,
|
|
48397
|
+
`Write \`${environment}: { provider: "${legacy}" }\` and make sure the package is installed. A provider is the package penv imports, so the config and the dependency tree name the same thing.`
|
|
48384
48398
|
);
|
|
48385
48399
|
}
|
|
48386
|
-
if (!PACKAGE_NAME.test(
|
|
48400
|
+
if (!PACKAGE_NAME.test(provider)) {
|
|
48387
48401
|
return new PenvError(
|
|
48388
|
-
"
|
|
48389
|
-
`The provider
|
|
48390
|
-
`Name the provider's package, e.g. \`${environment}:
|
|
48402
|
+
"PROVIDER_INVALID",
|
|
48403
|
+
`The provider \`${provider}\` for environment ${environment} is not a package name`,
|
|
48404
|
+
`Name the provider's package, e.g. \`${environment}: "@penvhq/provider-filesystem"\`. penv imports the package the \`provider\` names from this project's node_modules.`
|
|
48391
48405
|
);
|
|
48392
48406
|
}
|
|
48393
48407
|
return void 0;
|
|
@@ -48406,63 +48420,76 @@ function validateDefaultEnvironment(config2, declared) {
|
|
|
48406
48420
|
];
|
|
48407
48421
|
}
|
|
48408
48422
|
if (!declared.has(value2)) {
|
|
48409
|
-
return [new UnknownEnvironmentError(value2,
|
|
48423
|
+
return [new UnknownEnvironmentError(value2, [...declared])];
|
|
48410
48424
|
}
|
|
48411
48425
|
return [];
|
|
48412
48426
|
}
|
|
48413
|
-
function
|
|
48414
|
-
const
|
|
48415
|
-
|
|
48427
|
+
function mergedEnvironmentsBlock(config2) {
|
|
48428
|
+
const raw = config2;
|
|
48429
|
+
const carried = [];
|
|
48430
|
+
if (Array.isArray(config2.environments)) {
|
|
48431
|
+
carried.push("`environments` as a list");
|
|
48432
|
+
}
|
|
48433
|
+
if (raw.providers !== void 0) {
|
|
48434
|
+
carried.push("a `providers` block");
|
|
48435
|
+
}
|
|
48436
|
+
if (raw.keys !== void 0) {
|
|
48437
|
+
carried.push("a `keys` block");
|
|
48438
|
+
}
|
|
48439
|
+
if (carried.length === 0) {
|
|
48416
48440
|
return [];
|
|
48417
48441
|
}
|
|
48418
48442
|
return [
|
|
48419
48443
|
new PenvError(
|
|
48420
|
-
"
|
|
48421
|
-
|
|
48422
|
-
'
|
|
48444
|
+
"CONFIG_ENVIRONMENTS_MERGED",
|
|
48445
|
+
`penv.config.ts declares ${carried.join(" and ")}, and one \`environments\` record now holds all three`,
|
|
48446
|
+
'Give each environment one entry, in its provider\'s own words: `type` becomes `provider`, `location` becomes the field that provider declares (`project` for vercel, `path` for ssm and vault), `targets` becomes a single `target` defaulting to the environment\'s name, and `keys.<env>` becomes that entry\'s `keySource`. So `environments: ["production"], providers: { production: { type: "@penvhq/provider-vercel", location: "penv-cloud", targets: { production: "production" } } }, keys: { production: { source: "env", id: "production" } }` becomes `environments: { production: { provider: "@penvhq/provider-vercel", project: "penv-cloud", keySource: "env" } }`. A key id that is not the environment\'s own name has to stay in the object form \u2014 `keySource: { source: "env", id: "prod" }` \u2014 because the shorthand names the key after the environment, and a renamed key is a key the sealed values do not carry. An environment whose provider needs no fields is just the package name: `development: "@penvhq/provider-filesystem"`.'
|
|
48423
48447
|
)
|
|
48424
48448
|
];
|
|
48425
48449
|
}
|
|
48450
|
+
function providerMissing(environment) {
|
|
48451
|
+
return new PenvError(
|
|
48452
|
+
"PROVIDER_MISSING",
|
|
48453
|
+
`The entry for environment ${environment} declares no \`provider\``,
|
|
48454
|
+
`Name the package of the backend that holds this environment's values, e.g. \`${environment}: { provider: "@penvhq/provider-filesystem" }\`. If it still says \`type\`, that is the field \`provider\` replaced.`
|
|
48455
|
+
);
|
|
48456
|
+
}
|
|
48426
48457
|
function validateConfig(config2) {
|
|
48427
48458
|
const errors = [];
|
|
48459
|
+
const merged = mergedEnvironmentsBlock(config2);
|
|
48460
|
+
if (merged.length > 0) {
|
|
48461
|
+
return merged;
|
|
48462
|
+
}
|
|
48428
48463
|
const environments = config2.environments;
|
|
48429
|
-
if (
|
|
48464
|
+
if (environments === null || typeof environments !== "object") {
|
|
48430
48465
|
errors.push(
|
|
48431
48466
|
new PenvError(
|
|
48432
48467
|
"CONFIG_ENVIRONMENTS_INVALID",
|
|
48433
|
-
"`environments` in penv.config.ts is not an
|
|
48434
|
-
'Declare
|
|
48468
|
+
"`environments` in penv.config.ts is not an object",
|
|
48469
|
+
'Declare one entry per environment, e.g. `environments: { development: "@penvhq/provider-filesystem" }`.'
|
|
48435
48470
|
)
|
|
48436
48471
|
);
|
|
48437
48472
|
return errors;
|
|
48438
48473
|
}
|
|
48439
|
-
|
|
48474
|
+
const entries = environments;
|
|
48475
|
+
const names = Object.keys(entries);
|
|
48476
|
+
if (names.length === 0) {
|
|
48440
48477
|
errors.push(
|
|
48441
48478
|
new PenvError(
|
|
48442
48479
|
"CONFIG_ENVIRONMENTS_EMPTY",
|
|
48443
48480
|
"`environments` in penv.config.ts is empty, so no environment can ever be loaded",
|
|
48444
|
-
'Declare at least one
|
|
48481
|
+
'Declare at least one, e.g. `environments: { development: "@penvhq/provider-filesystem" }`. Environments are a whitelist \u2014 penv never infers one from a folder or a filename.'
|
|
48445
48482
|
)
|
|
48446
48483
|
);
|
|
48447
48484
|
}
|
|
48448
48485
|
const declared = /* @__PURE__ */ new Set();
|
|
48449
|
-
for (const environment of
|
|
48450
|
-
if (
|
|
48486
|
+
for (const environment of names) {
|
|
48487
|
+
if (environment.trim().length === 0) {
|
|
48451
48488
|
errors.push(
|
|
48452
48489
|
new PenvError(
|
|
48453
48490
|
"CONFIG_ENVIRONMENT_INVALID",
|
|
48454
|
-
`The environment \`${
|
|
48455
|
-
'Every
|
|
48456
|
-
)
|
|
48457
|
-
);
|
|
48458
|
-
continue;
|
|
48459
|
-
}
|
|
48460
|
-
if (declared.has(environment)) {
|
|
48461
|
-
errors.push(
|
|
48462
|
-
new PenvError(
|
|
48463
|
-
"CONFIG_ENVIRONMENT_DUPLICATE",
|
|
48464
|
-
`The environment \`${environment}\` is declared twice in penv.config.ts`,
|
|
48465
|
-
"Each environment is declared once. Remove the duplicate."
|
|
48491
|
+
`The environment \`${environment}\` in penv.config.ts is not a non-empty name`,
|
|
48492
|
+
'Every key in `environments` is a non-empty name, e.g. `"production"`.'
|
|
48466
48493
|
)
|
|
48467
48494
|
);
|
|
48468
48495
|
continue;
|
|
@@ -48471,63 +48498,36 @@ function validateConfig(config2) {
|
|
|
48471
48498
|
}
|
|
48472
48499
|
errors.push(...validateEnvironmentNames(config2));
|
|
48473
48500
|
errors.push(...validateDefaultEnvironment(config2, declared));
|
|
48474
|
-
const providers = config2.providers;
|
|
48475
|
-
if (providers === null || typeof providers !== "object" || Array.isArray(providers)) {
|
|
48476
|
-
errors.push(
|
|
48477
|
-
new PenvError(
|
|
48478
|
-
"CONFIG_PROVIDERS_INVALID",
|
|
48479
|
-
"`providers` in penv.config.ts is not an object",
|
|
48480
|
-
'Declare one provider per environment, e.g. `providers: { production: { type: "@penvhq/provider-filesystem" } }`.'
|
|
48481
|
-
)
|
|
48482
|
-
);
|
|
48483
|
-
return errors;
|
|
48484
|
-
}
|
|
48485
|
-
const providerEntries = providers;
|
|
48486
48501
|
for (const environment of declared) {
|
|
48487
|
-
const
|
|
48488
|
-
if (
|
|
48489
|
-
|
|
48490
|
-
|
|
48491
|
-
|
|
48492
|
-
|
|
48493
|
-
`Add \`${environment}: { type: "@penvhq/provider-filesystem" }\` to the \`providers\` block, or remove \`${environment}\` from \`environments\`.`
|
|
48494
|
-
)
|
|
48495
|
-
);
|
|
48502
|
+
const entry = own(entries, environment);
|
|
48503
|
+
if (typeof entry === "string") {
|
|
48504
|
+
const nameError2 = validateProviderName(environment, entry);
|
|
48505
|
+
if (nameError2 !== void 0) {
|
|
48506
|
+
errors.push(nameError2);
|
|
48507
|
+
}
|
|
48496
48508
|
continue;
|
|
48497
48509
|
}
|
|
48498
|
-
if (
|
|
48510
|
+
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) {
|
|
48499
48511
|
errors.push(
|
|
48500
48512
|
new PenvError(
|
|
48501
|
-
"
|
|
48502
|
-
`The
|
|
48503
|
-
`Declare it as \`${environment}: {
|
|
48513
|
+
"ENVIRONMENT_ENTRY_INVALID",
|
|
48514
|
+
`The entry for environment ${environment} is ${describeValue(entry)}, not a provider package name or an entry object`,
|
|
48515
|
+
`Declare it as \`${environment}: "@penvhq/provider-filesystem"\`, or as \`${environment}: { provider: "@penvhq/provider-vercel", project: "acme-web" }\` when the provider needs fields.`
|
|
48504
48516
|
)
|
|
48505
48517
|
);
|
|
48506
48518
|
continue;
|
|
48507
48519
|
}
|
|
48508
|
-
const
|
|
48509
|
-
if (typeof
|
|
48510
|
-
errors.push(
|
|
48511
|
-
new PenvError(
|
|
48512
|
-
"PROVIDER_TYPE_MISSING",
|
|
48513
|
-
`The provider for environment ${environment} declares no \`type\``,
|
|
48514
|
-
`Name the package of the backend that holds this environment's values, e.g. \`${environment}: { type: "@penvhq/provider-filesystem" }\`.`
|
|
48515
|
-
)
|
|
48516
|
-
);
|
|
48520
|
+
const provider = entry.provider;
|
|
48521
|
+
if (typeof provider !== "string" || provider.trim().length === 0) {
|
|
48522
|
+
errors.push(providerMissing(environment));
|
|
48517
48523
|
continue;
|
|
48518
48524
|
}
|
|
48519
|
-
const
|
|
48520
|
-
if (
|
|
48521
|
-
errors.push(
|
|
48522
|
-
}
|
|
48523
|
-
}
|
|
48524
|
-
for (const environment of Object.keys(providerEntries)) {
|
|
48525
|
-
if (!declared.has(environment)) {
|
|
48526
|
-
errors.push(new UnknownEnvironmentError(environment, environments));
|
|
48525
|
+
const nameError = validateProviderName(environment, provider);
|
|
48526
|
+
if (nameError !== void 0) {
|
|
48527
|
+
errors.push(nameError);
|
|
48527
48528
|
}
|
|
48528
48529
|
}
|
|
48529
48530
|
errors.push(...validateKeys(config2, declared));
|
|
48530
|
-
errors.push(...legacySinksBlock(config2));
|
|
48531
48531
|
errors.push(...validateSchemaFile(config2));
|
|
48532
48532
|
errors.push(...validatePublicPrefixes(config2));
|
|
48533
48533
|
errors.push(...legacyNamesBlock(config2));
|
|
@@ -48596,8 +48596,9 @@ function legacyNamesBlock(config2) {
|
|
|
48596
48596
|
];
|
|
48597
48597
|
}
|
|
48598
48598
|
function assertEnvironment(environment, config2) {
|
|
48599
|
-
|
|
48600
|
-
|
|
48599
|
+
const declared = environmentNames(config2);
|
|
48600
|
+
if (!declared.includes(environment)) {
|
|
48601
|
+
throw new UnknownEnvironmentError(environment, declared);
|
|
48601
48602
|
}
|
|
48602
48603
|
if (!isLegalEnvironmentName(environment)) {
|
|
48603
48604
|
throw new IllegalEnvironmentNameError(environment);
|
|
@@ -48627,7 +48628,7 @@ function resolveEnvironment(config2, explicit) {
|
|
|
48627
48628
|
if (environment === void 0) {
|
|
48628
48629
|
throw new ConfigError(
|
|
48629
48630
|
"No environment is set, so penv cannot tell which environment to load",
|
|
48630
|
-
`Pass \`--env <environment>\` \u2014 one of ${quoteList(config2
|
|
48631
|
+
`Pass \`--env <environment>\` \u2014 one of ${quoteList(environmentNames(config2))} \u2014 or declare \`defaultEnvironment\` in penv.config.ts so every command has one.`
|
|
48631
48632
|
);
|
|
48632
48633
|
}
|
|
48633
48634
|
return environment;
|
|
@@ -48681,7 +48682,7 @@ var ALGORITHM = "aes-256-gcm";
|
|
|
48681
48682
|
function remedyFor(failure, location) {
|
|
48682
48683
|
switch (failure.reason) {
|
|
48683
48684
|
case "key-source-unavailable":
|
|
48684
|
-
return `penv could not consult a key source: ${failure.detail}. Make the key available where this environment expects it \u2014 if the source is your OS keychain, unlock it; if no key source is declared, add a \`
|
|
48685
|
+
return `penv could not consult a key source: ${failure.detail}. Make the key available where this environment expects it \u2014 if the source is your OS keychain, unlock it; if no key source is declared, add a \`keySource\` to this environment's entry in penv.config.ts.`;
|
|
48685
48686
|
case "key-absent":
|
|
48686
48687
|
return `The key that seals ${location} is not there: ${failure.detail}. Export the key, or re-seal the value under a key you hold with \`penv encrypt\`.`;
|
|
48687
48688
|
case "malformed-envelope":
|
|
@@ -48717,7 +48718,7 @@ var KeyUnavailableError = class extends PenvError {
|
|
|
48717
48718
|
super(
|
|
48718
48719
|
"KEY_UNAVAILABLE",
|
|
48719
48720
|
`Parameter ${parameter} is a secret for environment ${environment}, and penv has no key to seal it with: ${detail}`,
|
|
48720
|
-
"penv will not write a secret in plaintext, and will not invent a key. Declare
|
|
48721
|
+
"penv will not write a secret in plaintext, and will not invent a key. Declare this environment's `keySource` in penv.config.ts and make the key available, then run the command again."
|
|
48721
48722
|
);
|
|
48722
48723
|
this.parameter = parameter;
|
|
48723
48724
|
this.environment = environment;
|
|
@@ -50369,7 +50370,7 @@ var import_node_path7 = require("path");
|
|
|
50369
50370
|
// ../runtime/dist/index.js
|
|
50370
50371
|
init_cjs_shims();
|
|
50371
50372
|
|
|
50372
|
-
// ../runtime/dist/chunk-
|
|
50373
|
+
// ../runtime/dist/chunk-FPKLY3QL.js
|
|
50373
50374
|
init_cjs_shims();
|
|
50374
50375
|
|
|
50375
50376
|
// ../providers/filesystem/dist/index.js
|
|
@@ -50521,11 +50522,11 @@ function createFilesystemProvider(options) {
|
|
|
50521
50522
|
return new FilesystemProvider(options);
|
|
50522
50523
|
}
|
|
50523
50524
|
|
|
50524
|
-
// ../runtime/dist/chunk-
|
|
50525
|
+
// ../runtime/dist/chunk-FPKLY3QL.js
|
|
50525
50526
|
var LOCAL_TREE_TYPE = "@penvhq/provider-filesystem";
|
|
50526
50527
|
function hasRemoteSource(config2, environment) {
|
|
50527
|
-
const declared =
|
|
50528
|
-
return declared !== void 0 && declared.
|
|
50528
|
+
const declared = environmentEntry(config2, environment);
|
|
50529
|
+
return declared !== void 0 && declared.provider !== LOCAL_TREE_TYPE;
|
|
50529
50530
|
}
|
|
50530
50531
|
|
|
50531
50532
|
// ../runtime/dist/index.js
|
|
@@ -50719,11 +50720,15 @@ function penvOwnVariables(host) {
|
|
|
50719
50720
|
}
|
|
50720
50721
|
function strippedVariables(host, config2, credentials) {
|
|
50721
50722
|
const names = penvOwnVariables(host);
|
|
50722
|
-
for (const
|
|
50723
|
-
|
|
50723
|
+
for (const environment of environmentNames(config2)) {
|
|
50724
|
+
const provider = environmentEntry(config2, environment)?.provider;
|
|
50725
|
+
if (provider === void 0) {
|
|
50726
|
+
continue;
|
|
50727
|
+
}
|
|
50728
|
+
for (const name of own(PROVIDER_CREDENTIALS, provider) ?? []) {
|
|
50724
50729
|
names.add(name);
|
|
50725
50730
|
}
|
|
50726
|
-
for (const name of own(credentials, provider
|
|
50731
|
+
for (const name of own(credentials, provider) ?? []) {
|
|
50727
50732
|
names.add(name);
|
|
50728
50733
|
}
|
|
50729
50734
|
}
|
|
@@ -51319,22 +51324,10 @@ var import_node_path4 = require("path");
|
|
|
51319
51324
|
// src/env-flags.ts
|
|
51320
51325
|
init_cjs_shims();
|
|
51321
51326
|
var BASE_RESERVED = ["help", "version", "h", "v", "_", "--"];
|
|
51322
|
-
var COMMAND_FLAGS = [
|
|
51323
|
-
...BASE_RESERVED,
|
|
51324
|
-
"env",
|
|
51325
|
-
"out",
|
|
51326
|
-
"allow-decrypt",
|
|
51327
|
-
"destination",
|
|
51328
|
-
"dest",
|
|
51329
|
-
"d",
|
|
51330
|
-
"location",
|
|
51331
|
-
"l",
|
|
51332
|
-
"yes",
|
|
51333
|
-
"y"
|
|
51334
|
-
];
|
|
51327
|
+
var COMMAND_FLAGS = [...BASE_RESERVED, "env", "out", "allow-decrypt", "yes", "y"];
|
|
51335
51328
|
function shadowedEnvironments(config2) {
|
|
51336
51329
|
const flags = new Set(COMMAND_FLAGS);
|
|
51337
|
-
return config2.
|
|
51330
|
+
return environmentNames(config2).filter((environment) => flags.has(environment));
|
|
51338
51331
|
}
|
|
51339
51332
|
function shorthandCandidates(args, declared) {
|
|
51340
51333
|
const reserved = /* @__PURE__ */ new Set([...BASE_RESERVED, ...declared]);
|
|
@@ -51347,13 +51340,14 @@ function environmentFromShorthand(config2, candidates, explicit) {
|
|
|
51347
51340
|
if (candidates.length === 0) {
|
|
51348
51341
|
return void 0;
|
|
51349
51342
|
}
|
|
51350
|
-
const
|
|
51351
|
-
const
|
|
51343
|
+
const declared = environmentNames(config2);
|
|
51344
|
+
const hits = candidates.filter((candidate) => declared.includes(candidate));
|
|
51345
|
+
const strangers = candidates.filter((candidate) => !declared.includes(candidate));
|
|
51352
51346
|
if (strangers.length > 0) {
|
|
51353
51347
|
throw new PenvError(
|
|
51354
51348
|
"UNKNOWN_FLAG",
|
|
51355
51349
|
`${quoteList2(strangers)} ${strangers.length === 1 ? "is not a flag" : "are not flags"} this command takes, and ${strangers.length === 1 ? "names" : "name"} no declared environment`,
|
|
51356
|
-
`Declared environments work as bare flags: ${quoteList2(
|
|
51350
|
+
`Declared environments work as bare flags: ${quoteList2(declared)}. Anything else needs \`--env <name>\`.`
|
|
51357
51351
|
);
|
|
51358
51352
|
}
|
|
51359
51353
|
if (hits.length > 1) {
|
|
@@ -51560,14 +51554,18 @@ async function loadPluginProvider(type, context) {
|
|
|
51560
51554
|
function assertProvidersRegistered(config2, projectRoot, options) {
|
|
51561
51555
|
const local = localExtensions(projectRoot);
|
|
51562
51556
|
const ci = options?.ci ?? isCi(process.env.CI);
|
|
51563
|
-
for (const
|
|
51564
|
-
|
|
51557
|
+
for (const environment of environmentNames(config2)) {
|
|
51558
|
+
const provider = environmentEntry(config2, environment)?.provider;
|
|
51559
|
+
if (typeof provider !== "string" || provider.trim().length === 0) {
|
|
51560
|
+
throw providerMissing(environment);
|
|
51561
|
+
}
|
|
51562
|
+
if (isProviderRegistered(provider)) {
|
|
51565
51563
|
continue;
|
|
51566
51564
|
}
|
|
51567
|
-
if (ci && local.includes(provider
|
|
51568
|
-
throw localExtensionInCi(provider
|
|
51565
|
+
if (ci && local.includes(provider)) {
|
|
51566
|
+
throw localExtensionInCi(provider, environment);
|
|
51569
51567
|
}
|
|
51570
|
-
resolveExtension(provider
|
|
51568
|
+
resolveExtension(provider, projectRoot, environment, local);
|
|
51571
51569
|
}
|
|
51572
51570
|
}
|
|
51573
51571
|
function resolveExtension(type, projectRoot, environment, local = localExtensions(projectRoot)) {
|
|
@@ -51725,11 +51723,11 @@ function schemaShapeFileOf(project) {
|
|
|
51725
51723
|
return selfContainedSchemaModule(project.root, schemaFile) ?? SCHEMA_SHAPE_FILE;
|
|
51726
51724
|
}
|
|
51727
51725
|
async function sourceProviderFor(project, environment) {
|
|
51728
|
-
const providerConfig = project.config
|
|
51726
|
+
const providerConfig = environmentEntry(project.config, environment);
|
|
51729
51727
|
if (providerConfig === void 0) {
|
|
51730
51728
|
return createProvider(LOCAL_TREE_TYPE2, { root: project.root, config: project.config });
|
|
51731
51729
|
}
|
|
51732
|
-
return createSourceProvider(providerConfig.
|
|
51730
|
+
return createSourceProvider(providerConfig.provider, {
|
|
51733
51731
|
root: project.root,
|
|
51734
51732
|
config: project.config,
|
|
51735
51733
|
providerConfig,
|
|
@@ -51741,7 +51739,7 @@ function targetEnvironment(project, explicit, shorthand) {
|
|
|
51741
51739
|
return resolveEnvironment(project.config, explicit ?? fromFlags);
|
|
51742
51740
|
}
|
|
51743
51741
|
var KEY_SEPARATOR = /[./\\]/;
|
|
51744
|
-
var NO_ENVIRONMENTS = { environments:
|
|
51742
|
+
var NO_ENVIRONMENTS = { environments: {} };
|
|
51745
51743
|
function refFromKey(key, config2) {
|
|
51746
51744
|
const segments = key.split(KEY_SEPARATOR).filter((segment) => segment.length > 0);
|
|
51747
51745
|
const name = segments[segments.length - 1];
|
|
@@ -52064,8 +52062,9 @@ function discoverDotenvFiles(root) {
|
|
|
52064
52062
|
return files.sort((a, b) => order(a) < order(b) ? -1 : order(a) > order(b) ? 1 : 0);
|
|
52065
52063
|
}
|
|
52066
52064
|
function activeDotenvFiles(root, config2) {
|
|
52065
|
+
const declared = environmentNames(config2);
|
|
52067
52066
|
return discoverDotenvFiles(root).filter(
|
|
52068
|
-
(file2) => file2.environment === void 0 ||
|
|
52067
|
+
(file2) => file2.environment === void 0 || declared.includes(file2.environment)
|
|
52069
52068
|
);
|
|
52070
52069
|
}
|
|
52071
52070
|
function environmentsDeclaredBy(files) {
|
|
@@ -52804,11 +52803,12 @@ function packageManifest(specifier, root) {
|
|
|
52804
52803
|
}
|
|
52805
52804
|
function declaredCredentials(config2, root) {
|
|
52806
52805
|
const declared = {};
|
|
52807
|
-
for (const
|
|
52808
|
-
|
|
52806
|
+
for (const environment of environmentNames(config2)) {
|
|
52807
|
+
const provider = environmentEntry(config2, environment)?.provider;
|
|
52808
|
+
if (provider === void 0 || own(declared, provider) !== void 0) {
|
|
52809
52809
|
continue;
|
|
52810
52810
|
}
|
|
52811
|
-
const penv = packageManifest(provider
|
|
52811
|
+
const penv = packageManifest(provider, root)?.penv;
|
|
52812
52812
|
const credentials = isPlainObject5(penv) ? penv.credentials : void 0;
|
|
52813
52813
|
if (credentials === void 0) {
|
|
52814
52814
|
continue;
|
|
@@ -52816,11 +52816,11 @@ function declaredCredentials(config2, root) {
|
|
|
52816
52816
|
if (!Array.isArray(credentials) || credentials.some((name) => typeof name !== "string" || !VARIABLE2.test(name))) {
|
|
52817
52817
|
throw new PenvError(
|
|
52818
52818
|
"PROVIDER_CREDENTIALS_INVALID",
|
|
52819
|
-
`\`${provider
|
|
52819
|
+
`\`${provider}\` declares \`penv.credentials\`, and it is not a list of variable names`,
|
|
52820
52820
|
`Its package.json should read \`"penv": { "credentials": ["ACME_TOKEN"] }\` \u2014 penv strips exactly what an extension declares, so it will not guess at a declaration it cannot read.`
|
|
52821
52821
|
);
|
|
52822
52822
|
}
|
|
52823
|
-
declared[provider
|
|
52823
|
+
declared[provider] = credentials;
|
|
52824
52824
|
}
|
|
52825
52825
|
return declared;
|
|
52826
52826
|
}
|
|
@@ -53510,38 +53510,23 @@ function lineReader(input = process.stdin, output = process.stdout) {
|
|
|
53510
53510
|
// src/commands/push.ts
|
|
53511
53511
|
var LAST_PUSHED_KEY = "lastPushedAt";
|
|
53512
53512
|
async function destinationFor(project, environment, options) {
|
|
53513
|
-
|
|
53514
|
-
|
|
53515
|
-
type: options.destination,
|
|
53516
|
-
...options.location === void 0 ? {} : { location: options.location }
|
|
53517
|
-
};
|
|
53518
|
-
const provider2 = options.provider ?? await createSourceProvider(options.destination, {
|
|
53519
|
-
root: project.root,
|
|
53520
|
-
config: project.config,
|
|
53521
|
-
providerConfig,
|
|
53522
|
-
environment
|
|
53523
|
-
});
|
|
53524
|
-
return { provider: provider2, location: options.location };
|
|
53525
|
-
}
|
|
53526
|
-
const declared = project.config.providers[environment];
|
|
53527
|
-
const location = declared?.location;
|
|
53528
|
-
if (declared === void 0 || declared.type === LOCAL_TREE_TYPE2) {
|
|
53513
|
+
const declared = environmentEntry(project.config, environment);
|
|
53514
|
+
if (declared === void 0 || declared.provider === LOCAL_TREE_TYPE2) {
|
|
53529
53515
|
throw new PenvError(
|
|
53530
53516
|
"NO_DESTINATION",
|
|
53531
53517
|
`Environment ${environment}'s provider is the local records tree itself, so penv has nowhere to push`,
|
|
53532
|
-
`Declare
|
|
53518
|
+
`Declare the backend that holds it in penv.config.ts \u2014 e.g. \`${environment}: { provider: "@penvhq/provider-github", repository: "owner/repo" }\` \u2014 and run this again. A push only ever goes where the config says this environment lives.`
|
|
53533
53519
|
);
|
|
53534
53520
|
}
|
|
53535
53521
|
if (options.provider !== void 0) {
|
|
53536
|
-
return
|
|
53522
|
+
return options.provider;
|
|
53537
53523
|
}
|
|
53538
|
-
|
|
53524
|
+
return createSourceProvider(declared.provider, {
|
|
53539
53525
|
root: project.root,
|
|
53540
53526
|
config: project.config,
|
|
53541
53527
|
providerConfig: declared,
|
|
53542
53528
|
environment
|
|
53543
53529
|
});
|
|
53544
|
-
return { provider, location };
|
|
53545
53530
|
}
|
|
53546
53531
|
function plan(resolutions, config2, environment, allowDecrypt) {
|
|
53547
53532
|
const outbound = [];
|
|
@@ -53625,7 +53610,7 @@ async function ensureTargetApproved(provider, environment, options) {
|
|
|
53625
53610
|
await provider.ensureTarget(environment);
|
|
53626
53611
|
return true;
|
|
53627
53612
|
}
|
|
53628
|
-
async function pushProjection(project, provider, environment,
|
|
53613
|
+
async function pushProjection(project, provider, environment, options) {
|
|
53629
53614
|
const tree = localTree(project);
|
|
53630
53615
|
const keys = keySourceFor(project, environment);
|
|
53631
53616
|
const resolutions = resolveAllSync(tree, environment, keys, true);
|
|
@@ -53656,7 +53641,6 @@ async function pushProjection(project, provider, environment, location, options)
|
|
|
53656
53641
|
environment,
|
|
53657
53642
|
destination: provider.type,
|
|
53658
53643
|
mode: "projection",
|
|
53659
|
-
location,
|
|
53660
53644
|
pushed: outbound.length,
|
|
53661
53645
|
meta: 0,
|
|
53662
53646
|
repositorySecrets,
|
|
@@ -53672,7 +53656,7 @@ function crossesToRecords(file2, environment) {
|
|
|
53672
53656
|
}
|
|
53673
53657
|
return scope.kind === "environment" && scope.environment === environment;
|
|
53674
53658
|
}
|
|
53675
|
-
async function pushRecords(project, provider, environment
|
|
53659
|
+
async function pushRecords(project, provider, environment) {
|
|
53676
53660
|
const tree = localTree(project);
|
|
53677
53661
|
const files = tree.listSync().filter((file2) => crossesToRecords(file2, environment));
|
|
53678
53662
|
let pushed = 0;
|
|
@@ -53698,7 +53682,6 @@ async function pushRecords(project, provider, environment, location) {
|
|
|
53698
53682
|
environment,
|
|
53699
53683
|
destination: provider.type,
|
|
53700
53684
|
mode: "records",
|
|
53701
|
-
location,
|
|
53702
53685
|
pushed,
|
|
53703
53686
|
meta: meta3,
|
|
53704
53687
|
repositorySecrets: 0,
|
|
@@ -53710,11 +53693,11 @@ async function pushRecords(project, provider, environment, location) {
|
|
|
53710
53693
|
async function runPush(options) {
|
|
53711
53694
|
const project = openProject(options.cwd);
|
|
53712
53695
|
const environment = targetEnvironment(project, options.environment, options.envFlags);
|
|
53713
|
-
const
|
|
53696
|
+
const provider = await destinationFor(project, environment, options);
|
|
53714
53697
|
if (holdsProjection(provider)) {
|
|
53715
|
-
return pushProjection(project, provider, environment,
|
|
53698
|
+
return pushProjection(project, provider, environment, options);
|
|
53716
53699
|
}
|
|
53717
|
-
return pushRecords(project, provider, environment
|
|
53700
|
+
return pushRecords(project, provider, environment);
|
|
53718
53701
|
}
|
|
53719
53702
|
function renderPush(result2) {
|
|
53720
53703
|
if (result2.pushed === 0 && result2.meta === 0) {
|
|
@@ -53726,7 +53709,7 @@ function renderPush(result2) {
|
|
|
53726
53709
|
}
|
|
53727
53710
|
]);
|
|
53728
53711
|
}
|
|
53729
|
-
const target = `${result2.destination} for environment ${result2.environment}
|
|
53712
|
+
const target = `${result2.destination} for environment ${result2.environment}`;
|
|
53730
53713
|
if (result2.mode === "records") {
|
|
53731
53714
|
return formatRows([
|
|
53732
53715
|
{
|
|
@@ -53775,6 +53758,19 @@ function renderPush(result2) {
|
|
|
53775
53758
|
}
|
|
53776
53759
|
return formatRows(rows);
|
|
53777
53760
|
}
|
|
53761
|
+
var REDIRECT_FLAGS = ["destination", "dest", "d", "location", "l"];
|
|
53762
|
+
function assertNoRedirect(args) {
|
|
53763
|
+
const given = REDIRECT_FLAGS.filter((flag) => args[flag] !== void 0);
|
|
53764
|
+
const named = given[0];
|
|
53765
|
+
if (named === void 0) {
|
|
53766
|
+
return;
|
|
53767
|
+
}
|
|
53768
|
+
throw new PenvError(
|
|
53769
|
+
"REMOVED_FLAG",
|
|
53770
|
+
`\`--${named}\` is not a flag \`penv push\` takes`,
|
|
53771
|
+
"A push only ever goes where the config says this environment lives. Declare the destination in `environments.<env>` \u2014 the provider package, addressed in that provider's own words \u2014 and push with `--env <name>`."
|
|
53772
|
+
);
|
|
53773
|
+
}
|
|
53778
53774
|
var pushCommand = defineCommand({
|
|
53779
53775
|
meta: {
|
|
53780
53776
|
name: "push",
|
|
@@ -53786,16 +53782,6 @@ var pushCommand = defineCommand({
|
|
|
53786
53782
|
type: "boolean",
|
|
53787
53783
|
description: "Decrypt sealed values locally and push them as plaintext for the destination to re-seal"
|
|
53788
53784
|
},
|
|
53789
|
-
destination: {
|
|
53790
|
-
type: "string",
|
|
53791
|
-
alias: ["dest", "d"],
|
|
53792
|
-
description: "Push once to this provider package instead of the declared one"
|
|
53793
|
-
},
|
|
53794
|
-
location: {
|
|
53795
|
-
type: "string",
|
|
53796
|
-
alias: "l",
|
|
53797
|
-
description: "The destination-side place, when --destination needs one"
|
|
53798
|
-
},
|
|
53799
53785
|
yes: {
|
|
53800
53786
|
type: "boolean",
|
|
53801
53787
|
alias: "y",
|
|
@@ -53804,25 +53790,13 @@ var pushCommand = defineCommand({
|
|
|
53804
53790
|
},
|
|
53805
53791
|
run({ args }) {
|
|
53806
53792
|
return guard(async () => {
|
|
53793
|
+
assertNoRedirect(args);
|
|
53807
53794
|
const result2 = await runPush({
|
|
53808
53795
|
cwd: process.cwd(),
|
|
53809
53796
|
...args.env === void 0 ? {} : { environment: args.env },
|
|
53810
53797
|
...args["allow-decrypt"] === void 0 ? {} : { allowDecrypt: args["allow-decrypt"] },
|
|
53811
|
-
...args.destination === void 0 ? {} : { destination: args.destination },
|
|
53812
|
-
...args.location === void 0 ? {} : { location: args.location },
|
|
53813
53798
|
...args.yes === void 0 ? {} : { yes: args.yes },
|
|
53814
|
-
envFlags: shorthandCandidates(args, [
|
|
53815
|
-
"env",
|
|
53816
|
-
"allow-decrypt",
|
|
53817
|
-
"allowDecrypt",
|
|
53818
|
-
"destination",
|
|
53819
|
-
"dest",
|
|
53820
|
-
"d",
|
|
53821
|
-
"location",
|
|
53822
|
-
"l",
|
|
53823
|
-
"yes",
|
|
53824
|
-
"y"
|
|
53825
|
-
])
|
|
53799
|
+
envFlags: shorthandCandidates(args, ["env", "allow-decrypt", "allowDecrypt", "yes", "y"])
|
|
53826
53800
|
});
|
|
53827
53801
|
write(renderPush(result2));
|
|
53828
53802
|
});
|
|
@@ -53921,7 +53895,7 @@ async function runDoctor(options) {
|
|
|
53921
53895
|
check: "provider",
|
|
53922
53896
|
severity: "pass",
|
|
53923
53897
|
label: "Provider",
|
|
53924
|
-
subject: project.config
|
|
53898
|
+
subject: environmentEntry(project.config, environment)?.provider ?? project.provider.type
|
|
53925
53899
|
});
|
|
53926
53900
|
return {
|
|
53927
53901
|
environment,
|
|
@@ -54191,8 +54165,8 @@ async function projectionFindings(project, environment, override) {
|
|
|
54191
54165
|
if (override !== void 0) {
|
|
54192
54166
|
projection = override;
|
|
54193
54167
|
} else {
|
|
54194
|
-
const declared = project.config
|
|
54195
|
-
if (declared === void 0 || declared.
|
|
54168
|
+
const declared = environmentEntry(project.config, environment);
|
|
54169
|
+
if (declared === void 0 || declared.provider === LOCAL_TREE_TYPE2) {
|
|
54196
54170
|
return [];
|
|
54197
54171
|
}
|
|
54198
54172
|
let source;
|
|
@@ -54204,7 +54178,7 @@ async function projectionFindings(project, environment, override) {
|
|
|
54204
54178
|
check: "projection-unreachable",
|
|
54205
54179
|
severity: "unknown",
|
|
54206
54180
|
label: "Destination",
|
|
54207
|
-
subject: `could not build the ${declared.
|
|
54181
|
+
subject: `could not build the ${declared.provider} provider for ${environment}`,
|
|
54208
54182
|
detail: errorDetail(error51)
|
|
54209
54183
|
}
|
|
54210
54184
|
];
|
|
@@ -54477,8 +54451,8 @@ function refPathOf(ref) {
|
|
|
54477
54451
|
return [...ref.namespace, ref.name].join("/");
|
|
54478
54452
|
}
|
|
54479
54453
|
async function rotationSubjects(project, environment, local, override) {
|
|
54480
|
-
const providerConfig = project.config
|
|
54481
|
-
if (override === void 0 && (providerConfig === void 0 || providerConfig.
|
|
54454
|
+
const providerConfig = environmentEntry(project.config, environment);
|
|
54455
|
+
if (override === void 0 && (providerConfig === void 0 || providerConfig.provider === LOCAL_TREE_TYPE2)) {
|
|
54482
54456
|
return { kind: "read", subjects: local };
|
|
54483
54457
|
}
|
|
54484
54458
|
const source = override ?? await sourceProviderFor(project, environment);
|
|
@@ -54500,7 +54474,7 @@ async function rotationSubjects(project, environment, local, override) {
|
|
|
54500
54474
|
check: "rotation-overdue",
|
|
54501
54475
|
severity: "unknown",
|
|
54502
54476
|
label: "Rotation",
|
|
54503
|
-
subject: `could not reach the ${providerConfig?.
|
|
54477
|
+
subject: `could not reach the ${providerConfig?.provider ?? source.type} source of truth for ${environment}`,
|
|
54504
54478
|
detail: errorDetail(error51)
|
|
54505
54479
|
}
|
|
54506
54480
|
};
|
|
@@ -54621,8 +54595,8 @@ async function readRelevant(provider, environment) {
|
|
|
54621
54595
|
return entries;
|
|
54622
54596
|
}
|
|
54623
54597
|
async function providerDriftFindings(project, environment, override) {
|
|
54624
|
-
const providerConfig = project.config
|
|
54625
|
-
if (providerConfig === void 0 || providerConfig.
|
|
54598
|
+
const providerConfig = environmentEntry(project.config, environment);
|
|
54599
|
+
if (providerConfig === void 0 || providerConfig.provider === LOCAL_TREE_TYPE2) {
|
|
54626
54600
|
return [
|
|
54627
54601
|
{
|
|
54628
54602
|
check: "provider-value-drift",
|
|
@@ -54647,7 +54621,7 @@ async function providerDriftFindings(project, environment, override) {
|
|
|
54647
54621
|
check: "provider-value-drift",
|
|
54648
54622
|
severity: "unknown",
|
|
54649
54623
|
label: "Provider values",
|
|
54650
|
-
subject: `could not reach the ${providerConfig.
|
|
54624
|
+
subject: `could not reach the ${providerConfig.provider} provider for ${environment}`,
|
|
54651
54625
|
detail: errorDetail(error51)
|
|
54652
54626
|
}
|
|
54653
54627
|
];
|
|
@@ -54666,7 +54640,7 @@ async function providerDriftFindings(project, environment, override) {
|
|
|
54666
54640
|
severity: "unknown",
|
|
54667
54641
|
label: "Provider value unreadable",
|
|
54668
54642
|
subject: formatValueFile(here.file),
|
|
54669
|
-
detail: `the local value is sealed and did not open, so it cannot be compared against the ${providerConfig.
|
|
54643
|
+
detail: `the local value is sealed and did not open, so it cannot be compared against the ${providerConfig.provider} source of truth`
|
|
54670
54644
|
});
|
|
54671
54645
|
continue;
|
|
54672
54646
|
}
|
|
@@ -54676,7 +54650,7 @@ async function providerDriftFindings(project, environment, override) {
|
|
|
54676
54650
|
severity: "failure",
|
|
54677
54651
|
label: "Provider value drift",
|
|
54678
54652
|
subject: formatValueFile(here.file),
|
|
54679
|
-
detail: `the local tree and the ${providerConfig.
|
|
54653
|
+
detail: `the local tree and the ${providerConfig.provider} source of truth hold different values`
|
|
54680
54654
|
});
|
|
54681
54655
|
}
|
|
54682
54656
|
continue;
|
|
@@ -54690,7 +54664,7 @@ async function providerDriftFindings(project, environment, override) {
|
|
|
54690
54664
|
severity: "warning",
|
|
54691
54665
|
label: here !== void 0 ? "Only in the local tree" : "Only in the source",
|
|
54692
54666
|
subject: formatValueFile(present.file),
|
|
54693
|
-
detail: here !== void 0 ? `present locally, absent from the ${providerConfig.
|
|
54667
|
+
detail: here !== void 0 ? `present locally, absent from the ${providerConfig.provider} source of truth` : `present in the ${providerConfig.provider} source of truth, absent from the local tree`
|
|
54694
54668
|
});
|
|
54695
54669
|
}
|
|
54696
54670
|
if (findings.length > 0) {
|
|
@@ -54701,7 +54675,7 @@ async function providerDriftFindings(project, environment, override) {
|
|
|
54701
54675
|
check: "provider-value-drift",
|
|
54702
54676
|
severity: "pass",
|
|
54703
54677
|
label: "Provider values",
|
|
54704
|
-
subject: `every value matches the ${providerConfig.
|
|
54678
|
+
subject: `every value matches the ${providerConfig.provider} source of truth for ${environment}`
|
|
54705
54679
|
}
|
|
54706
54680
|
];
|
|
54707
54681
|
}
|
|
@@ -54801,7 +54775,7 @@ function targetScope(project, options, key) {
|
|
|
54801
54775
|
throw new PenvError(
|
|
54802
54776
|
"ENVIRONMENT_FLAG_EMPTY",
|
|
54803
54777
|
`\`--env\` for parameter ${key} names no environment`,
|
|
54804
|
-
`Pass a declared environment \u2014 ${project.config.
|
|
54778
|
+
`Pass a declared environment \u2014 ${environmentNames(project.config).map((e) => `\`${e}\``).join(", ")} \u2014 e.g. \`--env production\`, or drop \`--env\` to write the scope that has no environment.`
|
|
54805
54779
|
);
|
|
54806
54780
|
}
|
|
54807
54781
|
return scopeFrom({ ...options, environment: targetEnvironment(project, environment) });
|
|
@@ -54814,7 +54788,7 @@ function sealFor(project, file2, value2, parameter, environment) {
|
|
|
54814
54788
|
throw new PenvError(
|
|
54815
54789
|
"SECRET_SCOPE_AMBIGUOUS",
|
|
54816
54790
|
`Parameter ${parameter} is a secret, and ${recordPath(formatValueFile(file2))} names no environment`,
|
|
54817
|
-
"
|
|
54791
|
+
"A key is declared by its environment's `keySource` in penv.config.ts, so penv cannot tell which key should seal a file that every environment reads. Write it at an environment scope \u2014 add `--env <environment>` \u2014 or drop `secret` from the parameter's meta."
|
|
54818
54792
|
);
|
|
54819
54793
|
}
|
|
54820
54794
|
return sealValue(file2, value2, keySourceFor(project, environment), parameter, environment);
|
|
@@ -55892,8 +55866,14 @@ function environmentsFromFlag(flag) {
|
|
|
55892
55866
|
}
|
|
55893
55867
|
return [...new Set(names)];
|
|
55894
55868
|
}
|
|
55869
|
+
function environmentsRecord(names) {
|
|
55870
|
+
return Object.fromEntries(names.map((environment) => [environment, LOCAL_PROVIDER]));
|
|
55871
|
+
}
|
|
55895
55872
|
function configOf(decisions) {
|
|
55896
|
-
return {
|
|
55873
|
+
return {
|
|
55874
|
+
environments: environmentsRecord(decisions.environments),
|
|
55875
|
+
schemaFile: decisions.schemaFile
|
|
55876
|
+
};
|
|
55897
55877
|
}
|
|
55898
55878
|
function declaredIn2(root) {
|
|
55899
55879
|
const file2 = (0, import_node_path13.join)(root, CONFIG_FILE);
|
|
@@ -55925,7 +55905,7 @@ function planInit(root, flags = {}) {
|
|
|
55925
55905
|
if (schemaFile.length === 0) {
|
|
55926
55906
|
throw emptyFlag("schema");
|
|
55927
55907
|
}
|
|
55928
|
-
const error51 = validateSchemaFile({ environments:
|
|
55908
|
+
const error51 = validateSchemaFile({ environments: {}, schemaFile })[0];
|
|
55929
55909
|
if (error51 !== void 0) {
|
|
55930
55910
|
throw error51;
|
|
55931
55911
|
}
|
|
@@ -55948,7 +55928,7 @@ function planInit(root, flags = {}) {
|
|
|
55948
55928
|
}
|
|
55949
55929
|
const suggestedEnvironments = suggestEnvironments(root);
|
|
55950
55930
|
const safeDefault = flags.yes === true && declared === void 0;
|
|
55951
|
-
const environments = flags.environments ?? declared
|
|
55931
|
+
const environments = flags.environments ?? (declared === void 0 ? void 0 : environmentNames(declared)) ?? (safeDefault ? [DEVELOPMENT] : []);
|
|
55952
55932
|
const defaultEnvironment = declared?.defaultEnvironment ?? (safeDefault ? DEVELOPMENT : void 0);
|
|
55953
55933
|
if (safeDefault) {
|
|
55954
55934
|
notes.push(
|
|
@@ -56081,27 +56061,27 @@ export { schema };
|
|
|
56081
56061
|
|
|
56082
56062
|
` + loadComment + loadCall;
|
|
56083
56063
|
}
|
|
56064
|
+
function entryKey(name) {
|
|
56065
|
+
return /^[A-Za-z_$][\w$]*$/.test(name) ? name : JSON.stringify(name);
|
|
56066
|
+
}
|
|
56084
56067
|
function renderEnvironments(decisions) {
|
|
56085
|
-
const shared = " // Environments are a whitelist
|
|
56068
|
+
const shared = " // Environments are a whitelist, and each entry is that environment's whole\n // declaration: which provider holds it, in that provider's own words, and\n // which key seals it. A segment is an environment only if it is named here.\n";
|
|
56086
56069
|
if (decisions.environments.length === 0) {
|
|
56087
56070
|
return `${shared} // It starts empty because which environments you deploy is not something penv
|
|
56088
56071
|
// can read off your codebase, and an environment you do not have is worse
|
|
56089
|
-
// than one you have not declared yet. Name yours
|
|
56090
|
-
// environments:
|
|
56091
|
-
//
|
|
56092
|
-
|
|
56093
|
-
|
|
56094
|
-
|
|
56072
|
+
// than one you have not declared yet. Name yours:
|
|
56073
|
+
// environments: {
|
|
56074
|
+
// development: "@penvhq/provider-filesystem",
|
|
56075
|
+
// production: { provider: "@penvhq/provider-vault", path: "penv", keySource: "env" },
|
|
56076
|
+
// },
|
|
56077
|
+
environments: {},
|
|
56095
56078
|
`;
|
|
56096
56079
|
}
|
|
56097
|
-
const
|
|
56098
|
-
const providers = decisions.environments.map((name) => ` ${JSON.stringify(name)}: { type: "@penvhq/provider-filesystem" },
|
|
56080
|
+
const entries = decisions.environments.map((name) => ` ${entryKey(name)}: ${JSON.stringify(LOCAL_PROVIDER)},
|
|
56099
56081
|
`).join("");
|
|
56100
|
-
return `${shared}
|
|
56101
|
-
|
|
56102
|
-
|
|
56103
|
-
providers: {
|
|
56104
|
-
${providers} },
|
|
56082
|
+
return `${shared} // A provider that needs no fields is just its package name.
|
|
56083
|
+
environments: {
|
|
56084
|
+
${entries} },
|
|
56105
56085
|
`;
|
|
56106
56086
|
}
|
|
56107
56087
|
function renderConfigModule(decisions) {
|
|
@@ -56620,13 +56600,13 @@ function planCutover(input) {
|
|
|
56620
56600
|
const declared = declaredIn2(root);
|
|
56621
56601
|
const named = environmentsDeclaredBy(selected);
|
|
56622
56602
|
const chosen = named.length > 0 ? named : [requireEnvironment(input)];
|
|
56623
|
-
const environments = declared === void 0 ? chosen : declared
|
|
56603
|
+
const environments = declared === void 0 ? chosen : environmentNames(declared);
|
|
56624
56604
|
for (const environment of chosen) {
|
|
56625
56605
|
if (!environments.includes(environment)) {
|
|
56626
56606
|
throw new PenvError(
|
|
56627
56607
|
"INIT_ENVIRONMENT_UNDECLARED",
|
|
56628
56608
|
`${CONFIG_FILE} declares ${describeList(environments)}, and adopting these files needs \`${environment}\` declared too`,
|
|
56629
|
-
`Add \`${environment}\` to \`environments\` in ${CONFIG_FILE},
|
|
56609
|
+
`Add \`${environment}: "${LOCAL_PROVIDER}"\` to \`environments\` in ${CONFIG_FILE}, or name the backend that holds it, then run \`penv init\` again. Nothing was changed.`
|
|
56630
56610
|
);
|
|
56631
56611
|
}
|
|
56632
56612
|
}
|
|
@@ -56693,10 +56673,7 @@ function distinct(refs) {
|
|
|
56693
56673
|
}
|
|
56694
56674
|
function configFor(decisions) {
|
|
56695
56675
|
return {
|
|
56696
|
-
environments: decisions.environments,
|
|
56697
|
-
providers: Object.fromEntries(
|
|
56698
|
-
decisions.environments.map((environment) => [environment, { type: LOCAL_PROVIDER }])
|
|
56699
|
-
),
|
|
56676
|
+
environments: environmentsRecord(decisions.environments),
|
|
56700
56677
|
schemaFile: decisions.schemaFile,
|
|
56701
56678
|
...decisions.defaultEnvironment === void 0 ? {} : { defaultEnvironment: decisions.defaultEnvironment },
|
|
56702
56679
|
...decisions.publicPrefixes.length === 0 ? {} : { publicPrefixes: [...decisions.publicPrefixes] }
|
|
@@ -57036,7 +57013,8 @@ function offeredEnvironment(root) {
|
|
|
57036
57013
|
if (declared === void 0) {
|
|
57037
57014
|
return DEVELOPMENT;
|
|
57038
57015
|
}
|
|
57039
|
-
|
|
57016
|
+
const names = environmentNames(declared);
|
|
57017
|
+
return declared.defaultEnvironment ?? (names.includes(DEVELOPMENT) ? DEVELOPMENT : names[0] ?? DEVELOPMENT);
|
|
57040
57018
|
}
|
|
57041
57019
|
async function cutoverWithYes(root, base, adoption) {
|
|
57042
57020
|
const selected = selectionForYes(adoption);
|
|
@@ -57144,10 +57122,11 @@ var BACKUP_SUFFIX = ".backup";
|
|
|
57144
57122
|
var DOTENV_SEGMENT = "env";
|
|
57145
57123
|
var LOCAL3 = "local";
|
|
57146
57124
|
function assertDeclared(segment, config2) {
|
|
57147
|
-
|
|
57125
|
+
const declared = environmentNames(config2);
|
|
57126
|
+
if (declared.includes(segment)) {
|
|
57148
57127
|
return segment;
|
|
57149
57128
|
}
|
|
57150
|
-
throw new UnknownEnvironmentError(segment,
|
|
57129
|
+
throw new UnknownEnvironmentError(segment, declared);
|
|
57151
57130
|
}
|
|
57152
57131
|
function scopeFromFilename(file2, config2) {
|
|
57153
57132
|
const name = (0, import_node_path14.basename)(file2);
|
|
@@ -57217,7 +57196,7 @@ function explicitEnvironment(options, source, config2) {
|
|
|
57217
57196
|
throw new PenvError(
|
|
57218
57197
|
"IMPORT_ENV_FLAG_EMPTY",
|
|
57219
57198
|
`\`--env\` for the import of ${source} names no environment`,
|
|
57220
|
-
`Pass a declared environment \u2014 ${config2.
|
|
57199
|
+
`Pass a declared environment \u2014 ${environmentNames(config2).map((e) => `\`${e}\``).join(", ")} \u2014 e.g. \`--env production\`, or drop \`--env\` to import ${source} as the scope that has no environment. Nothing was imported.`
|
|
57221
57200
|
);
|
|
57222
57201
|
}
|
|
57223
57202
|
function assertEnvironmentAgrees(derived, explicit, source) {
|
|
@@ -57244,7 +57223,7 @@ function environmentNamed(file2, explicit) {
|
|
|
57244
57223
|
}
|
|
57245
57224
|
function decisionsOf(config2, cwd) {
|
|
57246
57225
|
return {
|
|
57247
|
-
environments: config2
|
|
57226
|
+
environments: environmentNames(config2),
|
|
57248
57227
|
// `import` re-scaffolds env.ts for an existing project; injection is an init
|
|
57249
57228
|
// choice, so it is not turned on here.
|
|
57250
57229
|
inject: false,
|
|
@@ -57300,7 +57279,7 @@ function importDotenv(options) {
|
|
|
57300
57279
|
backup,
|
|
57301
57280
|
scope,
|
|
57302
57281
|
environment,
|
|
57303
|
-
environments: config2
|
|
57282
|
+
environments: environmentNames(config2),
|
|
57304
57283
|
variables: parsed.entries.length,
|
|
57305
57284
|
orphanComments: parsed.orphanComments,
|
|
57306
57285
|
steps
|
|
@@ -57446,12 +57425,12 @@ function envVarFor2(id) {
|
|
|
57446
57425
|
function runKeyCreate(options) {
|
|
57447
57426
|
const project = openProject(options.cwd);
|
|
57448
57427
|
const environment = targetEnvironment(project, options.environment);
|
|
57449
|
-
const declared = project.config
|
|
57428
|
+
const declared = keyConfigFor(project.config, environment);
|
|
57450
57429
|
if (declared === void 0) {
|
|
57451
57430
|
throw new PenvError(
|
|
57452
57431
|
"KEY_SOURCE_UNDECLARED",
|
|
57453
57432
|
`Environment ${environment} declares no key source, so penv does not know what a key for it would be`,
|
|
57454
|
-
`
|
|
57433
|
+
`Give its entry in penv.config.ts a \`keySource\` \u2014 e.g. \`${environment}: { provider: "@penvhq/provider-filesystem", keySource: "env" }\` \u2014 then run this again. The key is named after the environment unless the object form names another.`
|
|
57455
57434
|
);
|
|
57456
57435
|
}
|
|
57457
57436
|
const key = (0, import_node_crypto.randomBytes)(KEY_BYTES).toString("base64");
|
|
@@ -57784,7 +57763,7 @@ async function planFile(project, source, target, parameter) {
|
|
|
57784
57763
|
throw new PenvError(
|
|
57785
57764
|
"SECRET_SCOPE_AMBIGUOUS",
|
|
57786
57765
|
`${recordPath(formatValueFile(source))} is encrypted at a scope that names no environment, so penv cannot tell which key would re-seal it`,
|
|
57787
|
-
"
|
|
57766
|
+
"A key is declared by its environment's `keySource` in penv.config.ts. Decrypt it with `penv decrypt`, move the parameter, then encrypt it again at its new address."
|
|
57788
57767
|
);
|
|
57789
57768
|
}
|
|
57790
57769
|
const keys = keySourceFor(project, environment);
|