dotsec 4.0.0-beta.f6d5ebb.0 → 5.0.0-beta.2d72d7d

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.
@@ -1,1493 +0,0 @@
1
- import { Command, Option } from 'commander';
2
- import fs from 'fs';
3
- import path from 'node:path';
4
- import { bundleRequire } from 'bundle-require';
5
- import JoyCon from 'joycon';
6
- import path2 from 'path';
7
- import fs2, { stat } from 'node:fs/promises';
8
- import prompts from 'prompts';
9
- import chalk2 from 'chalk';
10
- import 'cli-table';
11
- import { expand } from 'dotenv-expand';
12
- import fs3 from 'node:fs';
13
- import { camelCase } from 'camel-case';
14
- import { spawn } from 'node:child_process';
15
- import Ajv from 'ajv';
16
- import yargsParser from 'yargs-parser';
17
-
18
- // src/cli/index.ts
19
-
20
- // src/constants.ts
21
- var DOTSEC_DEFAULT_CONFIG_FILE = "dotsec.config.ts";
22
- var DOTSEC_CONFIG_FILES = [DOTSEC_DEFAULT_CONFIG_FILE];
23
- var DOTSEC_DEFAULT_DOTSEC_FILENAME = ".sec";
24
- var DOTSEC_DEFAULT_DOTENV_FILENAME = ".env";
25
- var defaultConfig = {
26
- defaults: {
27
- // encryptionEngine: "pke",
28
- // plugins: {
29
- // pke: {},
30
- // },
31
- options: {
32
- showRedacted: false
33
- }
34
- }
35
- };
36
- function jsoncParse(data) {
37
- try {
38
- return new Function(`return ${data.trim()}`)();
39
- } catch {
40
- return {};
41
- }
42
- }
43
- var loadJson = async (filepath) => {
44
- try {
45
- return jsoncParse(await fs.promises.readFile(filepath, "utf8"));
46
- } catch (error) {
47
- if (error instanceof Error) {
48
- throw new Error(
49
- `Failed to parse ${path.relative(process.cwd(), filepath)}: ${error.message}`
50
- );
51
- } else {
52
- throw error;
53
- }
54
- }
55
- };
56
- var getMagicalConfig = async (filename) => {
57
- const cwd = process.cwd();
58
- const configJoycon = new JoyCon();
59
- const configPath = await configJoycon.resolve({
60
- files: filename ? [filename] : [...DOTSEC_CONFIG_FILES, "package.json"],
61
- cwd,
62
- stopDir: path2.parse(cwd).root,
63
- packageKey: "dotsec"
64
- });
65
- if (filename && configPath === null) {
66
- throw new Error(`Could not find config file ${filename}`);
67
- }
68
- if (configPath) {
69
- if (configPath.endsWith(".json")) {
70
- const rawData = await loadJson(configPath);
71
- let data;
72
- if (configPath.endsWith("package.json") && rawData.dotsec !== void 0) {
73
- data = rawData.dotsec;
74
- } else {
75
- data = rawData;
76
- }
77
- return {
78
- source: "json",
79
- contents: {
80
- ...defaultConfig,
81
- ...data,
82
- defaults: {
83
- ...data?.defaults,
84
- ...defaultConfig.defaults,
85
- options: {
86
- ...data?.defaults?.options,
87
- ...defaultConfig.defaults?.options
88
- },
89
- plugins: {
90
- ...data?.defaults?.plugins,
91
- ...defaultConfig.defaults?.plugins
92
- }
93
- },
94
- push: {
95
- ...data?.push
96
- }
97
- }
98
- };
99
- } else if (configPath.endsWith(".ts")) {
100
- const bundleRequireResult = await bundleRequire({
101
- filepath: configPath
102
- });
103
- const data = bundleRequireResult.mod.dotsec || bundleRequireResult.mod.default || bundleRequireResult.mod;
104
- return {
105
- source: "ts",
106
- contents: {
107
- ...defaultConfig,
108
- ...data,
109
- defaults: {
110
- ...data?.defaults,
111
- ...defaultConfig.defaults,
112
- plugins: {
113
- ...data?.defaults?.plugins,
114
- ...defaultConfig.defaults?.plugins
115
- },
116
- options: {
117
- ...data?.defaults?.options,
118
- ...defaultConfig.defaults?.options
119
- }
120
- },
121
- push: {
122
- ...data?.push
123
- }
124
- }
125
- };
126
- }
127
- }
128
- return { source: "defaultConfig", contents: defaultConfig };
129
- };
130
-
131
- // src/lib/loadDotsecPlugin.ts
132
- var loadDotsecPlugin = async (options) => {
133
- return import(options.name).then((imported) => {
134
- return imported.default;
135
- });
136
- };
137
- var addPluginOptions = (options, command, mandatory) => {
138
- if (options) {
139
- Object.values(options).map((option) => {
140
- let optionProps;
141
- if (Array.isArray(option)) {
142
- const [flags, description, defaultValue] = option;
143
- optionProps = {
144
- flags,
145
- description,
146
- defaultValue
147
- };
148
- } else {
149
- const { flags, description, defaultValue, choices, env, fn } = option;
150
- optionProps = {
151
- flags,
152
- description,
153
- defaultValue,
154
- choices,
155
- env,
156
- fn
157
- };
158
- }
159
- if (optionProps) {
160
- const newOption = new Option(
161
- optionProps.flags,
162
- optionProps.description
163
- );
164
- if (optionProps.fn) {
165
- newOption.argParser(optionProps.fn);
166
- }
167
- if (optionProps.defaultValue) {
168
- newOption.default(optionProps.defaultValue);
169
- }
170
- if (optionProps.env) {
171
- newOption.env(optionProps.env);
172
- }
173
- if (mandatory) {
174
- newOption.makeOptionMandatory(true);
175
- }
176
- if (optionProps.choices) {
177
- newOption.choices(optionProps.choices);
178
- }
179
- command.addOption(newOption);
180
- }
181
- });
182
- }
183
- };
184
- var readContentsFromFile = async (filePath) => {
185
- return await fs2.readFile(filePath, "utf-8");
186
- };
187
- var writeContentsToFile = async (filePath, contents) => {
188
- return await fs2.writeFile(filePath, contents, "utf-8");
189
- };
190
- var fileExists = async (source) => {
191
- try {
192
- await stat(source);
193
- return true;
194
- } catch {
195
- return false;
196
- }
197
- };
198
- var promptOverwriteIfFileExists = async ({
199
- filePath,
200
- skip
201
- }) => {
202
- let overwriteResponse;
203
- if (await fileExists(filePath) && skip !== true) {
204
- overwriteResponse = await prompts({
205
- type: "confirm",
206
- name: "overwrite",
207
- message: () => {
208
- return `Overwrite './${path.relative(process.cwd(), filePath)}' ?`;
209
- }
210
- });
211
- } else {
212
- overwriteResponse = void 0;
213
- }
214
- return overwriteResponse;
215
- };
216
-
217
- // src/lib/parse.ts
218
- var LINE = /^(#.*)|(\s?\r?\n)|(?:^|^)\s*(?:export\s+)?([\w.-]*)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?(\s*)(#.*)?(?:$|$)/gm;
219
- var parse = (src) => {
220
- const obj = {};
221
- const blocks = [];
222
- let lines = src.toString();
223
- lines = lines.replace(/\r\n?/gm, "\n");
224
- let match;
225
- while ((match = LINE.exec(lines)) != null) {
226
- const key = match[3];
227
- if (match?.[1]?.[0] === "#") {
228
- blocks.push({ type: "comment", raw: match[1] });
229
- } else if (match?.[2]) {
230
- blocks.push({ type: "whitespace", raw: match[2] });
231
- } else {
232
- let value = match[4] || "";
233
- value = value.trim();
234
- const maybeQuote = value[0];
235
- value = value.replace(/^(['"`])([\s\S]*)\1$/gm, "$2");
236
- if (maybeQuote === '"') {
237
- value = value.replace(/\\n/g, "\n");
238
- value = value.replace(/\\r/g, "\r");
239
- }
240
- obj[key] = value;
241
- blocks.push({
242
- type: "value",
243
- key,
244
- value,
245
- raw: value + (match[5] ? match[5] : "") + (match[6] ? match[6] : "")
246
- });
247
- }
248
- }
249
- return { blocks, obj };
250
- };
251
- if (import.meta.vitest) {
252
- const { it, expect } = import.meta.vitest;
253
- it("parse", () => {
254
- const input1 = "KEY=value";
255
- const input2 = 'KEY="value"';
256
- const input3 = "KEY='value'";
257
- const input4 = "KEY=value # this is a comment";
258
- expect(parse(input1)).toMatchInlineSnapshot(`
259
- {
260
- "blocks": [
261
- {
262
- "key": "KEY",
263
- "raw": "value",
264
- "type": "value",
265
- "value": "value",
266
- },
267
- ],
268
- "obj": {
269
- "KEY": "value",
270
- },
271
- }
272
- `);
273
- expect(parse(input2)).toMatchInlineSnapshot(`
274
- {
275
- "blocks": [
276
- {
277
- "key": "KEY",
278
- "raw": "value",
279
- "type": "value",
280
- "value": "value",
281
- },
282
- ],
283
- "obj": {
284
- "KEY": "value",
285
- },
286
- }
287
- `);
288
- expect(parse(input3)).toMatchInlineSnapshot(`
289
- {
290
- "blocks": [
291
- {
292
- "key": "KEY",
293
- "raw": "value",
294
- "type": "value",
295
- "value": "value",
296
- },
297
- ],
298
- "obj": {
299
- "KEY": "value",
300
- },
301
- }
302
- `);
303
- expect(parse(input4)).toMatchInlineSnapshot(`
304
- {
305
- "blocks": [
306
- {
307
- "key": "KEY",
308
- "raw": "value# this is a comment",
309
- "type": "value",
310
- "value": "value",
311
- },
312
- ],
313
- "obj": {
314
- "KEY": "value",
315
- },
316
- }
317
- `);
318
- });
319
- }
320
- var strong = (str) => chalk2.yellow.bold(str);
321
-
322
- // src/types/colors.ts
323
- var backgroundColors = [
324
- "black",
325
- "red",
326
- "green",
327
- "yellow",
328
- "blue",
329
- "magenta",
330
- "cyan",
331
- "white",
332
- "black-bright",
333
- "gray",
334
- "grey",
335
- "red-bright",
336
- "green-bright",
337
- "yellow-bright",
338
- "blue-bright",
339
- "magenta-bright",
340
- "cyan-bright",
341
- "white-bright"
342
- ];
343
-
344
- // src/cli/options/sharedOptions.ts
345
- var envFileOption = {
346
- option: [
347
- "--env-file <envFile>",
348
- `Path to .env file. If not provided, will look for value in 'ENV_FILE' environment variable. If not provided, will look for '${DOTSEC_DEFAULT_DOTENV_FILENAME}' file in current directory.`,
349
- DOTSEC_DEFAULT_DOTENV_FILENAME
350
- ],
351
- env: "ENV_FILE"
352
- };
353
- var secFileOption = {
354
- option: [
355
- "--sec-file, <secFile>",
356
- `Path to .sec file. If not provided, will look for value in 'SEC_FILE' environment variable. If not provided, will look for '${DOTSEC_DEFAULT_DOTSEC_FILENAME}' file in current directory.`,
357
- DOTSEC_DEFAULT_DOTSEC_FILENAME
358
- ],
359
- env: "SEC_FILE"
360
- };
361
- var usingOption = {
362
- flags: "--using <using>",
363
- description: "Wether to use a dot env file or a dot sec file",
364
- choices: ["env", "sec"],
365
- env: "DOTSEC_USING"
366
- };
367
- var usingNoEncryptionEngineOption = {
368
- flags: "--using <using>",
369
- description: "Wether to use a dot env file or a dot sec file",
370
- choices: ["env"],
371
- env: "DOTSEC_USING"
372
- };
373
- var showOutputPrefixOption = {
374
- flags: "--show-output-prefix",
375
- description: "Show output prefix",
376
- env: "DOTSEC_SHOW_OUTPUT_PREFIX"
377
- };
378
- var outputPrefixOption = {
379
- flags: "--output-prefix <outputPrefix>",
380
- description: "Output prefix",
381
- env: "DOTSEC_OUTPUT_PREFIX"
382
- };
383
- var outputBackgroundColorOption = {
384
- flags: "--output-background-color <outputBackgroundColor>",
385
- description: "Background color of the output.",
386
- env: "DOTSEC_OUTPUT_BACKGROUND_COLOR",
387
- choices: [...backgroundColors, true]
388
- };
389
- var yesOption = {
390
- option: ["--yes", "Skip confirmation prompts"]
391
- };
392
- var configFileOption = {
393
- option: ["-c, --config-file, --configFile <configFile>", "Config file"],
394
- env: "DOTSEC_CONFIG_FILE"
395
- };
396
- var pluginOption = {
397
- option: ["--plugin <plugin>", "Comma-separated list of plugins to use"],
398
- env: "DOTSEC_PLUGIN"
399
- };
400
- var engineOption = {
401
- option: ["--engine <engine>", "Encryption engine to use"],
402
- env: "DOTSEC_ENGINE"
403
- };
404
- var createManifestOption = {
405
- option: [
406
- "--create-manifest",
407
- "Create a markdown manifest file. See the --manifest-file option for more information."
408
- ],
409
- env: "CREATE_MANIFEST"
410
- };
411
- var manifestFilePrefixOption = {
412
- option: [
413
- "--manifest-file-prefix <manifestFilePrefix>",
414
- "Mmanifest file prefix"
415
- ],
416
- env: "ENCRYPTION_MANIFEST_FILE"
417
- };
418
-
419
- // src/cli/options/decrypt.ts
420
- var decryptCommandDefaults = {
421
- decrypt: {
422
- options: {
423
- configFile: configFileOption,
424
- envFile: envFileOption,
425
- secFile: secFileOption,
426
- createManifest: createManifestOption,
427
- manifestFilePrefix: manifestFilePrefixOption,
428
- yes: yesOption
429
- },
430
- description: "Decrypt a sec file",
431
- helpText: `Examples:
432
-
433
-
434
- Decrypt .sec file to .env file
435
-
436
- $ npx dotsec decrypt
437
-
438
-
439
- Specify a different .sec file
440
-
441
- $ npx dotsec decrypt --sec-file .sec.dev
442
- $ SEC_FILE=.sec.dev npx dotsec decrypt
443
-
444
- Specify a different .env file
445
-
446
- $ npx dotsec decrypt --env-file .env.dev
447
- $ ENV_FILE=.env.dev npx dotsec decrypt
448
-
449
- Write a manifest markdown file
450
-
451
- $ npx dotsec decrypt --create-manifest
452
- $ CREATE_MANIFEST=true npx dotsec decrypt
453
-
454
- Specify a different manifest file
455
-
456
- $ npx dotsec decrypt --manifest-file .manifest.dev
457
- $ MANIFEST_FILE=decryption-manifest.md npx dotsec decrypt
458
- `
459
- }
460
- };
461
- var decrypt_default = decryptCommandDefaults;
462
-
463
- // src/cli/options/dotsec.ts
464
- var dotsecCommandDefaults = {
465
- dotsec: {
466
- options: {
467
- configFile: configFileOption,
468
- plugin: pluginOption
469
- }
470
- }
471
- };
472
- var dotsec_default = dotsecCommandDefaults;
473
-
474
- // src/cli/options/encrypt.ts
475
- var encryptCommandDefaults = {
476
- encrypt: {
477
- options: {
478
- configFile: configFileOption,
479
- envFile: envFileOption,
480
- secFile: secFileOption,
481
- createManifest: createManifestOption,
482
- manifestFile: manifestFilePrefixOption,
483
- yes: yesOption
484
- },
485
- description: "Encrypt an env file",
486
- helpText: `Examples:
487
-
488
-
489
- Encrypt .env file to .sec file
490
-
491
- $ npx dotsec encrypt
492
-
493
-
494
- Specify a different .env file
495
-
496
- $ npx dotsec encrypt --env-file .env.dev
497
- $ ENV_FILE=.env.dev npx dotsec encrypt
498
-
499
-
500
- Specify a different .sec file
501
-
502
- $ npx dotsec encrypt --sec-file .sec.dev
503
- $ SEC_FILE=.sec.dev npx dotsec encrypt
504
-
505
-
506
- Write a manifest markdown file
507
-
508
- $ npx dotsec encrypt --create-manifest
509
- $ CREATE_MANIFEST=true npx dotsec encrypt
510
-
511
-
512
- Specify a different manifest file
513
-
514
- $ npx dotsec encrypt --manifest-file manifest.dev
515
- $ MANIFEST_FILE=encryption-manifest.md npx dotsec encrypt
516
- `
517
- }
518
- };
519
- var encrypt_default = encryptCommandDefaults;
520
-
521
- // src/cli/options/init.ts
522
- var initCommandDefaults = {
523
- init: {
524
- options: {
525
- configFile: configFileOption,
526
- yes: yesOption
527
- },
528
- description: "Initialize a dotsec project by creating a dotsec.config.ts file.",
529
- helpText: `Examples:
530
-
531
- Create a dotsec.config.ts file in the current directory
532
-
533
- $ npx dotsec init
534
-
535
-
536
- Overwrite an existing dotsec.config.ts file in the current directory
537
-
538
- $ npx dotsec init --yes
539
-
540
-
541
- Create a dotsec config file in the current directory with a specific config file name
542
-
543
- By specifying the --config-file option, you can create a dotsec config file with a specific name.
544
-
545
- $ npx dotsec init --config-file dotsec.config.ts
546
-
547
- $ DOTSEC_CONFIG_FILE=my.config.ts npx dotsec init
548
- `
549
- }
550
- };
551
- var init_default = initCommandDefaults;
552
-
553
- // src/cli/options/push.ts
554
- var pushCommandDefaults = {
555
- push: {
556
- options: {
557
- configFile: configFileOption,
558
- envFile: envFileOption,
559
- secFile: secFileOption,
560
- yes: yesOption
561
- },
562
- requiredOptions: {
563
- using: usingOption
564
- },
565
- description: "Push variables from env or sec file to a remote",
566
- helpText: `Examples:
567
-
568
- Push variables from .env file to remote
569
-
570
- $ npx dotsec push --using env
571
- $ DOTSEC_USING=env npx dotsec push
572
-
573
-
574
- Push variables from .sec file to remote
575
-
576
- $ npx dotsec push --using sec
577
- $ DOTSEC_USING=sec npx dotsec push
578
- `
579
- }
580
- };
581
- var push_default = pushCommandDefaults;
582
-
583
- // src/cli/options/run.ts
584
- var runCommandDefaults = {
585
- runEnvOnly: {
586
- usage: "--using env [commandArgs...]",
587
- options: {
588
- configFile: configFileOption,
589
- envFile: envFileOption,
590
- yes: yesOption,
591
- engine: engineOption,
592
- outputBackgroundColor: outputBackgroundColorOption,
593
- showOutputPrefix: showOutputPrefixOption,
594
- outputPrefix: outputPrefixOption
595
- },
596
- requiredOptions: {
597
- using: usingNoEncryptionEngineOption
598
- },
599
- description: "Run a command in a separate process and populate env with contents of a dotenv file.",
600
- helpText: `Examples:
601
-
602
- Run a command with a .env file
603
-
604
- $ npx dotsec run --using env node -e "console.log(process.env)"
605
-
606
-
607
- Run a command with a specific .env file
608
-
609
- $ npx dotsec run --using env --env-file .env node -e "console.log(process.env)"
610
-
611
-
612
- Run a command with a specific ENV_FILE variable
613
-
614
- $ ENV_FILE=.env.dev npx dotsec run --using env node -e "console.log(process.env)"
615
-
616
-
617
- You can also specify 'using' as an environment variable
618
-
619
- $ DOTSEC_USING=env npx dotsec run node -e "console.log(process.env)"
620
- `
621
- },
622
- run: {
623
- options: {
624
- configFile: configFileOption,
625
- envFile: envFileOption,
626
- secFile: secFileOption,
627
- yes: yesOption,
628
- outputBackgroundColor: outputBackgroundColorOption,
629
- hideOutputPrefix: showOutputPrefixOption,
630
- outputPrefix: outputPrefixOption
631
- },
632
- requiredOptions: {
633
- using: usingOption
634
- },
635
- usage: "[--using env] [--using sec] [commandArgs...]",
636
- description: `Run a command in a separate process and populate env with either
637
- - contents of a dotenv file
638
- - decrypted values of a dotsec file.
639
-
640
- The --withEnv option will take precedence over the --withSec option. If neither are specified, the --withEnv option will be used by default.`,
641
- helpText: `${"Examples:"}
642
-
643
- ${"Run a command with a .env file"}
644
-
645
- $ dotsec run echo "hello world"
646
-
647
-
648
- ${"Run a command with a specific .env file"}
649
-
650
- $ dotsec run --with-env --env-file .env.dev echo "hello world"
651
-
652
-
653
- ${"Run a command with a .sec file"}
654
-
655
- $ dotsec run --with-sec echo "hello world"
656
-
657
-
658
- ${"Run a command with a specific .sec file"}
659
-
660
- $ dotsec run --with-sec --sec-file .sec.dev echo "hello world"
661
- `
662
- }
663
- // push: {
664
- // options: {
665
- // ...dotsecCommandDefaults.dotsec.options,
666
- // withEnv: withEnvOption,
667
- // withSec: withSecOption,
668
- // envFile: envFileOption,
669
- // secFile: secFileOption,
670
- // yes: yesOption,
671
- // },
672
- // requiredOptions: {
673
- // ...dotsecCommandDefaults.dotsec.requiredOptions,
674
- // },
675
- // },
676
- };
677
- var run_default = runCommandDefaults;
678
-
679
- // src/cli/options/index.ts
680
- var commandOptions = {
681
- ...dotsec_default,
682
- ...init_default,
683
- ...encrypt_default,
684
- ...decrypt_default,
685
- ...run_default,
686
- ...push_default
687
- };
688
- var expandCommandOption = (commandOption) => {
689
- if (Array.isArray(commandOption)) {
690
- const [flags, description, defaultValue] = commandOption;
691
- const optionProps = {
692
- flags,
693
- description,
694
- defaultValue
695
- };
696
- return optionProps;
697
- } else {
698
- if ("option" in commandOption) {
699
- const [flags, description, defaultValue] = commandOption.option;
700
- const optionProps = {
701
- flags,
702
- description,
703
- defaultValue,
704
- env: commandOption.env
705
- };
706
- return optionProps;
707
- }
708
- return commandOption;
709
- }
710
- };
711
- var createOption = (commandOption, options) => {
712
- const defaultOptionValueFromConfig = options?.dotsecConfig?.defaults?.options?.[options?.optionKey];
713
- const optionProps = expandCommandOption(commandOption);
714
- const newOption = new Option(optionProps.flags, optionProps.description);
715
- if (optionProps.fn) {
716
- newOption.argParser(optionProps.fn);
717
- }
718
- if (optionProps.defaultValue) {
719
- newOption.default(defaultOptionValueFromConfig || optionProps.defaultValue);
720
- }
721
- if (optionProps.env) {
722
- newOption.env(optionProps.env);
723
- }
724
- if (options.required) {
725
- newOption.makeOptionMandatory(true);
726
- }
727
- if (optionProps.choices) {
728
- newOption.choices(optionProps.choices);
729
- }
730
- return newOption;
731
- };
732
- var setProgramOptions = (params) => {
733
- const { program: program2, commandName, dotsecConfig } = params;
734
- const programOptions = commandOptions[commandName || program2.name()];
735
- if (programOptions) {
736
- const { options, requiredOptions, description, usage, helpText } = programOptions;
737
- if (options) {
738
- Object.keys(options).forEach((optionKey) => {
739
- const commandOption = options[optionKey];
740
- const newOption = createOption(commandOption, {
741
- dotsecConfig,
742
- optionKey
743
- });
744
- program2.addOption(newOption);
745
- });
746
- }
747
- if (requiredOptions) {
748
- Object.keys(requiredOptions).forEach((requiredOptionKey) => {
749
- const requiredOption = requiredOptions[requiredOptionKey];
750
- const newOption = createOption(requiredOption, {
751
- required: true,
752
- dotsecConfig,
753
- optionKey: requiredOptionKey
754
- });
755
- program2.addOption(newOption);
756
- });
757
- }
758
- if (description) {
759
- program2.description(description);
760
- }
761
- if (usage) {
762
- program2.usage(usage);
763
- }
764
- if (helpText) {
765
- program2.description(helpText);
766
- }
767
- }
768
- };
769
-
770
- // src/cli/commands/decrypt.ts
771
- var addEncryptProgram = async (program2, options) => {
772
- const { dotsecConfig, decryptHandlers } = options;
773
- const subProgram = program2.enablePositionalOptions().passThroughOptions().command("decrypt").action(async (_options, command) => {
774
- try {
775
- const {
776
- // verbose,
777
- envFile,
778
- secFile,
779
- engine,
780
- createManifest,
781
- manifestFile,
782
- yes
783
- } = command.optsWithGlobals();
784
- const encryptionEngine = engine || dotsecConfig?.defaults?.encryptionEngine;
785
- const pluginCliDecrypt = (decryptHandlers || []).find((handler) => {
786
- return handler.triggerOptionValue === encryptionEngine;
787
- });
788
- if (!pluginCliDecrypt) {
789
- throw new Error(
790
- `No decryption plugin found, available decryption engine(s): ${options.decryptHandlers.map((e) => `--${e.triggerOptionValue}`).join(", ")}`
791
- );
792
- }
793
- console.log(
794
- "Decrypting with",
795
- strong(
796
- pluginCliDecrypt.encryptionEngineName || pluginCliDecrypt.triggerOptionValue
797
- ),
798
- "engine"
799
- );
800
- const allOptionKeys = [
801
- ...Object.keys(pluginCliDecrypt.options || {}),
802
- ...Object.keys(pluginCliDecrypt.requiredOptions || {})
803
- ];
804
- const allOptionsValues = Object.fromEntries(
805
- allOptionKeys.map((key) => {
806
- return [key, _options[key]];
807
- })
808
- );
809
- const dotsecString = await readContentsFromFile(secFile);
810
- const plaintext = await pluginCliDecrypt.handler({
811
- ciphertext: dotsecString,
812
- ...allOptionsValues
813
- });
814
- const dotenvOverwriteResponse = await promptOverwriteIfFileExists({
815
- filePath: envFile,
816
- skip: yes
817
- });
818
- if (dotenvOverwriteResponse === void 0 || dotenvOverwriteResponse.overwrite === true) {
819
- await writeContentsToFile(envFile, plaintext);
820
- console.log(
821
- `Wrote plaintext contents of ${strong(secFile)} file to ${strong(
822
- envFile
823
- )}`
824
- );
825
- }
826
- if (createManifest || dotsecConfig?.defaults?.options?.createManifest) {
827
- const dotenvVars = parse(plaintext).obj;
828
- const markdownManifest = `# Dotsec decryption manifest
829
-
830
- ## Overview
831
-
832
- - plaintext source: ${envFile}
833
- - ciphertext target: ${secFile}
834
- - created: ${( new Date()).toUTCString()}
835
- - Decryption engine: ${pluginCliDecrypt.encryptionEngineName || pluginCliDecrypt.triggerOptionValue}
836
- - Decryption engine options: ${JSON.stringify(allOptionsValues)}
837
-
838
- ## Variables
839
-
840
- | Key |
841
- | --- |
842
- ${Object.keys(dotenvVars).map((key) => {
843
- return `| \`${key} \`| `;
844
- }).join("\n")}
845
- `;
846
- const manifestTargetFile = manifestFile || `${envFile}.decryption-manifest.md`;
847
- await writeContentsToFile(manifestTargetFile, markdownManifest);
848
- console.log(
849
- `Wrote manifest of ${strong(envFile)} file to ${strong(
850
- manifestTargetFile
851
- )}`
852
- );
853
- }
854
- } catch (e) {
855
- console.error(strong(e.message));
856
- command.help();
857
- }
858
- });
859
- options.decryptHandlers.map((decryption) => {
860
- const { options: options2, requiredOptions } = decryption;
861
- addPluginOptions(options2, subProgram);
862
- addPluginOptions(requiredOptions, subProgram, true);
863
- });
864
- const engines = options.decryptHandlers.map((e) => e.triggerOptionValue);
865
- subProgram.option(
866
- "--engine <engine>",
867
- `Encryption engine${engines.length > 0 ? "s" : ""} to use: ${engines.length === 1 ? engines[0] : engines.join(", ")}`,
868
- engines.length === 1 ? engines[0] : void 0
869
- );
870
- setProgramOptions({ program: subProgram, dotsecConfig });
871
- return subProgram;
872
- };
873
- var decrypt_default2 = addEncryptProgram;
874
-
875
- // src/cli/commands/encrypt.ts
876
- var addEncryptProgram2 = async (program2, options) => {
877
- const { encryptHandlers, dotsecConfig } = options;
878
- const subProgram = program2.enablePositionalOptions().passThroughOptions().command("encrypt").action(async (_options, command) => {
879
- try {
880
- const {
881
- // verbose,
882
- envFile,
883
- secFile,
884
- engine,
885
- createManifest,
886
- manifestFile,
887
- yes
888
- } = command.optsWithGlobals();
889
- const encryptionEngine = engine || dotsecConfig?.defaults?.encryptionEngine;
890
- const pluginCliEncrypt = (encryptHandlers || []).find((handler) => {
891
- return handler.triggerOptionValue === encryptionEngine;
892
- });
893
- if (!pluginCliEncrypt) {
894
- throw new Error(
895
- `No encryption plugin found, available encryption engine(s): ${options.encryptHandlers.map((e) => e.triggerOptionValue).join(", ")}`
896
- );
897
- }
898
- const allOptionKeys = [
899
- ...Object.keys(pluginCliEncrypt.options || {}),
900
- ...Object.keys(pluginCliEncrypt.requiredOptions || {})
901
- ];
902
- const allOptionsValues = Object.fromEntries(
903
- allOptionKeys.map((key) => {
904
- return [key, _options[key]];
905
- })
906
- );
907
- const dotenvString = await readContentsFromFile(envFile);
908
- let dotsecString;
909
- try {
910
- dotsecString = await readContentsFromFile(secFile);
911
- } catch (e) {
912
- }
913
- const cipherText = await pluginCliEncrypt.handler({
914
- plaintext: dotenvString,
915
- ciphertext: dotsecString,
916
- ...allOptionsValues
917
- });
918
- const dotsecOverwriteResponse = await promptOverwriteIfFileExists({
919
- filePath: secFile,
920
- skip: yes
921
- });
922
- if (dotsecOverwriteResponse === void 0 || dotsecOverwriteResponse.overwrite === true) {
923
- await writeContentsToFile(secFile, cipherText);
924
- console.log(
925
- `Wrote encrypted contents of ${strong(envFile)} file to ${strong(
926
- secFile
927
- )}`
928
- );
929
- if (createManifest || dotsecConfig?.defaults?.options?.createManifest) {
930
- const dotenvVars = parse(dotenvString).obj;
931
- const markdownManifest = `# Dotsec encryption manifest
932
-
933
- ## Overview
934
-
935
- - plaintext source: ${envFile}
936
- - ciphertext target: ${secFile}
937
- - created: ${( new Date()).toUTCString()}
938
- - encryption engine: ${pluginCliEncrypt.encryptionEngineName || pluginCliEncrypt.triggerOptionValue}
939
- - encryption engine options: ${JSON.stringify(allOptionsValues)}
940
-
941
- ## Variables
942
-
943
- | Key |
944
- | --- |
945
- ${Object.keys(dotenvVars).map((key) => {
946
- return `| \`${key} \`| `;
947
- }).join("\n")}
948
- `;
949
- const manifestTargetFile = manifestFile || `${secFile}.encryption-manifest.md`;
950
- await writeContentsToFile(manifestTargetFile, markdownManifest);
951
- console.log(
952
- `Wrote manifest of ${strong(envFile)} file to ${strong(
953
- manifestTargetFile
954
- )}`
955
- );
956
- }
957
- }
958
- } catch (e) {
959
- console.error(strong(e.message));
960
- command.help();
961
- }
962
- });
963
- options.encryptHandlers.map((encryptionHandler) => {
964
- const { options: options2, requiredOptions } = encryptionHandler;
965
- addPluginOptions(options2, subProgram);
966
- addPluginOptions(requiredOptions, subProgram, true);
967
- });
968
- const engines = options.encryptHandlers.map((e) => e.triggerOptionValue);
969
- const encryptionEngineNames = options.encryptHandlers.map(
970
- (e) => e.encryptionEngineName
971
- );
972
- subProgram.option(
973
- "--engine <engine>",
974
- `Encryption engine${engines.length > 0 ? "s" : ""}: ${engines.length === 1 ? engines[0] : engines.join(", ")}`,
975
- engines.length === 1 ? engines[0] : void 0
976
- );
977
- setProgramOptions({ program: subProgram, dotsecConfig });
978
- subProgram.description(
979
- `Encrypt .env file using ${encryptionEngineNames.join(", ")}`
980
- );
981
- return subProgram;
982
- };
983
- var encrypt_default2 = addEncryptProgram2;
984
- var addInitProgram = async (program2, options) => {
985
- const { dotsecConfig } = options;
986
- const subProgram = program2.enablePositionalOptions().passThroughOptions().command("init").action(async (_options, command) => {
987
- const { configFile = "dotsec.config.ts", yes } = command.optsWithGlobals();
988
- try {
989
- const configTemplate = await readContentsFromFile(
990
- path.resolve(__dirname, "../../src/templates/dotsec.config.ts")
991
- );
992
- const dotsecConfigOverwriteResponse = await promptOverwriteIfFileExists(
993
- {
994
- filePath: configFile,
995
- skip: yes
996
- }
997
- );
998
- if (dotsecConfigOverwriteResponse === void 0 || dotsecConfigOverwriteResponse.overwrite === true) {
999
- await writeContentsToFile(configFile, configTemplate);
1000
- console.log(`Wrote config file to ${strong(configFile)}`);
1001
- }
1002
- } catch (e) {
1003
- command.error(e);
1004
- }
1005
- });
1006
- setProgramOptions({ program: subProgram, dotsecConfig });
1007
- return subProgram;
1008
- };
1009
- var init_default2 = addInitProgram;
1010
- var addPushProgram = async (program2, options) => {
1011
- const { dotsecConfig, handlers } = options;
1012
- const subProgram = program2.enablePositionalOptions().passThroughOptions().command("push").action(async (_options, command) => {
1013
- try {
1014
- const {
1015
- // verbose,
1016
- using,
1017
- envFile,
1018
- secFile,
1019
- engine,
1020
- yes
1021
- } = command.optsWithGlobals();
1022
- const encryptionEngine = engine || dotsecConfig?.defaults?.encryptionEngine;
1023
- const pluginCliDecrypt = (handlers || []).find((handler) => {
1024
- return handler.decrypt?.triggerOptionValue === encryptionEngine;
1025
- })?.decrypt;
1026
- const pluginCliPush = (handlers || []).find((handler) => {
1027
- return handler.push?.triggerOptionValue === encryptionEngine;
1028
- })?.push;
1029
- if (!pluginCliPush) {
1030
- throw new Error("No push plugin found!");
1031
- }
1032
- const allOptionKeys = [
1033
- ...Object.keys(pluginCliDecrypt?.options || {}),
1034
- ...Object.keys(pluginCliDecrypt?.requiredOptions || {}),
1035
- ...Object.keys(pluginCliPush?.options || {}),
1036
- ...Object.keys(pluginCliPush?.requiredOptions || {})
1037
- ];
1038
- const allOptionsValues = Object.fromEntries(
1039
- allOptionKeys.map((key) => {
1040
- return [key, _options[key]];
1041
- })
1042
- );
1043
- let envContents;
1044
- if (using === "env") {
1045
- if (!envFile) {
1046
- throw new Error("No dotenv file specified in --env-file option");
1047
- }
1048
- envContents = fs3.readFileSync(envFile, "utf8");
1049
- } else {
1050
- if (!secFile) {
1051
- throw new Error("No dotsec file specified in --sec-file option");
1052
- }
1053
- if (!pluginCliDecrypt) {
1054
- throw new Error(
1055
- `No decryption plugin found, available decryption engine(s): ${handlers.map((e) => `--${e.decrypt?.triggerOptionValue}`).join(", ")}`
1056
- );
1057
- }
1058
- const dotSecContents = fs3.readFileSync(secFile, "utf8");
1059
- envContents = await pluginCliDecrypt.handler({
1060
- ciphertext: dotSecContents,
1061
- ...allOptionsValues
1062
- });
1063
- }
1064
- if (envContents) {
1065
- const dotenvVars = parse(envContents).obj;
1066
- const expandedEnvVars = expand({
1067
- ignoreProcessEnv: true,
1068
- parsed: {
1069
- // add standard env variables
1070
- ...process.env,
1071
- // add custom env variables, either from .env or .sec, (or empty object if none)
1072
- ...dotenvVars
1073
- }
1074
- });
1075
- if (expandedEnvVars.parsed) {
1076
- await pluginCliPush.handler({
1077
- push: expandedEnvVars.parsed,
1078
- yes,
1079
- ...allOptionsValues
1080
- });
1081
- }
1082
- } else {
1083
- throw new Error("No .env or .sec file provided");
1084
- }
1085
- } catch (e) {
1086
- console.error(e);
1087
- process.exit(1);
1088
- }
1089
- });
1090
- setProgramOptions({ program: subProgram, dotsecConfig });
1091
- const engines = options.handlers.map(
1092
- ({ decrypt }) => decrypt.triggerOptionValue
1093
- );
1094
- subProgram.option(
1095
- "--engine <engine>",
1096
- `Encryption engine${engines.length > 0 ? "s" : ""} to use: ${engines.length === 1 ? engines[0] : engines.join(", ")}`,
1097
- engines.length === 1 ? engines[0] : void 0
1098
- );
1099
- const allOptions = {};
1100
- options.handlers.forEach((handlers2) => {
1101
- Object.keys(handlers2).map((handlerName) => {
1102
- const { options: cliOptions, requiredOptions } = handlers2[handlerName];
1103
- Object.keys(cliOptions || {}).forEach((key) => {
1104
- allOptions[key] = Array.isArray(cliOptions[key]) ? cliOptions[key] : { ...allOptions[key], ...cliOptions[key] };
1105
- });
1106
- Object.keys(requiredOptions || {}).forEach((key) => {
1107
- allOptions[key] = Array.isArray(requiredOptions[key]) ? requiredOptions[key] : {
1108
- ...allOptions[key],
1109
- ...requiredOptions[key],
1110
- required: true
1111
- };
1112
- });
1113
- });
1114
- });
1115
- const usage = [];
1116
- const descriptions = [];
1117
- handlers.forEach((handler) => {
1118
- if (handler.push?.description) {
1119
- descriptions.push(handler.push.description);
1120
- }
1121
- if (handler.push?.usage) {
1122
- usage.push(handler.push.usage);
1123
- }
1124
- });
1125
- if (descriptions.length > 0) {
1126
- subProgram.description(descriptions.join("\n"));
1127
- }
1128
- if (usage.length > 0) {
1129
- subProgram.usage(usage.join("\n"));
1130
- }
1131
- addPluginOptions(
1132
- Object.fromEntries(
1133
- Object.entries(allOptions).filter(
1134
- ([_key, value]) => value.required !== true
1135
- )
1136
- ),
1137
- subProgram
1138
- );
1139
- addPluginOptions(
1140
- Object.fromEntries(
1141
- Object.entries(allOptions).filter(
1142
- ([_key, value]) => value.required === true
1143
- )
1144
- ),
1145
- subProgram,
1146
- true
1147
- );
1148
- return subProgram;
1149
- };
1150
- var push_default2 = addPushProgram;
1151
- var addRunProgam = (program2, options) => {
1152
- const { dotsecConfig, decryptHandlers } = options || {};
1153
- const hasDecryptEngine = decryptHandlers !== void 0 && decryptHandlers.length > 0;
1154
- const subProgram = program2.command("run <command...>").allowUnknownOption(true).enablePositionalOptions().passThroughOptions().showHelpAfterError(true).action(
1155
- async (commands, _options, command) => {
1156
- try {
1157
- const {
1158
- envFile,
1159
- using,
1160
- secFile,
1161
- engine,
1162
- outputBackgroundColor,
1163
- showOutputPrefix,
1164
- outputPrefix
1165
- } = command.optsWithGlobals();
1166
- let envContents;
1167
- if (using === "env" || hasDecryptEngine === false) {
1168
- if (!envFile) {
1169
- throw new Error("No dotenv file specified in --env-file option");
1170
- }
1171
- envContents = fs3.readFileSync(envFile, "utf8");
1172
- } else if (using === "sec") {
1173
- if (!secFile) {
1174
- throw new Error("No dotsec file specified in --sec-file option");
1175
- }
1176
- const encryptionEngine = engine || dotsecConfig?.defaults?.encryptionEngine;
1177
- const pluginCliDecrypt = (decryptHandlers || []).find((handler) => {
1178
- return handler.triggerOptionValue === encryptionEngine;
1179
- });
1180
- if (!pluginCliDecrypt) {
1181
- throw new Error(
1182
- `No decryption plugin found, available decryption engine(s): ${(decryptHandlers || []).map((e) => `--${e.triggerOptionValue}`).join(", ")}`
1183
- );
1184
- }
1185
- const allOptionKeys = [
1186
- ...Object.keys(pluginCliDecrypt.options || {}),
1187
- ...Object.keys(pluginCliDecrypt.requiredOptions || {})
1188
- ];
1189
- const allOptionsValues = Object.fromEntries(
1190
- allOptionKeys.map((key) => {
1191
- return [key, _options[key]];
1192
- })
1193
- );
1194
- try {
1195
- const dotSecContents = fs3.readFileSync(secFile, "utf8");
1196
- envContents = await pluginCliDecrypt.handler({
1197
- ciphertext: dotSecContents,
1198
- ...allOptionsValues
1199
- });
1200
- } catch (e) {
1201
- console.error("Something bad happened while decrypting.");
1202
- console.error(`File: ${secFile}`);
1203
- throw e;
1204
- }
1205
- }
1206
- if (envContents) {
1207
- const dotenvVars = parse(envContents).obj;
1208
- const expandedEnvVars = expand({
1209
- ignoreProcessEnv: true,
1210
- parsed: {
1211
- // add standard env variables
1212
- ...process.env,
1213
- // add custom env variables, either from .env or .sec, (or empty object if none)
1214
- ...dotenvVars
1215
- }
1216
- });
1217
- const [userCommand, ...userCommandArgs] = commands;
1218
- const waiter = await new Promise((resolve) => {
1219
- const cprocess = spawn(userCommand, [...userCommandArgs], {
1220
- stdio: "pipe",
1221
- shell: false,
1222
- env: {
1223
- ...expandedEnvVars.parsed,
1224
- ...process.env,
1225
- __DOTSEC_ENV__: JSON.stringify(Object.keys(dotenvVars))
1226
- }
1227
- });
1228
- const expandedEnvVarsWithoutEnv = expand({
1229
- ignoreProcessEnv: true,
1230
- parsed: {
1231
- // add standard env variables
1232
- // add custom env variables, either from .env or .sec, (or empty object if none)
1233
- ...dotenvVars
1234
- }
1235
- });
1236
- cprocess.stdout.setEncoding("utf8");
1237
- let backgroundColor = outputBackgroundColor || dotsecConfig.defaults?.options?.outputBackgroundColor;
1238
- if (typeof backgroundColor === "boolean" && backgroundColor === true) {
1239
- backgroundColor = "red-bright";
1240
- }
1241
- let addBackgroundColor = (str) => str;
1242
- if (backgroundColor) {
1243
- if (!backgroundColors.includes(backgroundColor)) {
1244
- throw new Error(
1245
- `Invalid background color: ${backgroundColor}`
1246
- );
1247
- }
1248
- const backgroundColorFnName = camelCase(
1249
- `bg-${backgroundColor}`
1250
- );
1251
- if (chalk2[backgroundColorFnName]) {
1252
- addBackgroundColor = chalk2[backgroundColorFnName];
1253
- } else {
1254
- console.warn(
1255
- `Invalid background color: ${backgroundColorFnName}, using default: red`
1256
- );
1257
- addBackgroundColor = chalk2.bgRedBright;
1258
- }
1259
- }
1260
- const prefix = showOutputPrefix || dotsecConfig?.defaults?.options?.showOutputPrefix ? `${dotsecConfig?.defaults?.options?.outputPrefix || outputPrefix || "(dotsec) "}` : "";
1261
- let lineBuffer = "";
1262
- cprocess.stdout.on("data", function(data) {
1263
- lineBuffer += data.toString();
1264
- const lines = lineBuffer.split("\n");
1265
- for (let i = 0; i < lines.length - 1; i++) {
1266
- const line = lines[i];
1267
- const redactedLines = Object.entries(
1268
- expandedEnvVarsWithoutEnv.parsed || {}
1269
- ).sort(([, a], [, b]) => {
1270
- if (a.length > b.length) {
1271
- return -1;
1272
- } else if (a.length < b.length) {
1273
- return 1;
1274
- } else {
1275
- return 0;
1276
- }
1277
- }).reduce((acc, [key, value]) => {
1278
- if (dotsecConfig?.redaction?.show?.includes(key)) {
1279
- return acc;
1280
- } else {
1281
- const redactedValue = value.replace(/./g, "*");
1282
- return acc.replace(value, redactedValue);
1283
- }
1284
- }, line);
1285
- console.log(prefix + addBackgroundColor(redactedLines));
1286
- }
1287
- lineBuffer = lines[lines.length - 1];
1288
- });
1289
- cprocess.stdout.on("end", function() {
1290
- console.log(prefix + addBackgroundColor(lineBuffer));
1291
- });
1292
- cprocess.stderr.setEncoding("utf8");
1293
- cprocess.stderr.on("data", function(data) {
1294
- process.stderr.write(data.toString());
1295
- });
1296
- cprocess.on("exit", (code) => {
1297
- resolve(code);
1298
- });
1299
- });
1300
- if (waiter !== 0) {
1301
- process.exit(waiter || 1);
1302
- }
1303
- } else {
1304
- throw new Error("No .env or .sec file provided");
1305
- }
1306
- } catch (e) {
1307
- console.error(strong(e.message));
1308
- command.help();
1309
- }
1310
- }
1311
- );
1312
- setProgramOptions({
1313
- program: subProgram,
1314
- commandName: hasDecryptEngine ? "run" : "runEnvOnly",
1315
- dotsecConfig
1316
- });
1317
- if (hasDecryptEngine) {
1318
- decryptHandlers?.map((run) => {
1319
- const { options: options2, requiredOptions } = run;
1320
- addPluginOptions(options2, subProgram);
1321
- addPluginOptions(requiredOptions, subProgram, true);
1322
- });
1323
- const engines = decryptHandlers?.map((e) => e.triggerOptionValue);
1324
- subProgram.option(
1325
- "--engine <engine>",
1326
- `Encryption engine${engines.length > 0 ? "s" : ""}: ${engines.join(", "), engines.length === 1 ? engines[0] : void 0}`
1327
- // engines.length === 1 ? engines[0] : undefined,
1328
- );
1329
- }
1330
- return subProgram;
1331
- };
1332
- var run_default2 = addRunProgam;
1333
- var separator = {
1334
- keyword: "separator",
1335
- type: "string",
1336
- metaSchema: {
1337
- type: "string",
1338
- description: "value separator"
1339
- },
1340
- modifying: true,
1341
- valid: true,
1342
- errors: false,
1343
- compile: (schema) => (data, ctx) => {
1344
- if (ctx) {
1345
- const { parentData, parentDataProperty } = ctx;
1346
- parentData[parentDataProperty] = data === "" ? [] : data.split(schema);
1347
- return true;
1348
- } else {
1349
- return false;
1350
- }
1351
- }
1352
- };
1353
- var program = new Command();
1354
- (async () => {
1355
- const parsedOptions = yargsParser(process.argv);
1356
- const argvPluginModules = [];
1357
- if (parsedOptions.plugin) {
1358
- if (Array.isArray(parsedOptions.plugin)) {
1359
- argvPluginModules.push(...parsedOptions.plugin);
1360
- } else {
1361
- argvPluginModules.push(parsedOptions.plugin);
1362
- }
1363
- }
1364
- const someConfigFile = parsedOptions.configFile || parsedOptions.c;
1365
- const configFile = [
1366
- ...Array.isArray(someConfigFile) ? someConfigFile : [someConfigFile]
1367
- ]?.[0] || process.env.DOTSEC_CONFIG_FILE;
1368
- const { contents: dotsecConfig = {} } = await getMagicalConfig(configFile);
1369
- const { defaults = {}, push: pushVariables, plugins } = dotsecConfig;
1370
- program.name("dotsec").description(".env, but secure").version("1.0.0").passThroughOptions().action((_options, other) => {
1371
- other.help();
1372
- });
1373
- setProgramOptions({ program, dotsecConfig });
1374
- const ajv = new Ajv({
1375
- allErrors: true,
1376
- removeAdditional: true,
1377
- useDefaults: true,
1378
- coerceTypes: true,
1379
- allowUnionTypes: true,
1380
- addUsedSchema: false,
1381
- keywords: [separator]
1382
- });
1383
- const pluginModules = {};
1384
- if (plugins) {
1385
- for (const pluginName of plugins) {
1386
- if (!defaults?.plugins?.[pluginName]) {
1387
- defaults.plugins = {
1388
- ...defaults.plugins,
1389
- [pluginName]: {}
1390
- };
1391
- }
1392
- }
1393
- }
1394
- if (argvPluginModules.length > 0) {
1395
- for (const pluginModule of argvPluginModules) {
1396
- const plugin = await loadDotsecPlugin({ name: pluginModule });
1397
- const loadedPlugin = await plugin({
1398
- dotsecConfig,
1399
- ajv,
1400
- configFile
1401
- });
1402
- pluginModules[loadedPlugin.name] = pluginModule;
1403
- if (argvPluginModules.length === 1) {
1404
- dotsecConfig.defaults = {
1405
- ...dotsecConfig.defaults,
1406
- encryptionEngine: String(loadedPlugin.name),
1407
- plugins: {
1408
- ...dotsecConfig.defaults?.plugins,
1409
- [loadedPlugin.name]: {
1410
- ...dotsecConfig.defaults?.plugins?.[loadedPlugin.name]
1411
- }
1412
- }
1413
- };
1414
- }
1415
- }
1416
- }
1417
- if (defaults?.encryptionEngine) {
1418
- if (!defaults?.plugins?.[defaults.encryptionEngine]) {
1419
- defaults.plugins = {
1420
- ...defaults.plugins,
1421
- [defaults.encryptionEngine]: {}
1422
- };
1423
- }
1424
- }
1425
- if (defaults?.plugins) {
1426
- Object.entries(defaults?.plugins).forEach(
1427
- ([pluginName, pluginModule]) => {
1428
- if (pluginModule?.name) {
1429
- pluginModules[pluginName] = pluginModule?.name;
1430
- } else {
1431
- pluginModules[pluginName] = `@dotsec/plugin-${pluginName}`;
1432
- }
1433
- }
1434
- );
1435
- }
1436
- Object.values(pushVariables || {}).forEach((pushVariable) => {
1437
- Object.keys(pushVariable).forEach((pluginName) => {
1438
- if (!pluginModules[pluginName]) {
1439
- pluginModules[pluginName] = `@dotsec/plugin-${pluginName}`;
1440
- }
1441
- });
1442
- });
1443
- const cliPluginEncryptHandlers = [];
1444
- const cliPluginDecryptHandlers = [];
1445
- const cliPluginPushHandlers = [];
1446
- for (const pluginName of Object.keys(pluginModules)) {
1447
- const pluginModule = pluginModules[pluginName];
1448
- const initDotsecPlugin = await loadDotsecPlugin({ name: pluginModule });
1449
- const { addCliCommand, cliHandlers: cli } = await initDotsecPlugin({
1450
- ajv,
1451
- dotsecConfig,
1452
- configFile
1453
- });
1454
- if (cli?.encrypt) {
1455
- cliPluginEncryptHandlers.push(cli.encrypt);
1456
- }
1457
- if (cli?.decrypt) {
1458
- cliPluginDecryptHandlers.push(cli.decrypt);
1459
- if (cli?.push) {
1460
- cliPluginPushHandlers.push({ push: cli.push, decrypt: cli.decrypt });
1461
- }
1462
- }
1463
- if (addCliCommand) {
1464
- addCliCommand({ program });
1465
- }
1466
- }
1467
- if (cliPluginEncryptHandlers.length) {
1468
- await encrypt_default2(program, {
1469
- dotsecConfig,
1470
- encryptHandlers: cliPluginEncryptHandlers
1471
- });
1472
- }
1473
- if (cliPluginDecryptHandlers.length) {
1474
- await decrypt_default2(program, {
1475
- dotsecConfig,
1476
- decryptHandlers: cliPluginDecryptHandlers
1477
- });
1478
- }
1479
- if (cliPluginPushHandlers.length) {
1480
- await push_default2(program, {
1481
- dotsecConfig,
1482
- handlers: cliPluginPushHandlers
1483
- });
1484
- }
1485
- await init_default2(program, { dotsecConfig });
1486
- await run_default2(program, {
1487
- dotsecConfig,
1488
- decryptHandlers: cliPluginDecryptHandlers
1489
- });
1490
- await program.parse();
1491
- })();
1492
- //# sourceMappingURL=out.js.map
1493
- //# sourceMappingURL=index.mjs.map