@api3/commons 0.6.2 → 0.7.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 (42) hide show
  1. package/README.md +10 -0
  2. package/dist/config-hash/index.d.ts +4 -0
  3. package/dist/config-hash/index.d.ts.map +1 -0
  4. package/dist/config-hash/index.js +30 -0
  5. package/dist/config-hash/index.js.map +1 -0
  6. package/dist/config-parsing/index.d.ts +15 -0
  7. package/dist/config-parsing/index.d.ts.map +1 -0
  8. package/dist/config-parsing/index.js +55 -0
  9. package/dist/config-parsing/index.js.map +1 -0
  10. package/dist/eslint/react.js +1 -1
  11. package/dist/eslint/react.js.map +1 -1
  12. package/dist/http/index.d.ts +29 -0
  13. package/dist/http/index.d.ts.map +1 -0
  14. package/dist/http/index.js +36 -0
  15. package/dist/http/index.js.map +1 -0
  16. package/dist/logger/index.d.ts.map +1 -1
  17. package/dist/logger/index.js +15 -15
  18. package/dist/logger/index.js.map +1 -1
  19. package/dist/node-index.d.ts +2 -0
  20. package/dist/node-index.d.ts.map +1 -1
  21. package/dist/node-index.js +2 -0
  22. package/dist/node-index.js.map +1 -1
  23. package/dist/processing/unsafe-evaluate.d.ts.map +1 -1
  24. package/dist/processing/unsafe-evaluate.js +0 -2
  25. package/dist/processing/unsafe-evaluate.js.map +1 -1
  26. package/package.json +3 -1
  27. package/src/config-hash/README.md +25 -0
  28. package/src/config-hash/index.test.ts +93 -0
  29. package/src/config-hash/index.ts +25 -0
  30. package/src/config-parsing/README.md +48 -0
  31. package/src/config-parsing/index.test.ts +158 -0
  32. package/src/config-parsing/index.ts +75 -0
  33. package/src/eslint/react.js +1 -1
  34. package/src/http/README.md +3 -0
  35. package/src/http/index.test.ts +43 -0
  36. package/src/http/index.ts +61 -0
  37. package/src/logger/index.test.ts +19 -17
  38. package/src/logger/index.ts +15 -16
  39. package/src/node-index.ts +2 -0
  40. package/src/processing/processing.test.ts +1 -1
  41. package/src/processing/unsafe-evaluate.test.ts +0 -1
  42. package/src/processing/unsafe-evaluate.ts +0 -2
package/README.md CHANGED
@@ -24,6 +24,16 @@ pnpm add @api3/commons
24
24
 
25
25
  Read the documentation and sources of each module how to use it in the project.
26
26
 
27
+ ### Modules
28
+
29
+ - [blockchain-utilities](./src/blockchain-utilities/README.md)
30
+ - [config-hash](./src/config-hash/README.md)
31
+ - [config-parsing](./src/config-parsing/README.md)
32
+ - [eslint](./src/eslint/README.md)
33
+ - [http](./src/http/README.md)
34
+ - [logger](./src/logger/README.md)
35
+ - [processing](./src/processing/README.md)
36
+
27
37
  ## Using the package in universal context
28
38
 
29
39
  Some modules may be used only in both browser and Node.js context and some are Node.js only. To support this
@@ -0,0 +1,4 @@
1
+ export declare const sortObjectKeysRecursively: (value: any) => any;
2
+ export declare const serializePlainObject: (plainObject: any) => string;
3
+ export declare const createSha256Hash: (value: string) => string;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config-hash/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,yBAAyB,UAAW,GAAG,QAYnD,CAAC;AAEF,eAAO,MAAM,oBAAoB,gBAAiB,GAAG,WAGpD,CAAC;AAEF,eAAO,MAAM,gBAAgB,UAAW,MAAM,WAA4D,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createSha256Hash = exports.serializePlainObject = exports.sortObjectKeysRecursively = void 0;
7
+ const node_crypto_1 = require("node:crypto");
8
+ const isObject_1 = __importDefault(require("lodash/isObject"));
9
+ // We need to make sure the object is stringified in the same way every time, so we sort the keys alphabetically.
10
+ const sortObjectKeysRecursively = (value) => {
11
+ if (value === null)
12
+ return null;
13
+ if (!(0, isObject_1.default)(value) || Array.isArray(value))
14
+ return value;
15
+ const sortedKeys = Object.keys(value).sort();
16
+ const sortedObject = {};
17
+ for (const key of sortedKeys) {
18
+ sortedObject[key] = (0, exports.sortObjectKeysRecursively)(value[key]);
19
+ }
20
+ return sortedObject;
21
+ };
22
+ exports.sortObjectKeysRecursively = sortObjectKeysRecursively;
23
+ const serializePlainObject = (plainObject) => {
24
+ const sortedObject = (0, exports.sortObjectKeysRecursively)(plainObject);
25
+ return JSON.stringify(sortedObject);
26
+ };
27
+ exports.serializePlainObject = serializePlainObject;
28
+ const createSha256Hash = (value) => `0x${(0, node_crypto_1.createHash)('sha256').update(value).digest('hex')}`;
29
+ exports.createSha256Hash = createSha256Hash;
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config-hash/index.ts"],"names":[],"mappings":";;;;;;AAAA,6CAAyC;AAEzC,+DAAuC;AAEvC,iHAAiH;AAC1G,MAAM,yBAAyB,GAAG,CAAC,KAAU,EAAE,EAAE;IACtD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC,IAAA,kBAAQ,EAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE3D,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,MAAM,YAAY,GAAQ,EAAE,CAAC;IAE7B,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE;QAC5B,YAAY,CAAC,GAAG,CAAC,GAAG,IAAA,iCAAyB,EAAE,KAAa,CAAC,GAAG,CAAC,CAAC,CAAC;KACpE;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAZW,QAAA,yBAAyB,6BAYpC;AAEK,MAAM,oBAAoB,GAAG,CAAC,WAAgB,EAAE,EAAE;IACvD,MAAM,YAAY,GAAG,IAAA,iCAAyB,EAAC,WAAW,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;AACtC,CAAC,CAAC;AAHW,QAAA,oBAAoB,wBAG/B;AAEK,MAAM,gBAAgB,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAA9F,QAAA,gBAAgB,oBAA8E"}
@@ -0,0 +1,15 @@
1
+ import dotenv from 'dotenv';
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>;
7
+ export type Secrets = Record<string, string>;
8
+ export interface InterpolationOptions {
9
+ allowBlankSecretValue: boolean;
10
+ }
11
+ export type AnyObject = Record<string, unknown>;
12
+ export declare function interpolateSecretsIntoConfig<T = AnyObject>(config: T, secrets: unknown, options?: InterpolationOptions): T;
13
+ export declare const loadSecrets: (path: string) => dotenv.DotenvParseOutput;
14
+ export declare const loadConfig: (path: string) => any;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.loadConfig = exports.loadSecrets = exports.interpolateSecretsIntoConfig = exports.nonBlankSecretsSchema = exports.secretsSchema = exports.secretNameSchema = exports.secretNamePattern = void 0;
7
+ const node_fs_1 = require("node:fs");
8
+ const dotenv_1 = __importDefault(require("dotenv"));
9
+ const reduce_1 = __importDefault(require("lodash/reduce"));
10
+ const template_1 = __importDefault(require("lodash/template"));
11
+ const zod_1 = require("zod");
12
+ exports.secretNamePattern = /^[A-Z][\dA-Z_]*$/;
13
+ exports.secretNameSchema = zod_1.z
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' }));
18
+ // Regular expression that does not match anything, ensuring no escaping or interpolation happens
19
+ // https://github.com/lodash/lodash/blob/4.17.15/lodash.js#L199
20
+ // eslint-disable-next-line prefer-named-capture-group
21
+ const NO_MATCH_REGEXP = /($^)/;
22
+ // Regular expression matching ES template literal delimiter (${}) with escaping
23
+ // https://github.com/lodash/lodash/blob/4.17.15/lodash.js#L175
24
+ // eslint-disable-next-line prefer-named-capture-group
25
+ const ES_MATCH_REGEXP = /(?<!\\)\${([^\\}]*(?:\\.[^\\}]*)*)}/g;
26
+ // Regular expression matching the escaped ES template literal delimiter (${}). We need to use "\\\\" (four backslashes)
27
+ // because "\\" becomes "\\\\" when converted to string
28
+ // eslint-disable-next-line prefer-named-capture-group
29
+ 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);
33
+ const stringifiedSecrets = (0, reduce_1.default)(validatedSecrets, (acc, value, key) => {
34
+ return {
35
+ ...acc,
36
+ // Convert to value to JSON to encode new lines as "\n". The resulting value will be a JSON string with quotes
37
+ // which are sliced off.
38
+ [key]: JSON.stringify(value).slice(1, -1),
39
+ };
40
+ }, {});
41
+ const interpolatedConfig = (0, template_1.default)(JSON.stringify(config), {
42
+ escape: NO_MATCH_REGEXP,
43
+ evaluate: NO_MATCH_REGEXP,
44
+ interpolate: ES_MATCH_REGEXP,
45
+ })(stringifiedSecrets);
46
+ // Un-escape the escaped config interpolations (e.g. to enable interpolation in processing snippets). Optimistically
47
+ // assume, the config type has not changed.
48
+ return JSON.parse(interpolatedConfig.replaceAll(ESCAPED_ES_MATCH_REGEXP, '$1'));
49
+ }
50
+ exports.interpolateSecretsIntoConfig = interpolateSecretsIntoConfig;
51
+ const loadSecrets = (path) => dotenv_1.default.parse((0, node_fs_1.readFileSync)(path, 'utf8'));
52
+ exports.loadSecrets = loadSecrets;
53
+ const loadConfig = (path) => JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8'));
54
+ exports.loadConfig = loadConfig;
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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,5 +1,5 @@
1
1
  "use strict";
2
- // eslint-disable-next-line @typescript-eslint/no-var-requires
2
+ // eslint-disable-next-line @typescript-eslint/no-var-requires, lodash/import-scope
3
3
  const { merge } = require('lodash');
4
4
  // eslint-disable-next-line @typescript-eslint/no-var-requires
5
5
  const { universalRestrictedImportsConfig, universalImportOrderConfig } = require('./internal');
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/eslint/react.js"],"names":[],"mappings":";AAAA,8DAA8D;AAC9D,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEpC,8DAA8D;AAC9D,MAAM,EAAE,gCAAgC,EAAE,0BAA0B,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAE/F,MAAM,CAAC,OAAO,GAAG;IACf,MAAM,EAAE,2BAA2B;IACnC,aAAa,EAAE;QACb,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE;YACZ,GAAG,EAAE,IAAI,EAAE,sBAAsB;SAClC;QACD,UAAU,EAAE,QAAQ,EAAE,mCAAmC;KAC1D;IACD,QAAQ,EAAE;QACR,KAAK,EAAE;YACL,OAAO,EAAE,QAAQ,EAAE,6CAA6C;SACjE;KACF;IACD,GAAG,EAAE;QACH,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,IAAI;KACd;IACD,OAAO,EAAE,CAAC,kBAAkB,EAAE,gCAAgC,CAAC;IAC/D,OAAO,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,CAAC;IAC5D,KAAK,EAAE;QACL,cAAc,EAAE;YACd,OAAO;YACP,KAAK,CAAC,EAAE,EAAE,0BAA0B,EAAE;gBACpC,4BAA4B;gBAC5B,UAAU,EAAE;oBACV;wBACE,OAAO,EAAE,OAAO;wBAChB,KAAK,EAAE,SAAS;wBAChB,QAAQ,EAAE,QAAQ;qBACnB;iBACF;aACF,CAAC;SACH;QACD,kCAAkC;QAClC,gCAAgC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,sBAAsB,EAAE,QAAQ,EAAE,CAAC;QAC3F,8BAA8B,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACzD,wBAAwB,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACnD,gCAAgC,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC;QAC/G,yBAAyB,EAAE,KAAK;QAChC,8BAA8B,EAAE,KAAK;QACrC,yBAAyB,EAAE,KAAK;QAChC,kBAAkB,EAAE,KAAK;QACzB,wBAAwB,EAAE,KAAK;QAC/B,qBAAqB,EAAE,KAAK;QAC5B,8BAA8B,EAAE,KAAK;QACrC,mBAAmB,EAAE,KAAK;QAC1B,mBAAmB,EAAE,KAAK;QAC1B,4BAA4B,EAAE,KAAK;QACnC,uBAAuB,EAAE,KAAK;QAC9B,mCAAmC,EAAE,KAAK;QAC1C,8BAA8B,EAAE,KAAK;QACrC,sBAAsB,EAAE,KAAK;QAC7B,qBAAqB,EAAE,KAAK;QAC5B,6BAA6B,EAAE,KAAK;QACpC,4BAA4B,EAAE,KAAK;QACnC,8BAA8B,EAAE,KAAK;QACrC,kBAAkB,EAAE,KAAK;QACzB,0BAA0B,EAAE,KAAK;QACjC,6BAA6B,EAAE,KAAK;QACpC,yBAAyB,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACrE,qCAAqC,EAAE,OAAO;QAE9C,+CAA+C;QAC/C,0CAA0C,EAAE;YAC1C,OAAO;YACP,KAAK,CAAC,EAAE,EAAE,gCAAgC,EAAE;gBAC1C,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,OAAO;wBACb,WAAW,EAAE,CAAC,SAAS,CAAC;wBACxB,OAAO,EACL,uHAAuH;qBAC1H;iBACF;aACF,CAAC;SACH;QAED,mCAAmC;QACnC,qBAAqB,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;KAC3C;CACF,CAAC"}
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/eslint/react.js"],"names":[],"mappings":";AAAA,mFAAmF;AACnF,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEpC,8DAA8D;AAC9D,MAAM,EAAE,gCAAgC,EAAE,0BAA0B,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;AAE/F,MAAM,CAAC,OAAO,GAAG;IACf,MAAM,EAAE,2BAA2B;IACnC,aAAa,EAAE;QACb,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE;YACZ,GAAG,EAAE,IAAI,EAAE,sBAAsB;SAClC;QACD,UAAU,EAAE,QAAQ,EAAE,mCAAmC;KAC1D;IACD,QAAQ,EAAE;QACR,KAAK,EAAE;YACL,OAAO,EAAE,QAAQ,EAAE,6CAA6C;SACjE;KACF;IACD,GAAG,EAAE;QACH,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,IAAI;KACd;IACD,OAAO,EAAE,CAAC,kBAAkB,EAAE,gCAAgC,CAAC;IAC/D,OAAO,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,CAAC;IAC5D,KAAK,EAAE;QACL,cAAc,EAAE;YACd,OAAO;YACP,KAAK,CAAC,EAAE,EAAE,0BAA0B,EAAE;gBACpC,4BAA4B;gBAC5B,UAAU,EAAE;oBACV;wBACE,OAAO,EAAE,OAAO;wBAChB,KAAK,EAAE,SAAS;wBAChB,QAAQ,EAAE,QAAQ;qBACnB;iBACF;aACF,CAAC;SACH;QACD,kCAAkC;QAClC,gCAAgC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,sBAAsB,EAAE,QAAQ,EAAE,CAAC;QAC3F,8BAA8B,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACzD,wBAAwB,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACnD,gCAAgC,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC;QAC/G,yBAAyB,EAAE,KAAK;QAChC,8BAA8B,EAAE,KAAK;QACrC,yBAAyB,EAAE,KAAK;QAChC,kBAAkB,EAAE,KAAK;QACzB,wBAAwB,EAAE,KAAK;QAC/B,qBAAqB,EAAE,KAAK;QAC5B,8BAA8B,EAAE,KAAK;QACrC,mBAAmB,EAAE,KAAK;QAC1B,mBAAmB,EAAE,KAAK;QAC1B,4BAA4B,EAAE,KAAK;QACnC,uBAAuB,EAAE,KAAK;QAC9B,mCAAmC,EAAE,KAAK;QAC1C,8BAA8B,EAAE,KAAK;QACrC,sBAAsB,EAAE,KAAK;QAC7B,qBAAqB,EAAE,KAAK;QAC5B,6BAA6B,EAAE,KAAK;QACpC,4BAA4B,EAAE,KAAK;QACnC,8BAA8B,EAAE,KAAK;QACrC,kBAAkB,EAAE,KAAK;QACzB,0BAA0B,EAAE,KAAK;QACjC,6BAA6B,EAAE,KAAK;QACpC,yBAAyB,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACrE,qCAAqC,EAAE,OAAO;QAE9C,+CAA+C;QAC/C,0CAA0C,EAAE;YAC1C,OAAO;YACP,KAAK,CAAC,EAAE,EAAE,gCAAgC,EAAE;gBAC1C,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,OAAO;wBACb,WAAW,EAAE,CAAC,SAAS,CAAC;wBACxB,OAAO,EACL,uHAAuH;qBAC1H;iBACF;aACF,CAAC;SACH;QAED,mCAAmC;QACnC,qBAAqB,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;KAC3C;CACF,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { type Method, type AxiosError, type AxiosResponse } from 'axios';
2
+ export interface Request {
3
+ readonly method: Method;
4
+ readonly url: string;
5
+ readonly headers?: Record<string, string>;
6
+ readonly queryParams?: Record<string, any>;
7
+ readonly timeout?: number;
8
+ readonly body?: unknown;
9
+ }
10
+ export interface ErrorResponse {
11
+ readonly axiosResponse: Pick<AxiosResponse, 'data' | 'headers' | 'status'> | undefined;
12
+ readonly message: string;
13
+ readonly code: string | undefined;
14
+ }
15
+ export declare const extractAxiosErrorData: (error: AxiosError) => ErrorResponse;
16
+ interface ExecuteRequestSuccess<T> {
17
+ success: true;
18
+ errorData: undefined;
19
+ data: T;
20
+ }
21
+ interface ExecuteRequestError {
22
+ success: false;
23
+ errorData: ErrorResponse;
24
+ data: undefined;
25
+ }
26
+ export type ExecuteRequestResult<T> = ExecuteRequestError | ExecuteRequestSuccess<T>;
27
+ export declare function executeRequest<T>(request: Request): Promise<ExecuteRequestResult<T>>;
28
+ export {};
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AACA,OAAc,EAAE,KAAK,MAAM,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAKhF,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC,GAAG,SAAS,CAAC;IACvF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,eAAO,MAAM,qBAAqB,UAAW,UAAU,KAAG,aAOzD,CAAC;AAEF,UAAU,qBAAqB,CAAC,CAAC;IAC/B,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC;CACT;AACD,UAAU,mBAAmB;IAC3B,OAAO,EAAE,KAAK,CAAC;IACf,SAAS,EAAE,aAAa,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,mBAAmB,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAErF,wBAAsB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAiB1F"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.executeRequest = exports.extractAxiosErrorData = void 0;
7
+ const promise_utils_1 = require("@api3/promise-utils");
8
+ const axios_1 = __importDefault(require("axios"));
9
+ const pick_1 = __importDefault(require("lodash/pick"));
10
+ const DEFAULT_TIMEOUT_MS = 10_000;
11
+ const extractAxiosErrorData = (error) => {
12
+ // Inspired by: https://axios-http.com/docs/handling_errors
13
+ return {
14
+ axiosResponse: error.response ? (0, pick_1.default)(error.response, ['data', 'status']) : undefined,
15
+ message: error.message,
16
+ code: error.code,
17
+ };
18
+ };
19
+ exports.extractAxiosErrorData = extractAxiosErrorData;
20
+ async function executeRequest(request) {
21
+ const { url, method, body, headers = {}, queryParams = {}, timeout = DEFAULT_TIMEOUT_MS } = request;
22
+ const goAxios = await (0, promise_utils_1.go)(async () => (0, axios_1.default)({
23
+ url,
24
+ method,
25
+ headers,
26
+ data: body,
27
+ params: queryParams,
28
+ timeout,
29
+ }));
30
+ if (!goAxios.success)
31
+ return { success: false, errorData: (0, exports.extractAxiosErrorData)(goAxios.error), data: undefined };
32
+ const response = goAxios.data;
33
+ return { success: true, errorData: undefined, data: response.data };
34
+ }
35
+ exports.executeRequest = executeRequest;
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAyC;AACzC,kDAAgF;AAChF,uDAA+B;AAE/B,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAiB3B,MAAM,qBAAqB,GAAG,CAAC,KAAiB,EAAiB,EAAE;IACxE,2DAA2D;IAC3D,OAAO;QACL,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAA,cAAI,EAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QACpF,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;KACA,CAAC;AACrB,CAAC,CAAC;AAPW,QAAA,qBAAqB,yBAOhC;AAeK,KAAK,UAAU,cAAc,CAAI,OAAgB;IACtD,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE,WAAW,GAAG,EAAE,EAAE,OAAO,GAAG,kBAAkB,EAAE,GAAG,OAAO,CAAC;IAEpG,MAAM,OAAO,GAAG,MAAM,IAAA,kBAAE,EAAwC,KAAK,IAAI,EAAE,CACzE,IAAA,eAAK,EAAC;QACJ,GAAG;QACH,MAAM;QACN,OAAO;QACP,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,WAAW;QACnB,OAAO;KACR,CAAC,CACH,CAAC;IACF,IAAI,CAAC,OAAO,CAAC,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAA,6BAAqB,EAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAClH,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAE9B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;AACtE,CAAC;AAjBD,wCAiBC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logger/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAK9B,eAAO,MAAM,gBAAgB,6BAA8B,CAAC;AAE5D,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,eAAO,MAAM,eAAe,6CAA8C,CAAC;AAE3E,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAqCD,eAAO,MAAM,gBAAgB,WAAY,SAAS,mBAiBjD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE7C,MAAM,WAAW,MAAM;IACrB,cAAc,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3D,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACvD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACtD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAKtD,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC,GACtD,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC,CAAC;IAClE,KAAK,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC9C;AAID,eAAO,MAAM,OAAO,WAAY,cAAc,KAAG,MAyChD,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAAY,OAAO,KAAG,SAuBnD,CAAC;AAEF,eAAO,MAAM,YAAY,WAAY,SAAS,WAG7C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/logger/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAK9B,eAAO,MAAM,gBAAgB,6BAA8B,CAAC;AAE5D,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,eAAO,MAAM,eAAe,6CAA8C,CAAC;AAE3E,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAqCD,eAAO,MAAM,gBAAgB,WAAY,SAAS,mBAgBjD,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE7C,MAAM,WAAW,MAAM;IACrB,cAAc,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3D,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACvD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACtD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAKtD,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC,GACtD,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC,CAAC;IAClE,KAAK,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC9C;AAcD,eAAO,MAAM,OAAO,WAAY,cAAc,KAAG,MA+BhD,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAAY,OAAO,KAAG,SAuBnD,CAAC;AAEF,eAAO,MAAM,YAAY,WAAY,SAAS,WAG7C,CAAC"}
@@ -45,43 +45,43 @@ const createBaseLogger = (config) => {
45
45
  return winston_1.default.createLogger({
46
46
  level: minLevel,
47
47
  // This format is recommended by the "winston-console-format" package.
48
- format: winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.ms(), winston_1.default.format.errors({ stack: true }), winston_1.default.format.splat(), winston_1.default.format.json()),
48
+ format: winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.errors({ stack: true }), winston_1.default.format.splat(), winston_1.default.format.json()),
49
49
  silent: !enabled,
50
50
  exitOnError: false,
51
51
  transports: [createConsoleTransport(config)],
52
52
  });
53
53
  };
54
54
  exports.createBaseLogger = createBaseLogger;
55
+ const createFullContext = (localContext) => {
56
+ const globalContext = (0, async_storage_1.getAsyncLocalStorage)().getStore();
57
+ if (!globalContext && !localContext)
58
+ return;
59
+ const fullContext = { ...globalContext, ...localContext };
60
+ // If the context contains a `name` or `message` field, it will override the `name` and `message` fields of the log
61
+ // entry. To avoid this, we return the context as a separate field.
62
+ return { ctx: fullContext };
63
+ };
55
64
  // Winston by default merges content of `context` among the rest of the fields for the JSON format.
56
65
  // That's causing an override of fields `name` and `message` if they are present.
57
66
  const wrapper = (logger) => {
58
67
  return {
59
68
  debug: (message, localContext) => {
60
- const globalContext = (0, async_storage_1.getAsyncLocalStorage)().getStore();
61
- const fullContext = globalContext || localContext ? { ...globalContext, ...localContext } : undefined;
62
- logger.debug(message, fullContext);
69
+ logger.debug(message, createFullContext(localContext));
63
70
  },
64
71
  info: (message, localContext) => {
65
- const globalContext = (0, async_storage_1.getAsyncLocalStorage)().getStore();
66
- const fullContext = globalContext || localContext ? { ...globalContext, ...localContext } : undefined;
67
- logger.info(message, fullContext);
72
+ logger.info(message, createFullContext(localContext));
68
73
  },
69
74
  warn: (message, localContext) => {
70
- const globalContext = (0, async_storage_1.getAsyncLocalStorage)().getStore();
71
- const fullContext = globalContext || localContext ? { ...globalContext, ...localContext } : undefined;
72
- logger.warn(message, fullContext);
75
+ logger.warn(message, createFullContext(localContext));
73
76
  },
74
77
  // We need to handle both overloads of the `error` function
75
78
  error: (message, errorOrLocalContext, localContext) => {
76
- const globalContext = (0, async_storage_1.getAsyncLocalStorage)().getStore();
77
79
  // eslint-disable-next-line lodash/prefer-lodash-typecheck
78
80
  if (errorOrLocalContext instanceof Error) {
79
- const fullContext = globalContext || localContext ? { ...globalContext, ...localContext } : undefined;
80
- logger.error(message, errorOrLocalContext, fullContext);
81
+ logger.error(message, errorOrLocalContext, createFullContext(localContext));
81
82
  }
82
83
  else {
83
- const fullContext = globalContext || errorOrLocalContext ? { ...globalContext, ...errorOrLocalContext } : undefined;
84
- logger.error(message, fullContext);
84
+ logger.error(message, createFullContext(errorOrLocalContext));
85
85
  }
86
86
  },
87
87
  child: (options) => (0, exports.wrapper)(logger.child(options)),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/logger/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/logger/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  export * from './universal-index';
2
2
  export * from './logger';
3
3
  export * from './processing';
4
+ export * from './config-parsing';
5
+ export * from './config-hash';
4
6
  //# sourceMappingURL=node-index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-index.d.ts","sourceRoot":"","sources":["../src/node-index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"node-index.d.ts","sourceRoot":"","sources":["../src/node-index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC"}
@@ -18,4 +18,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
18
18
  __exportStar(require("./universal-index"), exports);
19
19
  __exportStar(require("./logger"), exports);
20
20
  __exportStar(require("./processing"), exports);
21
+ __exportStar(require("./config-parsing"), exports);
22
+ __exportStar(require("./config-hash"), exports);
21
23
  //# sourceMappingURL=node-index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-index.js","sourceRoot":"","sources":["../src/node-index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iHAAiH;AACjH,oDAAkC;AAClC,2CAAyB;AACzB,+CAA6B"}
1
+ {"version":3,"file":"node-index.js","sourceRoot":"","sources":["../src/node-index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iHAAiH;AACjH,oDAAkC;AAClC,2CAAyB;AACzB,+CAA6B;AAC7B,mDAAiC;AACjC,gDAA8B"}
@@ -1 +1 @@
1
- {"version":3,"file":"unsafe-evaluate.d.ts","sourceRoot":"","sources":["../../src/processing/unsafe-evaluate.ts"],"names":[],"mappings":"AAiFA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,cAAc,SAAU,MAAM,mBAAmB,OAAO,MAAM,EAAE,OAAO,CAAC,WAAW,MAAM,YAarG,CAAC;AAEF,eAAO,MAAM,gBAAgB,SAAgB,MAAM,WAAW,OAAO,WAAW,MAAM,iBAmCrF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,mBAAmB,SAAgB,MAAM,mBAAmB,OAAO,MAAM,EAAE,OAAO,CAAC,WAAW,MAAM,qBAoChH,CAAC"}
1
+ {"version":3,"file":"unsafe-evaluate.d.ts","sourceRoot":"","sources":["../../src/processing/unsafe-evaluate.ts"],"names":[],"mappings":"AA+EA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,cAAc,SAAU,MAAM,mBAAmB,OAAO,MAAM,EAAE,OAAO,CAAC,WAAW,MAAM,YAarG,CAAC;AAEF,eAAO,MAAM,gBAAgB,SAAgB,MAAM,WAAW,OAAO,WAAW,MAAM,iBAmCrF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,mBAAmB,SAAgB,MAAM,mBAAmB,OAAO,MAAM,EAAE,OAAO,CAAC,WAAW,MAAM,qBAoChH,CAAC"}
@@ -33,7 +33,6 @@ const node_stream_1 = __importDefault(require("node:stream"));
33
33
  const node_string_decoder_1 = __importDefault(require("node:string_decoder"));
34
34
  const node_timers_1 = __importDefault(require("node:timers"));
35
35
  const node_tls_1 = __importDefault(require("node:tls"));
36
- const node_trace_events_1 = __importDefault(require("node:trace_events"));
37
36
  const node_tty_1 = __importDefault(require("node:tty"));
38
37
  const node_url_1 = __importDefault(require("node:url"));
39
38
  const node_util_1 = __importDefault(require("node:util"));
@@ -72,7 +71,6 @@ const builtInNodeModules = {
72
71
  string_decoder: node_string_decoder_1.default,
73
72
  timers: node_timers_1.default,
74
73
  tls: node_tls_1.default,
75
- trace_events: node_trace_events_1.default,
76
74
  tty: node_tty_1.default,
77
75
  url: node_url_1.default,
78
76
  util: node_util_1.default,
@@ -1 +1 @@
1
- {"version":3,"file":"unsafe-evaluate.js","sourceRoot":"","sources":["../../src/processing/unsafe-evaluate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"unsafe-evaluate.js","sourceRoot":"","sources":["../../src/processing/unsafe-evaluate.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api3/commons",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "keywords": [],
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -24,6 +24,8 @@
24
24
  "@api3/promise-utils": "^0.4.0",
25
25
  "@typescript-eslint/eslint-plugin": "^6.2.1",
26
26
  "@typescript-eslint/parser": "^6.2.1",
27
+ "axios": "^1.6.7",
28
+ "dotenv": "^16.4.5",
27
29
  "eslint-config-next": "^13.1.6",
28
30
  "eslint-plugin-check-file": "^2.6.2",
29
31
  "eslint-plugin-cypress": "^2.14.0",
@@ -0,0 +1,25 @@
1
+ # Config hashing
2
+
3
+ > Small Node.js module that allows creating a hash from a config object.
4
+
5
+ This module uses Node.js built-in `crypto` module to access the `sha256` hashing algorithm. A similar functionality can
6
+ be achieved in the browser environment using the `SubtleCrypto` API. Open an issue if you need this functionality in
7
+ browser.
8
+
9
+ ## Usage
10
+
11
+ 1. Call `serializePlainObject` to uniquely serialize a config file. This functions recursively sorts the properties of
12
+ an object, such that `{a: 1, b: 2}` and `{b: 2, a: 1}` will produce the same result.
13
+ 2. Call `createSha256Hash` to create a hash from the serialized object.
14
+
15
+ ```ts
16
+ const serializedConfig = serializePlainObject(config);
17
+ const hash = createSha256Hash(serializedConfig);
18
+ ```
19
+
20
+ To simulate the same behavior in UNIX shell, you can use the following command:
21
+
22
+ ```sh
23
+ # Assumes jq, tr, sha256sum and awk are available
24
+ jq --sort-keys --compact-output . ./file.json | tr -d '\n' | sha256sum | awk '{ print "0x"$1 }'
25
+ ```
@@ -0,0 +1,93 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+
5
+ import { createSha256Hash, serializePlainObject, sortObjectKeysRecursively } from '.';
6
+
7
+ describe(sortObjectKeysRecursively.name, () => {
8
+ it('should sort the keys alphabetically', () => {
9
+ const plainObject = {
10
+ c: 3,
11
+ a: 1,
12
+ b: 2,
13
+ };
14
+
15
+ expect(sortObjectKeysRecursively(plainObject)).toStrictEqual({ a: 1, b: 2, c: 3 });
16
+ });
17
+
18
+ it('should handle nested objects', () => {
19
+ const plainObject = {
20
+ c: 3,
21
+ a: 1,
22
+ b: {
23
+ e: 5,
24
+ d: 4,
25
+ },
26
+ };
27
+
28
+ expect(sortObjectKeysRecursively(plainObject)).toStrictEqual({ a: 1, b: { d: 4, e: 5 }, c: 3 });
29
+ });
30
+
31
+ it('handles other primitive values', () => {
32
+ const plainObject = {
33
+ c: 'c-val',
34
+ a: 1,
35
+ F: null,
36
+ B: false,
37
+ b: [2, null, 1],
38
+ };
39
+
40
+ expect(sortObjectKeysRecursively(plainObject)).toStrictEqual({
41
+ B: false,
42
+ F: null,
43
+ a: 1,
44
+ b: [2, null, 1],
45
+ c: 'c-val',
46
+ });
47
+ });
48
+ });
49
+
50
+ describe(serializePlainObject.name, () => {
51
+ it('creates the same serialization string for equal objects', () => {
52
+ const plainObject = {
53
+ c: 'c-val',
54
+ a: 1,
55
+ F: null,
56
+ B: false,
57
+ b: [2, null, 1],
58
+ };
59
+ const otherPlainObject = {
60
+ a: 1,
61
+ F: null,
62
+ B: false,
63
+ c: 'c-val',
64
+ b: [2, null, 1],
65
+ };
66
+
67
+ expect(serializePlainObject(plainObject)).toBe(serializePlainObject(otherPlainObject));
68
+ });
69
+ });
70
+
71
+ describe(createSha256Hash.name, () => {
72
+ it('should create same hash as SubtleCrypto in browser', () => {
73
+ // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string
74
+ const text = 'An obscure body in the S-K System, your majesty. The inhabitants refer to it as the planet Earth.';
75
+
76
+ expect(createSha256Hash(text)).toBe('0x6efd383745a964768989b9df420811abc6e5873f874fc22a76fe9258e020c2e1');
77
+ });
78
+ });
79
+
80
+ test('can produce the same hash on UNIX', () => {
81
+ const fixturePath = join(__dirname, '../../test/fixtures/config-hash/file.json');
82
+
83
+ // Compute the hash using this module
84
+ const rawConfig = JSON.parse(readFileSync(fixturePath, 'utf8'));
85
+ const serializedConfig = serializePlainObject(rawConfig);
86
+ const hash = createSha256Hash(serializedConfig);
87
+
88
+ // Compute the hash using UNIX commands
89
+ const unixCommand = `jq --sort-keys --compact-output . ${fixturePath} | tr -d '\n' | sha256sum | awk '{ print "0x"$1 }'`;
90
+ const unixCommandHash = execSync(unixCommand, { encoding: 'utf8' }).trim();
91
+
92
+ expect(hash).toBe(unixCommandHash);
93
+ });
@@ -0,0 +1,25 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ import isObject from 'lodash/isObject';
4
+
5
+ // We need to make sure the object is stringified in the same way every time, so we sort the keys alphabetically.
6
+ export const sortObjectKeysRecursively = (value: any) => {
7
+ if (value === null) return null;
8
+ if (!isObject(value) || Array.isArray(value)) return value;
9
+
10
+ const sortedKeys = Object.keys(value).sort();
11
+ const sortedObject: any = {};
12
+
13
+ for (const key of sortedKeys) {
14
+ sortedObject[key] = sortObjectKeysRecursively((value as any)[key]);
15
+ }
16
+
17
+ return sortedObject;
18
+ };
19
+
20
+ export const serializePlainObject = (plainObject: any) => {
21
+ const sortedObject = sortObjectKeysRecursively(plainObject);
22
+ return JSON.stringify(sortedObject);
23
+ };
24
+
25
+ export const createSha256Hash = (value: string) => `0x${createHash('sha256').update(value).digest('hex')}`;
@@ -0,0 +1,48 @@
1
+ # Config parsing
2
+
3
+ > Node.js module for parsing configuration files with support of interpolating secrets.
4
+
5
+ ## Usage
6
+
7
+ ### Parsing a configuration file and secrets
8
+
9
+ You can use the following helper functions to read the configuration and secrets file from filesystem:
10
+
11
+ ```ts
12
+ const rawConfig = loadConfig(join(__dirname, 'config.json'));
13
+ const rawSecrets = loadSecrets(join(__dirname, 'secrets.env'));
14
+ ```
15
+
16
+ ### Creating the full configuration object
17
+
18
+ The module defines a `interpolateSecretsIntoConfig` function that takes a config object along with the secrets and
19
+ returns the config with the secrets interpolated into it.
20
+
21
+ Examples:
22
+
23
+ ```ts
24
+ // Basic interpolation
25
+ const rawConfig = {
26
+ prop: 'value',
27
+ secret: '${SECRET}',
28
+ };
29
+ const config = interpolateSecretsIntoConfig(rawConfig, { SECRET: 'secretValue' }); // { prop: 'value', secret: 'secretValue' }
30
+ ```
31
+
32
+ ```ts
33
+ // Allows escaping the interpolation syntax
34
+ const rawConfig = {
35
+ prop: 'value',
36
+ secret: '\\${SECRET}',
37
+ };
38
+ const config = interpolateSecretsIntoConfig(rawConfig, { SECRET: 'secretValue' }); // { prop: 'value', secret: '${SECRET}' }
39
+ ```
40
+
41
+ ```ts
42
+ // Throws an error if something is not right
43
+ const rawConfig = {
44
+ prop: 'value',
45
+ secret: '${SECRET}',
46
+ };
47
+ const config = interpolateSecretsIntoConfig(rawConfig); // Error: SECRET is not defined
48
+ ```
@@ -0,0 +1,158 @@
1
+ import { ZodError } from 'zod';
2
+
3
+ import { interpolateSecretsIntoConfig } from './index';
4
+
5
+ const rawConfig = {
6
+ property: 'value',
7
+ secretB: '${SECRET_B}',
8
+ secretA: '${SECRET_A}',
9
+ };
10
+
11
+ describe(interpolateSecretsIntoConfig.name, () => {
12
+ it('interpolates secrets into config', () => {
13
+ const config = interpolateSecretsIntoConfig(rawConfig, {
14
+ SECRET_A: 'secretValueA',
15
+ SECRET_B: 'secretValueB',
16
+ });
17
+
18
+ expect(config).toStrictEqual({
19
+ property: 'value',
20
+ secretA: 'secretValueA',
21
+ secretB: 'secretValueB',
22
+ });
23
+ });
24
+
25
+ it('allows empty secrets by default', () => {
26
+ const config = interpolateSecretsIntoConfig(rawConfig, {
27
+ SECRET_A: '',
28
+ SECRET_B: '',
29
+ });
30
+
31
+ expect(config).toStrictEqual({
32
+ property: 'value',
33
+ secretA: '',
34
+ secretB: '',
35
+ });
36
+ });
37
+
38
+ it('disallows empty secrets when configured so', () => {
39
+ expect(() => {
40
+ interpolateSecretsIntoConfig(
41
+ rawConfig,
42
+ {
43
+ SECRET_A: '',
44
+ SECRET_B: '',
45
+ },
46
+ { allowBlankSecretValue: false }
47
+ );
48
+ }).toThrow('Secret cannot be blank');
49
+ });
50
+
51
+ it('can use "\\" to escape interpolation', () => {
52
+ const escapedConfig = {
53
+ ...rawConfig,
54
+ secretA: '\\${SECRET_A}',
55
+ };
56
+ const config = interpolateSecretsIntoConfig(escapedConfig, {
57
+ SECRET_A: 'secretValueA',
58
+ SECRET_B: 'secretValueB',
59
+ });
60
+
61
+ expect(config).toStrictEqual({
62
+ property: 'value',
63
+ secretA: '${SECRET_A}',
64
+ secretB: 'secretValueB',
65
+ });
66
+ });
67
+
68
+ it('allows extraneous secrets', () => {
69
+ const config = interpolateSecretsIntoConfig(rawConfig, {
70
+ SECRET_A: 'secretValueA',
71
+ SECRET_B: 'secretValueB',
72
+ SECRET_C: 'secretValueC',
73
+ });
74
+
75
+ expect(config).toStrictEqual({
76
+ property: 'value',
77
+ secretA: 'secretValueA',
78
+ secretB: 'secretValueB',
79
+ });
80
+ });
81
+
82
+ it('throws an error when a secret is missing', () => {
83
+ expect(() => {
84
+ interpolateSecretsIntoConfig(rawConfig, {
85
+ SECRET_A: 'secretValueA',
86
+ });
87
+ }).toThrow('SECRET_B is not defined');
88
+ });
89
+
90
+ it('allows no secrets', () => {
91
+ const noSecretsConfig = { value: 'no secrets' };
92
+
93
+ expect(interpolateSecretsIntoConfig(noSecretsConfig, {})).toStrictEqual(noSecretsConfig);
94
+ });
95
+
96
+ it('throws when secret name is invalid', () => {
97
+ expect(() => {
98
+ interpolateSecretsIntoConfig(rawConfig, {
99
+ SECRET_A: 'secretValueA',
100
+ '0_SECRET_STARTING_WITH_NUMBER': 'invalid',
101
+ });
102
+ }).toThrow(
103
+ new ZodError([
104
+ {
105
+ validation: 'regex',
106
+ code: 'invalid_string',
107
+ message: 'Secret name is not a valid. Secret name must match /^[A-Z][\\dA-Z_]*$/',
108
+ path: ['0_SECRET_STARTING_WITH_NUMBER'],
109
+ },
110
+ ])
111
+ );
112
+
113
+ expect(() => {
114
+ interpolateSecretsIntoConfig(rawConfig, {
115
+ SECRET_A: 'secretValueA',
116
+ 'CANNOT-CONTAIN-HYPHEN': 'invalid',
117
+ });
118
+ }).toThrow(
119
+ new ZodError([
120
+ {
121
+ validation: 'regex',
122
+ code: 'invalid_string',
123
+ message: 'Secret name is not a valid. Secret name must match /^[A-Z][\\dA-Z_]*$/',
124
+ path: ['CANNOT-CONTAIN-HYPHEN'],
125
+ },
126
+ ])
127
+ );
128
+ });
129
+
130
+ it('provides up to date README examples', () => {
131
+ // Basic interpolation
132
+ const basicInterpolationConfig = {
133
+ prop: 'value',
134
+ secret: '${SECRET}',
135
+ };
136
+ expect(interpolateSecretsIntoConfig(basicInterpolationConfig, { SECRET: 'secretValue' })).toStrictEqual({
137
+ prop: 'value',
138
+ secret: 'secretValue',
139
+ });
140
+
141
+ // Allows escaping the interpolation syntax
142
+ const escapingInterpolationConfig = {
143
+ prop: 'value',
144
+ secret: '\\${SECRET}',
145
+ };
146
+ expect(interpolateSecretsIntoConfig(escapingInterpolationConfig, { SECRET: 'secretValue' })).toStrictEqual({
147
+ prop: 'value',
148
+ secret: '${SECRET}',
149
+ });
150
+
151
+ // Throws an error if something is not right
152
+ const missingSecretConfig = {
153
+ prop: 'value',
154
+ secret: '${SECRET}',
155
+ };
156
+ expect(() => interpolateSecretsIntoConfig(missingSecretConfig, {})).toThrow('SECRET is not defined');
157
+ });
158
+ });
@@ -0,0 +1,75 @@
1
+ import { readFileSync } from 'node:fs';
2
+
3
+ import dotenv from 'dotenv';
4
+ import reduce from 'lodash/reduce';
5
+ import template from 'lodash/template';
6
+ import { z } from 'zod';
7
+
8
+ export const secretNamePattern = /^[A-Z][\dA-Z_]*$/;
9
+
10
+ export const secretNameSchema = z
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());
15
+
16
+ export const nonBlankSecretsSchema = z.record(
17
+ secretNameSchema,
18
+ z.string().min(1, { message: 'Secret cannot be blank' })
19
+ );
20
+
21
+ export type Secrets = Record<string, string>;
22
+
23
+ // Regular expression that does not match anything, ensuring no escaping or interpolation happens
24
+ // https://github.com/lodash/lodash/blob/4.17.15/lodash.js#L199
25
+ // eslint-disable-next-line prefer-named-capture-group
26
+ const NO_MATCH_REGEXP = /($^)/;
27
+ // Regular expression matching ES template literal delimiter (${}) with escaping
28
+ // https://github.com/lodash/lodash/blob/4.17.15/lodash.js#L175
29
+ // eslint-disable-next-line prefer-named-capture-group
30
+ const ES_MATCH_REGEXP = /(?<!\\)\${([^\\}]*(?:\\.[^\\}]*)*)}/g;
31
+ // Regular expression matching the escaped ES template literal delimiter (${}). We need to use "\\\\" (four backslashes)
32
+ // because "\\" becomes "\\\\" when converted to string
33
+ // eslint-disable-next-line prefer-named-capture-group
34
+ const ESCAPED_ES_MATCH_REGEXP = /\\\\(\${([^\\}]*(?:\\.[^\\}]*)*)})/g;
35
+
36
+ export interface InterpolationOptions {
37
+ allowBlankSecretValue: boolean;
38
+ }
39
+
40
+ export type AnyObject = Record<string, unknown>;
41
+
42
+ export function interpolateSecretsIntoConfig<T = AnyObject>(
43
+ config: T,
44
+ secrets: unknown,
45
+ options: InterpolationOptions = { allowBlankSecretValue: true }
46
+ ) {
47
+ const { allowBlankSecretValue } = options;
48
+ const validatedSecrets = (allowBlankSecretValue ? secretsSchema : nonBlankSecretsSchema).parse(secrets);
49
+
50
+ const stringifiedSecrets = reduce(
51
+ validatedSecrets,
52
+ (acc, value, key) => {
53
+ return {
54
+ ...acc,
55
+ // Convert to value to JSON to encode new lines as "\n". The resulting value will be a JSON string with quotes
56
+ // which are sliced off.
57
+ [key]: JSON.stringify(value).slice(1, -1),
58
+ };
59
+ },
60
+ {} as Secrets
61
+ );
62
+
63
+ const interpolatedConfig = template(JSON.stringify(config), {
64
+ escape: NO_MATCH_REGEXP,
65
+ evaluate: NO_MATCH_REGEXP,
66
+ interpolate: ES_MATCH_REGEXP,
67
+ })(stringifiedSecrets);
68
+ // Un-escape the escaped config interpolations (e.g. to enable interpolation in processing snippets). Optimistically
69
+ // assume, the config type has not changed.
70
+ return JSON.parse(interpolatedConfig.replaceAll(ESCAPED_ES_MATCH_REGEXP, '$1')) as T;
71
+ }
72
+
73
+ export const loadSecrets = (path: string) => dotenv.parse(readFileSync(path, 'utf8'));
74
+
75
+ export const loadConfig = (path: string) => JSON.parse(readFileSync(path, 'utf8'));
@@ -1,4 +1,4 @@
1
- // eslint-disable-next-line @typescript-eslint/no-var-requires
1
+ // eslint-disable-next-line @typescript-eslint/no-var-requires, lodash/import-scope
2
2
  const { merge } = require('lodash');
3
3
 
4
4
  // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -0,0 +1,3 @@
1
+ # Http
2
+
3
+ > Http is a module that provides a simple way to make http requests.
@@ -0,0 +1,43 @@
1
+ import { AxiosError, type AxiosResponse } from 'axios';
2
+
3
+ import { executeRequest, extractAxiosErrorData } from '.';
4
+
5
+ describe(extractAxiosErrorData.name, () => {
6
+ it('should return an error response object', () => {
7
+ const axiosError = new AxiosError('error message', '500', undefined, {}, {
8
+ data: 'error data',
9
+ status: 500,
10
+ statusText: 'Internal Server Error',
11
+ } as any as AxiosResponse);
12
+
13
+ expect(extractAxiosErrorData(axiosError)).toStrictEqual({
14
+ axiosResponse: {
15
+ data: 'error data',
16
+ status: 500,
17
+ },
18
+ code: '500',
19
+ message: 'error message',
20
+ });
21
+ });
22
+ });
23
+
24
+ describe(executeRequest.name, () => {
25
+ it('fails to call invalid URL', async () => {
26
+ const request = {
27
+ method: 'GET',
28
+ url: 'http://localhost:9999',
29
+ } as const;
30
+
31
+ const response = await executeRequest(request);
32
+
33
+ expect(response).toStrictEqual({
34
+ data: undefined,
35
+ errorData: {
36
+ axiosResponse: undefined,
37
+ code: 'ECONNREFUSED',
38
+ message: expect.any(String), // The message is empty in node@20, but "connect ECONNREFUSED ::1:9999" on node@18
39
+ },
40
+ success: false,
41
+ });
42
+ });
43
+ });
@@ -0,0 +1,61 @@
1
+ import { go } from '@api3/promise-utils';
2
+ import axios, { type Method, type AxiosError, type AxiosResponse } from 'axios';
3
+ import pick from 'lodash/pick';
4
+
5
+ const DEFAULT_TIMEOUT_MS = 10_000;
6
+
7
+ export interface Request {
8
+ readonly method: Method;
9
+ readonly url: string;
10
+ readonly headers?: Record<string, string>;
11
+ readonly queryParams?: Record<string, any>;
12
+ readonly timeout?: number;
13
+ readonly body?: unknown;
14
+ }
15
+
16
+ export interface ErrorResponse {
17
+ readonly axiosResponse: Pick<AxiosResponse, 'data' | 'headers' | 'status'> | undefined;
18
+ readonly message: string;
19
+ readonly code: string | undefined;
20
+ }
21
+
22
+ export const extractAxiosErrorData = (error: AxiosError): ErrorResponse => {
23
+ // Inspired by: https://axios-http.com/docs/handling_errors
24
+ return {
25
+ axiosResponse: error.response ? pick(error.response, ['data', 'status']) : undefined,
26
+ message: error.message,
27
+ code: error.code,
28
+ } as ErrorResponse;
29
+ };
30
+
31
+ interface ExecuteRequestSuccess<T> {
32
+ success: true;
33
+ errorData: undefined;
34
+ data: T;
35
+ }
36
+ interface ExecuteRequestError {
37
+ success: false;
38
+ errorData: ErrorResponse;
39
+ data: undefined;
40
+ }
41
+
42
+ export type ExecuteRequestResult<T> = ExecuteRequestError | ExecuteRequestSuccess<T>;
43
+
44
+ export async function executeRequest<T>(request: Request): Promise<ExecuteRequestResult<T>> {
45
+ const { url, method, body, headers = {}, queryParams = {}, timeout = DEFAULT_TIMEOUT_MS } = request;
46
+
47
+ const goAxios = await go<Promise<AxiosResponse<T>>, AxiosError>(async () =>
48
+ axios({
49
+ url,
50
+ method,
51
+ headers,
52
+ data: body,
53
+ params: queryParams,
54
+ timeout,
55
+ })
56
+ );
57
+ if (!goAxios.success) return { success: false, errorData: extractAxiosErrorData(goAxios.error), data: undefined };
58
+ const response = goAxios.data;
59
+
60
+ return { success: true, errorData: undefined, data: response.data };
61
+ }
@@ -1,4 +1,4 @@
1
- import { noop } from 'lodash';
1
+ import noop from 'lodash/noop';
2
2
 
3
3
  import { type LogConfig, createBaseLogger, wrapper } from '.';
4
4
 
@@ -29,9 +29,9 @@ describe('log context', () => {
29
29
  logger.debug('parent end');
30
30
  });
31
31
 
32
- expect(baseLogger.debug).toHaveBeenCalledWith('parent start', { requestId: 'parent' });
33
- expect(baseLogger.debug).toHaveBeenCalledWith('child', { requestId: 'child' });
34
- expect(baseLogger.debug).toHaveBeenCalledWith('parent end', { requestId: 'parent' });
32
+ expect(baseLogger.debug).toHaveBeenCalledWith('parent start', { ctx: { requestId: 'parent' } });
33
+ expect(baseLogger.debug).toHaveBeenCalledWith('child', { ctx: { requestId: 'child' } });
34
+ expect(baseLogger.debug).toHaveBeenCalledWith('parent end', { ctx: { requestId: 'parent' } });
35
35
  });
36
36
 
37
37
  it('works with async functions', async () => {
@@ -48,9 +48,9 @@ describe('log context', () => {
48
48
  });
49
49
 
50
50
  expect(baseLogger.debug).toHaveBeenCalledTimes(3);
51
- expect(baseLogger.debug).toHaveBeenCalledWith('parent start', { requestId: 'parent' });
52
- expect(baseLogger.debug).toHaveBeenCalledWith('child', { requestId: 'child' });
53
- expect(baseLogger.debug).toHaveBeenCalledWith('parent end', { requestId: 'parent' });
51
+ expect(baseLogger.debug).toHaveBeenCalledWith('parent start', { ctx: { requestId: 'parent' } });
52
+ expect(baseLogger.debug).toHaveBeenCalledWith('child', { ctx: { requestId: 'child' } });
53
+ expect(baseLogger.debug).toHaveBeenCalledWith('parent end', { ctx: { requestId: 'parent' } });
54
54
  });
55
55
 
56
56
  it('works with deeply nested functions', async () => {
@@ -78,14 +78,14 @@ describe('log context', () => {
78
78
  });
79
79
 
80
80
  expect(baseLogger.debug).toHaveBeenCalledTimes(8);
81
- expect(baseLogger.debug).toHaveBeenCalledWith('parent start', { parent: true });
82
- expect(baseLogger.debug).toHaveBeenCalledWith('A start', { parent: true, A: true });
83
- expect(baseLogger.debug).toHaveBeenCalledWith('C', { parent: true, A: true, B: true });
84
- expect(baseLogger.debug).toHaveBeenCalledWith('D', { parent: true, A: true, B: true });
85
- expect(baseLogger.debug).toHaveBeenCalledWith('E', { parent: true, A: true, B: true });
86
- expect(baseLogger.debug).toHaveBeenCalledWith('B end', { parent: true, A: true, B: true });
87
- expect(baseLogger.debug).toHaveBeenCalledWith('A end', { parent: true, A: true });
88
- expect(baseLogger.debug).toHaveBeenCalledWith('parent end', { parent: true });
81
+ expect(baseLogger.debug).toHaveBeenCalledWith('parent start', { ctx: { parent: true } });
82
+ expect(baseLogger.debug).toHaveBeenCalledWith('A start', { ctx: { parent: true, A: true } });
83
+ expect(baseLogger.debug).toHaveBeenCalledWith('C', { ctx: { parent: true, A: true, B: true } });
84
+ expect(baseLogger.debug).toHaveBeenCalledWith('D', { ctx: { parent: true, A: true, B: true } });
85
+ expect(baseLogger.debug).toHaveBeenCalledWith('E', { ctx: { parent: true, A: true, B: true } });
86
+ expect(baseLogger.debug).toHaveBeenCalledWith('B end', { ctx: { parent: true, A: true, B: true } });
87
+ expect(baseLogger.debug).toHaveBeenCalledWith('A end', { ctx: { parent: true, A: true } });
88
+ expect(baseLogger.debug).toHaveBeenCalledWith('parent end', { ctx: { parent: true } });
89
89
  });
90
90
 
91
91
  it('throws if the sync callback function throws', () => {
@@ -118,10 +118,12 @@ describe('log context', () => {
118
118
  logger.error('message, error and context', new Error('some-error'), { requestId: 'parent' });
119
119
 
120
120
  expect(baseLogger.error).toHaveBeenNthCalledWith(1, 'only message', undefined);
121
- expect(baseLogger.error).toHaveBeenNthCalledWith(2, 'message and context', { requestId: 'parent' });
121
+ expect(baseLogger.error).toHaveBeenNthCalledWith(2, 'message and context', { ctx: { requestId: 'parent' } });
122
122
  expect(baseLogger.error).toHaveBeenNthCalledWith(3, 'message and error', new Error('some-error'), undefined);
123
123
  expect(baseLogger.error).toHaveBeenNthCalledWith(4, 'message, error and context', new Error('some-error'), {
124
- requestId: 'parent',
124
+ ctx: {
125
+ requestId: 'parent',
126
+ },
125
127
  });
126
128
  });
127
129
  });
@@ -61,7 +61,6 @@ export const createBaseLogger = (config: LogConfig) => {
61
61
  // This format is recommended by the "winston-console-format" package.
62
62
  format: winston.format.combine(
63
63
  winston.format.timestamp(),
64
- winston.format.ms(),
65
64
  winston.format.errors({ stack: true }),
66
65
  winston.format.splat(),
67
66
  winston.format.json()
@@ -88,36 +87,36 @@ export interface Logger {
88
87
  child: (options: { name: string }) => Logger;
89
88
  }
90
89
 
90
+ const createFullContext = (localContext: LogContext | undefined) => {
91
+ const globalContext = getAsyncLocalStorage().getStore();
92
+ if (!globalContext && !localContext) return;
93
+ const fullContext = { ...globalContext, ...localContext };
94
+
95
+ // If the context contains a `name` or `message` field, it will override the `name` and `message` fields of the log
96
+ // entry. To avoid this, we return the context as a separate field.
97
+ return { ctx: fullContext };
98
+ };
99
+
91
100
  // Winston by default merges content of `context` among the rest of the fields for the JSON format.
92
101
  // That's causing an override of fields `name` and `message` if they are present.
93
102
  export const wrapper = (logger: winston.Logger): Logger => {
94
103
  return {
95
104
  debug: (message, localContext) => {
96
- const globalContext = getAsyncLocalStorage().getStore();
97
- const fullContext = globalContext || localContext ? { ...globalContext, ...localContext } : undefined;
98
- logger.debug(message, fullContext);
105
+ logger.debug(message, createFullContext(localContext));
99
106
  },
100
107
  info: (message, localContext) => {
101
- const globalContext = getAsyncLocalStorage().getStore();
102
- const fullContext = globalContext || localContext ? { ...globalContext, ...localContext } : undefined;
103
- logger.info(message, fullContext);
108
+ logger.info(message, createFullContext(localContext));
104
109
  },
105
110
  warn: (message, localContext) => {
106
- const globalContext = getAsyncLocalStorage().getStore();
107
- const fullContext = globalContext || localContext ? { ...globalContext, ...localContext } : undefined;
108
- logger.warn(message, fullContext);
111
+ logger.warn(message, createFullContext(localContext));
109
112
  },
110
113
  // We need to handle both overloads of the `error` function
111
114
  error: (message, errorOrLocalContext: Error | LogContext, localContext?: LogContext) => {
112
- const globalContext = getAsyncLocalStorage().getStore();
113
115
  // eslint-disable-next-line lodash/prefer-lodash-typecheck
114
116
  if (errorOrLocalContext instanceof Error) {
115
- const fullContext = globalContext || localContext ? { ...globalContext, ...localContext } : undefined;
116
- logger.error(message, errorOrLocalContext, fullContext);
117
+ logger.error(message, errorOrLocalContext, createFullContext(localContext));
117
118
  } else {
118
- const fullContext =
119
- globalContext || errorOrLocalContext ? { ...globalContext, ...errorOrLocalContext } : undefined;
120
- logger.error(message, fullContext);
119
+ logger.error(message, createFullContext(errorOrLocalContext));
121
120
  }
122
121
  },
123
122
  child: (options) => wrapper(logger.child(options)),
package/src/node-index.ts CHANGED
@@ -2,3 +2,5 @@
2
2
  export * from './universal-index';
3
3
  export * from './logger';
4
4
  export * from './processing';
5
+ export * from './config-parsing';
6
+ export * from './config-hash';
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable jest/prefer-strict-equal */ // Because the errors are thrown from the "vm" module (different context), they are not strictly equal.
2
2
  import { ZodError } from 'zod';
3
3
 
4
- import { createEndpoint } from '../../test/fixtures';
4
+ import { createEndpoint } from '../../test/fixtures/processing';
5
5
 
6
6
  import {
7
7
  addReservedParameters,
@@ -143,7 +143,6 @@ describe(unsafeEvaluateV2.name, () => {
143
143
  'string_decoder',
144
144
  'timers',
145
145
  'tls',
146
- 'trace_events',
147
146
  'tty',
148
147
  'url',
149
148
  'util',
@@ -27,7 +27,6 @@ import stream from 'node:stream';
27
27
  import string_decoder from 'node:string_decoder';
28
28
  import timers from 'node:timers';
29
29
  import tls from 'node:tls';
30
- import trace_events from 'node:trace_events';
31
30
  import tty from 'node:tty';
32
31
  import url from 'node:url';
33
32
  import util from 'node:util';
@@ -69,7 +68,6 @@ const builtInNodeModules = {
69
68
  string_decoder,
70
69
  timers,
71
70
  tls,
72
- trace_events,
73
71
  tty,
74
72
  url,
75
73
  util,