dotsec 1.0.0-alpha.9 → 2.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,29 @@
1
1
  # dotsec
2
2
 
3
- Like dotenv, but encrypted.
4
-
5
- Encrypts your .env file with the AWS Encryption SDK so you can safely commit it to your repository.
3
+ The solution offers encryption and decryption of `.env` files to and from `.sec` files, the ability to run a command with the values of a `.env`/`.sec` file in its environment, and the ability to push selected `.env`/`.sec` entries to AWS Systems Manager Parameter Store and AWS Secrets Manager.
4
+ Encrypts your `.env` file with the AWS Encryption SDK so you can safely commit it to your repository.
6
5
 
7
6
  ## Features
8
7
 
9
- - Encryption of .env files to .sec files.
10
- - Decryption of .sec files to .env files.
11
- - Run a command with the values of a .env file in its environment.
12
- - Run a command with the values of a .sec file in its environment.
13
- - Push selected .env/.sec entries to AWS Systems Manager Parameter Store.
14
- - Push selected .env/.sec entries to AWS Secrets Manager.
8
+ - Encryption of `.env` files to `.sec` files.
9
+ - Decryption of `.sec` files to `.env` files.
10
+ - Run a command with the values of a `.env` file in its environment.
11
+ - Run a command with the values of a `.sec` file in its environment.
12
+ - Push selected `.env`/`.sec` entries to AWS Systems Manager Parameter Store.
13
+ - Push selected `.env`/`.sec` entries to AWS Secrets Manager.
14
+ - Holds no opinion on how you should manage your organization's user roles and permissions, you know best.
15
+
16
+ ### AWS plugin
17
+
18
+ - Supported KMS key types: symmetric and assymetric:
19
+ - `SYMMETRIC_DEFAULT`
20
+ - `RSA_2048`
21
+ - `RSAES_OAEP_SHA_256`
22
+ - `RSA_3072`
23
+ - `RSAES_OAEP_SHA_256`
24
+ - `RSA_4096`
25
+ - `RSAES_OAEP_SHA_256`
26
+ - `SM2PKE`
15
27
 
16
28
  ## Requirements
17
29
 
@@ -19,6 +31,86 @@ Encrypts your .env file with the AWS Encryption SDK so you can safely commit it
19
31
  - For usage enough credentials for using the KMS key to encrypt and/or decrypt.
20
32
  - An AWS KMS key with an alias.
21
33
 
34
+ ## Installation
35
+
36
+ ```sh
37
+ npm install --save-dev dotsec @dotsec/plugin-aws
38
+ ```
39
+
40
+ Add the folowing to dotsec.config.ts:
41
+
42
+ ```ts
43
+ import { DotsecPluginAws } from "@dotsec/plugin-aws";
44
+ import { DotsecConfig } from "dotsec";
45
+
46
+ export const dotsec: DotsecConfig<{ plugins: DotsecPluginAws }> = {
47
+ defaults: {
48
+ encryptionEngine: "aws",
49
+ },
50
+ };
51
+ ```
52
+
53
+ ## Usage
54
+
55
+ If you don't have a .env file, create one:
56
+
57
+ ```sh
58
+ I_CAN_SEE="clearly now"
59
+ SINGING="in the rain"
60
+ I_BLESS_THE_RAINS="down in Africa"
61
+ ```
62
+
63
+ ### Execute a command and use the values of a .env file in its environment
64
+
65
+ ```sh
66
+ npx dotsec run --with-env node -e "console.log(process.env.I_BLESS_THE_RAINS)"
67
+ ```
68
+
69
+ ### Encrypt a .env file to .sec
70
+
71
+ ```sh
72
+ npx dotsec encrypt
73
+ ```
74
+
75
+ ### Execute a command and use the values of a .sec file in its environment
76
+
77
+ ```sh
78
+ npx dotsec run --with-sec node -e "console.log(process.env.I_BLESS_THE_RAINS)"
79
+ ```
80
+
81
+ ### Decrypt a .sec file to .env
82
+
83
+ ```sh
84
+ npx dotsec decrypt
85
+ ```
86
+
87
+ ### Push selected .env entries to AWS Systems Manager Parameter Store
88
+
89
+ Edit the `dotsec.config.ts` file. Add the following to the `aws` object:
90
+
91
+ ```ts
92
+ {
93
+ ...
94
+ variables: {
95
+ "I_BLESS_THE_RAINS": {
96
+ push: {
97
+ aws: {
98
+ ssm: true
99
+ }
100
+ }
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ Run the following command:
107
+
108
+ ```sh
109
+ npx dotsec push
110
+ ```
111
+
112
+ > You might want to set AWS_REGION before running the command. If you don't, the region will be set to `eu-west-1`.
113
+ <!--
22
114
  ## Usage
23
115
 
24
116
  If you don't have an AWS KMS key with an alias, you can create one with the following command:
@@ -134,7 +226,7 @@ Take your favorite editor, and edit the `dotsec.config.ts` file. Add the followi
134
226
 
135
227
  ```sh
136
228
  npx dotsec push --env --to-aws-secrets-manager
137
- ```
229
+ ``` -->
138
230
 
139
231
  ### FAQ
140
232
 
@@ -153,13 +245,13 @@ We do, however, since this package is relatively new, I don't think you should.
153
245
  - Add support for Node preload modules like `node -r dotsec/register index.js`
154
246
  - Add watcher for `.env` file changes and automatically encrypt
155
247
  - Write guide on postinstall for npm/yarn/pnpm
156
- - Add chunking for encoding larger files with assymetric keys. Current limit is 4kb.
248
+ - ~~Add chunking for encoding larger files with assymetric keys. Current limit is 4kb.~~
157
249
  - Add support for other encryption SDKs like GCP KMS, Azure Key Vault, etc.
158
- - Split up dotsec package in multiple packages, one for each SDK.
250
+ - ~~Split up dotsec package in multiple packages, one for each encryption SDK.~~
159
251
  - Add support for pulling entries to GitHub actions secrets.
160
252
 
161
253
  ## Limitations
162
254
 
163
255
  - The only supported encryption SDK is the AWS Encryption SDK. For now.
164
- - Assymetric keys are supported, but the encrypted file size is limited to the payload size of the key. Until chunking is implemented, that is.
256
+ - ~~Assymetric keys are supported, but the encrypted file size is limited to the payload size of the key. Until chunking is implemented, that is.~~
165
257
  - AWS Secrets Manager secrets which are marked for deletion **cannot** be updated until the deletion is complete. As of writing, the minimum deletion time is 7 days. This means that if you want to update a deleted AWS Secrets Manager secret, you have to wait at least 7 days before you can update it again. This is a limitation of AWS Secrets Manager, not dotsec
package/dist/cli/index.js CHANGED
@@ -1,9 +1,41 @@
1
- var nn=Object.create;var ue=Object.defineProperty,on=Object.defineProperties,tn=Object.getOwnPropertyDescriptor,rn=Object.getOwnPropertyDescriptors,sn=Object.getOwnPropertyNames,ve=Object.getOwnPropertySymbols,an=Object.getPrototypeOf,Oe=Object.prototype.hasOwnProperty,cn=Object.prototype.propertyIsEnumerable;var _e=(e,n,t)=>n in e?ue(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t,r=(e,n)=>{for(var t in n||(n={}))Oe.call(n,t)&&_e(e,t,n[t]);if(ve)for(var t of ve(n))cn.call(n,t)&&_e(e,t,n[t]);return e},k=(e,n)=>on(e,rn(n)),mn=e=>ue(e,"__esModule",{value:!0});var pn=(e,n,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of sn(n))!Oe.call(e,o)&&o!=="default"&&ue(e,o,{get:()=>n[o],enumerable:!(t=tn(n,o))||t.enumerable});return e},y=e=>pn(mn(ue(e!=null?nn(an(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var Xe=y(require("commander"));var Z=y(require("@aws-sdk/client-kms"));var H=y(require("@aws-sdk/credential-providers")),Re=y(require("@aws-sdk/shared-ini-file-loader"));var Ae=y(require("chalk"));var T=e=>Ae.default.yellowBright(e),h=e=>Ae.default.yellow.bold(e);var Pe=async({argv:e,env:n})=>{var l,g,w;let t=await(0,Re.loadSharedConfigFiles)(),o,c,s;if(e.profile?(c={value:e.profile,origin:`command line option: ${T(e.profile)}`},o={value:await(0,H.fromIni)({profile:e.profile})(),origin:`${T(`[${e.profile}]`)} in credentials file`}):n.AWS_PROFILE?(c={value:n.AWS_PROFILE,origin:`env variable ${T("AWS_PROFILE")}: ${h(n.AWS_PROFILE)}`},o={value:await(0,H.fromIni)({profile:n.AWS_PROFILE})(),origin:`env variable ${T("AWS_PROFILE")}: ${h(n.AWS_PROFILE)}`}):n.AWS_ACCESS_KEY_ID&&n.AWS_SECRET_ACCESS_KEY?o={value:await(0,H.fromEnv)()(),origin:`env variables ${T("AWS_ACCESS_KEY_ID")} and ${T("AWS_SECRET_ACCESS_KEY")}`}:((l=t.credentialsFile)==null?void 0:l.default)&&(c={value:"default",origin:`${T("[default]")} in credentials file`},o={value:await(0,H.fromIni)({profile:"default"})(),origin:`profile ${T("[default]")}`}),e.region)s={value:e.region,origin:`command line option: ${T(e.region)}`};else if(n.AWS_REGION)s={value:n.AWS_REGION,origin:`env variable ${T("AWS_REGION")}: ${h(n.AWS_REGION)}`};else if(n.AWS_DEFAULT_REGION)s={value:n.AWS_DEFAULT_REGION,origin:`env variable ${T("AWS_DEFAULT_REGION")}: ${h(n.AWS_DEFAULT_REGION)}`};else if(c){let p=(w=(g=t==null?void 0:t.configFile)==null?void 0:g[c.value])==null?void 0:w.region;p&&(s={value:p,origin:`${T(`[profile ${c.value}]`)} in config file`})}let m=e.assumeRoleArn||n.AWS_ASSUME_ROLE_ARN;if(m){let p=e.assumeRoleArn?"command line option":"env variable";o={value:await(0,H.fromTemporaryCredentials)({masterCredentials:o==null?void 0:o.value,params:{DurationSeconds:e.assumeRoleSessionDuration||Number(n.AWS_ASSUME_ROLE_SESSION_DURATION)||3600,RoleArn:m},clientConfig:{region:s==null?void 0:s.value}})(),origin:`${p} ${T(`[${m}]`)}`}}return{credentialsAndOrigin:o,regionAndOrigin:s,profileAndOrigin:c}},be=({credentialsAndOrigin:e,regionAndOrigin:n,profileAndOrigin:t})=>{let o=[];return t&&o.push(`Got profile name from ${t.origin}`),e&&o.push(`Resolved credentials from ${e.origin}`),n&&o.push(`Resolved region from ${n.origin}`),o.join(`
2
- `)};var ie=async({argv:e,env:n})=>{let{credentialsAndOrigin:t,regionAndOrigin:o,profileAndOrigin:c}=await Pe({argv:{region:e.awsRegion,profile:e.awsProfile,assumeRoleArn:e.awsAssumeRoleArn,assumeRoleSessionDuration:e.awsAssumeRoleSessionDuration},env:r({},n)});if(e.verbose===!0&&console.log(be({credentialsAndOrigin:t,regionAndOrigin:o,profileAndOrigin:c})),!(t&&o)){if(!t)throw console.error("Could not find credentials"),new Error("Could not find credentials");if(!o)throw console.error("Could not find region"),new Error("Could not find region")}return{credentialsAndOrigin:t,regionAndOrigin:o}};var L=async e=>{var w,p;let{kms:{keyAlias:n}={},region:t}=e,{credentialsAndOrigin:o,regionAndOrigin:c}=await ie({argv:{},env:r({},process.env)}),s=new Z.KMSClient({credentials:o.value,region:t||c.value}),m=new Z.DescribeKeyCommand({KeyId:n}),g=(p=(w=(await s.send(m)).KeyMetadata)==null?void 0:w.EncryptionAlgorithms)==null?void 0:p[0];if(g===void 0)throw new Error("Could not determine encryption algorithm");return{async encrypt(a){let d=new Z.EncryptCommand({KeyId:n,Plaintext:Buffer.from(a),EncryptionAlgorithm:g}),i=await s.send(d);if(!i.CiphertextBlob)throw new Error(`Something bad happened: ${JSON.stringify({encryptCommand:d})}`);return Buffer.from(i.CiphertextBlob).toString("base64")},async decrypt(a){let d=new Z.DecryptCommand({KeyId:n,CiphertextBlob:Buffer.from(a,"base64"),EncryptionAlgorithm:g}),i=await s.send(d);if(!i.Plaintext)throw new Error(`Something bad happened: ${JSON.stringify({cipherText:a,decryptCommand:d})}`);let A=Buffer.from(i.Plaintext).toString();return this.verbose&&console.info(`Decrypting key '${a}'`),A},other:()=>{}}};var pe=y(require("node:fs/promises")),Fe=y(require("prompts")),ke=y(require("node:path")),se=async e=>await pe.default.readFile(e,"utf-8"),ne=async(e,n)=>await pe.default.writeFile(e,n,"utf-8"),ln=async e=>{try{return await(0,pe.stat)(e),!0}catch{return!1}},oe=async({filePath:e,skip:n})=>{let t;return await ln(e)&&n!==!0?t=await(0,Fe.default)({type:"confirm",name:"overwrite",message:()=>`Overwrite './${ke.default.relative(process.cwd(),e)}' ?`}):t=void 0,t};var De=y(require("node:path"));var v=y(require("typescript")),Te=y(require("node:fs")),xe=e=>{let n=v.createPrinter(),t=Te.default.readFileSync(e.configFile,"utf8"),o=g=>w=>{function p(a){var d,i,A,C,E,S,P,b,O,M,D,q,U,j,V,Y,B,J;if(a=v.visitEachChild(a,p,g),a.kind===v.SyntaxKind.StringLiteral){let u=(i=(d=a==null?void 0:a.parent)==null?void 0:d.parent)==null?void 0:i.parent;if(((E=(C=(A=e.config)==null?void 0:A.aws)==null?void 0:C.kms)==null?void 0:E.keyAlias)&&((S=u==null?void 0:u.getChildAt(0))==null?void 0:S.getText())==="kms"){let _=(P=u==null?void 0:u.parent)==null?void 0:P.parent;if((_==null?void 0:_.getChildAt(0).getText())==="aws")return v.createStringLiteral((M=(O=(b=e.config)==null?void 0:b.aws)==null?void 0:O.kms)==null?void 0:M.keyAlias)}if(((q=(D=e.config)==null?void 0:D.aws)==null?void 0:q.region)&&((j=(U=a==null?void 0:a.parent)==null?void 0:U.getChildAt(0))==null?void 0:j.getText())==="region"){let _=(Y=(V=a==null?void 0:a.parent)==null?void 0:V.parent)==null?void 0:Y.parent;if((_==null?void 0:_.getChildAt(0).getText())==="aws")return v.createStringLiteral((J=(B=e.config)==null?void 0:B.aws)==null?void 0:J.region)}}return a}return v.visitNode(w,p)},c=v.createSourceFile("test.ts",t,v.ScriptTarget.ES2015,!0,v.ScriptKind.TS),s=v.transform(c,[o]),m=s.transformed[0],l=n.printFile(m);return s.dispose(),l};var we="dotsec.config.ts",Ie=[we],ae=".sec",ce=".env",le="alias/dotsec",gn="SecureString",R={config:{aws:{kms:{keyAlias:le},ssm:{parameterType:gn}}}};var fn={dotsec:{options:{verbose:["--verbose","Verbose output",!1],configFile:["-c, --config-file, --configFile <configFile>","Config file",we]}},init:{options:{verbose:["--verbose","Verbose output",!1],configFile:["-c, --config-file, --configFile <configFile>","Config file",we],env:["--env","Path to .env file",ce],sec:["--sec","Path to .sec file",ae],yes:["--yes","Skip confirmation prompts",!1],awsKeyAlias:["--aws-key-alias <awsKeyAlias>","AWS KMS key alias, overrides the value provided in dotsec.config (config.aws.kms.keyAlias)","alias/dotsec"],awsRegion:["--aws-region <awsRegion>","AWS region, overrides the value provided in dotsec.config (config.aws.region) and AWS_REGION"]}},decrypt:{inheritsFrom:["dotsec"],options:{env:["--env <env>","Path to .env file",ce],sec:["--sec <sec>","Path to .sec file",ae],yes:["--yes","Skip confirmation prompts",!1],awsKeyAlias:["--aws-key-alias <awsKeyAlias>","AWS KMS key alias, overrides the value provided in dotsec.config (config.aws.kms.keyAlias)","alias/dotsec"],awsRegion:["--aws-region <awsRegion>","AWS region, overrides the value provided in dotsec.config (config.aws.region) and AWS_REGION"]}},encrypt:{inheritsFrom:["dotsec"],options:{env:["--env <env>","Path to .env file",ce],sec:["--sec <sec>","Path to .sec file",ae],yes:["--yes","Skip confirmation prompts",!1],awsKeyAlias:["--aws-key-alias <awsKeyAlias>","AWS KMS key alias, overrides the value provided in dotsec.config (config.aws.kms.keyAlias)","alias/dotsec"],awsRegion:["--aws-region <awsRegion>","AWS region, overrides the value provided in dotsec.config (config.aws.region) and AWS_REGION"]}},run:{inheritsFrom:["dotsec"],options:{env:["--env <env>","Path to .env file"],sec:["--sec [sec]","Path to .sec file"],awsKeyAlias:["--aws-key-alias <awsKeyAlias>","AWS KMS key alias, overrides the value provided in dotsec.config (config.aws.kms.keyAlias)","alias/dotsec"],awsRegion:["--aws-region <awsRegion>","AWS region, overrides the value provided in dotsec.config (config.aws.region) and AWS_REGION"]}},push:{inheritsFrom:["dotsec"],options:{toAwsSsm:["--to-aws-ssm, --toAwsSsm","Push to AWS SSM"],toAwsSecretsManager:["--to-aws-secrets-manager, --toAwsSecretsManager","Push to AWS Secrets Manager"],env:["--env [env]","Path to .env file"],sec:["--sec [sec]","Path to .sec file"],yes:["--yes","Skip confirmation prompts",!1],awsKeyAlias:["--aws-key-alias <awsKeyAlias>","AWS KMS key alias, overrides the value provided in dotsec.config (config.aws.kms.keyAlias)","alias/dotsec"],awsRegion:["--aws-region <awsRegion>","AWS region, overrides the value provided in dotsec.config (config.aws.region) and AWS_REGION"]}}},We=(e,n,t={})=>{let o=e[n];if(o)return o.inheritsFrom?o==null?void 0:o.inheritsFrom.reduce((c,s)=>{let m=We(e,s,c);return r({},m)},{options:r(r({},t.options),o.options),requiredOptions:r(r({},t.requiredOptions),o.requiredOptions)}):{options:r(r({},t.options),o.options),requiredOptions:r(r({},t.requiredOptions),o.requiredOptions)}},W=(e,n)=>{let t=We(fn,n||e.name());(t==null?void 0:t.options)&&Object.values(t.options).forEach(([o,c,s])=>{e.option(o,c,s)}),(t==null?void 0:t.requiredOptions)&&Object.values(t.requiredOptions).forEach(([o,c,s])=>{e.requiredOption(o,c,s)})};var dn=async e=>{let n=e.enablePositionalOptions().passThroughOptions().command("init").action(async(t,o)=>{var a,d,i,A,C,E;let{verbose:c,configFile:s,env:m,sec:l,awskeyAlias:g,awsRegion:w,yes:p}=o.optsWithGlobals();try{let S;S=await L({verbose:c,region:w||process.env.AWS_REGION||((d=(a=R.config)==null?void 0:a.aws)==null?void 0:d.region),kms:{keyAlias:g||((E=(C=(A=(i=R)==null?void 0:i.config)==null?void 0:A.aws)==null?void 0:C.kms)==null?void 0:E.keyAlias)}});let P=await se(m),b=await S.encrypt(P),O=await oe({filePath:l,skip:p});(O===void 0||O.overwrite===!0)&&(await ne(l,b),console.log(`Wrote encrypted contents of ${h(m)} contents file to ${h(l)}`));let M=xe({configFile:De.default.resolve(__dirname,"../../src/templates/dotsec.config.ts"),config:{aws:{kms:{keyAlias:g||le},region:w||process.env.AWS_REGION}}}),D=await oe({filePath:s,skip:p});(D===void 0||D.overwrite===!0)&&(await ne(s,M),console.log(`Wrote config file to ${h(s)}`))}catch(S){o.error(S)}});return W(n),n},Ne=dn;var Ee=y(require("node:fs")),Ue=y(require("cross-spawn")),je=y(require("dotenv"));var Ke=y(require("node:path")),Ge=y(require("bundle-require")),qe=y(require("joycon"));var Me=y(require("fs")),Le=y(require("node:path"));function un(e){try{return new Function(`return ${e.trim()}`)()}catch{return{}}}var $e=async e=>{try{return un(await Me.default.promises.readFile(e,"utf8"))}catch(n){throw n instanceof Error?new Error(`Failed to parse ${Le.default.relative(process.cwd(),e)}: ${n.message}`):n}};var z=async e=>{var c,s,m,l,g,w,p,a,d,i,A,C,E,S,P,b,O,M,D,q,U,j,V,Y,B,J,u,_,te,X,re,N,K,G,F,x;let n=process.cwd(),o=await new qe.default().resolve({files:e?[e]:[...Ie,"package.json"],cwd:n,stopDir:Ke.default.parse(n).root,packageKey:"dotsec"});if(e&&o===null)throw new Error(`Could not find config file ${e}`);if(o){if(o.endsWith(".json")){let I=await $e(o),f;return o.endsWith("package.json")&&I.dotsec!==void 0?f=I.dotsec:f=I,{source:"json",contents:k(r(r({},R),f),{config:k(r(r({},f==null?void 0:f.config),R.config),{aws:k(r(r({},(c=f==null?void 0:f.config)==null?void 0:c.aws),(m=(s=R)==null?void 0:s.config)==null?void 0:m.aws),{kms:r(r({},(w=(g=(l=R)==null?void 0:l.config)==null?void 0:g.aws)==null?void 0:w.kms),(a=(p=f.config)==null?void 0:p.aws)==null?void 0:a.kms),ssm:r(r({},(A=(i=(d=R)==null?void 0:d.config)==null?void 0:i.aws)==null?void 0:A.ssm),(E=(C=f.config)==null?void 0:C.aws)==null?void 0:E.ssm),secretsManager:r(r({},(b=(P=(S=R)==null?void 0:S.config)==null?void 0:P.aws)==null?void 0:b.secretsManager),(M=(O=f.config)==null?void 0:O.aws)==null?void 0:M.secretsManager)})})})}}else if(o.endsWith(".ts")){let I=await(0,Ge.bundleRequire)({filepath:o}),f=I.mod.dotsec||I.mod.default||I.mod;return{source:"ts",contents:k(r(r({},R),f),{config:k(r(r({},f==null?void 0:f.config),R.config),{aws:k(r(r({},(D=f==null?void 0:f.config)==null?void 0:D.aws),(U=(q=R)==null?void 0:q.config)==null?void 0:U.aws),{kms:r(r({},(Y=(V=(j=R)==null?void 0:j.config)==null?void 0:V.aws)==null?void 0:Y.kms),(J=(B=f.config)==null?void 0:B.aws)==null?void 0:J.kms),ssm:r(r({},(te=(_=(u=R)==null?void 0:u.config)==null?void 0:_.aws)==null?void 0:te.ssm),(re=(X=f.config)==null?void 0:X.aws)==null?void 0:re.ssm),secretsManager:r(r({},(G=(K=(N=R)==null?void 0:N.config)==null?void 0:K.aws)==null?void 0:G.secretsManager),(x=(F=f.config)==null?void 0:F.aws)==null?void 0:x.secretsManager)})})})}}}return{source:"defaultConfig",contents:R}};var wn=e=>{let n=e.command("run <command...>").allowUnknownOption().description("Run a command in a separate process and populate env with decrypted .env or encrypted .sec values").action(async(t,o,c)=>{var i,A,C;let{configFile:s,env:m,sec:l,keyAlias:g,region:w}=c.optsWithGlobals(),{contents:{config:p}={}}=await z(s),a=await L({verbose:!0,kms:{keyAlias:g||((A=(i=p==null?void 0:p.aws)==null?void 0:i.kms)==null?void 0:A.keyAlias)||le},region:w||((C=p==null?void 0:p.aws)==null?void 0:C.region)}),d;if(m)d=Ee.default.readFileSync(m,"utf8");else if(l){let E=Ee.default.readFileSync(l,"utf8");d=await a.decrypt(E)}else throw new Error('Must provide either "--env" or "--sec"');if(d){let E=(0,je.parse)(d),[S,...P]=t;(0,Ue.default)(S,[...P],{stdio:"inherit",shell:!1,env:k(r(r({},process.env),E),{__DOTSEC_ENV__:JSON.stringify(Object.keys(E))})}),c.help()}else throw new Error("No .env or .sec file provided")});return W(n,"run"),n},Ve=wn;var Sn=async e=>{let n=e.enablePositionalOptions().passThroughOptions().command("decrypt").action(async(t,o)=>{var d,i,A,C,E;let{configFile:c,verbose:s,env:m,sec:l,awskeyAlias:g,awsRegion:w,yes:p}=o.optsWithGlobals(),{contents:a}=await z(c);try{let S;S=await L({verbose:s,region:w||process.env.AWS_REGION||((i=(d=a.config)==null?void 0:d.aws)==null?void 0:i.region),kms:{keyAlias:g||((E=(C=(A=a==null?void 0:a.config)==null?void 0:A.aws)==null?void 0:C.kms)==null?void 0:E.keyAlias)}});let P=await se(l),b=await S.decrypt(P),O=await oe({filePath:m,skip:p});(O===void 0||O.overwrite===!0)&&(await ne(m,b),console.log(`Wrote plaintext contents of ${h(l)} file to ${h(m)}`))}catch(S){o.error(S)}});return W(n),n},Ye=Sn;var yn=async e=>{let n=e.enablePositionalOptions().passThroughOptions().command("encrypt").action(async(t,o)=>{var d,i,A,C,E;let{verbose:c,configFile:s,env:m,sec:l,awskeyAlias:g,awsRegion:w,yes:p}=o.optsWithGlobals(),{contents:a}=await z(s);try{let S;S=await L({verbose:c,region:w||process.env.AWS_REGION||((i=(d=a.config)==null?void 0:d.aws)==null?void 0:i.region),kms:{keyAlias:g||((E=(C=(A=a==null?void 0:a.config)==null?void 0:A.aws)==null?void 0:C.kms)==null?void 0:E.keyAlias)}});let P=await se(m),b=await S.encrypt(P),O=await oe({filePath:l,skip:p});(O===void 0||O.overwrite===!0)&&(await ne(l,b),console.log(`Wrote encrypted contents of ${h(m)} file to ${h(l)}`))}catch(S){o.error(S)}});return W(n),n},Be=yn;var ge=e=>typeof e=="boolean";var Ce=y(require("node:fs"));var ze=y(require("dotenv"));var Je=y(require("prompts")),Se=async({predicate:e,skip:n,message:t})=>n===!0?{confirm:!0}:(e?await e():!0)?await(0,Je.default)({type:"confirm",name:"confirm",message:()=>t}):{confirm:!0};var ye=y(require("@aws-sdk/client-ssm"));var He=async e=>{let{region:n}=e||{},{credentialsAndOrigin:t,regionAndOrigin:o}=await ie({argv:{},env:r({},process.env)}),c=new ye.SSMClient({credentials:t.value,region:n||o.value});return{async put(s){for(let m of s){let l=new ye.PutParameterCommand(k(r({},m),{Overwrite:!0}));await c.send(l)}}}};var $=y(require("@aws-sdk/client-secrets-manager"));var Ze=async e=>{let{region:n}=e||{},{credentialsAndOrigin:t,regionAndOrigin:o}=await ie({argv:{},env:r({},process.env)}),c=new $.SecretsManagerClient({credentials:t.value,region:n||o.value});return{async push(s){let m=[],l=[];for(let g of s){let w=new $.DescribeSecretCommand({SecretId:g.Name});try{let p=await c.send(w);l.push(new $.UpdateSecretCommand({SecretId:p.ARN,SecretString:g.SecretString}))}catch(p){p instanceof $.ResourceNotFoundException&&m.push(new $.CreateSecretCommand({Name:g.Name,SecretString:g.SecretString}))}}return{createSecretCommands:m,updateSecretCommands:l,push:async()=>{for(let g of m)await c.send(g);for(let g of l)await c.send(g)}}}}};var An=async e=>{let n=e.enablePositionalOptions().passThroughOptions().command("push").action(async(t,o)=>{var S,P,b,O,M,D,q,U,j,V,Y,B,J;let{configFile:c,verbose:s,env:m,sec:l,awskeyAlias:g,awsRegion:w,yes:p,toAwsSsm:a,toAwsSecretsManager:d}=o.optsWithGlobals();if(!(a||d))throw new Error("You must specify at least one of --to-aws-ssm or --to-aws-secrets-manager");let{contents:i}=await z(c),A,C;if(A=await L({verbose:s,region:w||process.env.AWS_REGION||((P=(S=i.config)==null?void 0:S.aws)==null?void 0:P.region),kms:{keyAlias:g||((M=(O=(b=i==null?void 0:i.config)==null?void 0:b.aws)==null?void 0:O.kms)==null?void 0:M.keyAlias)}}),m){let u=ge(m)?ce:m;C=Ce.default.readFileSync(u,"utf8")}else if(l){let u=ge(l)?ae:l,_=Ce.default.readFileSync(u,"utf8");C=await A.decrypt(_)}else throw new Error('Must provide either "--env" or "--sec"');let E=(0,ze.parse)(C);try{if(a){let u=(q=(D=i==null?void 0:i.config)==null?void 0:D.aws)==null?void 0:q.ssm,_=(u==null?void 0:u.parameterType)||"SecureString",te=(u==null?void 0:u.pathPrefix)||"",X=Object.entries(E).reduce((N,[K,G])=>{var F,x,I,f;if((F=i.variables)==null?void 0:F[K]){let ee=(x=i.variables)==null?void 0:x[K];if(ee){let me=`${te}${K}`;if((f=(I=ee.push)==null?void 0:I.aws)==null?void 0:f.ssm){let fe=ge(ee.push.aws.ssm)?{Name:me,Value:G,Type:_}:k(r({Name:me,Type:_},ee.push.aws.ssm),{Value:G});N.push(fe)}}}return N},[]),{confirm:re}=await Se({message:`Are you sure you want to push the following variables to AWS SSM Parameter Store?
3
- ${X.map(({Name:N})=>`- ${h(N||"[no name]")}`).join(`
4
- `)}`,skip:p});re===!0&&(console.log("pushing to AWS SSM Parameter Store"),await(await He({region:w||((j=(U=i==null?void 0:i.config)==null?void 0:U.aws)==null?void 0:j.region)})).put(X))}if(d){let u=(Y=(V=i==null?void 0:i.config)==null?void 0:V.aws)==null?void 0:Y.secretsManager,_=(u==null?void 0:u.pathPrefix)||"",te=await Ze({region:w||process.env.AWS_REGION||((J=(B=i.config)==null?void 0:B.aws)==null?void 0:J.region)}),X=Object.entries(E).reduce((F,[x,I])=>{var f,ee,me,fe;if((f=i.variables)==null?void 0:f[x]){let de=(ee=i.variables)==null?void 0:ee[x];if(de){let he=`${_}${x}`;if((fe=(me=de.push)==null?void 0:me.aws)==null?void 0:fe.ssm){let en=ge(de.push.aws.ssm)?{Name:he,SecretString:I}:k(r({Name:he},de.push.aws.ssm),{SecretString:I});F.push(en)}}}return F},[]),{push:re,updateSecretCommands:N,createSecretCommands:K}=await te.push(X),G=[];if(N.length>0){let{confirm:F}=await Se({message:`Are you sure you want to update the following variables to AWS SSM Secrets Manager?
5
- ${N.map(({input:{SecretId:x}})=>`- ${h(x||"[no name]")}`).join(`
6
- `)}`,skip:p});G.push(F)}if(K.length>0){let{confirm:F}=await Se({message:`Are you sure you want to create the following variables to AWS SSM Secrets Manager?
7
- ${K.map(({input:{Name:x}})=>`- ${h(x||"[no name]")}`).join(`
8
- `)}`,skip:p});G.push(F)}G.find(F=>F===!1)||(console.log("pushing to AWS Secrets Manager"),await re())}}catch(u){o.error(u)}});return W(n),n},Qe=An;var Q=new Xe.Command;Q.name("dotsec").description(".env, but secure").version("1.0.0").enablePositionalOptions().action((e,n)=>{n.help()});W(Q);(async()=>{await Ne(Q),await Ve(Q),await Ye(Q),await Be(Q),await Qe(Q),Q.parse()})();
1
+ var Ke=Object.create;var J=Object.defineProperty,We=Object.defineProperties,Ge=Object.getOwnPropertyDescriptor,Ue=Object.getOwnPropertyDescriptors,Je=Object.getOwnPropertyNames,re=Object.getOwnPropertySymbols,Me=Object.getPrototypeOf,se=Object.prototype.hasOwnProperty,Be=Object.prototype.propertyIsEnumerable;var ae=(e,t,r)=>t in e?J(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,c=(e,t)=>{for(var r in t||(t={}))se.call(t,r)&&ae(e,r,t[r]);if(re)for(var r of re(t))Be.call(t,r)&&ae(e,r,t[r]);return e},P=(e,t)=>We(e,Ue(t)),ze=e=>J(e,"__esModule",{value:!0});var Qe=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Je(t))!se.call(e,o)&&o!=="default"&&J(e,o,{get:()=>t[o],enumerable:!(r=Ge(t,o))||r.enumerable});return e},h=e=>Qe(ze(J(e!=null?Ke(Me(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var Re=h(require("commander"));var q="dotsec.config.ts",ce=[q],z=".sec",Q=".env",V={};var pe=h(require("fs")),le=h(require("node:path"));function Xe(e){try{return new Function(`return ${e.trim()}`)()}catch{return{}}}var me=async e=>{try{return Xe(await pe.default.promises.readFile(e,"utf8"))}catch(t){throw t instanceof Error?new Error(`Failed to parse ${le.default.relative(process.cwd(),e)}: ${t.message}`):t}};var de=h(require("bundle-require")),fe=h(require("joycon")),ue=h(require("path")),ge=async e=>{var n,a,l,s;let t=process.cwd(),o=await new fe.default().resolve({files:e?[e]:[...ce,"package.json"],cwd:t,stopDir:ue.default.parse(t).root,packageKey:"dotsec"});if(e&&o===null)throw new Error(`Could not find config file ${e}`);if(o){if(o.endsWith(".json")){let p=await me(o),i;return o.endsWith("package.json")&&p.dotsec!==void 0?i=p.dotsec:i=p,{source:"json",contents:P(c(c({},V),i),{defaults:P(c(c({},i==null?void 0:i.defaults),V.defaults),{plugins:c(c({},(n=i==null?void 0:i.defaults)==null?void 0:n.plugins),(a=V.defaults)==null?void 0:a.plugins)}),push:c({},i==null?void 0:i.push)})}}else if(o.endsWith(".ts")){let p=await(0,de.bundleRequire)({filepath:o}),i=p.mod.dotsec||p.mod.default||p.mod;return{source:"ts",contents:P(c(c({},V),i),{defaults:P(c(c({},i==null?void 0:i.defaults),V.defaults),{plugins:c(c({},(l=i==null?void 0:i.defaults)==null?void 0:l.plugins),(s=V.defaults)==null?void 0:s.plugins)}),push:c({},i==null?void 0:i.push)})}}}return{source:"defaultConfig",contents:V}};var X=async e=>Promise.resolve().then(()=>h(require(e.name))).then(t=>t.default);var ye=h(require("commander")),_=(e,t,r)=>{e&&Object.values(e).map(o=>{let n;if(Array.isArray(o)){let[a,l,s]=o;n={flags:a,description:l,defaultValue:s}}else{let{flags:a,description:l,defaultValue:s,env:p,fn:i}=o;n={flags:a,description:l,defaultValue:s,env:p,fn:i}}if(n){let a=new ye.Option(n.flags,n.description);n.fn&&a.argParser(n.fn),n.defaultValue&&a.default(n.defaultValue),n.env&&a.env(n.env),r&&a.makeOptionMandatory(!0),t.addOption(a)}})};var K=h(require("node:fs/promises")),he=h(require("node:path")),Ce=h(require("prompts")),M=async e=>await K.default.readFile(e,"utf-8"),N=async(e,t)=>await K.default.writeFile(e,t,"utf-8"),Ye=async e=>{try{return await(0,K.stat)(e),!0}catch{return!1}},R=async({filePath:e,skip:t})=>{let r;return await Ye(e)&&t!==!0?r=await(0,Ce.default)({type:"confirm",name:"overwrite",message:()=>`Overwrite './${he.default.relative(process.cwd(),e)}' ?`}):r=void 0,r};var Oe=h(require("chalk")),Et=require("cli-table");var x=e=>Oe.default.yellow.bold(e);var Fe=h(require("commander"));var T={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 '${Q}' file in current directory.`,Q],env:"ENV_FILE"},k={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 '${z}' file in current directory.`,z],env:"SEC_FILE"},W={option:["--with-env, --withEnv","Run command using a dot env file"]},G={option:["--with-sec, --withSec","Run command with a dotsec file"]},j={option:["--yes","Skip confirmation prompts"]};var Ze={decrypt:{inheritsFrom:["dotsec"],options:{envFile:T,secFile:k,yes:j}}},we=Ze;var et={dotsec:{options:{verbose:["--verbose","Verbose output",!1],configFile:["-c, --config-file, --configFile <configFile>","Config file",q],plugin:["--plugin <plugin>","Comma-separated list of plugins to use"]}}},U=et;var tt={encrypt:{inheritsFrom:["dotsec"],options:{envFile:T,secFile:k,yes:j}}},ve=tt;var ot={init:{options:{verbose:["--verbose","Verbose output",!1],configFile:["-c, --config-file, --configFile <configFile>","Config file",q],envFile:T,secFile:k,yes:j}}},De=ot;var nt={pull:{inheritsFrom:["dotsec"],options:{withEnv:W,withSec:G,envFile:T,secFile:k,yes:j}}},B=nt;var it={runEnvOnly:{inheritsFrom:["dotsec"],usage:"[commandArgs...]",options:{envFile:T,yes:j},description:"Run a command in a separate process and populate env with contents of a dotenv file.",helpText:`Examples:
2
+
3
+ Run a command with a .env file
4
+
5
+ $ dotsec run echo "hello world"
6
+
7
+
8
+ Run a command with a specific .env file
9
+
10
+ $ dotsec run --env-file .env.dev echo "hello world"
11
+
12
+ Run a command with a specific ENV_FILE variable
13
+
14
+ $ ENV_FILE=.env.dev dotsec run echo "hello world"
15
+
16
+ `},run:{inheritsFrom:["dotsec"],options:{withEnv:W,withSec:G,envFile:T,secFile:k,yes:j},usage:"[--with-env --env-file .env] [--with-sec --sec-file .sec] [commandArgs...]",description:`Run a command in a separate process and populate env with either
17
+ - contents of a dotenv file
18
+ - decrypted values of a dotsec file.
19
+
20
+ The --withEnv option will take precedence over the --withSec option. If neither are specified, the --withEnv option will be used by default.`,helpText:`Examples:
21
+
22
+ Run a command with a .env file
23
+
24
+ $ dotsec run echo "hello world"
25
+
26
+
27
+ Run a command with a specific .env file
28
+
29
+ $ dotsec run --with-env --env-file .env.dev echo "hello world"
30
+
31
+
32
+ Run a command with a .sec file
33
+
34
+ $ dotsec run --with-sec echo "hello world"
35
+
36
+
37
+ Run a command with a specific .sec file
38
+
39
+ $ dotsec run --with-sec --sec-file .sec.dev echo "hello world"
40
+ `},push:{options:P(c({},U.dotsec.options),{withEnv:W,withSec:G,envFile:T,secFile:k,yes:j}),requiredOptions:c({},U.dotsec.requiredOptions)}},Ee=it;var rt=c(c(c(c(c(c(c({},U),De),ve),we),Ee),B),B);var st=e=>Array.isArray(e)?{option:e}:e,Pe=(e,t)=>{var p,i,m;let r=st(e),[o,n,a]=r.option,l=(m=(i=(p=t==null?void 0:t.dotsecConfig)==null?void 0:p.defaults)==null?void 0:i.options)==null?void 0:m[t==null?void 0:t.optionKey],s=new Fe.Option(o,n+(l?". Default from config.":""));return a&&s.default(l||a),r.env&&s.env(r.env),(t==null?void 0:t.required)&&s.makeOptionMandatory(!0),s},$=e=>{let{program:t,commandName:r,dotsecConfig:o}=e,n=rt[r||t.name()];if(n){let{options:a,requiredOptions:l,description:s,usage:p,helpText:i}=n;a&&Object.keys(a).forEach(m=>{let d=a[m],O=Pe(d,{dotsecConfig:o,optionKey:m});t.addOption(O)}),l&&Object.keys(l).forEach(m=>{let d=l[m],O=Pe(d,{required:!0,dotsecConfig:o,optionKey:m});t.addOption(O)}),s&&t.description(s),p&&t.description(p),i&&t.description(i)}};var at=async(e,t)=>{let{dotsecConfig:r,decryptHandlers:o}=t,n=e.enablePositionalOptions().passThroughOptions().command("decrypt").action(async(l,s)=>{var p;try{let{envFile:i,secFile:m,engine:d,yes:O}=s.optsWithGlobals(),F=d||((p=r==null?void 0:r.defaults)==null?void 0:p.encryptionEngine),E=(o||[]).find(v=>v.triggerOptionValue===F);if(!E)throw new Error(`No decryption plugin found, available decryption engine(s): ${t.decryptHandlers.map(v=>`--${v.triggerOptionValue}`).join(", ")}`);console.log("Decrypting with",x(E.encryptionEngineName||E.triggerOptionValue),"engine");let f=[...Object.keys(E.options||{}),...Object.keys(E.requiredOptions||{})],u=Object.fromEntries(f.map(v=>[v,l[v]])),g=await M(m),C=await E.handler(c({ciphertext:g},u)),y=await R({filePath:i,skip:O});(y===void 0||y.overwrite===!0)&&(await N(i,C),console.log(`Wrote plaintext contents of ${x(m)} file to ${x(i)}`))}catch(i){console.error(x(i.message)),s.help()}});t.decryptHandlers.map(l=>{let{options:s,requiredOptions:p}=l;_(s,n),_(p,n,!0)});let a=t.decryptHandlers.map(l=>l.triggerOptionValue);return n.option("--engine <engine>",`Encryption engine${a.length>0?"s":""} to use: ${a.length===1?a[0]:a.join(", ")}`,a.length===1?a[0]:void 0),$({program:n,dotsecConfig:r}),n},xe=at;var ct=async(e,t)=>{let{encryptHandlers:r,dotsecConfig:o}=t,n=e.enablePositionalOptions().passThroughOptions().command("encrypt").action(async(s,p)=>{var i;try{let{envFile:m,secFile:d,engine:O,yes:F}=p.optsWithGlobals(),E=O||((i=o==null?void 0:o.defaults)==null?void 0:i.encryptionEngine),f=(r||[]).find(w=>w.triggerOptionValue===E);if(!f)throw new Error(`No encryption plugin found, available encryption engine(s): ${t.encryptHandlers.map(w=>w.triggerOptionValue).join(", ")}`);console.log("Encrypting with",x(f.encryptionEngineName||f.triggerOptionValue),"engine");let u=[...Object.keys(f.options||{}),...Object.keys(f.requiredOptions||{})],g=Object.fromEntries(u.map(w=>[w,s[w]])),C=await M(m),y=await f.handler(c({plaintext:C},g)),v=await R({filePath:d,skip:F});(v===void 0||v.overwrite===!0)&&(await N(d,y),console.log(`Wrote encrypted contents of ${x(m)} file to ${x(d)}`))}catch(m){console.error(x(m.message)),p.help()}});t.encryptHandlers.map(s=>{let{options:p,requiredOptions:i}=s;_(p,n),_(i,n,!0)});let a=t.encryptHandlers.map(s=>s.triggerOptionValue),l=t.encryptHandlers.map(s=>s.encryptionEngineName);return n.option("--engine <engine>",`Encryption engine${a.length>0?"s":""}: ${a.length===1?a[0]:a.join(", ")}`),$({program:n,dotsecConfig:o}),n.description(`Encrypt .env file using ${l.join(", ")}`),n},be=ct;var Se=h(require("node:fs")),D=h(require("typescript")),Te=e=>{let t=D.createPrinter(),r=Se.default.readFileSync(e.configFile,"utf8"),o=p=>i=>{function m(d){var O,F,E,f,u,g,C,y,v,w,b,S,L,ee,te,oe,ne,ie;if(d=D.visitEachChild(d,m,p),d.kind===D.SyntaxKind.StringLiteral){let I=(F=(O=d==null?void 0:d.parent)==null?void 0:O.parent)==null?void 0:F.parent;if(((u=(f=(E=e.config)==null?void 0:E.aws)==null?void 0:f.kms)==null?void 0:u.keyAlias)&&((g=I==null?void 0:I.getChildAt(0))==null?void 0:g.getText())==="kms"){let H=(C=I==null?void 0:I.parent)==null?void 0:C.parent;if((H==null?void 0:H.getChildAt(0).getText())==="aws")return D.createStringLiteral((w=(v=(y=e.config)==null?void 0:y.aws)==null?void 0:v.kms)==null?void 0:w.keyAlias)}if(((S=(b=e.config)==null?void 0:b.aws)==null?void 0:S.region)&&((ee=(L=d==null?void 0:d.parent)==null?void 0:L.getChildAt(0))==null?void 0:ee.getText())==="region"){let H=(oe=(te=d==null?void 0:d.parent)==null?void 0:te.parent)==null?void 0:oe.parent;if((H==null?void 0:H.getChildAt(0).getText())==="aws")return D.createStringLiteral((ie=(ne=e.config)==null?void 0:ne.aws)==null?void 0:ie.region)}}return d}return D.visitNode(i,m)},n=D.createSourceFile("test.ts",r,D.ScriptTarget.ES2015,!0,D.ScriptKind.TS),a=D.transform(n,[o]),l=a.transformed[0],s=t.printFile(l);return a.dispose(),s};var je=h(require("node:path")),pt=async(e,t)=>{let{dotsecConfig:r}=t,o=e.enablePositionalOptions().passThroughOptions().command("init").action(async(n,a)=>{let{configFile:l,yes:s}=a.optsWithGlobals();try{let p=Te({configFile:je.default.resolve(__dirname,"../../src/templates/dotsec.config.ts")}),i=await R({filePath:l,skip:s});(i===void 0||i.overwrite===!0)&&(await N(l,p),console.log(`Wrote config file to ${x(l)}`))}catch(p){a.error(p)}});return $({program:o,dotsecConfig:r}),o},$e=pt;var ke=h(require("dotenv")),_e=h(require("dotenv-expand")),Y=h(require("node:fs")),lt=async(e,t)=>{let{dotsecConfig:r,handlers:o}=t,n=e.enablePositionalOptions().passThroughOptions().command("push").action(async(a,l)=>{var s,p,i;try{let{envFile:m,secFile:d,withEnv:O,withSec:F,engine:E,yes:f}=l.optsWithGlobals(),u=E||((s=r==null?void 0:r.defaults)==null?void 0:s.encryptionEngine),g=(p=(o||[]).find(b=>{var S;return((S=b.decrypt)==null?void 0:S.triggerOptionValue)===u}))==null?void 0:p.decrypt,C=(i=(o||[]).find(b=>{var S;return((S=b.push)==null?void 0:S.triggerOptionValue)===u}))==null?void 0:i.push;if(!C)throw new Error("No push plugin found!");let y=[...Object.keys((g==null?void 0:g.options)||{}),...Object.keys((g==null?void 0:g.requiredOptions)||{}),...Object.keys((C==null?void 0:C.options)||{}),...Object.keys((C==null?void 0:C.requiredOptions)||{})],v=Object.fromEntries(y.map(b=>[b,a[b]]));if(O&&F)throw new Error("Cannot use both --with-env and --with-sec");let w;if(O||!(O||F)){if(!m)throw new Error("No dotenv file specified in --env-file option");w=Y.default.readFileSync(m,"utf8")}else if(F){if(!d)throw new Error("No dotsec file specified in --sec-file option");if(!g)throw new Error(`No decryption plugin found, available decryption engine(s): ${o.map(S=>{var L;return`--${(L=S.decrypt)==null?void 0:L.triggerOptionValue}`}).join(", ")}`);let b=Y.default.readFileSync(d,"utf8");w=await g.handler(c({ciphertext:b},v))}if(w){let b=(0,ke.parse)(w),S=(0,_e.expand)({ignoreProcessEnv:!0,parsed:c(c({},process.env),b)});S.parsed&&await C.handler(c({push:S.parsed,yes:f},v))}else throw new Error("No .env or .sec file provided")}catch(m){console.error(m),process.exit(1)}});return $({program:n,dotsecConfig:r}),n},Ae=lt;var Z=h(require("node:fs")),Ve=h(require("dotenv")),He=h(require("dotenv-expand"));var Ie=h(require("node:child_process")),mt=(e,t)=>{let{dotsecConfig:r,decryptHandlers:o}=t||{},n=o!==void 0&&o.length>0,a=e.command("run <command...>").allowUnknownOption(!0).enablePositionalOptions().passThroughOptions().showHelpAfterError(!0).action(async(l,s,p)=>{var i;try{let{envFile:m,secFile:d,withEnv:O,withSec:F,engine:E}=p.optsWithGlobals();if(O&&F)throw new Error("Cannot use both --with-env and --with-sec");let f;if(O||!(O||F)||n===!1){if(!m)throw new Error("No dotenv file specified in --env-file option");f=Z.default.readFileSync(m,"utf8")}else if(F){if(!d)throw new Error("No dotsec file specified in --sec-file option");let u=E||((i=r==null?void 0:r.defaults)==null?void 0:i.encryptionEngine),g=(o||[]).find(w=>w.triggerOptionValue===u);if(!g)throw new Error(`No decryption plugin found, available decryption engine(s): ${(o||[]).map(w=>`--${w.triggerOptionValue}`).join(", ")}`);let C=[...Object.keys(g.options||{}),...Object.keys(g.requiredOptions||{})],y=Object.fromEntries(C.map(w=>[w,s[w]])),v=Z.default.readFileSync(d,"utf8");f=await g.handler(c({ciphertext:v},y))}if(f){let u=(0,Ve.parse)(f),g=(0,He.expand)({ignoreProcessEnv:!0,parsed:c(c({},process.env),u)}),[C,...y]=l,v=(0,Ie.spawnSync)(C,[...y],{stdio:"inherit",shell:!1,encoding:"utf-8",env:P(c(c({},g.parsed),process.env),{__DOTSEC_ENV__:JSON.stringify(Object.keys(u))})});v.status!==0&&process.exit(v.status||1)}else throw new Error("No .env or .sec file provided")}catch(m){console.error(x(m.message)),p.help()}});if($({program:a,commandName:n?"run":"runEnvOnly",dotsecConfig:r}),n){o==null||o.map(s=>{let{options:p,requiredOptions:i}=s;_(p,a),_(i,a,!0)});let l=o==null?void 0:o.map(s=>s.triggerOptionValue);a.option("--engine <engine>",`Encryption engine${l.length>0?"s":""}: ${l.join(", "),l.length===1?l[0]:void 0}`)}return a},Ne=mt;var Le=h(require("ajv")),qe=h(require("yargs-parser")),dt={keyword:"separator",type:"string",metaSchema:{type:"string",description:"value separator"},modifying:!0,valid:!0,errors:!1,compile:e=>(t,r)=>{if(r){let{parentData:o,parentDataProperty:n}=r;return o[n]=t===""?[]:t.split(e),!0}else return!1}},A=new Re.Command;(async()=>{var d,O,F,E;let e=(0,qe.default)(process.argv),t=[];e.plugin&&(Array.isArray(e.plugin)?t.push(...e.plugin):t.push(e.plugin));let r=[...Array.isArray(e.config)?e.config:[e.config],...Array.isArray(e.c)?e.c:[e.c]][0],{contents:o={}}=await ge(r),{defaults:n,push:a}=o;A.name("dotsec").description(".env, but secure").version("1.0.0").enablePositionalOptions().action((f,u)=>{u.help()}),$({program:A,dotsecConfig:o});let l=new Le.default({allErrors:!0,removeAdditional:!0,useDefaults:!0,coerceTypes:!0,allowUnionTypes:!0,addUsedSchema:!1,keywords:[dt]}),s={};if(t.length>0)for(let f of t){let g=await(await X({name:f}))({dotsecConfig:o,ajv:l,configFile:r});s[g.name]=f,t.length===1&&(o.defaults=P(c({},o.defaults),{encryptionEngine:String(g.name),plugins:P(c({},(d=o.defaults)==null?void 0:d.plugins),{[g.name]:c({},(F=(O=o.defaults)==null?void 0:O.plugins)==null?void 0:F[g.name])})}))}(n==null?void 0:n.encryptionEngine)&&(((E=n==null?void 0:n.plugins)==null?void 0:E[n.encryptionEngine])||(n.plugins=P(c({},n.plugins),{[n.encryptionEngine]:{}}))),(n==null?void 0:n.plugins)&&Object.entries(n==null?void 0:n.plugins).forEach(([f,u])=>{(u==null?void 0:u.module)?s[f]=u==null?void 0:u.module:s[f]=`@dotsec/plugin-${f}`}),Object.values(a||{}).forEach(f=>{Object.keys(f).forEach(u=>{s[u]||(s[u]=`@dotsec/plugin-${u}`)})});let p=[],i=[],m=[];for(let f of Object.keys(s)){let u=s[f],g=await X({name:u}),{addCliCommand:C,cliHandlers:y}=await g({ajv:l,dotsecConfig:o,configFile:r});(y==null?void 0:y.encrypt)&&p.push(y.encrypt),(y==null?void 0:y.decrypt)&&(i.push(y.decrypt),(y==null?void 0:y.push)&&m.push({push:y.push,decrypt:y.decrypt})),C&&C({program:A})}p.length&&await be(A,{dotsecConfig:o,encryptHandlers:p}),i.length&&await xe(A,{dotsecConfig:o,decryptHandlers:i}),m.length&&await Ae(A,{dotsecConfig:o,handlers:m}),await $e(A,{dotsecConfig:o}),await Ne(A,{dotsecConfig:o,decryptHandlers:i}),await A.parse()})();
9
41
  //# sourceMappingURL=index.js.map