@dotenvx/primitives 0.2.1 → 0.4.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.
Files changed (2) hide show
  1. package/dist/index.cjs +324 -23
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -3146,7 +3146,7 @@ var require_hash_to_curve = __commonJS({
3146
3146
  k: "number",
3147
3147
  hash: "function"
3148
3148
  });
3149
- const { p, k, m, hash, expand, DST } = options;
3149
+ const { p, k, m, hash, expand: expand2, DST } = options;
3150
3150
  if (!(0, utils_ts_1.isHash)(options.hash))
3151
3151
  throw new Error("expected valid hash");
3152
3152
  (0, utils_ts_1.abytes)(msg);
@@ -3155,11 +3155,11 @@ var require_hash_to_curve = __commonJS({
3155
3155
  const L = Math.ceil((log2p + k) / 8);
3156
3156
  const len_in_bytes = count * m * L;
3157
3157
  let prb;
3158
- if (expand === "xmd") {
3158
+ if (expand2 === "xmd") {
3159
3159
  prb = expand_message_xmd(msg, DST, len_in_bytes, hash);
3160
- } else if (expand === "xof") {
3160
+ } else if (expand2 === "xof") {
3161
3161
  prb = expand_message_xof(msg, DST, len_in_bytes, k, hash);
3162
- } else if (expand === "_internal_pass") {
3162
+ } else if (expand2 === "_internal_pass") {
3163
3163
  prb = msg;
3164
3164
  } else {
3165
3165
  throw new Error('expand must be "xmd" or "xof"');
@@ -5318,7 +5318,7 @@ var require_hkdf = __commonJS({
5318
5318
  Object.defineProperty(exports2, "__esModule", { value: true });
5319
5319
  exports2.hkdf = void 0;
5320
5320
  exports2.extract = extract;
5321
- exports2.expand = expand;
5321
+ exports2.expand = expand2;
5322
5322
  var hmac_ts_1 = require_hmac();
5323
5323
  var utils_ts_1 = require_utils2();
5324
5324
  function extract(hash, ikm, salt) {
@@ -5329,7 +5329,7 @@ var require_hkdf = __commonJS({
5329
5329
  }
5330
5330
  var HKDF_COUNTER = /* @__PURE__ */ Uint8Array.from([0]);
5331
5331
  var EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();
5332
- function expand(hash, prk, info, length = 32) {
5332
+ function expand2(hash, prk, info, length = 32) {
5333
5333
  (0, utils_ts_1.ahash)(hash);
5334
5334
  (0, utils_ts_1.anumber)(length);
5335
5335
  const olen = hash.outputLen;
@@ -5353,7 +5353,7 @@ var require_hkdf = __commonJS({
5353
5353
  (0, utils_ts_1.clean)(T, HKDF_COUNTER);
5354
5354
  return okm.slice(0, length);
5355
5355
  }
5356
- var hkdf = (hash, ikm, salt, info, length) => expand(hash, extract(hash, ikm, salt), info, length);
5356
+ var hkdf = (hash, ikm, salt, info, length) => expand2(hash, extract(hash, ikm, salt), info, length);
5357
5357
  exports2.hkdf = hkdf;
5358
5358
  }
5359
5359
  });
@@ -5588,18 +5588,18 @@ var require_symmetric = __commonJS({
5588
5588
  function _encrypt(func, key, data, nonceLength, tagLength, AAD) {
5589
5589
  const nonce = (0, webcrypto_1.randomBytes)(nonceLength);
5590
5590
  const cipher = func(key, nonce, AAD);
5591
- const encrypted = cipher.encrypt(data);
5592
- const cipherTextLength = encrypted.length - tagLength;
5593
- const cipherText = encrypted.subarray(0, cipherTextLength);
5594
- const tag = encrypted.subarray(cipherTextLength);
5591
+ const encrypted2 = cipher.encrypt(data);
5592
+ const cipherTextLength = encrypted2.length - tagLength;
5593
+ const cipherText = encrypted2.subarray(0, cipherTextLength);
5594
+ const tag = encrypted2.subarray(cipherTextLength);
5595
5595
  return (0, utils_1.concatBytes)(nonce, tag, cipherText);
5596
5596
  }
5597
5597
  function _decrypt(func, key, data, nonceLength, tagLength, AAD) {
5598
5598
  const nonce = data.subarray(0, nonceLength);
5599
5599
  const cipher = func(key, Uint8Array.from(nonce), AAD);
5600
- const encrypted = data.subarray(nonceLength);
5601
- const tag = encrypted.subarray(0, tagLength);
5602
- const cipherText = encrypted.subarray(tagLength);
5600
+ const encrypted2 = data.subarray(nonceLength);
5601
+ const tag = encrypted2.subarray(0, tagLength);
5602
+ const cipherText = encrypted2.subarray(tagLength);
5603
5603
  return cipher.decrypt((0, utils_1.concatBytes)(cipherText, tag));
5604
5604
  }
5605
5605
  }
@@ -5838,17 +5838,17 @@ var require_dist = __commonJS({
5838
5838
  const receiverPK = receiverRawPK instanceof Uint8Array ? new index_js_1.PublicKey(receiverRawPK, curve) : index_js_1.PublicKey.fromHex(receiverRawPK, curve);
5839
5839
  const sharedKey = ephemeralSK.encapsulate(receiverPK, config.isHkdfKeyCompressed);
5840
5840
  const ephemeralPK = ephemeralSK.publicKey.toBytes(config.isEphemeralKeyCompressed);
5841
- const encrypted = (0, index_js_2.symEncrypt)(config, sharedKey, data);
5842
- return (0, utils_1.concatBytes)(ephemeralPK, encrypted);
5841
+ const encrypted2 = (0, index_js_2.symEncrypt)(config, sharedKey, data);
5842
+ return (0, utils_1.concatBytes)(ephemeralPK, encrypted2);
5843
5843
  }
5844
5844
  function decrypt2(receiverRawSK, data, config = config_js_1.ECIES_CONFIG) {
5845
5845
  const curve = config.ellipticCurve;
5846
5846
  const receiverSK = receiverRawSK instanceof Uint8Array ? new index_js_1.PrivateKey(receiverRawSK, curve) : index_js_1.PrivateKey.fromHex(receiverRawSK, curve);
5847
5847
  const keySize = config.ephemeralKeySize;
5848
5848
  const ephemeralPK = new index_js_1.PublicKey(data.subarray(0, keySize), curve);
5849
- const encrypted = data.subarray(keySize);
5849
+ const encrypted2 = data.subarray(keySize);
5850
5850
  const sharedKey = ephemeralPK.decapsulate(receiverSK, config.isHkdfKeyCompressed);
5851
- return (0, index_js_2.symDecrypt)(config, sharedKey, encrypted);
5851
+ return (0, index_js_2.symDecrypt)(config, sharedKey, encrypted2);
5852
5852
  }
5853
5853
  var config_js_2 = require_config();
5854
5854
  Object.defineProperty(exports2, "ECIES_CONFIG", { enumerable: true, get: function() {
@@ -5872,11 +5872,13 @@ var require_errors = __commonJS({
5872
5872
  INVALID_PRIVATE_KEY: "https://github.com/dotenvx/dotenvx/issues/465",
5873
5873
  WRONG_PRIVATE_KEY: "https://github.com/dotenvx/dotenvx/issues/466",
5874
5874
  MALFORMED_ENCRYPTED_DATA: "https://github.com/dotenvx/dotenvx/issues/467",
5875
- DECRYPTION_FAILED: "https://github.com/dotenvx/dotenvx/issues/757"
5875
+ DECRYPTION_FAILED: "https://github.com/dotenvx/dotenvx/issues/757",
5876
+ COMMAND_SUBSTITUTION_FAILED: "https://github.com/dotenvx/dotenvx/issues/532"
5876
5877
  };
5877
5878
  var Errors = class {
5878
5879
  constructor(options = {}) {
5879
5880
  this.message = options.message;
5881
+ this.command = options.command;
5880
5882
  }
5881
5883
  missingPrivateKey() {
5882
5884
  const code = "MISSING_PRIVATE_KEY";
@@ -5928,20 +5930,42 @@ var require_errors = __commonJS({
5928
5930
  e.messageWithHelp = `${message}. ${help}`;
5929
5931
  return e;
5930
5932
  }
5933
+ commandSubstitutionFailed() {
5934
+ const code = "COMMAND_SUBSTITUTION_FAILED";
5935
+ const message = `[${code}] could not evaluate command '${this.command}': ${this.message}`;
5936
+ const help = `fix: [${ISSUE_BY_CODE[code]}]`;
5937
+ const e = new Error(message);
5938
+ e.code = code;
5939
+ e.help = help;
5940
+ e.messageWithHelp = `${message}. ${help}`;
5941
+ return e;
5942
+ }
5931
5943
  };
5932
5944
  Errors.ISSUE_BY_CODE = ISSUE_BY_CODE;
5933
5945
  module2.exports = Errors;
5934
5946
  }
5935
5947
  });
5936
5948
 
5949
+ // src/encrypted.js
5950
+ var require_encrypted = __commonJS({
5951
+ "src/encrypted.js"(exports2, module2) {
5952
+ var PREFIX = "encrypted:";
5953
+ function encrypted2(value) {
5954
+ return value.startsWith(PREFIX);
5955
+ }
5956
+ module2.exports = encrypted2;
5957
+ module2.exports.PREFIX = PREFIX;
5958
+ }
5959
+ });
5960
+
5937
5961
  // src/decrypt.js
5938
5962
  var require_decrypt = __commonJS({
5939
5963
  "src/decrypt.js"(exports2, module2) {
5940
5964
  var { decrypt: eciesDecrypt } = require_dist();
5941
5965
  var Errors = require_errors();
5942
- var PREFIX = "encrypted:";
5966
+ var encrypted2 = require_encrypted();
5943
5967
  function decrypt2(privateKeyHex, encryptedValue) {
5944
- if (!encryptedValue.startsWith(PREFIX)) {
5968
+ if (!encrypted2(encryptedValue)) {
5945
5969
  return encryptedValue;
5946
5970
  }
5947
5971
  if (!privateKeyHex || privateKeyHex.length < 1) {
@@ -5949,7 +5973,7 @@ var require_decrypt = __commonJS({
5949
5973
  }
5950
5974
  try {
5951
5975
  const privateKey = Buffer.from(privateKeyHex, "hex");
5952
- const ciphertext = Buffer.from(encryptedValue.substring(PREFIX.length), "base64");
5976
+ const ciphertext = Buffer.from(encryptedValue.substring(encrypted2.PREFIX.length), "base64");
5953
5977
  return Buffer.from(eciesDecrypt(privateKey, ciphertext)).toString("utf8");
5954
5978
  } catch (e) {
5955
5979
  if (e.message === "Invalid private key") {
@@ -5967,8 +5991,285 @@ var require_decrypt = __commonJS({
5967
5991
  }
5968
5992
  });
5969
5993
 
5994
+ // src/derive.js
5995
+ var require_derive = __commonJS({
5996
+ "src/derive.js"(exports2, module2) {
5997
+ var { PrivateKey } = require_dist();
5998
+ function derive2(privateKeyHex) {
5999
+ return new PrivateKey(Buffer.from(privateKeyHex, "hex")).publicKey.toHex();
6000
+ }
6001
+ module2.exports = derive2;
6002
+ }
6003
+ });
6004
+
6005
+ // src/evaluate.js
6006
+ var require_evaluate = __commonJS({
6007
+ "src/evaluate.js"(exports2, module2) {
6008
+ var { execSync } = require("child_process");
6009
+ var Errors = require_errors();
6010
+ function chomp(value) {
6011
+ return value.replace(/[\r\n]+$/, "");
6012
+ }
6013
+ function evaluate2(value, opts) {
6014
+ const processEnv = opts.processEnv || process.env;
6015
+ const runningParsed = opts.runningParsed || {};
6016
+ const matches = value.match(/\$\(([^)]+(?:\)[^(]*)*)\)/g) || [];
6017
+ return matches.reduce((newValue, match) => {
6018
+ const command = match.slice(2, -1);
6019
+ let result;
6020
+ try {
6021
+ result = execSync(command, { env: { ...processEnv, ...runningParsed } }).toString();
6022
+ } catch (e) {
6023
+ throw new Errors({ command, message: e.message.trim() }).commandSubstitutionFailed();
6024
+ }
6025
+ result = chomp(result);
6026
+ return newValue.replace(match, result);
6027
+ }, value);
6028
+ }
6029
+ module2.exports = evaluate2;
6030
+ }
6031
+ });
6032
+
6033
+ // src/expand.js
6034
+ var require_expand = __commonJS({
6035
+ "src/expand.js"(exports2, module2) {
6036
+ function expand2(value, opts) {
6037
+ const overload = opts.overload;
6038
+ const processEnv = opts.processEnv || process.env;
6039
+ const runningParsed = opts.runningParsed || {};
6040
+ const literals = opts.literals || {};
6041
+ let env = { ...runningParsed, ...processEnv };
6042
+ if (overload) {
6043
+ env = { ...processEnv, ...runningParsed };
6044
+ }
6045
+ const regex = /(?<!\\)\${([^{}]+)}|(?<!\\)\$([A-Za-z_][A-Za-z0-9_]*)/g;
6046
+ let result = value;
6047
+ let match;
6048
+ while ((match = regex.exec(result)) !== null) {
6049
+ const [template, bracedExpression, unbracedExpression] = match;
6050
+ const expression = bracedExpression || unbracedExpression;
6051
+ const opRegex = /(:\+|\+|:-|-)/;
6052
+ const opMatch = expression.match(opRegex);
6053
+ const splitter = opMatch ? opMatch[0] : null;
6054
+ const r = expression.split(splitter);
6055
+ let defaultValue;
6056
+ let value2;
6057
+ const name = r.shift();
6058
+ if ([":+", "+"].includes(splitter)) {
6059
+ defaultValue = env[name] ? r.join(splitter) : "";
6060
+ value2 = null;
6061
+ } else {
6062
+ defaultValue = r.join(splitter);
6063
+ value2 = env[name];
6064
+ }
6065
+ if (value2) {
6066
+ result = result.replace(template, value2);
6067
+ } else {
6068
+ result = result.replace(template, defaultValue);
6069
+ }
6070
+ if (result === env[name]) {
6071
+ break;
6072
+ }
6073
+ if (literals[name] && /\$\{[^}]+\}|\$[A-Za-z_][A-Za-z0-9_]*/.test(literals[name])) {
6074
+ break;
6075
+ }
6076
+ regex.lastIndex = 0;
6077
+ }
6078
+ return result;
6079
+ }
6080
+ module2.exports = expand2;
6081
+ }
6082
+ });
6083
+
6084
+ // src/scan.js
6085
+ var require_scan = __commonJS({
6086
+ "src/scan.js"(exports2, module2) {
6087
+ function trimmer(value) {
6088
+ return (value || "").trim();
6089
+ }
6090
+ function getQuote(value) {
6091
+ const v = trimmer(value);
6092
+ const maybeQuote = v[0];
6093
+ let q = "";
6094
+ switch (maybeQuote) {
6095
+ // single
6096
+ case "'":
6097
+ q = "'";
6098
+ break;
6099
+ // double
6100
+ case '"':
6101
+ q = '"';
6102
+ break;
6103
+ // backtick
6104
+ case "`":
6105
+ q = "`";
6106
+ break;
6107
+ // empty
6108
+ default:
6109
+ q = "";
6110
+ }
6111
+ return q;
6112
+ }
6113
+ function clean(value, quote) {
6114
+ let v = trimmer(value);
6115
+ v = v.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
6116
+ if (quote === '"') {
6117
+ v = v.replace(/\\n/g, "\n");
6118
+ v = v.replace(/\\r/g, "\r");
6119
+ v = v.replace(/\\t/g, " ");
6120
+ }
6121
+ return v;
6122
+ }
6123
+ function scan2(src, transform) {
6124
+ const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
6125
+ const parsed = {};
6126
+ const lines = (src || "").toString().replace(/\r\n?/mg, "\n");
6127
+ let match;
6128
+ while ((match = LINE.exec(lines)) !== null) {
6129
+ const name = match[1];
6130
+ const raw = match[2];
6131
+ const quote = getQuote(raw);
6132
+ const value = clean(raw, quote);
6133
+ let parsedValue = value;
6134
+ if (typeof transform === "function") {
6135
+ parsedValue = transform({
6136
+ name,
6137
+ value,
6138
+ quote
6139
+ });
6140
+ }
6141
+ parsed[name] = parsedValue;
6142
+ }
6143
+ return {
6144
+ parsed
6145
+ };
6146
+ }
6147
+ module2.exports = scan2;
6148
+ }
6149
+ });
6150
+
6151
+ // src/keyring.js
6152
+ var require_keyring = __commonJS({
6153
+ "src/keyring.js"(exports2, module2) {
6154
+ var fs = require("fs");
6155
+ var derive2 = require_derive();
6156
+ var scan2 = require_scan();
6157
+ function keysFromFile(filepath = ".env.keys") {
6158
+ try {
6159
+ const src = fs.readFileSync(filepath, "utf8");
6160
+ const { parsed } = scan2(src);
6161
+ return parsed;
6162
+ } catch (_e) {
6163
+ return {};
6164
+ }
6165
+ }
6166
+ function keyring2() {
6167
+ const mem = {};
6168
+ const processEnv = process.env;
6169
+ const keysFilepath = ".env.keys";
6170
+ const sources = {
6171
+ ...keysFromFile(keysFilepath),
6172
+ ...processEnv
6173
+ // process.env wins
6174
+ };
6175
+ for (const name in sources) {
6176
+ if (name.startsWith("DOTENV_PRIVATE_KEY")) {
6177
+ try {
6178
+ const privateKeyHex = sources[name];
6179
+ const publicKeyHex = derive2(privateKeyHex);
6180
+ mem[publicKeyHex] = privateKeyHex;
6181
+ } catch (_e) {
6182
+ }
6183
+ }
6184
+ }
6185
+ return mem;
6186
+ }
6187
+ module2.exports = keyring2;
6188
+ }
6189
+ });
6190
+
6191
+ // src/parse.js
6192
+ var require_parse = __commonJS({
6193
+ "src/parse.js"(exports2, module2) {
6194
+ var decrypt2 = require_decrypt();
6195
+ var keyring2 = require_keyring();
6196
+ var encrypted2 = require_encrypted();
6197
+ var evaluate2 = require_evaluate();
6198
+ var expand2 = require_expand();
6199
+ var scan2 = require_scan();
6200
+ function resolveEscapeSequences(value) {
6201
+ return value.replace(/\\\$/g, "$");
6202
+ }
6203
+ function parse2(src, opts = {}) {
6204
+ const overload = opts.overload;
6205
+ const processEnv = opts.processEnv || process.env;
6206
+ const ring = keyring2();
6207
+ function inProcessEnv(name) {
6208
+ return Object.prototype.hasOwnProperty.call(processEnv, name);
6209
+ }
6210
+ let publicKeyHex;
6211
+ let runningParsed = {};
6212
+ let literals = {};
6213
+ const { parsed } = scan2(src, ({ name, value, quote }) => {
6214
+ let parsedValue = value;
6215
+ if (name.startsWith("DOTENV_PUBLIC_KEY")) {
6216
+ publicKeyHex = parsedValue;
6217
+ }
6218
+ if (!overload && inProcessEnv(name)) {
6219
+ parsedValue = processEnv[name];
6220
+ }
6221
+ try {
6222
+ parsedValue = decrypt2(ring[publicKeyHex], parsedValue);
6223
+ } catch (_e) {
6224
+ }
6225
+ const encryptedPrefixed = encrypted2(parsedValue);
6226
+ let evaled = false;
6227
+ if (!encryptedPrefixed && quote !== "'" && (!inProcessEnv(name) || processEnv[name] === parsedValue)) {
6228
+ const priorEvaled = parsedValue;
6229
+ try {
6230
+ parsedValue = evaluate2(priorEvaled, { processEnv, runningParsed });
6231
+ } catch (_e) {
6232
+ }
6233
+ if (priorEvaled !== parsedValue) {
6234
+ evaled = true;
6235
+ }
6236
+ }
6237
+ if (!encryptedPrefixed && !evaled && quote !== "'" && (!processEnv[name] || overload)) {
6238
+ parsedValue = resolveEscapeSequences(expand2(parsedValue, { processEnv, runningParsed, literals }));
6239
+ }
6240
+ if (quote === "'") {
6241
+ literals[name] = parsedValue;
6242
+ }
6243
+ runningParsed[name] = parsedValue;
6244
+ if (Object.prototype.hasOwnProperty.call(processEnv, name) && !overload) {
6245
+ } else {
6246
+ }
6247
+ return parsedValue;
6248
+ });
6249
+ return {
6250
+ parsed
6251
+ };
6252
+ }
6253
+ module2.exports = parse2;
6254
+ }
6255
+ });
6256
+
5970
6257
  // src/index.js
5971
6258
  var decrypt = require_decrypt();
6259
+ var derive = require_derive();
6260
+ var encrypted = require_encrypted();
6261
+ var evaluate = require_evaluate();
6262
+ var expand = require_expand();
6263
+ var keyring = require_keyring();
6264
+ var parse = require_parse();
6265
+ var scan = require_scan();
5972
6266
  module.exports = {
5973
- decrypt
6267
+ decrypt,
6268
+ derive,
6269
+ encrypted,
6270
+ evaluate,
6271
+ expand,
6272
+ keyring,
6273
+ parse,
6274
+ scan
5974
6275
  };
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.2.1",
2
+ "version": "0.4.0",
3
3
  "name": "@dotenvx/primitives",
4
4
  "description": "a secure dotenv–from the creator of `dotenv`",
5
5
  "author": "@motdotla",