dotsec 4.0.0-alpha.2 → 4.0.0-alpha.21

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