@karmaniverous/get-dotenv 2.6.7 → 3.0.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.
@@ -7,7 +7,8 @@ exports.getDotenvSync = exports.getDotenv = void 0;
7
7
  var _dotenvExpand = require("dotenv-expand");
8
8
  var _fsExtra = _interopRequireDefault(require("fs-extra"));
9
9
  var _path = _interopRequireDefault(require("path"));
10
- var _uuid = require("uuid");
10
+ var _nanoid = require("nanoid");
11
+ var _dotenvDefaults = require("./dotenvDefaults.js");
11
12
  var _readDotenv = require("./readDotenv.js");
12
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
14
  // npm imports
@@ -19,19 +20,20 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
19
20
  *
20
21
  * @typedef {Object} OptionsType
21
22
  *
22
- * @property {string} [dotenvToken] - token indicating a dotenv file (default: '.env')
23
+ * @property {string} [dotenvToken] - token indicating a dotenv file
23
24
  * @property {string} [dynamicPath] - path to file exporting an object keyed to dynamic variable functions
24
25
  * @property {string} [env] - target environment
25
- * @property {bool} [excludeDynamic] - exclude dynamic variables (default: false)
26
- * @property {bool} [excludeEnv] - exclude environment-specific variables (default: false)
27
- * @property {bool} [excludeGlobal] - exclude global & dynamic variables (default: false)
28
- * @property {bool} [excludePrivate] - exclude private variables (default: false)
29
- * @property {bool} [excludePublic] - exclude public variables (default: false)
30
- * @property {bool} [loadProcess] - load dotenv to process.env (default: false)
31
- * @property {bool} [log] - log result to console (default: false)
26
+ * @property {bool} [excludeDynamic] - exclude dynamic variables
27
+ * @property {bool} [excludeEnv] - exclude environment-specific variables
28
+ * @property {bool} [excludeGlobal] - exclude global & dynamic variables
29
+ * @property {bool} [excludePrivate] - exclude private variables
30
+ * @property {bool} [excludePublic] - exclude public variables
31
+ * @property {bool} [loadProcess] - load dotenv to process.env
32
+ * @property {bool} [log] - log result to logger
33
+ * @property {function} [logger] - logger function
32
34
  * @property {string} [outputPath] - if populated, writes consolidated .env file to this path (follows {@link https://github.com/motdotla/dotenv-expand/blob/master/tests/.env dotenv-expand rules})
33
- * @property {string[]} [paths] - array of input directory paths (default ['./'])
34
- * @property {string} [privateToken] - token indicating private variables (default: 'local').
35
+ * @property {string[]} [paths] - array of input directory paths
36
+ * @property {string} [privateToken] - token indicating private variables
35
37
  */
36
38
 
37
39
  /**
@@ -45,34 +47,44 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
45
47
  * @returns {Promise<object>} The combined parsed dotenv object.
46
48
  */
47
49
  const getDotenv = async function () {
50
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
51
+ // Apply defaults.
48
52
  let {
49
- dotenvToken = '.env',
53
+ dotenvToken,
50
54
  env,
51
55
  dynamicPath,
52
- excludeDynamic = false,
53
- excludeEnv = false,
54
- excludeGlobal = false,
55
- excludePrivate = false,
56
- excludePublic = false,
57
- loadProcess = false,
58
- log = false,
56
+ excludeDynamic,
57
+ excludeEnv,
58
+ excludeGlobal,
59
+ excludePrivate,
60
+ excludePublic,
61
+ loadProcess,
62
+ log,
63
+ logger,
59
64
  outputPath,
60
- paths = ['./'],
61
- privateToken = 'local'
62
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
65
+ paths,
66
+ privateToken
67
+ } = {
68
+ ..._dotenvDefaults.dotenvDefaults,
69
+ ...options
70
+ };
71
+
63
72
  // Read .env files.
64
- const parsed = await paths.reduce(async (e, p) => ({
65
- ...(await e),
66
- ...(excludePublic ? {} : {
67
- ...(excludeGlobal ? {} : await (0, _readDotenv.readDotenv)(_path.default.resolve(p, dotenvToken))),
68
- ...(env && !excludeEnv ? await (0, _readDotenv.readDotenv)(_path.default.resolve(p, `${dotenvToken}.${env}`)) : {})
69
- }),
70
- ...(excludePrivate ? {} : {
71
- ...(excludeGlobal ? {} : await (0, _readDotenv.readDotenv)(_path.default.resolve(p, `${dotenvToken}.${privateToken}`))),
72
- ...(env && !excludeEnv ? await (0, _readDotenv.readDotenv)(_path.default.resolve(p, `${dotenvToken}.${env}.${privateToken}`)) : {})
73
- })
74
- }), {});
75
- const outputKey = (0, _uuid.v4)();
73
+ const parsed = await paths.reduce(async (e, p) => {
74
+ let publicGlobal = excludePublic || excludeGlobal ? {} : (0, _readDotenv.readDotenv)(_path.default.resolve(p, dotenvToken));
75
+ let publicEnv = excludePublic || excludeEnv ? {} : (0, _readDotenv.readDotenv)(_path.default.resolve(p, `${dotenvToken}.${env}`));
76
+ let privateGlobal = excludePrivate || excludeGlobal ? {} : (0, _readDotenv.readDotenv)(_path.default.resolve(p, `${dotenvToken}.${privateToken}`));
77
+ let privateEnv = excludePrivate || excludeEnv ? {} : (0, _readDotenv.readDotenv)(_path.default.resolve(p, `${dotenvToken}.${env}.${privateToken}`));
78
+ [e, publicGlobal, publicEnv, privateGlobal, privateEnv] = await Promise.all([e, publicGlobal, publicEnv, privateGlobal, privateEnv]);
79
+ return {
80
+ ...e,
81
+ ...publicGlobal,
82
+ ...publicEnv,
83
+ ...privateGlobal,
84
+ ...privateEnv
85
+ };
86
+ }, {});
87
+ const outputKey = (0, _nanoid.nanoid)();
76
88
  const {
77
89
  parsed: dotenv
78
90
  } = (0, _dotenvExpand.expand)({
@@ -108,14 +120,14 @@ const getDotenv = async function () {
108
120
  }
109
121
 
110
122
  // Log result.
111
- if (log) console.log(dotenv);
123
+ if (log) logger(dotenv);
112
124
 
113
125
  // Load process.env.
114
126
  if (loadProcess) Object.assign(process.env, dotenv, {
115
127
  getdotenvOptions: JSON.stringify({
116
128
  dotenvToken,
117
- dynamicPath,
118
129
  env,
130
+ dynamicPath,
119
131
  excludeDynamic,
120
132
  excludeEnv,
121
133
  excludeGlobal,
@@ -142,34 +154,42 @@ const getDotenv = async function () {
142
154
  */
143
155
  exports.getDotenv = getDotenv;
144
156
  const getDotenvSync = function () {
157
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
158
+ // Apply defaults.
145
159
  let {
146
- dotenvToken = '.env',
147
- dynamicPath,
160
+ dotenvToken,
148
161
  env,
149
- excludeDynamic = false,
150
- excludeEnv = false,
151
- excludeGlobal = false,
152
- excludePrivate = false,
153
- excludePublic = false,
154
- loadProcess = false,
155
- log = false,
162
+ dynamicPath,
163
+ excludeDynamic,
164
+ excludeEnv,
165
+ excludeGlobal,
166
+ excludePrivate,
167
+ excludePublic,
168
+ loadProcess,
169
+ log,
156
170
  outputPath,
157
- paths = ['./'],
158
- privateToken = 'local'
159
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
171
+ paths,
172
+ privateToken
173
+ } = {
174
+ ..._dotenvDefaults.dotenvDefaults,
175
+ ...options
176
+ };
177
+
160
178
  // Read .env files.
161
- const parsed = paths.reduce((e, p) => ({
162
- ...e,
163
- ...(excludePublic ? {} : {
164
- ...(excludeGlobal ? {} : (0, _readDotenv.readDotenvSync)(_path.default.resolve(p, dotenvToken))),
165
- ...(env && !excludeEnv ? (0, _readDotenv.readDotenvSync)(_path.default.resolve(p, `${dotenvToken}.${env}`)) : {})
166
- }),
167
- ...(excludePrivate ? {} : {
168
- ...(excludeGlobal ? {} : (0, _readDotenv.readDotenvSync)(_path.default.resolve(p, `${dotenvToken}.${privateToken}`))),
169
- ...(env && !excludeEnv ? (0, _readDotenv.readDotenvSync)(_path.default.resolve(p, `${dotenvToken}.${env}.${privateToken}`)) : {})
170
- })
171
- }), {});
172
- const outputKey = (0, _uuid.v4)();
179
+ const parsed = paths.reduce((e, p) => {
180
+ let publicGlobal = excludePublic || excludeGlobal ? {} : (0, _readDotenv.readDotenvSync)(_path.default.resolve(p, dotenvToken));
181
+ let publicEnv = excludePublic || excludeEnv ? {} : (0, _readDotenv.readDotenvSync)(_path.default.resolve(p, `${dotenvToken}.${env}`));
182
+ let privateGlobal = excludePrivate || excludeGlobal ? {} : (0, _readDotenv.readDotenvSync)(_path.default.resolve(p, `${dotenvToken}.${privateToken}`));
183
+ let privateEnv = excludePrivate || excludeEnv ? {} : (0, _readDotenv.readDotenvSync)(_path.default.resolve(p, `${dotenvToken}.${env}.${privateToken}`));
184
+ return {
185
+ ...e,
186
+ ...publicGlobal,
187
+ ...publicEnv,
188
+ ...privateGlobal,
189
+ ...privateEnv
190
+ };
191
+ }, {});
192
+ const outputKey = (0, _nanoid.nanoid)();
173
193
  const {
174
194
  parsed: dotenv
175
195
  } = (0, _dotenvExpand.expand)({
@@ -9,10 +9,10 @@ Object.defineProperty(exports, "dotenvExpand", {
9
9
  return _dotenvExpand.dotenvExpand;
10
10
  }
11
11
  });
12
- Object.defineProperty(exports, "getAwsSsoCredentials", {
12
+ Object.defineProperty(exports, "getCli", {
13
13
  enumerable: true,
14
14
  get: function () {
15
- return _getAwsSsoCredentials.getAwsSsoCredentials;
15
+ return _getCli.getCli;
16
16
  }
17
17
  });
18
18
  Object.defineProperty(exports, "getDotenv", {
@@ -27,13 +27,6 @@ Object.defineProperty(exports, "getDotenvSync", {
27
27
  return _getDotenv.getDotenvSync;
28
28
  }
29
29
  });
30
- Object.defineProperty(exports, "parseBranch", {
31
- enumerable: true,
32
- get: function () {
33
- return _parseBranch.parseBranch;
34
- }
35
- });
36
30
  var _dotenvExpand = require("./dotenvExpand.js");
37
- var _getAwsSsoCredentials = require("./getAwsSsoCredentials.js");
38
31
  var _getDotenv = require("./getDotenv.js");
39
- var _parseBranch = require("./parseBranch.js");
32
+ var _getCli = require("./getCli.js");
@@ -0,0 +1,13 @@
1
+ export const dotenvDefaults = {
2
+ dotenvToken: '.env',
3
+ excludeDynamic: false,
4
+ excludeEnv: false,
5
+ excludeGlobal: false,
6
+ excludePrivate: false,
7
+ excludePublic: false,
8
+ loadProcess: false,
9
+ log: false,
10
+ logger: console.log,
11
+ paths: ['./'],
12
+ privateToken: 'local',
13
+ };
package/lib/getCli.js ADDED
@@ -0,0 +1,283 @@
1
+ // npm imports
2
+ import { boolean } from 'boolean';
3
+ import { Command } from 'commander';
4
+ import { execaCommand } from 'execa';
5
+ import fromPairs from 'lodash.frompairs';
6
+ import isString from 'lodash.isstring';
7
+
8
+ // lib imports
9
+ import { dotenvDefaults } from './dotenvDefaults.js';
10
+ import { dotenvExpand } from './dotenvExpand.js';
11
+ import { getDotenv } from './getDotenv.js';
12
+
13
+ const booleanExpand = (value) => boolean(dotenvExpand(value));
14
+
15
+ /**
16
+ * GetDotenv CLI Options type
17
+ *
18
+ * @typedef {Object} GetDotenvCliOptions
19
+ * @property {string} [cliInvocation] - cli invocation string (used for cli help)
20
+ * @property {string} [dotenvToken] - token indicating a dotenv file
21
+ * @property {string} [dynamicPath] - path to file exporting an object keyed to dynamic variable functions
22
+ * @property {string} [env] - target environment
23
+ * @property {bool} [excludeDynamic] - exclude dynamic variables
24
+ * @property {bool} [excludeEnv] - exclude environment-specific variables
25
+ * @property {bool} [excludeGlobal] - exclude global & dynamic variables
26
+ * @property {bool} [excludePrivate] - exclude private variables
27
+ * @property {bool} [excludePublic] - exclude public variables
28
+ * @property {bool} [log] - log result to console
29
+ * @property {function} [logger] - logger function
30
+ * @property {string} [outputPath] - if populated, writes consolidated .env file to this path (follows {@link https://github.com/motdotla/dotenv-expand/blob/master/tests/.env dotenv-expand rules})
31
+ * @property {string} [paths] - space-delimited list of input directory paths
32
+ * @property {string} [privateToken] - token indicating private variables.
33
+ * @property {bool|string} [shell] - execa shell option
34
+ * @property {bool} [suppressDotenv] - suppress dotenv loading
35
+ */
36
+
37
+ /**
38
+ * GetDotenv CLI Pre-hook Callback type. Transforms inbound options & executes side effects.
39
+ *
40
+ * @async
41
+ * @callback GetDotenvPreHookCallback
42
+ * @param {GetDotenvCliOptions} options - inbound GetDotenv CLI Options object
43
+ * @returns {GetDotenvCliOptions} transformed GetDotenv CLI Options object (undefined return value is ignored)
44
+ */
45
+
46
+ /**
47
+ * GetDotenv CLI Post-hook Callback type. Executes side effects within getdotenv context.
48
+ *
49
+ * @async
50
+ * @callback GetDotenvPostHookCallback
51
+ * @param {GetDotenvCliOptions} options - GetDotenv CLI Options object
52
+ * @param {object} dotenv - dotenv object
53
+ */
54
+
55
+ /**
56
+ * GetDotenv CLI Config type
57
+ *
58
+ * @typedef {Object} GetDotenvCliConfig
59
+ * @property {object} [config] - config options
60
+ * @property {GetDotenvCliOptions} [config.defaultOptions] - default options
61
+ * @property {GetDotenvPreHookCallback} [config.preHook] - transforms inbound options & executes side effects
62
+ * @property {GetDotenvPostHookCallback} [config.postHook] - executes side effects within getdotenv context
63
+ */
64
+
65
+ /**
66
+ * Generate a CLI for get-dotenv.
67
+ *
68
+ * @param {GetDotenvCliConfig} [config] - config object
69
+ * @returns {object} The CLI command.
70
+ */
71
+ export const getCli = ({ defaultOptions = {}, preHook, postHook } = {}) => {
72
+ let {
73
+ cliInvocation = 'getdotenv',
74
+ command,
75
+ dotenvToken,
76
+ dynamicPath,
77
+ env,
78
+ excludeDynamic,
79
+ excludeEnv,
80
+ excludeGlobal,
81
+ excludePrivate,
82
+ excludePublic,
83
+ log,
84
+ outputPath,
85
+ paths,
86
+ pathsDelimiter = '\\s+',
87
+ privateToken,
88
+ shell,
89
+ suppressDotenv,
90
+ vars,
91
+ varsAssignor = '=',
92
+ varsDelimiter = '\\s+',
93
+ } = {
94
+ ...dotenvDefaults,
95
+ ...defaultOptions,
96
+ };
97
+
98
+ if (Array.isArray(paths)) paths = paths.join(' ');
99
+
100
+ return (
101
+ new Command()
102
+ .name(cliInvocation)
103
+ // .usage('[options] [command] [command options] [commad args]')
104
+ .description(
105
+ 'Base CLI. All options except delimiters follow dotenv-expand rules.'
106
+ )
107
+ .enablePositionalOptions()
108
+ .passThroughOptions()
109
+ .option('-e, --env <string>', 'environment name', dotenvExpand, env)
110
+ .option(
111
+ '-p, --paths <string>',
112
+ 'delimited list of paths to dotenv directory',
113
+ dotenvExpand,
114
+ paths
115
+ )
116
+ .option(
117
+ '--paths-delimiter <string>',
118
+ 'regex paths delimiter',
119
+ pathsDelimiter
120
+ )
121
+ .option(
122
+ '-v, --vars <string>',
123
+ 'delimited list KEY=VALUE pairs',
124
+ dotenvExpand,
125
+ vars
126
+ )
127
+ .option(
128
+ '--vars-delimiter <string>',
129
+ 'regex vars delimiter',
130
+ varsDelimiter
131
+ )
132
+ .option(
133
+ '--vars-assignor <string>',
134
+ 'regex vars assignment operator',
135
+ varsAssignor
136
+ )
137
+ .option(
138
+ '-y, --dynamic-path <string>',
139
+ 'dynamic variables path',
140
+ dotenvExpand,
141
+ dynamicPath
142
+ )
143
+ .option(
144
+ '-o, --output-path <string>',
145
+ 'consolidated output file, follows dotenv-expand rules using loaded env vars',
146
+ dotenvExpand,
147
+ outputPath
148
+ )
149
+ .option(
150
+ '-n, --exclude-env [bool]',
151
+ 'exclude environment-specific variables',
152
+ booleanExpand,
153
+ excludeEnv ?? false
154
+ )
155
+ .option(
156
+ '-g, --exclude-global [bool]',
157
+ 'exclude global & dynamic variables',
158
+ booleanExpand,
159
+ excludeGlobal ?? false
160
+ )
161
+ .option(
162
+ '-r, --exclude-private [bool]',
163
+ 'exclude private variables',
164
+ booleanExpand,
165
+ excludePrivate ?? false
166
+ )
167
+ .option(
168
+ '-u, --exclude-public [bool]',
169
+ 'exclude public variables',
170
+ booleanExpand,
171
+ excludePublic ?? false
172
+ )
173
+ .option(
174
+ '-z, --exclude-dynamic [bool]',
175
+ 'exclude dynamic variables',
176
+ booleanExpand,
177
+ excludeDynamic ?? false
178
+ )
179
+ .option(
180
+ '-l, --log [bool]',
181
+ 'console log extracted variables',
182
+ booleanExpand,
183
+ log ?? false
184
+ )
185
+ .option(
186
+ '-x, --suppress-dotenv',
187
+ 'suppress dotenv loading',
188
+ booleanExpand,
189
+ suppressDotenv ?? false
190
+ )
191
+ .option(
192
+ '-c, --command <string>',
193
+ 'shell command string',
194
+ dotenvExpand,
195
+ command
196
+ )
197
+ .option('-s, --shell <string>', 'execa shell option', dotenvExpand, shell)
198
+ .option(
199
+ '--dotenv-token <string>',
200
+ 'token indicating a dotenv file',
201
+ dotenvExpand,
202
+ dotenvToken
203
+ )
204
+ .option(
205
+ '--private-token <string>',
206
+ 'token indicating private variables',
207
+ dotenvExpand,
208
+ privateToken
209
+ )
210
+ .addCommand(
211
+ new Command()
212
+ .name('cmd')
213
+ .description('execute shell command string (default command)')
214
+ .configureHelp({ showGlobalOptions: true })
215
+ .enablePositionalOptions()
216
+ .passThroughOptions()
217
+ .action(async (options, { args, parent }) => {
218
+ if (args.length)
219
+ await execaCommand(args.join(' '), {
220
+ stdio: 'inherit',
221
+ shell: parent.opts().shell,
222
+ });
223
+ }),
224
+ { isDefault: true }
225
+ )
226
+ .hook('preSubcommand', async (thisCommand) => {
227
+ // Inherit options from parent command.
228
+ let options = {
229
+ ...(process.env['getdotenvOptions']
230
+ ? JSON.parse(process.env['getdotenvOptions'])
231
+ : {}),
232
+ ...thisCommand.opts(),
233
+ };
234
+
235
+ // Execute pre-hook.
236
+ if (preHook) options = (await preHook(options)) ?? options;
237
+
238
+ // Get options.
239
+ let {
240
+ command,
241
+ paths,
242
+ pathsDelimiter,
243
+ suppressDotenv,
244
+ vars,
245
+ varsDelimiter,
246
+ varsAssignor,
247
+ ...rest
248
+ } = options;
249
+
250
+ // Parse vars.
251
+ if (vars?.length)
252
+ Object.assign(
253
+ process.env,
254
+ fromPairs(
255
+ vars
256
+ .split(new RegExp(varsDelimiter))
257
+ .map((v) => v.split(new RegExp(varsAssignor)))
258
+ )
259
+ );
260
+
261
+ // Execute getdotenv.
262
+ if (paths?.length && !suppressDotenv) {
263
+ if (isString(paths)) paths = paths?.split(new RegExp(pathsDelimiter));
264
+
265
+ var dotenv = await getDotenv({
266
+ ...rest,
267
+ loadProcess: true,
268
+ paths,
269
+ });
270
+ }
271
+
272
+ // Execute post-hook.
273
+ if (postHook) await postHook(options, dotenv);
274
+
275
+ // Execute shell command.
276
+ if (command)
277
+ await execaCommand(command, {
278
+ stdio: 'inherit',
279
+ shell,
280
+ });
281
+ })
282
+ );
283
+ };