dotsec 1.0.0-alpha.2 → 1.0.0-alpha.20

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/esm/cli.js DELETED
@@ -1,2245 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
21
- var __export = (target, all) => {
22
- __markAsModule(target);
23
- for (var name in all)
24
- __defProp(target, name, { get: all[name], enumerable: true });
25
- };
26
-
27
- // src/cli.ts
28
- import { hideBin } from "yargs/helpers";
29
- import yargs from "yargs/yargs";
30
-
31
- // src/commonCliOptions.ts
32
- var commonCliOptions = {
33
- awsProfile: {
34
- string: true,
35
- describe: "AWS profile"
36
- },
37
- awsRegion: {
38
- string: true,
39
- describe: "AWS region"
40
- },
41
- awsKeyAlias: {
42
- string: true,
43
- describe: "AWS KMS key alias"
44
- },
45
- awsKeyArn: {
46
- string: true,
47
- describe: "AWS KMS key id"
48
- },
49
- awsKey: {
50
- string: true,
51
- describe: "AWS KMS key arn"
52
- },
53
- envFile: {
54
- string: true,
55
- describe: ".env file"
56
- },
57
- ignoreMissingEnvFile: {
58
- boolean: true,
59
- describe: `Don't halt on missing .env file`
60
- },
61
- secFile: {
62
- string: true,
63
- describe: ".sec file",
64
- default: ".sec"
65
- },
66
- awsAssumeRoleArn: {
67
- string: true,
68
- describe: "arn or role to assume. Can also be set using the AWS_ASSUME_ROLE_ARN environment variable, or, when using --env-file in the target env file. The cli option overrides the environment variable."
69
- },
70
- awsAssumeRoleSessionDuration: {
71
- number: true,
72
- describe: "Duration of assume role sessions. Defaults to 3600 seconds. Can also be set using the AWS_ASSUME_ROLE_SESSION_DURATION environment variable, or, when using --env-file in the target env file. The cli option overrides the environment variable."
73
- },
74
- useTopLevelsAsEnvironments: {
75
- boolean: true,
76
- describe: "Use top level keys as environments"
77
- },
78
- verbose: {
79
- boolean: true,
80
- describe: "Be verbose"
81
- },
82
- encryptedSecretsFile: {
83
- string: true,
84
- describe: "filename of json file for reading encrypted secrets"
85
- },
86
- jsonFilter: {
87
- string: true,
88
- describe: "dot separated filter path, for example a.b.c will return { a: { b: { c: ... }}}"
89
- },
90
- searchpath: {
91
- string: true,
92
- describe: "search path in which to look for secrets tree"
93
- },
94
- yes: {
95
- boolean: true,
96
- describe: "Proceeds without confirmation"
97
- },
98
- dryRun: {
99
- boolean: true,
100
- describe: "Do a dry run"
101
- }
102
- };
103
-
104
- // src/commands/convert.ts
105
- var convertModule = {
106
- command: "convert",
107
- describe: "does stuff",
108
- builder: {
109
- "env-file": commonCliOptions.envFile,
110
- "search-path": commonCliOptions.searchpath,
111
- "aws-profile": commonCliOptions.awsProfile,
112
- "aws-region": commonCliOptions.awsRegion,
113
- "aws-key-alias": commonCliOptions.awsKeyAlias,
114
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
115
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
116
- "use-top-levels-as-environments": commonCliOptions.useTopLevelsAsEnvironments,
117
- verbose: commonCliOptions.verbose,
118
- yes: __spreadValues({}, commonCliOptions.yes)
119
- },
120
- handler: (a) => {
121
- console.log(a.d);
122
- console.log(a["env-file"]);
123
- }
124
- };
125
- var convert_default = convertModule;
126
-
127
- // src/commands/defaultCommand.ts
128
- var defaultCommand_exports = {};
129
- __export(defaultCommand_exports, {
130
- builder: () => builder,
131
- command: () => command,
132
- desc: () => desc,
133
- handler: () => handler
134
- });
135
- import fs3 from "node:fs";
136
- import path5 from "node:path";
137
- import { KMSClient as KMSClient2, DecryptCommand } from "@aws-sdk/client-kms";
138
- import { redBright as redBright2 } from "chalk";
139
- import { constantCase } from "constant-case";
140
- import { spawn } from "cross-spawn";
141
- import { parse } from "dotenv";
142
- import flat from "flat";
143
-
144
- // src/lib/config-old/index.ts
145
- import path2 from "node:path";
146
- import { bundleRequire } from "bundle-require";
147
- import JoyCon from "joycon";
148
-
149
- // src/lib/json.ts
150
- import fs from "fs";
151
- import path from "node:path";
152
- function jsoncParse(data) {
153
- try {
154
- return new Function("return " + data.trim())();
155
- } catch {
156
- return {};
157
- }
158
- }
159
- var loadJson = async (filepath) => {
160
- try {
161
- return jsoncParse(await fs.promises.readFile(filepath, "utf8"));
162
- } catch (error) {
163
- if (error instanceof Error) {
164
- throw new Error(`Failed to parse ${path.relative(process.cwd(), filepath)}: ${error.message}`);
165
- } else {
166
- throw error;
167
- }
168
- }
169
- };
170
-
171
- // src/lib/config-old/constants.ts
172
- var defaultConfig = {
173
- aws: {
174
- keyAlias: "alias/top-secret"
175
- }
176
- };
177
-
178
- // src/lib/config-old/index.ts
179
- var getConfig = async () => {
180
- const cwd = process.cwd();
181
- const configJoycon = new JoyCon();
182
- const configPath = await configJoycon.resolve({
183
- files: [
184
- "dotsec.config.ts",
185
- "dotsec.config.js",
186
- "dotsec.config.cjs",
187
- "dotsec.config.mjs",
188
- "dotsec.config.json",
189
- "package.json"
190
- ],
191
- cwd,
192
- stopDir: path2.parse(cwd).root,
193
- packageKey: "dotsec"
194
- });
195
- if (configPath) {
196
- if (configPath.endsWith(".json")) {
197
- const rawData = await loadJson(configPath);
198
- let data;
199
- if (configPath.endsWith("package.json") && rawData.dotsec !== void 0) {
200
- data = rawData.dotsec;
201
- } else {
202
- data = rawData;
203
- }
204
- return __spreadProps(__spreadValues(__spreadValues({}, defaultConfig), data), {
205
- aws: __spreadValues(__spreadValues({}, defaultConfig.aws), data.aws)
206
- });
207
- }
208
- const config = await bundleRequire({
209
- filepath: configPath
210
- });
211
- const retrievedConfig = config.mod.dotsec || config.mod.default || config.mod;
212
- return __spreadValues(__spreadValues({}, defaultConfig), retrievedConfig);
213
- }
214
- return __spreadValues({}, defaultConfig);
215
- };
216
-
217
- // src/lib/encryptedSecrets.ts
218
- import fs2 from "fs";
219
- import path4 from "path";
220
- import { redBright } from "chalk";
221
-
222
- // src/utils/io.ts
223
- import { stat } from "fs/promises";
224
- import prompts from "prompts";
225
- import path3 from "node:path";
226
- var fileExists = async (source) => {
227
- try {
228
- await stat(source);
229
- return true;
230
- } catch {
231
- return false;
232
- }
233
- };
234
- var promptOverwriteIfFileExists = async ({
235
- filePath,
236
- skip
237
- }) => {
238
- let overwriteResponse;
239
- if (await fileExists(filePath) && skip !== true) {
240
- overwriteResponse = await prompts({
241
- type: "confirm",
242
- name: "overwrite",
243
- message: () => {
244
- return `Overwrite './${path3.relative(process.cwd(), filePath)}' ?`;
245
- }
246
- });
247
- } else {
248
- overwriteResponse = void 0;
249
- }
250
- return overwriteResponse;
251
- };
252
-
253
- // src/lib/encryptedSecrets.ts
254
- var loadEncryptedSecrets = async ({
255
- encryptedSecretsFile
256
- }) => {
257
- const encryptedSecretsPath = path4.resolve(process.cwd(), encryptedSecretsFile);
258
- if (!await fileExists(encryptedSecretsPath)) {
259
- throw new Error(`Could not open ${redBright(encryptedSecretsPath)}`);
260
- }
261
- const encryptedSecrets = JSON.parse(fs2.readFileSync(encryptedSecretsPath, { encoding: "utf8" }));
262
- if (!encryptedSecrets) {
263
- throw new Error(`No encrypted secrets found in ${redBright(encryptedSecretsPath)}`);
264
- }
265
- if (!encryptedSecrets.encryptedParameters) {
266
- throw new Error(`Expected 'encryptedParameters' property, but got none`);
267
- }
268
- return encryptedSecrets;
269
- };
270
-
271
- // src/utils/getCredentialsProfileRegion.ts
272
- import {
273
- fromEnv,
274
- fromIni,
275
- fromTemporaryCredentials
276
- } from "@aws-sdk/credential-providers";
277
- import { loadSharedConfigFiles } from "@aws-sdk/shared-ini-file-loader";
278
-
279
- // src/utils/logger.ts
280
- import chalk from "chalk";
281
- import { highlight, plain } from "cli-highlight";
282
- var _logger;
283
- var getLogger = () => {
284
- if (!_logger) {
285
- _logger = console;
286
- }
287
- return _logger;
288
- };
289
- var emphasis = (str) => chalk.yellowBright(str);
290
- var strong = (str) => chalk.yellow.bold(str);
291
- var myTheme = {
292
- attr: chalk.yellow.bold,
293
- string: chalk.yellowBright.dim,
294
- params: chalk.red,
295
- deletion: chalk.red.strikethrough,
296
- number: plain
297
- };
298
- var prettyCode = (str) => {
299
- return highlight(str, { theme: myTheme });
300
- };
301
-
302
- // src/utils/getCredentialsProfileRegion.ts
303
- var getCredentialsProfileRegion = async ({
304
- argv,
305
- env
306
- }) => {
307
- var _a, _b, _c;
308
- const sharedConfigFiles = await loadSharedConfigFiles();
309
- let credentialsAndOrigin = void 0;
310
- let profileAndOrigin = void 0;
311
- let regionAndOrigin = void 0;
312
- if (argv.profile) {
313
- profileAndOrigin = {
314
- value: argv.profile,
315
- origin: `command line option: ${emphasis(argv.profile)}`
316
- };
317
- credentialsAndOrigin = {
318
- value: await fromIni({
319
- profile: argv.profile
320
- })(),
321
- origin: `${emphasis(`[${argv.profile}]`)} in credentials file`
322
- };
323
- } else if (env.AWS_PROFILE) {
324
- profileAndOrigin = {
325
- value: env.AWS_PROFILE,
326
- origin: `env variable ${emphasis("AWS_PROFILE")}: ${strong(env.AWS_PROFILE)}`
327
- };
328
- credentialsAndOrigin = {
329
- value: await fromIni({
330
- profile: env.AWS_PROFILE
331
- })(),
332
- origin: `env variable ${emphasis("AWS_PROFILE")}: ${strong(env.AWS_PROFILE)}`
333
- };
334
- } else if (env.AWS_ACCESS_KEY_ID && env.AWS_SECRET_ACCESS_KEY) {
335
- credentialsAndOrigin = {
336
- value: await fromEnv()(),
337
- origin: `env variables ${emphasis("AWS_ACCESS_KEY_ID")} and ${emphasis("AWS_SECRET_ACCESS_KEY")}`
338
- };
339
- } else if ((_a = sharedConfigFiles.credentialsFile) == null ? void 0 : _a.default) {
340
- profileAndOrigin = {
341
- value: "default",
342
- origin: `${emphasis("[default]")} in credentials file`
343
- };
344
- credentialsAndOrigin = {
345
- value: await fromIni({
346
- profile: "default"
347
- })(),
348
- origin: `profile ${emphasis("[default]")}`
349
- };
350
- }
351
- if (argv.region) {
352
- regionAndOrigin = {
353
- value: argv.region,
354
- origin: `command line option: ${emphasis(argv.region)}`
355
- };
356
- } else if (env.AWS_REGION) {
357
- regionAndOrigin = {
358
- value: env.AWS_REGION,
359
- origin: `env variable ${emphasis("AWS_REGION")}: ${strong(env.AWS_REGION)}`
360
- };
361
- } else if (env.AWS_DEFAULT_REGION) {
362
- regionAndOrigin = {
363
- value: env.AWS_DEFAULT_REGION,
364
- origin: `env variable ${emphasis("AWS_DEFAULT_REGION")}: ${strong(env.AWS_DEFAULT_REGION)}`
365
- };
366
- } else if (profileAndOrigin) {
367
- const foundRegion = (_c = (_b = sharedConfigFiles == null ? void 0 : sharedConfigFiles.configFile) == null ? void 0 : _b[profileAndOrigin.value]) == null ? void 0 : _c.region;
368
- if (foundRegion) {
369
- regionAndOrigin = {
370
- value: foundRegion,
371
- origin: `${emphasis(`[profile ${profileAndOrigin.value}]`)} in config file`
372
- };
373
- }
374
- }
375
- const assumedRole = argv.assumeRoleArn || env.AWS_ASSUME_ROLE_ARN;
376
- if (assumedRole) {
377
- const origin = argv.assumeRoleArn ? "command line option" : "env variable";
378
- credentialsAndOrigin = {
379
- value: await fromTemporaryCredentials({
380
- masterCredentials: credentialsAndOrigin == null ? void 0 : credentialsAndOrigin.value,
381
- params: {
382
- DurationSeconds: argv.assumeRoleSessionDuration || Number(env.AWS_ASSUME_ROLE_SESSION_DURATION) || 3600,
383
- RoleArn: assumedRole
384
- },
385
- clientConfig: {
386
- region: regionAndOrigin == null ? void 0 : regionAndOrigin.value
387
- }
388
- })(),
389
- origin: `${origin} ${emphasis(`[${assumedRole}]`)}`
390
- };
391
- }
392
- return { credentialsAndOrigin, regionAndOrigin, profileAndOrigin };
393
- };
394
- var printVerboseCredentialsProfileRegion = ({
395
- credentialsAndOrigin,
396
- regionAndOrigin,
397
- profileAndOrigin
398
- }) => {
399
- const out = [];
400
- if (profileAndOrigin) {
401
- out.push(`Got profile name from ${profileAndOrigin.origin}`);
402
- }
403
- if (credentialsAndOrigin) {
404
- out.push(`Resolved credentials from ${credentialsAndOrigin.origin}`);
405
- }
406
- if (regionAndOrigin) {
407
- out.push(`Resolved region from ${regionAndOrigin.origin}`);
408
- }
409
- return out.join("\n");
410
- };
411
-
412
- // src/lib/partial-commands/handleCredentialsAndRegion.ts
413
- var handleCredentialsAndRegion = async ({
414
- argv,
415
- env
416
- }) => {
417
- const { credentialsAndOrigin, regionAndOrigin, profileAndOrigin } = await getCredentialsProfileRegion({
418
- argv: {
419
- region: argv.awsRegion,
420
- profile: argv.awsProfile,
421
- assumeRoleArn: argv.awsAssumeRoleArn,
422
- assumeRoleSessionDuration: argv.awsAssumeRoleSessionDuration
423
- },
424
- env: __spreadValues({}, env)
425
- });
426
- if (argv.verbose === true) {
427
- console.log(printVerboseCredentialsProfileRegion({
428
- credentialsAndOrigin,
429
- regionAndOrigin,
430
- profileAndOrigin
431
- }));
432
- }
433
- if (!credentialsAndOrigin || !regionAndOrigin) {
434
- if (!credentialsAndOrigin) {
435
- console.error("Could not find credentials");
436
- throw new Error("Could not find credentials");
437
- }
438
- if (!regionAndOrigin) {
439
- console.error("Could not find region");
440
- throw new Error("Could not find region");
441
- }
442
- }
443
- return { credentialsAndOrigin, regionAndOrigin };
444
- };
445
-
446
- // src/utils/kms.ts
447
- import {
448
- DescribeKeyCommand,
449
- KMSClient
450
- } from "@aws-sdk/client-kms";
451
- var getKMSClient = ({
452
- configuration
453
- }) => {
454
- const kmsClient = new KMSClient(configuration);
455
- return kmsClient;
456
- };
457
- var getEncryptionAlgorithm = async (kmsClient, awsKeyAlias) => {
458
- var _a, _b;
459
- const describeKeyCommand = new DescribeKeyCommand({
460
- KeyId: awsKeyAlias
461
- });
462
- const describeKeyResult = await kmsClient.send(describeKeyCommand);
463
- const encryptionAlgorithm = (_b = (_a = describeKeyResult.KeyMetadata) == null ? void 0 : _a.EncryptionAlgorithms) == null ? void 0 : _b[0];
464
- if (encryptionAlgorithm === void 0) {
465
- throw new Error(`Could not determine encryption algorithm`);
466
- }
467
- return encryptionAlgorithm;
468
- };
469
-
470
- // src/commands/defaultCommand.ts
471
- var command = "$0 <command>";
472
- var desc = "Decrypts a .sec file, injects the results into a separate process and runs a command";
473
- var builder = {
474
- "aws-profile": commonCliOptions.awsProfile,
475
- "aws-region": commonCliOptions.awsRegion,
476
- "aws-key-alias": commonCliOptions.awsKeyAlias,
477
- "sec-file": commonCliOptions.secFile,
478
- "env-file": commonCliOptions.envFile,
479
- "ignore-missing-env-file": commonCliOptions.ignoreMissingEnvFile,
480
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
481
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
482
- "encrypted-secrets-file": commonCliOptions.encryptedSecretsFile,
483
- "json-filter": commonCliOptions.jsonFilter,
484
- verbose: commonCliOptions.verbose,
485
- command: { string: true, required: true }
486
- };
487
- var handleSec = async ({
488
- secFile,
489
- credentialsAndOrigin,
490
- regionAndOrigin,
491
- awsKeyAlias
492
- }) => {
493
- const secSource = path5.resolve(process.cwd(), secFile);
494
- if (!await fileExists(secSource)) {
495
- console.error(`Could not open ${redBright2(secSource)}`);
496
- return;
497
- }
498
- const parsedSec = parse(fs3.readFileSync(secSource, { encoding: "utf8" }));
499
- const kmsClient = new KMSClient2({
500
- credentials: credentialsAndOrigin.value,
501
- region: regionAndOrigin.value
502
- });
503
- const encryptionAlgorithm = await getEncryptionAlgorithm(kmsClient, awsKeyAlias);
504
- const envEntries = await Promise.all(Object.entries(parsedSec).map(async ([key, cipherText]) => {
505
- const decryptCommand = new DecryptCommand({
506
- KeyId: awsKeyAlias,
507
- CiphertextBlob: Buffer.from(cipherText, "base64"),
508
- EncryptionAlgorithm: encryptionAlgorithm
509
- });
510
- const decryptionResult = await kmsClient.send(decryptCommand);
511
- if (!(decryptionResult == null ? void 0 : decryptionResult.Plaintext)) {
512
- throw new Error(`No: ${JSON.stringify({
513
- key,
514
- cipherText,
515
- decryptCommand
516
- })}`);
517
- }
518
- const value = Buffer.from(decryptionResult.Plaintext).toString();
519
- return [key, value];
520
- }));
521
- const env = Object.fromEntries(envEntries);
522
- return env;
523
- };
524
- var handleEncryptedJson = async ({
525
- encryptedSecretsFile,
526
- jsonFilter,
527
- credentialsAndOrigin,
528
- regionAndOrigin,
529
- awsKeyAlias
530
- }) => {
531
- const encryptedSecrets = await loadEncryptedSecrets({
532
- encryptedSecretsFile
533
- });
534
- const flattened = flat.flatten(encryptedSecrets.encryptedParameters, {
535
- delimiter: "__",
536
- transformKey: (key) => {
537
- return constantCase(key);
538
- }
539
- });
540
- const kmsClient = new KMSClient2({
541
- credentials: credentialsAndOrigin.value,
542
- region: regionAndOrigin.value
543
- });
544
- const encryptionAlgorithm = await getEncryptionAlgorithm(kmsClient, awsKeyAlias);
545
- const filterKey = jsonFilter == null ? void 0 : jsonFilter.split(".").map((part) => constantCase(part)).join("__");
546
- const envEntries = await Promise.all(Object.entries(flattened).filter(([key]) => {
547
- if (filterKey) {
548
- return key.indexOf(filterKey) === 0;
549
- }
550
- return true;
551
- }).map(async ([key, cipherText]) => {
552
- const decryptCommand = new DecryptCommand({
553
- KeyId: awsKeyAlias,
554
- CiphertextBlob: Buffer.from(cipherText, "base64"),
555
- EncryptionAlgorithm: encryptionAlgorithm
556
- });
557
- const decryptionResult = await kmsClient.send(decryptCommand);
558
- if (!(decryptionResult == null ? void 0 : decryptionResult.Plaintext)) {
559
- throw new Error(`No: ${JSON.stringify({
560
- key,
561
- cipherText,
562
- decryptCommand
563
- })}`);
564
- }
565
- const value = Buffer.from(decryptionResult.Plaintext).toString();
566
- return [key, value];
567
- }));
568
- const env = Object.fromEntries(envEntries);
569
- return env;
570
- };
571
- var handler = async (argv) => {
572
- const config = await getConfig();
573
- try {
574
- let env;
575
- let awsEnv;
576
- try {
577
- if (argv.envFile) {
578
- env = parse(fs3.readFileSync(argv.envFile, { encoding: "utf8" }));
579
- if (argv.awsAssumeRoleArn || process.env.AWS_ASSUME_ROLE_ARN || (env == null ? void 0 : env.AWS_ASSUME_ROLE_ARN)) {
580
- const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
581
- argv: __spreadProps(__spreadValues({}, argv), {
582
- awsRegion: config.aws.region || argv.awsRegion,
583
- awsProfile: config.aws.profile || argv.awsProfile,
584
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
585
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
586
- }),
587
- env: __spreadValues({}, process.env)
588
- });
589
- awsEnv = {
590
- AWS_ACCESS_KEY_ID: credentialsAndOrigin.value.accessKeyId,
591
- AWS_SECRET_ACCESS_KEY: credentialsAndOrigin.value.secretAccessKey
592
- };
593
- if (credentialsAndOrigin.value.sessionToken) {
594
- awsEnv.AWS_SESSION_TOKEN = credentialsAndOrigin.value.sessionToken;
595
- }
596
- }
597
- } else {
598
- const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
599
- argv: __spreadProps(__spreadValues({}, argv), {
600
- awsRegion: config.aws.region || argv.awsRegion,
601
- awsProfile: config.aws.profile || argv.awsProfile,
602
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
603
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
604
- }),
605
- env: __spreadValues({}, process.env)
606
- });
607
- if ((argv.awsAssumeRoleArn || process.env.AWS_ASSUME_ROLE_ARN || (env == null ? void 0 : env.AWS_ASSUME_ROLE_ARN)) && credentialsAndOrigin.value.sessionToken !== void 0) {
608
- awsEnv = {
609
- AWS_ACCESS_KEY_ID: credentialsAndOrigin.value.accessKeyId,
610
- AWS_SECRET_ACCESS_KEY: credentialsAndOrigin.value.secretAccessKey,
611
- AWS_SESSION_TOKEN: credentialsAndOrigin.value.sessionToken
612
- };
613
- }
614
- if (argv.verbose) {
615
- console.log({ credentialsAndOrigin, regionAndOrigin });
616
- }
617
- const awsKeyAlias = argv.awsKeyAlias || config.aws.keyAlias;
618
- if (argv.encryptedSecretsFile) {
619
- env = await handleEncryptedJson({
620
- encryptedSecretsFile: argv.encryptedSecretsFile,
621
- jsonFilter: argv.jsonFilter,
622
- credentialsAndOrigin,
623
- regionAndOrigin,
624
- awsKeyAlias
625
- });
626
- } else {
627
- env = await handleSec({
628
- secFile: argv.secFile,
629
- credentialsAndOrigin,
630
- regionAndOrigin,
631
- awsKeyAlias
632
- });
633
- }
634
- }
635
- } catch (e) {
636
- if (argv.ignoreMissingEnvFile !== true) {
637
- throw e;
638
- }
639
- }
640
- const userCommandArgs = process.argv.slice(process.argv.indexOf(argv.command) + 1);
641
- if (argv.command) {
642
- spawn(argv.command, [...userCommandArgs], {
643
- stdio: "inherit",
644
- shell: false,
645
- env: __spreadValues(__spreadValues(__spreadValues({}, process.env), awsEnv), env)
646
- });
647
- }
648
- } catch (e) {
649
- console.error(e);
650
- }
651
- };
652
-
653
- // src/commands/dot-sec-to-dot-env.ts
654
- var dot_sec_to_dot_env_exports = {};
655
- __export(dot_sec_to_dot_env_exports, {
656
- builder: () => builder2,
657
- command: () => command2,
658
- desc: () => desc2,
659
- handler: () => handler2
660
- });
661
- import fs7 from "node:fs";
662
- import path9 from "node:path";
663
- import {
664
- parse as parse2
665
- } from "dotenv";
666
-
667
- // src/lib/wtf/crypto.ts
668
- import {
669
- DecryptCommand as DecryptCommand2,
670
- DescribeKeyCommand as DescribeKeyCommand2,
671
- EncryptCommand
672
- } from "@aws-sdk/client-kms";
673
- import {
674
- CreateSecretCommand,
675
- ListSecretsCommand,
676
- PutSecretValueCommand
677
- } from "@aws-sdk/client-secrets-manager";
678
- import {
679
- ParameterTier,
680
- ParameterType,
681
- PutParameterCommand
682
- } from "@aws-sdk/client-ssm";
683
- import { constantCase as constantCase2 } from "constant-case";
684
-
685
- // src/utils/secretsManager.ts
686
- import {
687
- SecretsManagerClient
688
- } from "@aws-sdk/client-secrets-manager";
689
- var getSecretsManagerClient = ({
690
- configuration
691
- }) => {
692
- const secretsManagerClient = new SecretsManagerClient(configuration);
693
- return secretsManagerClient;
694
- };
695
-
696
- // src/utils/ssm.ts
697
- import { SSMClient } from "@aws-sdk/client-ssm";
698
- var getSSMClient = ({
699
- configuration
700
- }) => {
701
- const ssmClient = new SSMClient(configuration);
702
- return ssmClient;
703
- };
704
-
705
- // src/lib/wtf/types.ts
706
- var isString = (value) => {
707
- return typeof value === "string";
708
- };
709
- var isNumber = (value) => {
710
- return typeof value === "number";
711
- };
712
- var isBoolean = (value) => {
713
- return typeof value === "boolean";
714
- };
715
- var isSSMParameter = (leafOrTree) => {
716
- const ssmParameter = leafOrTree;
717
- return typeof ssmParameter === "object" && ssmParameter !== null && "type" in ssmParameter && ssmParameter.type === "ssm";
718
- };
719
- var isRegularParameterObject = (value) => {
720
- const regularParameter = value;
721
- return typeof regularParameter === "object" && regularParameter !== null && "type" in regularParameter && regularParameter.type === "standard";
722
- };
723
- var isRegularParameter = (leafOrTree) => {
724
- const leaf = leafOrTree;
725
- return isString(leaf) || isNumber(leaf) || isBoolean(leaf) || isRegularParameterObject(leaf);
726
- };
727
- var isEncryptedSSMParameter = (leafOrTree) => {
728
- const leaf = leafOrTree;
729
- return leaf.type !== void 0 && leaf.type === "ssm" && leaf.encryptedValue !== void 0;
730
- };
731
- var isEncryptedRegularParameter = (leafOrTree) => {
732
- const leaf = leafOrTree;
733
- return leaf.type !== void 0 && leaf.type === "standard" && leaf.encryptedValue !== void 0;
734
- };
735
- var isSecretsManagerParameter = (leafOrTree) => {
736
- const leaf = leafOrTree;
737
- return leaf.type !== void 0 && leaf.type === "secretsManager" && !(isString(leaf) || isNumber(leaf) || isBoolean(leaf));
738
- };
739
- var isDotSecTree = (leafOrTree) => {
740
- if (typeof leafOrTree === "object" && !Array.isArray(leafOrTree) && leafOrTree !== null && !isSSMParameter(leafOrTree) && !isRegularParameter(leafOrTree) && !isEncryptedSSMParameter(leafOrTree) && !isEncryptedRegularParameter(leafOrTree) && !isSecretsManagerParameter(leafOrTree)) {
741
- return true;
742
- }
743
- return false;
744
- };
745
-
746
- // src/lib/wtf/flat.ts
747
- var flattenTree = (tree) => {
748
- const lazy = {};
749
- const innerParser = (leafOrTree, paths = []) => {
750
- if (isDotSecTree(leafOrTree)) {
751
- Object.entries(leafOrTree).map(([key, value]) => {
752
- innerParser(value, [...paths, key]);
753
- });
754
- } else {
755
- lazy[paths.join("/")] = leafOrTree;
756
- }
757
- };
758
- innerParser(tree);
759
- return lazy;
760
- };
761
- var flattenPlainText = (dotSec) => {
762
- return __spreadProps(__spreadValues({}, dotSec), { plaintext: flattenTree(dotSec.plaintext) });
763
- };
764
- var flattenEncrypted = (dotSec) => {
765
- return __spreadProps(__spreadValues({}, dotSec), { encrypted: flattenTree(dotSec.encrypted) });
766
- };
767
- var expandTree = (tree) => {
768
- const lazy = {};
769
- Object.entries(tree).map(([key, value]) => {
770
- const paths = key.split("/");
771
- let current = lazy;
772
- paths.forEach((pathKey, index) => {
773
- if (!current[pathKey]) {
774
- if (index === paths.length - 1) {
775
- current[pathKey] = value;
776
- } else {
777
- current[pathKey] = {};
778
- }
779
- }
780
- current = current[pathKey];
781
- });
782
- });
783
- return lazy;
784
- };
785
- var expandPlainText = (dotSec) => {
786
- return __spreadProps(__spreadValues({}, dotSec), { plaintext: expandTree(dotSec.plaintext) });
787
- };
788
- var expandEncrypted = (dotSec) => {
789
- return __spreadProps(__spreadValues({}, dotSec), { encrypted: expandTree(dotSec.encrypted) });
790
- };
791
-
792
- // src/lib/wtf/crypto.ts
793
- var maybeJson = (value) => {
794
- try {
795
- return JSON.parse(value);
796
- } catch (e) {
797
- return value;
798
- }
799
- };
800
- var decryptedEncrypted = async (options) => {
801
- var _a, _b;
802
- const { dotSecEncrypted, credentials, region, verbose, keyAlias } = options;
803
- const dotSecEncryptedFlattened = flattenEncrypted(dotSecEncrypted);
804
- const { info, table } = getLogger();
805
- const kmsClient = getKMSClient({
806
- configuration: {
807
- credentials,
808
- region
809
- },
810
- verbose
811
- });
812
- const awsKeyAlias = keyAlias || ((_b = (_a = dotSecEncrypted.config) == null ? void 0 : _a.aws) == null ? void 0 : _b.keyAlias);
813
- if (!awsKeyAlias) {
814
- throw new Error("No key alias specified");
815
- }
816
- if (verbose) {
817
- info(`Encrypting using key alias ${emphasis(awsKeyAlias)} in ${emphasis(await kmsClient.config.region())}`);
818
- const describeKeyCommand = new DescribeKeyCommand2({
819
- KeyId: awsKeyAlias
820
- });
821
- const describeKeyResult = await kmsClient.send(describeKeyCommand);
822
- info("keyMetaData", __spreadValues({}, describeKeyResult.KeyMetadata));
823
- }
824
- const encryptionAlgorithm = await getEncryptionAlgorithm(kmsClient, awsKeyAlias);
825
- const dotSecFlattened = {
826
- config: __spreadValues({}, dotSecEncrypted.config),
827
- plaintext: {}
828
- };
829
- for (const [key, encryptedValue] of Object.entries(dotSecEncryptedFlattened.encrypted)) {
830
- const decryptCommand = new DecryptCommand2({
831
- KeyId: awsKeyAlias,
832
- CiphertextBlob: Buffer.from(encryptedValue.encryptedValue, "base64"),
833
- EncryptionAlgorithm: encryptionAlgorithm
834
- });
835
- const decryptionResult = await kmsClient.send(decryptCommand);
836
- if (!decryptionResult.Plaintext) {
837
- throw new Error(`Something bad happened: ${JSON.stringify({
838
- key,
839
- cipherText: encryptedValue,
840
- decryptCommand
841
- })}`);
842
- }
843
- if (verbose) {
844
- info(`Decrypting key ${emphasis(key)} ${strong("ok")}`);
845
- }
846
- const decryptedValue = Buffer.from(decryptionResult.Plaintext).toString();
847
- const decryptedKeyValue = JSON.parse(decryptedValue);
848
- dotSecFlattened.plaintext[key] = maybeJson(decryptedKeyValue.value);
849
- }
850
- return expandPlainText(dotSecFlattened);
851
- };
852
- var encryptPlainText = async (options) => {
853
- var _a, _b;
854
- const { dotSecPlainText, credentials, region, verbose, keyAlias } = options;
855
- const dotSecFlattened = flattenPlainText(dotSecPlainText);
856
- const { info } = getLogger();
857
- const kmsClient = getKMSClient({
858
- configuration: {
859
- credentials,
860
- region
861
- },
862
- verbose
863
- });
864
- const awsKeyAlias = keyAlias || ((_b = (_a = dotSecFlattened.config) == null ? void 0 : _a.aws) == null ? void 0 : _b.keyAlias);
865
- if (!awsKeyAlias) {
866
- throw new Error("No key alias specified");
867
- }
868
- if (verbose) {
869
- info(`Encrypting using key alias ${emphasis(awsKeyAlias)} in ${emphasis(await kmsClient.config.region())}`);
870
- const describeKeyCommand = new DescribeKeyCommand2({
871
- KeyId: awsKeyAlias
872
- });
873
- const describeKeyResult = await kmsClient.send(describeKeyCommand);
874
- info("keyMetaData", __spreadValues({}, describeKeyResult.KeyMetadata));
875
- }
876
- const encryptionAlgorithm = await getEncryptionAlgorithm(kmsClient, awsKeyAlias);
877
- const encryptedDotSecFlattened = {
878
- config: __spreadValues({}, dotSecFlattened.config),
879
- encrypted: {}
880
- };
881
- for (const [key, plainTextValue] of Object.entries(dotSecFlattened.plaintext)) {
882
- let plainTextValueCopy = plainTextValue;
883
- if (typeof plainTextValueCopy !== "string" && typeof plainTextValueCopy !== "number" && typeof plainTextValueCopy !== "boolean") {
884
- plainTextValueCopy = JSON.stringify(plainTextValue);
885
- }
886
- const damn = JSON.stringify({ key, value: plainTextValueCopy });
887
- const encryptCommand = new EncryptCommand({
888
- KeyId: awsKeyAlias,
889
- Plaintext: Buffer.from(String(damn)),
890
- EncryptionAlgorithm: encryptionAlgorithm
891
- });
892
- const encryptionResult = await kmsClient.send(encryptCommand);
893
- if (!encryptionResult.CiphertextBlob) {
894
- throw new Error(`Something bad happened: ${JSON.stringify({
895
- key,
896
- value: plainTextValue,
897
- encryptCommand
898
- })}`);
899
- }
900
- if (verbose) {
901
- info(`Encrypting key ${emphasis(key)} ${strong("ok")}`);
902
- }
903
- const cipherText = Buffer.from(encryptionResult.CiphertextBlob).toString("base64");
904
- if (isRegularParameter(plainTextValue)) {
905
- encryptedDotSecFlattened.encrypted[key] = {
906
- type: "standard",
907
- encryptedValue: cipherText
908
- };
909
- } else if (isSSMParameter(plainTextValue)) {
910
- encryptedDotSecFlattened.encrypted[key] = {
911
- type: "ssm",
912
- encryptedValue: cipherText
913
- };
914
- } else if (isSecretsManagerParameter(plainTextValue)) {
915
- encryptedDotSecFlattened.encrypted[key] = {
916
- type: "secretsManager",
917
- encryptedValue: cipherText
918
- };
919
- }
920
- }
921
- return expandEncrypted(encryptedDotSecFlattened);
922
- };
923
- var createStorePlaintextTasks = async (options) => {
924
- var _a, _b, _c, _d, _e, _f, _g, _h;
925
- const { dotSecPlainText, credentials, region, verbose, keyAlias } = options;
926
- const dotSecPlainTextFlattened = flattenPlainText(dotSecPlainText);
927
- const { info } = getLogger();
928
- const ssmClient = getSSMClient({
929
- configuration: {
930
- credentials,
931
- region
932
- },
933
- verbose
934
- });
935
- const secretsManagerClient = getSecretsManagerClient({
936
- configuration: {
937
- credentials,
938
- region
939
- },
940
- verbose
941
- });
942
- const secretNameArnTuples = (_b = (_a = await secretsManagerClient.send(new ListSecretsCommand({}))) == null ? void 0 : _a.SecretList) == null ? void 0 : _b.map((secret) => [secret.Name, secret.ARN]).filter(([name, ARN]) => name && ARN);
943
- const existingSecrets = secretNameArnTuples ? Object.fromEntries(secretNameArnTuples) : {};
944
- const awsKeyAlias = keyAlias || ((_d = (_c = dotSecPlainText.config) == null ? void 0 : _c.aws) == null ? void 0 : _d.keyAlias);
945
- if (!awsKeyAlias) {
946
- throw new Error(`No key alias specified`);
947
- }
948
- if (verbose) {
949
- info(`Encrypting to SSM and/or SecretsManager in ${emphasis(region)}`);
950
- }
951
- const putParameterCommands = [];
952
- const createSecretCommands = [];
953
- const putSecretValueCommands = [];
954
- for (const [keyPath, plainTextValue] of Object.entries(dotSecPlainTextFlattened.plaintext)) {
955
- let storageValue;
956
- if (isRegularParameter(plainTextValue)) {
957
- if (isRegularParameterObject(plainTextValue)) {
958
- storageValue = plainTextValue.value;
959
- } else {
960
- storageValue = plainTextValue;
961
- }
962
- } else if (isSSMParameter(plainTextValue)) {
963
- storageValue = plainTextValue.value;
964
- } else if (isSecretsManagerParameter(plainTextValue)) {
965
- storageValue = plainTextValue.value;
966
- } else {
967
- throw new Error("Invalid parameter type");
968
- }
969
- if (!isString(storageValue) && !isNumber(storageValue) && !isBoolean(storageValue)) {
970
- storageValue = JSON.stringify(storageValue);
971
- }
972
- if (isSSMParameter(plainTextValue) || isRegularParameter(plainTextValue) && ((_e = dotSecPlainText.config) == null ? void 0 : _e.standardParameterStorageType) === "ssm" && (isRegularParameterObject(plainTextValue) ? plainTextValue.dontStore !== true : true)) {
973
- let parameterTier = ParameterTier.STANDARD;
974
- let parameterType = ParameterType.STRING;
975
- let description;
976
- if (isSSMParameter(plainTextValue)) {
977
- if ((_f = plainTextValue == null ? void 0 : plainTextValue.ssm) == null ? void 0 : _f.tier) {
978
- parameterTier = plainTextValue.ssm.tier;
979
- }
980
- if ((_g = plainTextValue == null ? void 0 : plainTextValue.ssm) == null ? void 0 : _g.type) {
981
- parameterType = plainTextValue.ssm.type;
982
- }
983
- if (plainTextValue == null ? void 0 : plainTextValue.description) {
984
- description = plainTextValue.description;
985
- }
986
- }
987
- const putParameterCommand = new PutParameterCommand({
988
- Name: `/${keyPath}`,
989
- Value: String(storageValue),
990
- Type: parameterType,
991
- Tier: parameterTier,
992
- Description: description,
993
- Overwrite: true
994
- });
995
- putParameterCommands.push(putParameterCommand);
996
- } else if (isSecretsManagerParameter(plainTextValue) || isRegularParameter(plainTextValue) && ((_h = dotSecPlainText.config) == null ? void 0 : _h.standardParameterStorageType) === "secretsManager" && (isRegularParameterObject(plainTextValue) ? plainTextValue.dontStore !== true : true)) {
997
- const existingSecretARN = existingSecrets[keyPath];
998
- if (!existingSecretARN) {
999
- const createSecretCommand = new CreateSecretCommand({
1000
- Name: keyPath,
1001
- SecretString: String(storageValue)
1002
- });
1003
- createSecretCommands.push(createSecretCommand);
1004
- } else {
1005
- const putSecretCommand = new PutSecretValueCommand({
1006
- SecretId: existingSecretARN,
1007
- SecretString: String(storageValue)
1008
- });
1009
- putSecretValueCommands.push(putSecretCommand);
1010
- }
1011
- }
1012
- }
1013
- return {
1014
- total: putParameterCommands.length + createSecretCommands.length + putSecretValueCommands.length,
1015
- putParameterCommands,
1016
- createSecretCommands,
1017
- putSecretValueCommands
1018
- };
1019
- };
1020
- var executeStorePlainTextTasks = async (options) => {
1021
- const { credentials, region, verbose, tasks } = options;
1022
- const { info } = getLogger();
1023
- const ssmClient = getSSMClient({
1024
- configuration: {
1025
- credentials,
1026
- region
1027
- },
1028
- verbose
1029
- });
1030
- const secretsManagerClient = getSecretsManagerClient({
1031
- configuration: {
1032
- credentials,
1033
- region
1034
- },
1035
- verbose
1036
- });
1037
- for (const putParameterCommand of tasks.putParameterCommands) {
1038
- process.stdout.write(`Storing SSM parameter ${emphasis(putParameterCommand.input.Name || "<unnamed> ")}... `);
1039
- await ssmClient.send(putParameterCommand);
1040
- process.stdout.write(`done
1041
- `);
1042
- }
1043
- for (const createSecretCommand of tasks.createSecretCommands) {
1044
- process.stdout.write(`Creating Secret ${emphasis(createSecretCommand.input.Name || "<unnamed> ")}... `);
1045
- await secretsManagerClient.send(createSecretCommand);
1046
- process.stdout.write(`done
1047
- `);
1048
- }
1049
- for (const putSecretValueCommand of tasks.putSecretValueCommands) {
1050
- process.stdout.write(`Updating Secret ${emphasis(putSecretValueCommand.input.SecretId || "<unknown id> ")}... `);
1051
- await secretsManagerClient.send(putSecretValueCommand);
1052
- process.stdout.write(`done
1053
- `);
1054
- }
1055
- };
1056
- var prettyPrintTasks = (tasks) => {
1057
- const { info, table } = getLogger();
1058
- const { putParameterCommands, createSecretCommands, putSecretValueCommands } = tasks;
1059
- const ssmTasks = putParameterCommands.map((command10) => {
1060
- return {
1061
- name: command10.input.Name,
1062
- description: command10.input.Description || "<no description>",
1063
- tier: command10.input.Tier,
1064
- type: command10.input.Type,
1065
- value: command10.input.Value
1066
- };
1067
- });
1068
- info(emphasis(`AWS Systems Manager > Parameter Store: create or update`));
1069
- table(ssmTasks);
1070
- const createSecretTasks = createSecretCommands.map((command10) => {
1071
- return {
1072
- secretName: command10.input.Name,
1073
- description: command10.input.Description || "<no description>",
1074
- value: "**** redacted ****>"
1075
- };
1076
- });
1077
- if (createSecretTasks.length) {
1078
- info(emphasis(`AWS Secrets Manager Secrets: create`));
1079
- table(createSecretTasks);
1080
- }
1081
- const updateSecretTasks = putSecretValueCommands.map((command10) => {
1082
- return {
1083
- secretName: command10.input.SecretId,
1084
- value: "**** redacted ****>"
1085
- };
1086
- });
1087
- if (updateSecretTasks.length) {
1088
- info(emphasis(`AWS Secrets Manager Secrets: update`));
1089
- table(updateSecretTasks);
1090
- }
1091
- };
1092
- var decryptRawDotSecValues = async (options) => {
1093
- const { info } = getLogger();
1094
- const {
1095
- dotSecKeysValues: rawDotSec,
1096
- credentials,
1097
- region,
1098
- verbose,
1099
- keyAlias,
1100
- searchPath
1101
- } = options;
1102
- const kmsClient = getKMSClient({
1103
- configuration: {
1104
- credentials,
1105
- region
1106
- },
1107
- verbose
1108
- });
1109
- const s = searchPath == null ? void 0 : searchPath.split(".").map((part) => `${constantCase2(part)}_`).join("");
1110
- const awsKeyAlias = keyAlias;
1111
- if (!keyAlias) {
1112
- throw new Error("No key alias specified");
1113
- }
1114
- const encryptionAlgorithm = await getEncryptionAlgorithm(kmsClient, keyAlias);
1115
- const dotEnvLines = [];
1116
- const filtered = s ? Object.fromEntries(Object.entries(rawDotSec).filter(([key]) => key.startsWith(s)).map(([key, value]) => [key.replace(s, ""), value])) : rawDotSec;
1117
- for (const [key, encryptedValue] of Object.entries(filtered)) {
1118
- const decryptCommand = new DecryptCommand2({
1119
- KeyId: awsKeyAlias,
1120
- CiphertextBlob: Buffer.from(encryptedValue, "base64"),
1121
- EncryptionAlgorithm: encryptionAlgorithm
1122
- });
1123
- const decryptionResult = await kmsClient.send(decryptCommand);
1124
- if (!decryptionResult.Plaintext) {
1125
- throw new Error(`Something bad happened: ${JSON.stringify({
1126
- key,
1127
- cipherText: encryptedValue,
1128
- decryptCommand
1129
- })}`);
1130
- }
1131
- if (verbose) {
1132
- info(`Decrypting key ${emphasis(key)} ${strong("ok")}`);
1133
- }
1134
- const decryptedValue = Buffer.from(decryptionResult.Plaintext).toString();
1135
- const parsedValue = JSON.parse(decryptedValue);
1136
- const stringOrJson = maybeJson(parsedValue.value);
1137
- if (isRegularParameter(stringOrJson)) {
1138
- if (isRegularParameterObject(stringOrJson)) {
1139
- dotEnvLines.push(`${key}=${JSON.stringify(stringOrJson.value)}`);
1140
- } else {
1141
- dotEnvLines.push(`${key}=${String(stringOrJson)}`);
1142
- }
1143
- } else if (isSSMParameter(stringOrJson)) {
1144
- dotEnvLines.push(`${key}=${JSON.stringify(stringOrJson.value)}`);
1145
- } else if (isSecretsManagerParameter(stringOrJson)) {
1146
- dotEnvLines.push(`${key}=${JSON.stringify(stringOrJson.value)}`);
1147
- }
1148
- }
1149
- return dotEnvLines.join("\n");
1150
- };
1151
-
1152
- // src/lib/wtf/io.ts
1153
- import fs6 from "node:fs";
1154
- import path8 from "node:path";
1155
- import { bundleRequire as bundleRequire2 } from "bundle-require";
1156
- import JoyCon2 from "joycon";
1157
-
1158
- // src/lib/wtf/json.ts
1159
- import fs4 from "fs";
1160
- import path6 from "node:path";
1161
- function jsoncParse2(data) {
1162
- try {
1163
- return new Function("return " + data.trim())();
1164
- } catch {
1165
- return {};
1166
- }
1167
- }
1168
- var loadJson2 = async (filepath) => {
1169
- try {
1170
- return jsoncParse2(await fs4.promises.readFile(filepath, "utf8"));
1171
- } catch (error) {
1172
- if (error instanceof Error) {
1173
- throw new Error(`Failed to parse ${path6.relative(process.cwd(), filepath)}: ${error.message}`);
1174
- } else {
1175
- throw error;
1176
- }
1177
- }
1178
- };
1179
-
1180
- // src/lib/wtf/yaml.ts
1181
- import fs5 from "fs";
1182
- import path7 from "node:path";
1183
- import YAML from "yaml";
1184
- var loadYml = async (filepath) => {
1185
- try {
1186
- return YAML.parse(await fs5.promises.readFile(filepath, "utf8"));
1187
- } catch (error) {
1188
- if (error instanceof Error) {
1189
- throw new Error(`Failed to parse ${path7.relative(process.cwd(), filepath)}: ${error.message}`);
1190
- } else {
1191
- throw error;
1192
- }
1193
- }
1194
- };
1195
-
1196
- // src/lib/wtf/io.ts
1197
- var getDotSecPlainText = async ({
1198
- defaultConfig: defaultConfig2,
1199
- options
1200
- }) => {
1201
- var _a, _b, _c, _d, _e, _f;
1202
- const { info } = getLogger();
1203
- const { filename, verbose } = options || {};
1204
- const cwd = process.cwd();
1205
- const configJoycon = new JoyCon2();
1206
- const files = filename ? [filename] : [
1207
- "secrets.json",
1208
- "secrets.yaml",
1209
- "secrets.yml",
1210
- "secrets.ts"
1211
- ];
1212
- if (verbose) {
1213
- info(`Looking for file(s) with the following signature(s): ${strong(files.join(", "))}`);
1214
- }
1215
- const configPath = await configJoycon.resolve({
1216
- files,
1217
- cwd,
1218
- stopDir: path8.parse(cwd).root,
1219
- packageKey: "secrets"
1220
- });
1221
- if (configPath) {
1222
- if (verbose) {
1223
- info(`Found plaintext secrets at ${strong(configPath)}`);
1224
- }
1225
- let configType;
1226
- let data;
1227
- if (configPath.endsWith(".json")) {
1228
- configType = "json";
1229
- data = await loadJson2(configPath);
1230
- } else if (configPath.endsWith(".yaml") || configPath.endsWith(".yml")) {
1231
- configType = "yml";
1232
- data = await loadYml(configPath);
1233
- } else if (configPath.endsWith(".ts")) {
1234
- const bundleRequireResult = await bundleRequire2({
1235
- filepath: configPath
1236
- });
1237
- configType = "ts";
1238
- data = bundleRequireResult.mod.dotsec || bundleRequireResult.mod.default || bundleRequireResult.mod;
1239
- }
1240
- if (!configType) {
1241
- throw new Error(`Expected configType, but got none`);
1242
- }
1243
- if (!data) {
1244
- throw new Error(`Expected data, but got none`);
1245
- }
1246
- const validatedConfig = {
1247
- config: __spreadProps(__spreadValues({}, data.config), {
1248
- aws: {
1249
- regions: ((_b = (_a = data == null ? void 0 : data.config) == null ? void 0 : _a.aws) == null ? void 0 : _b.regions) && Array.isArray((_d = (_c = data == null ? void 0 : data.config) == null ? void 0 : _c.aws) == null ? void 0 : _d.regions) ? data.config.aws.regions : defaultConfig2.config.aws.regions,
1250
- keyAlias: ((_f = (_e = data == null ? void 0 : data.config) == null ? void 0 : _e.aws) == null ? void 0 : _f.keyAlias) || defaultConfig2.config.aws.keyAlias
1251
- }
1252
- })
1253
- };
1254
- return {
1255
- fileType: configType,
1256
- path: configPath,
1257
- dotSecPlainText: __spreadValues(__spreadValues({}, data), validatedConfig)
1258
- };
1259
- }
1260
- throw new Error("No secrets file found");
1261
- };
1262
- var getDotSecEncrypted = async ({
1263
- defaultConfig: defaultConfig2,
1264
- options
1265
- }) => {
1266
- var _a, _b, _c, _d, _e, _f;
1267
- const { filename, verbose } = options || {};
1268
- const cwd = process.cwd();
1269
- const configJoycon = new JoyCon2();
1270
- const configPath = await configJoycon.resolve({
1271
- files: filename ? [filename] : [
1272
- "secrets.encrypted.json",
1273
- "secrets.encrypted.yaml",
1274
- "secrets.encrypted.yml",
1275
- "secrets.encrypted.ts"
1276
- ],
1277
- cwd,
1278
- stopDir: path8.parse(cwd).root,
1279
- packageKey: "secrets"
1280
- });
1281
- if (configPath) {
1282
- if (verbose) {
1283
- console.log(`Found encrypted secrets file at ${configPath}`);
1284
- }
1285
- let configType;
1286
- let data;
1287
- if (configPath.endsWith(".json")) {
1288
- configType = "json";
1289
- data = await loadJson2(configPath);
1290
- } else if (configPath.endsWith(".yaml") || configPath.endsWith(".yml")) {
1291
- configType = path8.parse(configPath).ext.substring(1);
1292
- data = await loadYml(configPath);
1293
- }
1294
- if (!configType) {
1295
- throw new Error(`Config file ${configPath} is not supported`);
1296
- }
1297
- if (!data) {
1298
- throw new Error("Did not find any data");
1299
- }
1300
- const validatedConfig = {
1301
- config: __spreadProps(__spreadValues({}, data.config), {
1302
- aws: {
1303
- regions: ((_b = (_a = data == null ? void 0 : data.config) == null ? void 0 : _a.aws) == null ? void 0 : _b.regions) && Array.isArray((_d = (_c = data == null ? void 0 : data.config) == null ? void 0 : _c.aws) == null ? void 0 : _d.regions) ? data.config.aws.regions : defaultConfig2.config.aws.regions,
1304
- keyAlias: ((_f = (_e = data == null ? void 0 : data.config) == null ? void 0 : _e.aws) == null ? void 0 : _f.keyAlias) || defaultConfig2.config.aws.keyAlias
1305
- }
1306
- })
1307
- };
1308
- return {
1309
- fileType: configType,
1310
- path: configPath,
1311
- dotSecEncrypted: __spreadValues(__spreadValues({}, data), validatedConfig)
1312
- };
1313
- }
1314
- throw new Error("No encrypted secrets file found");
1315
- };
1316
- var loadFile = async (filepath) => {
1317
- try {
1318
- return await fs6.promises.readFile(filepath, "utf8");
1319
- } catch (error) {
1320
- if (error instanceof Error) {
1321
- throw new Error(`Failed to parse ${path8.relative(process.cwd(), filepath)}: ${error.message}`);
1322
- } else {
1323
- throw error;
1324
- }
1325
- }
1326
- };
1327
-
1328
- // src/commands/dot-sec-to-dot-env.ts
1329
- var command2 = "dot-sec-to-dot-env";
1330
- var desc2 = `Creates .env file from a .sec file.`;
1331
- var builder2 = {
1332
- "sec-file": commonCliOptions.secFile,
1333
- "env-file": commonCliOptions.envFile,
1334
- "aws-profile": commonCliOptions.awsProfile,
1335
- "aws-region": commonCliOptions.awsRegion,
1336
- "aws-key-alias": commonCliOptions.awsKeyAlias,
1337
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
1338
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
1339
- "use-top-levels-as-environments": commonCliOptions.useTopLevelsAsEnvironments,
1340
- verbose: commonCliOptions.verbose,
1341
- yes: __spreadValues({}, commonCliOptions.yes)
1342
- };
1343
- var handler2 = async (argv) => {
1344
- const config = await getConfig();
1345
- const { error } = getLogger();
1346
- try {
1347
- const defaultRegion = config.aws.region || argv.awsRegion;
1348
- const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
1349
- argv: __spreadProps(__spreadValues({}, argv), {
1350
- awsRegion: defaultRegion,
1351
- awsProfile: config.aws.profile || argv.awsProfile,
1352
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
1353
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
1354
- }),
1355
- env: __spreadValues({}, process.env)
1356
- });
1357
- const dotSecFilename = argv.secFile || ".sec";
1358
- const dotSecPath = path9.resolve(process.cwd(), dotSecFilename);
1359
- const dotSecString = await loadFile(dotSecPath);
1360
- const dotSecKeysValues = parse2(dotSecString);
1361
- const dotEnvString = await decryptRawDotSecValues({
1362
- dotSecKeysValues,
1363
- credentials: credentialsAndOrigin.value,
1364
- region: regionAndOrigin.value,
1365
- keyAlias: argv.awsKeyAlias || "alias/dotsec",
1366
- verbose: argv.verbose
1367
- });
1368
- const dotEnvFilename = argv.envFile || `.env`;
1369
- const dotEnvPath = path9.resolve(process.cwd(), dotEnvFilename);
1370
- const overwriteResponse = await promptOverwriteIfFileExists({
1371
- filePath: dotEnvPath,
1372
- skip: argv.yes
1373
- });
1374
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
1375
- fs7.writeFileSync(dotEnvPath, dotEnvString);
1376
- }
1377
- } catch (e) {
1378
- error(e);
1379
- }
1380
- };
1381
-
1382
- // src/commands/encrypted-secrets-to-dot-env.ts
1383
- var encrypted_secrets_to_dot_env_exports = {};
1384
- __export(encrypted_secrets_to_dot_env_exports, {
1385
- builder: () => builder3,
1386
- command: () => command3,
1387
- desc: () => desc3,
1388
- handler: () => handler3
1389
- });
1390
- import fs8 from "fs";
1391
- import path10 from "node:path";
1392
-
1393
- // src/lib/wtf/dotenv.ts
1394
- import { constantCase as constantCase3 } from "constant-case";
1395
- var fromPlainTextLeafsToEnvEntries = (leafs) => {
1396
- return Object.entries(leafs).map(([key, plainTextValue]) => {
1397
- const parts = key.split("/");
1398
- const dotEnvKeyPath = parts.map((k) => constantCase3(k)).join("_");
1399
- let storageValue;
1400
- if (isRegularParameter(plainTextValue)) {
1401
- if (isRegularParameterObject(plainTextValue)) {
1402
- storageValue = plainTextValue.value;
1403
- } else {
1404
- storageValue = plainTextValue;
1405
- }
1406
- } else if (isSSMParameter(plainTextValue)) {
1407
- storageValue = plainTextValue.value;
1408
- } else if (isSecretsManagerParameter(plainTextValue)) {
1409
- storageValue = plainTextValue.value;
1410
- } else {
1411
- throw new Error("Invalid parameter type");
1412
- }
1413
- if (!isString(storageValue) && !isNumber(storageValue) && !isBoolean(storageValue)) {
1414
- storageValue = JSON.stringify(storageValue);
1415
- }
1416
- return `${dotEnvKeyPath}=${String(storageValue)}`;
1417
- });
1418
- };
1419
- var toDotEnv = (options) => {
1420
- const { info } = getLogger();
1421
- const { dotSecPlainText, searchPath, verbose } = options;
1422
- let tree = dotSecPlainText.plaintext;
1423
- if (searchPath) {
1424
- if (verbose) {
1425
- info(`Searching for path: ${strong(searchPath)}`);
1426
- }
1427
- const pathParts = searchPath.split("/");
1428
- for (const pathPart of pathParts) {
1429
- tree = tree[pathPart];
1430
- if (tree === void 0) {
1431
- throw new Error(`Invalid search path: '${searchPath}', part: '${pathPart}' could not be found`);
1432
- }
1433
- }
1434
- }
1435
- const flattenedTree = flattenTree(tree);
1436
- return fromPlainTextLeafsToEnvEntries(flattenedTree).join("\n");
1437
- };
1438
- var toDotEnvPerEnvironment = (options) => {
1439
- const { info } = getLogger();
1440
- const { dotSecPlainText, searchPath, verbose } = options;
1441
- const environments = Object.keys(dotSecPlainText.plaintext);
1442
- return Object.fromEntries(environments.map((environment) => {
1443
- let tree = dotSecPlainText.plaintext[environment];
1444
- if (searchPath) {
1445
- if (verbose) {
1446
- info(`Searching for path: ${strong(searchPath)}`);
1447
- }
1448
- const pathParts = searchPath.split("/");
1449
- for (const pathPart of pathParts) {
1450
- tree = tree[pathPart];
1451
- if (tree === void 0) {
1452
- throw new Error(`Invalid search path: '${searchPath}', part: '${pathPart}' could not be found`);
1453
- }
1454
- }
1455
- }
1456
- return [
1457
- environment,
1458
- fromPlainTextLeafsToEnvEntries(flattenTree(tree)).join("\n")
1459
- ];
1460
- }));
1461
- };
1462
-
1463
- // src/commands/encrypted-secrets-to-dot-env.ts
1464
- var command3 = "encrypted-secrets-to-dot-env";
1465
- var desc3 = `Creates .env file from an encrypted secrets file.
1466
- If '--use-top-levels-as-environments' is set, it will create a .env file for each top level key in the encrypted secrets file.`;
1467
- var builder3 = {
1468
- "encrypted-secrets-file": {
1469
- string: true,
1470
- describe: "filename of json file for writing encrypted secrets",
1471
- default: "secrets.encrypted.json"
1472
- },
1473
- "env-file": commonCliOptions.envFile,
1474
- "search-path": commonCliOptions.searchpath,
1475
- "aws-profile": commonCliOptions.awsProfile,
1476
- "aws-region": commonCliOptions.awsRegion,
1477
- "aws-key-alias": commonCliOptions.awsKeyAlias,
1478
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
1479
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
1480
- "use-top-levels-as-environments": commonCliOptions.useTopLevelsAsEnvironments,
1481
- verbose: commonCliOptions.verbose,
1482
- yes: __spreadValues({}, commonCliOptions.yes)
1483
- };
1484
- var handler3 = async (argv) => {
1485
- var _a;
1486
- const config = await getConfig();
1487
- const { info, error } = getLogger();
1488
- try {
1489
- const defaultRegion = config.aws.region || argv.awsRegion;
1490
- const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
1491
- argv: __spreadProps(__spreadValues({}, argv), {
1492
- awsRegion: defaultRegion,
1493
- awsProfile: config.aws.profile || argv.awsProfile,
1494
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
1495
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
1496
- }),
1497
- env: __spreadValues({}, process.env)
1498
- });
1499
- const { fileType, dotSecEncrypted } = await getDotSecEncrypted({
1500
- defaultConfig: {
1501
- config: {
1502
- aws: {
1503
- keyAlias: "alias/dotsec",
1504
- regions: [regionAndOrigin.value]
1505
- }
1506
- }
1507
- },
1508
- options: {
1509
- verbose: argv.verbose
1510
- }
1511
- });
1512
- if (!dotSecEncrypted.encrypted) {
1513
- throw new Error(`Expected 'encrypted' property, but got none`);
1514
- }
1515
- const dotSecPlainText = await decryptedEncrypted({
1516
- dotSecEncrypted,
1517
- credentials: credentialsAndOrigin.value,
1518
- region: regionAndOrigin.value,
1519
- keyAlias: argv.awsKeyAlias,
1520
- verbose: argv.verbose
1521
- });
1522
- if (argv.useTopLevelsAsEnvironments || ((_a = dotSecEncrypted.config) == null ? void 0 : _a.useTopLevelsAsEnvironments)) {
1523
- const dotEnvsPerEnvironment = toDotEnvPerEnvironment({
1524
- dotSecPlainText,
1525
- verbose: argv.verbose
1526
- });
1527
- for (const [environment, dotEnv] of Object.entries(dotEnvsPerEnvironment)) {
1528
- const fileName = `.env.${environment}`;
1529
- const dotEnvPath = path10.resolve(process.cwd(), fileName);
1530
- info(`target: ${strong(dotEnvPath)}
1531
- `);
1532
- info(prettyCode(dotEnv));
1533
- info(`
1534
- `);
1535
- const overwriteResponse = await promptOverwriteIfFileExists({
1536
- filePath: dotEnvPath,
1537
- skip: argv.yes
1538
- });
1539
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
1540
- fs8.writeFileSync(dotEnvPath, dotEnv);
1541
- }
1542
- }
1543
- } else {
1544
- const dotEnv = toDotEnv({
1545
- dotSecPlainText,
1546
- verbose: argv.verbose,
1547
- searchPath: argv.searchPath
1548
- });
1549
- const fileName = argv.envFile || `.env`;
1550
- const dotEnvPath = path10.resolve(process.cwd(), fileName);
1551
- info(`target: ${strong(dotEnvPath)}
1552
- `);
1553
- info(prettyCode(dotEnv));
1554
- info(`
1555
- `);
1556
- const overwriteResponse = await promptOverwriteIfFileExists({
1557
- filePath: dotEnvPath,
1558
- skip: argv.yes
1559
- });
1560
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
1561
- fs8.writeFileSync(dotEnvPath, dotEnv);
1562
- }
1563
- }
1564
- } catch (e) {
1565
- error(e);
1566
- }
1567
- };
1568
-
1569
- // src/commands/encrypted-secrets-to-dot-sec.ts
1570
- var encrypted_secrets_to_dot_sec_exports = {};
1571
- __export(encrypted_secrets_to_dot_sec_exports, {
1572
- builder: () => builder4,
1573
- command: () => command4,
1574
- desc: () => desc4,
1575
- handler: () => handler4
1576
- });
1577
- import fs9 from "fs";
1578
- import path11 from "node:path";
1579
-
1580
- // src/lib/wtf/dotsec.ts
1581
- import { constantCase as constantCase4 } from "constant-case";
1582
- var fromEncryptedLeafsToEnvEntries = (leafs) => {
1583
- return Object.entries(leafs).map(([key, plainTextValue]) => {
1584
- const parts = key.split("/");
1585
- const dotEnvKeyPath = parts.map((k) => constantCase4(k)).join("_");
1586
- let storageValue;
1587
- if (isEncryptedRegularParameter(plainTextValue)) {
1588
- storageValue = plainTextValue.encryptedValue;
1589
- } else if (isEncryptedSSMParameter(plainTextValue)) {
1590
- storageValue = plainTextValue.encryptedValue;
1591
- } else if (isSecretsManagerParameter(plainTextValue)) {
1592
- storageValue = plainTextValue.encryptedValue;
1593
- } else {
1594
- throw new Error("Invalid parameter type");
1595
- }
1596
- return `${dotEnvKeyPath}=${String(storageValue)}`;
1597
- });
1598
- };
1599
- var toDotSec = (options) => {
1600
- const { info } = getLogger();
1601
- const { dotSecEncrypted, searchPath, verbose } = options;
1602
- let tree = dotSecEncrypted.encrypted;
1603
- if (searchPath) {
1604
- if (verbose) {
1605
- info(`Searching for path: ${strong(searchPath)}`);
1606
- }
1607
- const pathParts = searchPath.split("/");
1608
- for (const pathPart of pathParts) {
1609
- tree = tree[pathPart];
1610
- }
1611
- }
1612
- const flattenedTree = flattenTree(tree);
1613
- return fromEncryptedLeafsToEnvEntries(flattenedTree).join("\n");
1614
- };
1615
- var toDotSecPerEnvironment = (options) => {
1616
- const { info } = getLogger();
1617
- const { dotSecEncrypted, searchPath, verbose } = options;
1618
- const environments = Object.keys(dotSecEncrypted.encrypted);
1619
- return Object.fromEntries(environments.map((environment) => {
1620
- let tree = dotSecEncrypted.encrypted[environment];
1621
- if (searchPath) {
1622
- if (verbose) {
1623
- info(`Searching for path: ${strong(searchPath)}`);
1624
- }
1625
- const pathParts = searchPath.split("/");
1626
- for (const pathPart of pathParts) {
1627
- tree = tree[pathPart];
1628
- }
1629
- }
1630
- return [
1631
- environment,
1632
- fromEncryptedLeafsToEnvEntries(flattenTree(tree)).join("\n")
1633
- ];
1634
- }));
1635
- };
1636
-
1637
- // src/commands/encrypted-secrets-to-dot-sec.ts
1638
- var command4 = "encrypted-secrets-to-dot-sec";
1639
- var desc4 = `Creates .sec file from an encrypted secrets file.
1640
- If '--use-top-levels-as-environments' is set, it will create a .sec file for each top level key in the encrypted secrets file.`;
1641
- var builder4 = {
1642
- "encrypted-secrets-file": {
1643
- string: true,
1644
- describe: "filename of json file for writing encrypted secrets",
1645
- default: "secrets.encrypted.json"
1646
- },
1647
- "sec-file": commonCliOptions.secFile,
1648
- "search-path": commonCliOptions.searchpath,
1649
- "aws-profile": commonCliOptions.awsProfile,
1650
- "aws-region": commonCliOptions.awsRegion,
1651
- "aws-key-alias": commonCliOptions.awsKeyAlias,
1652
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
1653
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
1654
- "use-top-levels-as-environments": commonCliOptions.useTopLevelsAsEnvironments,
1655
- verbose: commonCliOptions.verbose,
1656
- yes: __spreadValues({}, commonCliOptions.yes)
1657
- };
1658
- var handler4 = async (argv) => {
1659
- var _a;
1660
- const config = await getConfig();
1661
- const { info, error } = getLogger();
1662
- try {
1663
- const defaultRegion = config.aws.region || argv.awsRegion;
1664
- const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
1665
- argv: __spreadProps(__spreadValues({}, argv), {
1666
- awsRegion: defaultRegion,
1667
- awsProfile: config.aws.profile || argv.awsProfile,
1668
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
1669
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
1670
- }),
1671
- env: __spreadValues({}, process.env)
1672
- });
1673
- const { fileType, dotSecEncrypted } = await getDotSecEncrypted({
1674
- defaultConfig: {
1675
- config: {
1676
- aws: {
1677
- keyAlias: "alias/dotsec",
1678
- regions: [regionAndOrigin.value]
1679
- }
1680
- }
1681
- },
1682
- options: {
1683
- verbose: argv.verbose
1684
- }
1685
- });
1686
- if (!dotSecEncrypted.encrypted) {
1687
- throw new Error(`Expected 'encrypted' property, but got none`);
1688
- }
1689
- const dotSecPlainText = await decryptedEncrypted({
1690
- dotSecEncrypted,
1691
- credentials: credentialsAndOrigin.value,
1692
- region: regionAndOrigin.value,
1693
- keyAlias: argv.awsKeyAlias,
1694
- verbose: argv.verbose
1695
- });
1696
- if (argv.useTopLevelsAsEnvironments || ((_a = dotSecEncrypted.config) == null ? void 0 : _a.useTopLevelsAsEnvironments)) {
1697
- const dotSecsPerEnvironment = toDotSecPerEnvironment({
1698
- dotSecEncrypted,
1699
- searchPath: argv.searchPath,
1700
- verbose: argv.verbose
1701
- });
1702
- for (const [environment, dotSec] of Object.entries(dotSecsPerEnvironment)) {
1703
- const fileName = `.sec.${environment}`;
1704
- const dotSecPath = path11.resolve(process.cwd(), fileName);
1705
- info(`target: ${strong(dotSecPath)}
1706
- `);
1707
- info(prettyCode(dotSec));
1708
- info(`
1709
- `);
1710
- const overwriteResponse = await promptOverwriteIfFileExists({
1711
- filePath: dotSecPath,
1712
- skip: argv.yes
1713
- });
1714
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
1715
- fs9.writeFileSync(dotSecPath, dotSec);
1716
- }
1717
- }
1718
- } else {
1719
- const dotSec = toDotSec({
1720
- dotSecEncrypted,
1721
- searchPath: argv.searchPath,
1722
- verbose: argv.verbose
1723
- });
1724
- const fileName = argv.secFile || `.sec`;
1725
- const dotSecPath = path11.resolve(process.cwd(), fileName);
1726
- info(`target: ${strong(dotSecPath)}
1727
- `);
1728
- info(prettyCode(dotSec));
1729
- info(`
1730
- `);
1731
- const overwriteResponse = await promptOverwriteIfFileExists({
1732
- filePath: dotSecPath,
1733
- skip: argv.yes
1734
- });
1735
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
1736
- fs9.writeFileSync(dotSecPath, dotSec);
1737
- }
1738
- }
1739
- } catch (e) {
1740
- error(e);
1741
- }
1742
- };
1743
-
1744
- // src/commands/encrypted-secrets-to-plaintext-secrets.ts
1745
- var encrypted_secrets_to_plaintext_secrets_exports = {};
1746
- __export(encrypted_secrets_to_plaintext_secrets_exports, {
1747
- builder: () => builder5,
1748
- command: () => command5,
1749
- desc: () => desc5,
1750
- handler: () => handler5
1751
- });
1752
- import fs10 from "node:fs";
1753
- import path12 from "node:path";
1754
- import YAML2 from "yaml";
1755
- var command5 = "encrypted-secrets-to-plaintext-secrets";
1756
- var desc5 = "Decrypts an encrypted file and stores the result in a plaintext file";
1757
- var builder5 = {
1758
- "secrets-file": {
1759
- string: true,
1760
- describe: "filename of json file reading secrets",
1761
- default: "secrets.json"
1762
- },
1763
- "encrypted-secrets-file": {
1764
- string: true,
1765
- describe: "filename of json file for writing encrypted secrets",
1766
- default: "secrets.encrypted.json"
1767
- },
1768
- "aws-profile": commonCliOptions.awsProfile,
1769
- "aws-region": commonCliOptions.awsRegion,
1770
- "aws-key-alias": commonCliOptions.awsKeyAlias,
1771
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
1772
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
1773
- verbose: commonCliOptions.verbose,
1774
- yes: __spreadValues({}, commonCliOptions.yes)
1775
- };
1776
- var handler5 = async (argv) => {
1777
- const config = await getConfig();
1778
- const { info, error } = getLogger();
1779
- try {
1780
- const defaultRegion = config.aws.region || argv.awsRegion;
1781
- const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
1782
- argv: __spreadProps(__spreadValues({}, argv), {
1783
- awsRegion: defaultRegion,
1784
- awsProfile: config.aws.profile || argv.awsProfile,
1785
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
1786
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
1787
- }),
1788
- env: __spreadValues({}, process.env)
1789
- });
1790
- const { fileType, dotSecEncrypted } = await getDotSecEncrypted({
1791
- defaultConfig: {
1792
- config: {
1793
- aws: {
1794
- keyAlias: "alias/dotsec",
1795
- regions: [regionAndOrigin.value]
1796
- }
1797
- }
1798
- },
1799
- options: {}
1800
- });
1801
- if (!dotSecEncrypted.encrypted) {
1802
- throw new Error(`Expected 'encrypted' property, but got none`);
1803
- }
1804
- const dotSecPlainText = await decryptedEncrypted({
1805
- dotSecEncrypted,
1806
- credentials: credentialsAndOrigin.value,
1807
- region: regionAndOrigin.value,
1808
- keyAlias: argv.awsKeyAlias,
1809
- verbose: argv.verbose
1810
- });
1811
- if (argv.secretsFile) {
1812
- const secretsFileExtension = path12.extname(argv.secretsFile).substring(1);
1813
- }
1814
- const secretsPath = path12.resolve(process.cwd(), path12.parse(argv.secretsFile || `secrets.json`).name + "." + fileType);
1815
- console.log("secretsPath", fileType, path12.parse(argv.secretsFile || `secrets.json`).name);
1816
- const converted = fileType === "yaml" || fileType === "yml" ? YAML2.stringify(dotSecPlainText) : JSON.stringify(dotSecPlainText, null, 2);
1817
- info(`target: ${strong(secretsPath)}
1818
- `);
1819
- info(prettyCode(converted));
1820
- info(`
1821
- `);
1822
- const overwriteResponse = await promptOverwriteIfFileExists({
1823
- filePath: secretsPath,
1824
- skip: argv.yes
1825
- });
1826
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
1827
- fs10.writeFileSync(secretsPath, converted);
1828
- }
1829
- } catch (e) {
1830
- error(e);
1831
- }
1832
- };
1833
-
1834
- // src/commands/offload-plaintext-secrets.ts
1835
- var offload_plaintext_secrets_exports = {};
1836
- __export(offload_plaintext_secrets_exports, {
1837
- builder: () => builder6,
1838
- command: () => command6,
1839
- desc: () => desc6,
1840
- handler: () => handler6
1841
- });
1842
- import prompts2 from "prompts";
1843
- var command6 = "offload-plaintext-secrets";
1844
- var desc6 = "Decrypts and pushes secret values to AWS SSM and SecretsManager";
1845
- var builder6 = {
1846
- "encrypted-secrets-file": {
1847
- string: true,
1848
- describe: "filename of json file for writing encrypted secrets",
1849
- default: "secrets.encrypted.json"
1850
- },
1851
- "aws-profile": commonCliOptions.awsProfile,
1852
- "aws-region": commonCliOptions.awsRegion,
1853
- "aws-key-alias": commonCliOptions.awsKeyAlias,
1854
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
1855
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
1856
- verbose: commonCliOptions.verbose,
1857
- yes: __spreadValues({}, commonCliOptions.yes)
1858
- };
1859
- var handler6 = async (argv) => {
1860
- const config = await getConfig();
1861
- const { info, error } = getLogger();
1862
- try {
1863
- const defaultRegion = config.aws.region || argv.awsRegion;
1864
- const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
1865
- argv: __spreadProps(__spreadValues({}, argv), {
1866
- awsRegion: defaultRegion,
1867
- awsProfile: config.aws.profile || argv.awsProfile,
1868
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
1869
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
1870
- }),
1871
- env: __spreadValues({}, process.env)
1872
- });
1873
- const { fileType, dotSecEncrypted } = await getDotSecEncrypted({
1874
- defaultConfig: {
1875
- config: {
1876
- aws: {
1877
- keyAlias: "alias/dotsec",
1878
- regions: [regionAndOrigin.value]
1879
- }
1880
- }
1881
- },
1882
- options: {}
1883
- });
1884
- if (!dotSecEncrypted.encrypted) {
1885
- throw new Error(`Expected 'encrypted' property, but got none`);
1886
- }
1887
- const dotSecPlainText = await decryptedEncrypted({
1888
- dotSecEncrypted,
1889
- credentials: credentialsAndOrigin.value,
1890
- region: regionAndOrigin.value,
1891
- keyAlias: argv.awsKeyAlias,
1892
- verbose: argv.verbose
1893
- });
1894
- const tasks = await createStorePlaintextTasks({
1895
- dotSecPlainText,
1896
- credentials: credentialsAndOrigin.value,
1897
- region: regionAndOrigin.value,
1898
- keyAlias: argv.awsKeyAlias,
1899
- verbose: argv.verbose
1900
- });
1901
- if (tasks.total > 0) {
1902
- prettyPrintTasks(tasks);
1903
- let proceed = argv.yes === true;
1904
- if (proceed === false) {
1905
- proceed = await prompts2({
1906
- type: "confirm",
1907
- name: "proceed",
1908
- message: () => {
1909
- return `Proceed ?`;
1910
- }
1911
- }).then((r) => r.proceed);
1912
- }
1913
- if (proceed) {
1914
- await executeStorePlainTextTasks({
1915
- credentials: credentialsAndOrigin.value,
1916
- region: regionAndOrigin.value,
1917
- verbose: argv.verbose,
1918
- tasks
1919
- });
1920
- }
1921
- } else {
1922
- info("Nothing to do");
1923
- }
1924
- } catch (e) {
1925
- error(e);
1926
- }
1927
- };
1928
-
1929
- // src/commands/plaintext-secrets-to-dot-env.ts
1930
- var plaintext_secrets_to_dot_env_exports = {};
1931
- __export(plaintext_secrets_to_dot_env_exports, {
1932
- builder: () => builder7,
1933
- command: () => command7,
1934
- desc: () => desc7,
1935
- handler: () => handler7
1936
- });
1937
- import fs11 from "fs";
1938
- import path13 from "node:path";
1939
- var command7 = "plaintext-secrets-to-dot-env";
1940
- var desc7 = `Creates .env file from a secrets file.
1941
- If '--use-top-levels-as-environments' is set, it will create a .env file for each top level key in the secrets file.`;
1942
- var builder7 = {
1943
- "secrets-file": {
1944
- string: true,
1945
- describe: "filename of json file reading secrets",
1946
- default: "secrets.json"
1947
- },
1948
- "env-file": commonCliOptions.envFile,
1949
- "search-path": commonCliOptions.searchpath,
1950
- "aws-profile": commonCliOptions.awsProfile,
1951
- "aws-region": commonCliOptions.awsRegion,
1952
- "aws-key-alias": commonCliOptions.awsKeyAlias,
1953
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
1954
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
1955
- "use-top-levels-as-environments": commonCliOptions.useTopLevelsAsEnvironments,
1956
- verbose: commonCliOptions.verbose,
1957
- yes: __spreadValues({}, commonCliOptions.yes),
1958
- "dry-run": commonCliOptions.dryRun
1959
- };
1960
- var handler7 = async (argv) => {
1961
- var _a;
1962
- const config = await getConfig();
1963
- const { info, error } = getLogger();
1964
- try {
1965
- const defaultRegion = config.aws.region || argv.awsRegion;
1966
- const { regionAndOrigin } = await handleCredentialsAndRegion({
1967
- argv: __spreadProps(__spreadValues({}, argv), {
1968
- awsRegion: defaultRegion,
1969
- awsProfile: config.aws.profile || argv.awsProfile,
1970
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
1971
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
1972
- }),
1973
- env: __spreadValues({}, process.env)
1974
- });
1975
- const { dotSecPlainText } = await getDotSecPlainText({
1976
- defaultConfig: {
1977
- config: {
1978
- aws: {
1979
- keyAlias: "alias/dotsec",
1980
- regions: [regionAndOrigin.value]
1981
- }
1982
- }
1983
- },
1984
- options: {
1985
- filename: argv.secretsFile,
1986
- verbose: argv.verbose
1987
- }
1988
- });
1989
- if (!dotSecPlainText.plaintext) {
1990
- throw new Error(`Expected 'encrypted' property, but got none`);
1991
- }
1992
- if (argv.useTopLevelsAsEnvironments || ((_a = dotSecPlainText.config) == null ? void 0 : _a.useTopLevelsAsEnvironments)) {
1993
- const dotEnvsPerEnvironment = toDotEnvPerEnvironment({
1994
- dotSecPlainText,
1995
- verbose: argv.verbose
1996
- });
1997
- for (const [environment, dotEnv] of Object.entries(dotEnvsPerEnvironment)) {
1998
- const fileName = `.env.${environment}`;
1999
- const dotEnvPath = path13.resolve(process.cwd(), fileName);
2000
- if (argv.dryRun) {
2001
- info(strong(`// ${dotEnvPath}`));
2002
- info(emphasis(dotEnv));
2003
- } else {
2004
- const overwriteResponse = await promptOverwriteIfFileExists({
2005
- filePath: dotEnvPath,
2006
- skip: argv.yes
2007
- });
2008
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
2009
- fs11.writeFileSync(dotEnvPath, dotEnv);
2010
- }
2011
- }
2012
- }
2013
- } else {
2014
- const dotEnv = toDotEnv({
2015
- dotSecPlainText,
2016
- verbose: argv.verbose,
2017
- searchPath: argv.searchPath
2018
- });
2019
- const fileName = argv.envFile || `.env`;
2020
- const dotEnvPath = path13.resolve(process.cwd(), fileName);
2021
- info(`target: ${strong(dotEnvPath)}
2022
- `);
2023
- info(prettyCode(dotEnv));
2024
- info(`
2025
- `);
2026
- const overwriteResponse = await promptOverwriteIfFileExists({
2027
- filePath: dotEnvPath,
2028
- skip: argv.yes
2029
- });
2030
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
2031
- fs11.writeFileSync(dotEnvPath, dotEnv);
2032
- }
2033
- }
2034
- } catch (e) {
2035
- error(e);
2036
- }
2037
- };
2038
-
2039
- // src/commands/plaintext-secrets-to-dot-sec.ts
2040
- var plaintext_secrets_to_dot_sec_exports = {};
2041
- __export(plaintext_secrets_to_dot_sec_exports, {
2042
- builder: () => builder8,
2043
- command: () => command8,
2044
- desc: () => desc8,
2045
- handler: () => handler8
2046
- });
2047
- import fs12 from "fs";
2048
- import path14 from "node:path";
2049
- var command8 = "plaintext-secrets-to-dot-sec";
2050
- var desc8 = `Creates .sec file from an secrets file.
2051
- If '--use-top-levels-as-environments' is set, it will create a .sec file for each top level key in the ecrets file.`;
2052
- var builder8 = {
2053
- "secrets-file": {
2054
- string: true,
2055
- describe: "filename of json file reading secrets"
2056
- },
2057
- "sec-file": commonCliOptions.secFile,
2058
- "aws-profile": commonCliOptions.awsProfile,
2059
- "aws-region": commonCliOptions.awsRegion,
2060
- "aws-key-alias": commonCliOptions.awsKeyAlias,
2061
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
2062
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
2063
- "use-top-levels-as-environments": commonCliOptions.useTopLevelsAsEnvironments,
2064
- verbose: commonCliOptions.verbose,
2065
- yes: __spreadValues({}, commonCliOptions.yes)
2066
- };
2067
- var handler8 = async (argv) => {
2068
- var _a;
2069
- const config = await getConfig();
2070
- const { info, error } = getLogger();
2071
- try {
2072
- const defaultRegion = config.aws.region || argv.awsRegion;
2073
- const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
2074
- argv: __spreadProps(__spreadValues({}, argv), {
2075
- awsRegion: defaultRegion,
2076
- awsProfile: config.aws.profile || argv.awsProfile,
2077
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
2078
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
2079
- }),
2080
- env: __spreadValues({}, process.env)
2081
- });
2082
- const { fileType, dotSecPlainText } = await getDotSecPlainText({
2083
- defaultConfig: {
2084
- config: {
2085
- aws: {
2086
- keyAlias: "alias/dotsec",
2087
- regions: [regionAndOrigin.value]
2088
- }
2089
- }
2090
- },
2091
- options: {
2092
- filename: argv.secretsFile,
2093
- verbose: argv.verbose
2094
- }
2095
- });
2096
- console.log("dotSecPlainText", dotSecPlainText);
2097
- const dotSecEncrypted = await encryptPlainText({
2098
- dotSecPlainText,
2099
- credentials: credentialsAndOrigin.value,
2100
- region: regionAndOrigin.value,
2101
- keyAlias: argv.awsKeyAlias,
2102
- verbose: argv.verbose
2103
- });
2104
- if (!dotSecPlainText.plaintext) {
2105
- throw new Error(`Expected 'encrypted' property, but got none`);
2106
- }
2107
- if (!dotSecEncrypted.encrypted) {
2108
- throw new Error(`Expected 'encrypted' property, but got none`);
2109
- }
2110
- if (argv.useTopLevelsAsEnvironments || ((_a = dotSecPlainText.config) == null ? void 0 : _a.useTopLevelsAsEnvironments)) {
2111
- const dotSecsPerEnvironment = toDotSecPerEnvironment({
2112
- dotSecEncrypted,
2113
- verbose: argv.verbose
2114
- });
2115
- for (const [environment, dotSec] of Object.entries(dotSecsPerEnvironment)) {
2116
- const fileName = `.sec.${environment}`;
2117
- const dotSecPath = path14.resolve(process.cwd(), fileName);
2118
- info(`target: ${strong(dotSecPath)}
2119
- `);
2120
- info(prettyCode(dotSec));
2121
- info(`
2122
- `);
2123
- const overwriteResponse = await promptOverwriteIfFileExists({
2124
- filePath: dotSecPath,
2125
- skip: argv.yes
2126
- });
2127
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
2128
- fs12.writeFileSync(dotSecPath, dotSec);
2129
- }
2130
- }
2131
- } else {
2132
- const dotSec = toDotSec({
2133
- dotSecEncrypted,
2134
- verbose: argv.verbose
2135
- });
2136
- const fileName = argv.secFile || `.sec`;
2137
- const dotSecPath = path14.resolve(process.cwd(), fileName);
2138
- info(`target: ${strong(dotSecPath)}
2139
- `);
2140
- info(prettyCode(dotSec));
2141
- info(`
2142
- `);
2143
- const overwriteResponse = await promptOverwriteIfFileExists({
2144
- filePath: dotSecPath,
2145
- skip: argv.yes
2146
- });
2147
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
2148
- fs12.writeFileSync(dotSecPath, dotSec);
2149
- }
2150
- }
2151
- } catch (e) {
2152
- error(e);
2153
- }
2154
- };
2155
-
2156
- // src/commands/plaintext-secrets-to-encrypted-secrets.ts
2157
- var plaintext_secrets_to_encrypted_secrets_exports = {};
2158
- __export(plaintext_secrets_to_encrypted_secrets_exports, {
2159
- builder: () => builder9,
2160
- command: () => command9,
2161
- desc: () => desc9,
2162
- handler: () => handler9
2163
- });
2164
- import fs13 from "node:fs";
2165
- import path15 from "node:path";
2166
- import YAML3 from "yaml";
2167
- var command9 = "plaintext-secrets-to-encrypted-secrets";
2168
- var desc9 = "Encrypts an unencrypted secretsfile";
2169
- var builder9 = {
2170
- "secrets-file": {
2171
- string: true,
2172
- describe: "filename of json file reading secrets"
2173
- },
2174
- "encrypted-secrets-file": {
2175
- string: true,
2176
- describe: "filename of json file for writing encrypted secrets",
2177
- default: "secrets.encrypted.json"
2178
- },
2179
- "aws-profile": commonCliOptions.awsProfile,
2180
- "aws-region": commonCliOptions.awsRegion,
2181
- "aws-key-alias": commonCliOptions.awsKeyAlias,
2182
- "aws-assume-role-arn": commonCliOptions.awsAssumeRoleArn,
2183
- "aws-assume-role-session-duration": commonCliOptions.awsAssumeRoleSessionDuration,
2184
- verbose: commonCliOptions.verbose,
2185
- yes: __spreadValues({}, commonCliOptions.yes)
2186
- };
2187
- var handler9 = async (argv) => {
2188
- const config = await getConfig();
2189
- const { info, error } = getLogger();
2190
- try {
2191
- const defaultRegion = config.aws.region || argv.awsRegion;
2192
- const { credentialsAndOrigin, regionAndOrigin } = await handleCredentialsAndRegion({
2193
- argv: __spreadProps(__spreadValues({}, argv), {
2194
- awsRegion: defaultRegion,
2195
- awsProfile: config.aws.profile || argv.awsProfile,
2196
- awsAssumeRoleArn: config.aws.assumeRoleArn || argv.awsAssumeRoleArn,
2197
- awsAssumeRoleSessionDuration: config.aws.assumeRoleSessionDuration || argv.awsAssumeRoleSessionDuration
2198
- }),
2199
- env: __spreadValues({}, process.env)
2200
- });
2201
- const { fileType, dotSecPlainText } = await getDotSecPlainText({
2202
- defaultConfig: {
2203
- config: {
2204
- aws: {
2205
- keyAlias: "alias/dotsec",
2206
- regions: [regionAndOrigin.value]
2207
- }
2208
- }
2209
- },
2210
- options: {
2211
- filename: argv.secretsFile
2212
- }
2213
- });
2214
- if (!dotSecPlainText.plaintext) {
2215
- throw new Error(`Expected 'plaintext' property, but got none`);
2216
- }
2217
- const dotSecEncrypted = await encryptPlainText({
2218
- dotSecPlainText,
2219
- credentials: credentialsAndOrigin.value,
2220
- region: regionAndOrigin.value,
2221
- keyAlias: argv.awsKeyAlias,
2222
- verbose: argv.verbose
2223
- });
2224
- const encryptedSecretsPath = path15.resolve(process.cwd(), path15.parse(argv.encryptedSecretsFile || `secrets.encrypted.json`).name + "." + fileType);
2225
- const converted = fileType === "yaml" || fileType === "yml" ? YAML3.stringify(dotSecEncrypted) : JSON.stringify(dotSecEncrypted, null, 2);
2226
- info(`target: ${strong(encryptedSecretsPath)}
2227
- `);
2228
- info(prettyCode(converted));
2229
- info(`
2230
- `);
2231
- const overwriteResponse = await promptOverwriteIfFileExists({
2232
- filePath: encryptedSecretsPath,
2233
- skip: argv.yes
2234
- });
2235
- if (overwriteResponse === void 0 || overwriteResponse.overwrite === true) {
2236
- fs13.writeFileSync(encryptedSecretsPath, converted);
2237
- }
2238
- } catch (e) {
2239
- error(e);
2240
- }
2241
- };
2242
-
2243
- // src/cli.ts
2244
- void yargs(hideBin(process.argv)).command(convert_default).command(defaultCommand_exports).command(plaintext_secrets_to_encrypted_secrets_exports).command(encrypted_secrets_to_plaintext_secrets_exports).command(encrypted_secrets_to_dot_env_exports).command(encrypted_secrets_to_dot_sec_exports).command(plaintext_secrets_to_dot_env_exports).command(plaintext_secrets_to_dot_sec_exports).command(dot_sec_to_dot_env_exports).command(offload_plaintext_secrets_exports).parse();
2245
- //# sourceMappingURL=cli.js.map