@api3/commons 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
1
  import dotenv from 'dotenv';
2
2
  import { z } from 'zod';
3
- export declare const secretNamePattern: RegExp;
4
- export declare const secretNameSchema: z.ZodString;
5
- export declare const secretsSchema: z.ZodRecord<z.ZodString, z.ZodString>;
6
- export declare const nonBlankSecretsSchema: z.ZodRecord<z.ZodString, z.ZodString>;
3
+ export declare const strictSecretNamePattern: RegExp;
4
+ export declare const strictSecretNameSchema: z.ZodString;
5
+ export declare const nonBlankSecretValueSchema: z.ZodString;
7
6
  export type Secrets = Record<string, string>;
8
7
  export interface InterpolationOptions {
9
- allowBlankSecretValue: boolean;
8
+ allowBlankSecretValue?: boolean;
9
+ validateSecretName?: boolean;
10
10
  }
11
11
  export type AnyObject = Record<string, unknown>;
12
12
  export declare function interpolateSecretsIntoConfig<T = AnyObject>(config: T, secrets: unknown, options?: InterpolationOptions): T;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config-parsing/index.ts"],"names":[],"mappings":"AAEA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,iBAAiB,QAAqB,CAAC;AAEpD,eAAO,MAAM,gBAAgB,aAEoF,CAAC;AAElH,eAAO,MAAM,aAAa,uCAAyC,CAAC;AAEpE,eAAO,MAAM,qBAAqB,uCAGjC,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAe7C,MAAM,WAAW,oBAAoB;IACnC,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,wBAAgB,4BAA4B,CAAC,CAAC,GAAG,SAAS,EACxD,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,oBAAsD,KA0BhE;AAED,eAAO,MAAM,WAAW,SAAU,MAAM,6BAA6C,CAAC;AAEtF,eAAO,MAAM,UAAU,SAAU,MAAM,QAA2C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config-parsing/index.ts"],"names":[],"mappings":"AAEA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,uBAAuB,QAAqB,CAAC;AAE1D,eAAO,MAAM,sBAAsB,aAKhC,CAAC;AAEJ,eAAO,MAAM,yBAAyB,aAA2D,CAAC;AAElG,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAe7C,MAAM,WAAW,oBAAoB;IACnC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,wBAAgB,4BAA4B,CAAC,CAAC,GAAG,SAAS,EACxD,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,oBAAoB,KA4B/B;AAED,eAAO,MAAM,WAAW,SAAU,MAAM,6BAA6C,CAAC;AAEtF,eAAO,MAAM,UAAU,SAAU,MAAM,QAA2C,CAAC"}
@@ -3,18 +3,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.loadConfig = exports.loadSecrets = exports.interpolateSecretsIntoConfig = exports.nonBlankSecretsSchema = exports.secretsSchema = exports.secretNameSchema = exports.secretNamePattern = void 0;
6
+ exports.loadConfig = exports.loadSecrets = exports.interpolateSecretsIntoConfig = exports.nonBlankSecretValueSchema = exports.strictSecretNameSchema = exports.strictSecretNamePattern = void 0;
7
7
  const node_fs_1 = require("node:fs");
8
8
  const dotenv_1 = __importDefault(require("dotenv"));
9
9
  const reduce_1 = __importDefault(require("lodash/reduce"));
10
10
  const template_1 = __importDefault(require("lodash/template"));
11
11
  const zod_1 = require("zod");
12
- exports.secretNamePattern = /^[A-Z][\dA-Z_]*$/;
13
- exports.secretNameSchema = zod_1.z
12
+ exports.strictSecretNamePattern = /^[A-Z][\dA-Z_]*$/;
13
+ exports.strictSecretNameSchema = zod_1.z
14
14
  .string()
15
- .regex(exports.secretNamePattern, `Secret name is not a valid. Secret name must match ${exports.secretNamePattern.toString()}`);
16
- exports.secretsSchema = zod_1.z.record(exports.secretNameSchema, zod_1.z.string());
17
- exports.nonBlankSecretsSchema = zod_1.z.record(exports.secretNameSchema, zod_1.z.string().min(1, { message: 'Secret cannot be blank' }));
15
+ .regex(exports.strictSecretNamePattern, `Secret name is not a valid. Secret name must match ${exports.strictSecretNamePattern.toString()}`);
16
+ exports.nonBlankSecretValueSchema = zod_1.z.string().min(1, { message: 'Secret cannot be blank' });
18
17
  // Regular expression that does not match anything, ensuring no escaping or interpolation happens
19
18
  // https://github.com/lodash/lodash/blob/4.17.15/lodash.js#L199
20
19
  // eslint-disable-next-line prefer-named-capture-group
@@ -27,9 +26,11 @@ const ES_MATCH_REGEXP = /(?<!\\)\${([^\\}]*(?:\\.[^\\}]*)*)}/g;
27
26
  // because "\\" becomes "\\\\" when converted to string
28
27
  // eslint-disable-next-line prefer-named-capture-group
29
28
  const ESCAPED_ES_MATCH_REGEXP = /\\\\(\${([^\\}]*(?:\\.[^\\}]*)*)})/g;
30
- function interpolateSecretsIntoConfig(config, secrets, options = { allowBlankSecretValue: true }) {
31
- const { allowBlankSecretValue } = options;
32
- const validatedSecrets = (allowBlankSecretValue ? exports.secretsSchema : exports.nonBlankSecretsSchema).parse(secrets);
29
+ function interpolateSecretsIntoConfig(config, secrets, options) {
30
+ const { allowBlankSecretValue = true, validateSecretName = true } = options ?? {};
31
+ const secretNameSchema = validateSecretName ? exports.strictSecretNameSchema : zod_1.z.string();
32
+ const secretValueSchema = allowBlankSecretValue ? zod_1.z.string() : exports.nonBlankSecretValueSchema;
33
+ const validatedSecrets = zod_1.z.record(secretNameSchema, secretValueSchema).parse(secrets);
33
34
  const stringifiedSecrets = (0, reduce_1.default)(validatedSecrets, (acc, value, key) => {
34
35
  return {
35
36
  ...acc,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config-parsing/index.ts"],"names":[],"mappings":";;;;;;AAAA,qCAAuC;AAEvC,oDAA4B;AAC5B,2DAAmC;AACnC,+DAAuC;AACvC,6BAAwB;AAEX,QAAA,iBAAiB,GAAG,kBAAkB,CAAC;AAEvC,QAAA,gBAAgB,GAAG,OAAC;KAC9B,MAAM,EAAE;KACR,KAAK,CAAC,yBAAiB,EAAE,sDAAsD,yBAAiB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAErG,QAAA,aAAa,GAAG,OAAC,CAAC,MAAM,CAAC,wBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAEvD,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAC3C,wBAAgB,EAChB,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC,CACzD,CAAC;AAIF,iGAAiG;AACjG,+DAA+D;AAC/D,sDAAsD;AACtD,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,gFAAgF;AAChF,+DAA+D;AAC/D,sDAAsD;AACtD,MAAM,eAAe,GAAG,sCAAsC,CAAC;AAC/D,wHAAwH;AACxH,uDAAuD;AACvD,sDAAsD;AACtD,MAAM,uBAAuB,GAAG,qCAAqC,CAAC;AAQtE,SAAgB,4BAA4B,CAC1C,MAAS,EACT,OAAgB,EAChB,UAAgC,EAAE,qBAAqB,EAAE,IAAI,EAAE;IAE/D,MAAM,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC;IAC1C,MAAM,gBAAgB,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,qBAAa,CAAC,CAAC,CAAC,6BAAqB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAExG,MAAM,kBAAkB,GAAG,IAAA,gBAAM,EAC/B,gBAAgB,EAChB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAClB,OAAO;YACL,GAAG,GAAG;YACN,8GAA8G;YAC9G,wBAAwB;YACxB,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SAC1C,CAAC;IACJ,CAAC,EACD,EAAa,CACd,CAAC;IAEF,MAAM,kBAAkB,GAAG,IAAA,kBAAQ,EAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;QAC1D,MAAM,EAAE,eAAe;QACvB,QAAQ,EAAE,eAAe;QACzB,WAAW,EAAE,eAAe;KAC7B,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACvB,oHAAoH;IACpH,2CAA2C;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAM,CAAC;AACvF,CAAC;AA7BD,oEA6BC;AAEM,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,gBAAM,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAAzE,QAAA,WAAW,eAA8D;AAE/E,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAAtE,QAAA,UAAU,cAA4D"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config-parsing/index.ts"],"names":[],"mappings":";;;;;;AAAA,qCAAuC;AAEvC,oDAA4B;AAC5B,2DAAmC;AACnC,+DAAuC;AACvC,6BAAwB;AAEX,QAAA,uBAAuB,GAAG,kBAAkB,CAAC;AAE7C,QAAA,sBAAsB,GAAG,OAAC;KACpC,MAAM,EAAE;KACR,KAAK,CACJ,+BAAuB,EACvB,sDAAsD,+BAAuB,CAAC,QAAQ,EAAE,EAAE,CAC3F,CAAC;AAES,QAAA,yBAAyB,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC,CAAC;AAIlG,iGAAiG;AACjG,+DAA+D;AAC/D,sDAAsD;AACtD,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,gFAAgF;AAChF,+DAA+D;AAC/D,sDAAsD;AACtD,MAAM,eAAe,GAAG,sCAAsC,CAAC;AAC/D,wHAAwH;AACxH,uDAAuD;AACvD,sDAAsD;AACtD,MAAM,uBAAuB,GAAG,qCAAqC,CAAC;AAStE,SAAgB,4BAA4B,CAC1C,MAAS,EACT,OAAgB,EAChB,OAA8B;IAE9B,MAAM,EAAE,qBAAqB,GAAG,IAAI,EAAE,kBAAkB,GAAG,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IAClF,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,CAAC,CAAC,8BAAsB,CAAC,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IAClF,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,iCAAyB,CAAC;IACzF,MAAM,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEtF,MAAM,kBAAkB,GAAG,IAAA,gBAAM,EAC/B,gBAAgB,EAChB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAClB,OAAO;YACL,GAAG,GAAG;YACN,8GAA8G;YAC9G,wBAAwB;YACxB,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SAC1C,CAAC;IACJ,CAAC,EACD,EAAa,CACd,CAAC;IAEF,MAAM,kBAAkB,GAAG,IAAA,kBAAQ,EAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;QAC1D,MAAM,EAAE,eAAe;QACvB,QAAQ,EAAE,eAAe;QACzB,WAAW,EAAE,eAAe;KAC7B,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACvB,oHAAoH;IACpH,2CAA2C;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAM,CAAC;AACvF,CAAC;AA/BD,oEA+BC;AAEM,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,gBAAM,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAAzE,QAAA,WAAW,eAA8D;AAE/E,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAAtE,QAAA,UAAU,cAA4D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api3/commons",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "keywords": [],
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -127,6 +127,38 @@ describe(interpolateSecretsIntoConfig.name, () => {
127
127
  );
128
128
  });
129
129
 
130
+ it('allows parsing secrets without validating secret names', () => {
131
+ const rawSecrets = {
132
+ SECRET_A: 'secretValueA',
133
+ SECRET_B: 'secretValueB',
134
+ 'CANNOT-CONTAIN-HYPHEN': 'invalid',
135
+ lowercasedSecret: 'valid',
136
+ };
137
+
138
+ expect(() => interpolateSecretsIntoConfig(rawConfig, rawSecrets)).toThrow(
139
+ new ZodError([
140
+ {
141
+ validation: 'regex',
142
+ code: 'invalid_string',
143
+ message: 'Secret name is not a valid. Secret name must match /^[A-Z][\\dA-Z_]*$/',
144
+ path: ['CANNOT-CONTAIN-HYPHEN'],
145
+ },
146
+ {
147
+ validation: 'regex',
148
+ code: 'invalid_string',
149
+ message: 'Secret name is not a valid. Secret name must match /^[A-Z][\\dA-Z_]*$/',
150
+ path: ['lowercasedSecret'],
151
+ },
152
+ ])
153
+ );
154
+
155
+ expect(interpolateSecretsIntoConfig(rawConfig, rawSecrets, { validateSecretName: false })).toStrictEqual({
156
+ property: 'value',
157
+ secretA: 'secretValueA',
158
+ secretB: 'secretValueB',
159
+ });
160
+ });
161
+
130
162
  it('provides up to date README examples', () => {
131
163
  // Basic interpolation
132
164
  const basicInterpolationConfig = {
@@ -5,18 +5,16 @@ import reduce from 'lodash/reduce';
5
5
  import template from 'lodash/template';
6
6
  import { z } from 'zod';
7
7
 
8
- export const secretNamePattern = /^[A-Z][\dA-Z_]*$/;
8
+ export const strictSecretNamePattern = /^[A-Z][\dA-Z_]*$/;
9
9
 
10
- export const secretNameSchema = z
10
+ export const strictSecretNameSchema = z
11
11
  .string()
12
- .regex(secretNamePattern, `Secret name is not a valid. Secret name must match ${secretNamePattern.toString()}`);
13
-
14
- export const secretsSchema = z.record(secretNameSchema, z.string());
12
+ .regex(
13
+ strictSecretNamePattern,
14
+ `Secret name is not a valid. Secret name must match ${strictSecretNamePattern.toString()}`
15
+ );
15
16
 
16
- export const nonBlankSecretsSchema = z.record(
17
- secretNameSchema,
18
- z.string().min(1, { message: 'Secret cannot be blank' })
19
- );
17
+ export const nonBlankSecretValueSchema = z.string().min(1, { message: 'Secret cannot be blank' });
20
18
 
21
19
  export type Secrets = Record<string, string>;
22
20
 
@@ -34,7 +32,8 @@ const ES_MATCH_REGEXP = /(?<!\\)\${([^\\}]*(?:\\.[^\\}]*)*)}/g;
34
32
  const ESCAPED_ES_MATCH_REGEXP = /\\\\(\${([^\\}]*(?:\\.[^\\}]*)*)})/g;
35
33
 
36
34
  export interface InterpolationOptions {
37
- allowBlankSecretValue: boolean;
35
+ allowBlankSecretValue?: boolean;
36
+ validateSecretName?: boolean;
38
37
  }
39
38
 
40
39
  export type AnyObject = Record<string, unknown>;
@@ -42,10 +41,12 @@ export type AnyObject = Record<string, unknown>;
42
41
  export function interpolateSecretsIntoConfig<T = AnyObject>(
43
42
  config: T,
44
43
  secrets: unknown,
45
- options: InterpolationOptions = { allowBlankSecretValue: true }
44
+ options?: InterpolationOptions
46
45
  ) {
47
- const { allowBlankSecretValue } = options;
48
- const validatedSecrets = (allowBlankSecretValue ? secretsSchema : nonBlankSecretsSchema).parse(secrets);
46
+ const { allowBlankSecretValue = true, validateSecretName = true } = options ?? {};
47
+ const secretNameSchema = validateSecretName ? strictSecretNameSchema : z.string();
48
+ const secretValueSchema = allowBlankSecretValue ? z.string() : nonBlankSecretValueSchema;
49
+ const validatedSecrets = z.record(secretNameSchema, secretValueSchema).parse(secrets);
49
50
 
50
51
  const stringifiedSecrets = reduce(
51
52
  validatedSecrets,