@hg-ts/config-loader 0.1.13 → 0.1.15

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 (32) hide show
  1. package/.eslintcache +1 -1
  2. package/dist/config-loader.d.ts +3 -4
  3. package/dist/config-loader.d.ts.map +1 -1
  4. package/dist/config-loader.js +7 -16
  5. package/dist/config-loader.js.map +1 -1
  6. package/dist/tests/config-loader.test-suite.d.ts.map +1 -1
  7. package/dist/tests/config-loader.test-suite.js +12 -18
  8. package/dist/tests/config-loader.test-suite.js.map +1 -1
  9. package/dist-esm/config-loader.d.ts +3 -4
  10. package/dist-esm/config-loader.d.ts.map +1 -1
  11. package/dist-esm/config-loader.js +7 -16
  12. package/dist-esm/config-loader.js.map +1 -1
  13. package/dist-esm/tests/config-loader.test-suite.d.ts.map +1 -1
  14. package/dist-esm/tests/config-loader.test-suite.js +12 -18
  15. package/dist-esm/tests/config-loader.test-suite.js.map +1 -1
  16. package/dist-esm/zod-extension.d.ts +7 -0
  17. package/dist-esm/zod-extension.d.ts.map +1 -0
  18. package/dist-esm/zod-extension.js +6 -0
  19. package/dist-esm/zod-extension.js.map +1 -0
  20. package/package.json +13 -16
  21. package/src/config-loader.ts +14 -25
  22. package/src/tests/config-loader.test-suite.ts +12 -16
  23. package/dist/decorators/enforce-env.decorator.d.ts +0 -2
  24. package/dist/decorators/enforce-env.decorator.d.ts.map +0 -1
  25. package/dist/decorators/enforce-env.decorator.js +0 -9
  26. package/dist/decorators/enforce-env.decorator.js.map +0 -1
  27. package/dist/decorators/index.d.ts +0 -2
  28. package/dist/decorators/index.d.ts.map +0 -1
  29. package/dist/decorators/index.js +0 -5
  30. package/dist/decorators/index.js.map +0 -1
  31. package/src/decorators/enforce-env.decorator.ts +0 -5
  32. package/src/decorators/index.ts +0 -1
package/.eslintcache CHANGED
@@ -1 +1 @@
1
- [{"/Volumes/Work/ts/hg/framework/packages/execution-mode/src/index.ts":"1","/Volumes/Work/ts/hg/framework/packages/config-loader/src/config-loader.ts":"2","/Volumes/Work/ts/hg/framework/packages/config-loader/src/decorators/enforce-env.decorator.ts":"3","/Volumes/Work/ts/hg/framework/packages/config-loader/src/decorators/index.ts":"4","/Volumes/Work/ts/hg/framework/packages/config-loader/src/exceptions/index.ts":"5","/Volumes/Work/ts/hg/framework/packages/config-loader/src/exceptions/no-base-config.exception.ts":"6","/Volumes/Work/ts/hg/framework/packages/config-loader/src/index.ts":"7","/Volumes/Work/ts/hg/framework/packages/config-loader/src/path-builder.ts":"8","/Volumes/Work/ts/hg/framework/packages/config-loader/src/tests/config-loader.test-suite.ts":"9","/Volumes/Work/ts/hg/framework/packages/config-loader/src/tests/path-builder.test-suite.ts":"10"},{"size":64,"mtime":1660865486194,"results":"11","hashOfConfig":"12"},{"size":2864,"mtime":1687103756867,"results":"13","hashOfConfig":"14"},{"size":174,"mtime":1665301649524,"results":"15","hashOfConfig":"14"},{"size":41,"mtime":1664831211487,"results":"16","hashOfConfig":"14"},{"size":44,"mtime":1664831211489,"results":"17","hashOfConfig":"14"},{"size":215,"mtime":1664831211490,"results":"18","hashOfConfig":"14"},{"size":84,"mtime":1665300013452,"results":"19","hashOfConfig":"14"},{"size":3437,"mtime":1665148294534,"results":"20","hashOfConfig":"14"},{"size":1807,"mtime":1665301650636,"results":"21","hashOfConfig":"14"},{"size":4026,"mtime":1665299715530,"results":"22","hashOfConfig":"14"},{"filePath":"23","messages":"24","suppressedMessages":"25","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"qbxc86",{"filePath":"26","messages":"27","suppressedMessages":"28","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"5sbno",{"filePath":"29","messages":"30","suppressedMessages":"31","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"32","messages":"33","suppressedMessages":"34","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"35","messages":"36","suppressedMessages":"37","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"38","messages":"39","suppressedMessages":"40","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"41","messages":"42","suppressedMessages":"43","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"44","messages":"45","suppressedMessages":"46","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"47","messages":"48","suppressedMessages":"49","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"50","messages":"51","suppressedMessages":"52","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Volumes/Work/ts/hg/framework/packages/execution-mode/src/index.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/config-loader.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/decorators/enforce-env.decorator.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/decorators/index.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/exceptions/index.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/exceptions/no-base-config.exception.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/index.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/path-builder.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/tests/config-loader.test-suite.ts",[],["53","54"],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/tests/path-builder.test-suite.ts",[],[],{"ruleId":"55","severity":2,"message":"56","line":2,"column":1,"nodeType":"57","messageId":"58","endLine":88,"endColumn":1,"suppressions":"59"},{"ruleId":"60","severity":2,"message":"61","line":73,"column":31,"nodeType":"62","messageId":"63","endLine":73,"endColumn":90,"suppressions":"64"},"max-classes-per-file","File has too many classes (2). Maximum allowed is 1.","Program","maximumExceeded",["65"],"no-nested-ternary","Do not nest ternary expressions.","ConditionalExpression","noNestedTernary",["66"],{"kind":"67","justification":"68"},{"kind":"67","justification":"68"},"directive",""]
1
+ [{"/Volumes/Work/ts/hg/framework/packages/execution-mode/src/index.ts":"1","/Volumes/Work/ts/hg/framework/packages/config-loader/src/config-loader.ts":"2","/Volumes/Work/ts/hg/framework/packages/config-loader/src/exceptions/index.ts":"3","/Volumes/Work/ts/hg/framework/packages/config-loader/src/exceptions/no-base-config.exception.ts":"4","/Volumes/Work/ts/hg/framework/packages/config-loader/src/index.ts":"5","/Volumes/Work/ts/hg/framework/packages/config-loader/src/path-builder.ts":"6","/Volumes/Work/ts/hg/framework/packages/config-loader/src/tests/config-loader.test-suite.ts":"7","/Volumes/Work/ts/hg/framework/packages/config-loader/src/tests/path-builder.test-suite.ts":"8"},{"size":64,"mtime":1660865486194,"results":"9","hashOfConfig":"10"},{"size":2454,"mtime":1713665849194,"results":"11","hashOfConfig":"12"},{"size":44,"mtime":1664831211489,"results":"13","hashOfConfig":"12"},{"size":215,"mtime":1664831211490,"results":"14","hashOfConfig":"12"},{"size":84,"mtime":1713665848874,"results":"15","hashOfConfig":"12"},{"size":3437,"mtime":1665148294534,"results":"16","hashOfConfig":"12"},{"size":1629,"mtime":1713666195154,"results":"17","hashOfConfig":"12"},{"size":4026,"mtime":1665299715530,"results":"18","hashOfConfig":"12"},{"filePath":"19","messages":"20","suppressedMessages":"21","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"qbxc86",{"filePath":"22","messages":"23","suppressedMessages":"24","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"5sbno",{"filePath":"25","messages":"26","suppressedMessages":"27","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"28","messages":"29","suppressedMessages":"30","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"31","messages":"32","suppressedMessages":"33","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"34","messages":"35","suppressedMessages":"36","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"37","messages":"38","suppressedMessages":"39","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"40","messages":"41","suppressedMessages":"42","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Volumes/Work/ts/hg/framework/packages/execution-mode/src/index.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/config-loader.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/exceptions/index.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/exceptions/no-base-config.exception.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/index.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/path-builder.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/tests/config-loader.test-suite.ts",[],[],"/Volumes/Work/ts/hg/framework/packages/config-loader/src/tests/path-builder.test-suite.ts",[],[]]
@@ -1,4 +1,4 @@
1
- /// <reference types="@hg-ts/types" />
1
+ import zod from '@hg-ts/validation';
2
2
  import { PathBuilderOptions } from './path-builder';
3
3
  export type ConfigLoaderOptions = PathBuilderOptions & {
4
4
  recursive?: boolean;
@@ -9,11 +9,10 @@ export declare class ConfigLoader {
9
9
  private readonly options;
10
10
  private readonly cacheMap;
11
11
  constructor(options?: ConfigLoaderOptions);
12
- load<ConfigType extends object>(ctor: Class<ConfigType>, name: string): Promise<ConfigType>;
12
+ load<ConfigType extends object>(schema: zod.Schema<ConfigType>, name: string): Promise<ConfigType>;
13
+ private validate;
13
14
  private loadRawConfig;
14
15
  private mergeConfigs;
15
- private transform;
16
- private validate;
17
16
  private loadConfigFile;
18
17
  }
19
18
  //# sourceMappingURL=config-loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":";AAOA,OAAO,EAAe,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEjE,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAOF,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgC;gBAEtC,OAAO,GAAE,mBAAwB;IAKvC,IAAI,CAAC,UAAU,SAAS,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;YAsB1F,aAAa;IAW3B,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,SAAS;YAIH,QAAQ;YAYR,cAAc;CAS5B"}
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAGA,OAAO,GAA8B,MAAM,mBAAmB,CAAC;AAG/D,OAAO,EAAe,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEjE,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAOF,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgC;gBAEtC,OAAO,GAAE,mBAAwB;IAKvC,IAAI,CAAC,UAAU,SAAS,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;YAoBjG,QAAQ;YAOR,aAAa;IAY3B,OAAO,CAAC,YAAY;YAeN,cAAc;CAS5B"}
@@ -4,8 +4,6 @@ exports.ConfigLoader = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
6
6
  const strict_1 = tslib_1.__importDefault(require("node:assert/strict"));
7
- const class_validator_1 = require("class-validator");
8
- const class_transformer_1 = require("class-transformer");
9
7
  const exceptions_1 = require("./exceptions");
10
8
  const path_builder_1 = require("./path-builder");
11
9
  class ConfigLoader {
@@ -16,20 +14,22 @@ class ConfigLoader {
16
14
  this.pathBuilder = new path_builder_1.PathBuilder(options);
17
15
  this.options = this.pathBuilder.options;
18
16
  }
19
- async load(ctor, name) {
17
+ async load(schema, name) {
20
18
  if (this.options.cache && this.cacheMap.has(name)) {
21
19
  const cacheItem = this.cacheMap.get(name);
22
- strict_1.default.ok(cacheItem.ctor === ctor, `cached instance of config "${name}" has another dto class`);
20
+ strict_1.default.ok(cacheItem.schema === schema, `cached instance of config "${name}" has another schema`);
23
21
  return cacheItem.config;
24
22
  }
25
23
  const rawConfig = await this.loadRawConfig(name);
26
- const config = this.transform(rawConfig, ctor);
27
- await this.validate(config);
24
+ const config = await this.validate(schema, rawConfig);
28
25
  if (this.options.cache) {
29
- this.cacheMap.set(name, { ctor, config });
26
+ this.cacheMap.set(name, { schema, config });
30
27
  }
31
28
  return config;
32
29
  }
30
+ async validate(schema, config) {
31
+ return schema.parseAsync(config);
32
+ }
33
33
  async loadRawConfig(name) {
34
34
  const paths = this.pathBuilder.build(name);
35
35
  const configs = await Promise.all(paths.map(async (path) => this.loadConfigFile(path)));
@@ -52,15 +52,6 @@ class ConfigLoader {
52
52
  };
53
53
  });
54
54
  }
55
- transform(rawConfig, ctor) {
56
- return (0, class_transformer_1.plainToInstance)(ctor, rawConfig);
57
- }
58
- async validate(config) {
59
- const validationErrors = await (0, class_validator_1.validate)(config);
60
- if (validationErrors.length > 0) {
61
- throw new AggregateError(validationErrors, 'Config validation error');
62
- }
63
- }
64
55
  async loadConfigFile(path) {
65
56
  try {
66
57
  const content = await promises_1.default.readFile(path, { encoding: 'utf-8' });
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":";;;;AAAA,wEAAkC;AAClC,wEAAwC;AAExC,qDAA2C;AAC3C,yDAAoD;AAEpD,6CAAqD;AACrD,iDAAiE;AAYjE,MAAa,YAAY;IACP,WAAW,CAAc;IACzB,OAAO,CAAsB;IAC7B,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEzD,YAAmB,UAA+B,EAAE;QACnD,IAAI,CAAC,WAAW,GAAG,IAAI,0BAAW,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;IACzC,CAAC;IAEM,KAAK,CAAC,IAAI,CAA4B,IAAuB,EAAE,IAAY;QACjF,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YAClD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;YAE3C,gBAAM,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,8BAA8B,IAAI,yBAAyB,CAAC,CAAC;YAEhG,OAAO,SAAS,CAAC,MAAoB,CAAC;SACtC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAEjD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE5B,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;YACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;SAC1C;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,IAAY;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtF,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YAChB,MAAM,IAAI,kCAAqB,CAAC,IAAI,CAAC,CAAC;SACtC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAEO,YAAY,CAAC,OAAkB;QACtC,OAAO,OAAO;aACZ,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC;aACjC,MAAM,CAAC,CAAC,MAAM,EAAqC,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC;aACjF,MAAM,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;YACxB,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;gBACtD,OAAO,MAAM,CAAC;aACd;YACD,OAAO;gBACN,GAAG,MAAM;gBACT,GAAG,IAAI;aACP,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,SAAS,CAA4B,SAAkB,EAAE,IAAuB;QACvF,OAAO,IAAA,mCAAe,EAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAA4B,MAAkB;QACnE,MAAM,gBAAgB,GAAG,MAAM,IAAA,0BAAQ,EAAC,MAAM,CAAC,CAAC;QAEhD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;YAKhC,MAAM,IAAI,cAAc,CAAC,gBAAgB,EAAE,yBAAyB,CAAC,CAAC;SACtE;IACF,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,IAAY;QACxC,IAAI;YACH,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAE/D,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;SACtC;QAAC,OAAO,KAAc,EAAE;YACxB,OAAO,IAAI,CAAC;SACZ;IACF,CAAC;CACD;AAnFD,oCAmFC"}
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.test-suite.d.ts","sourceRoot":"","sources":["../../src/tests/config-loader.test-suite.ts"],"names":[],"mappings":"AAGA,OAAO,EAIN,SAAS,EACT,MAAM,cAAc,CAAC;AAKtB,qBACa,qBAAsB,SAAQ,SAAS;IAEtC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBvB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAwBxC"}
1
+ {"version":3,"file":"config-loader.test-suite.d.ts","sourceRoot":"","sources":["../../src/tests/config-loader.test-suite.ts"],"names":[],"mappings":"AAEA,OAAO,EAIN,SAAS,EACT,MAAM,cAAc,CAAC;AAItB,qBACa,qBAAsB,SAAQ,SAAS;IAEtC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBvB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAsBxC"}
@@ -2,10 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConfigLoaderTestSuite = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const class_transformer_1 = require("class-transformer");
5
+ const validation_1 = tslib_1.__importDefault(require("@hg-ts/validation"));
6
6
  const tests_1 = require("@hg-ts/tests");
7
7
  const config_loader_1 = require("../config-loader");
8
- const decorators_1 = require("../decorators");
9
8
  let ConfigLoaderTestSuite = class ConfigLoaderTestSuite extends tests_1.TestSuite {
10
9
  async simple() {
11
10
  const loader = new config_loader_1.ConfigLoader();
@@ -47,24 +46,19 @@ let ConfigLoaderTestSuite = class ConfigLoaderTestSuite extends tests_1.TestSuit
47
46
  }
48
47
  async enforceEnv() {
49
48
  const loader = new config_loader_1.ConfigLoader();
50
- class Config {
51
- number;
52
- bool;
53
- }
54
- tslib_1.__decorate([
55
- (0, decorators_1.EnforceEnv)('SOME_NUMERIC_ENV'),
56
- (0, class_transformer_1.Transform)(({ value }) => (Number.isNaN(Number(value)) ? value : Number(value))),
57
- tslib_1.__metadata("design:type", Number)
58
- ], Config.prototype, "number", void 0);
59
- tslib_1.__decorate([
60
- (0, decorators_1.EnforceEnv)('SOME_BOOLEAN_ENV'),
61
- (0, class_transformer_1.Transform)(({ value }) => (value === 'true' ? true : value === 'false' ? false : value)),
62
- tslib_1.__metadata("design:type", Boolean)
63
- ], Config.prototype, "bool", void 0);
49
+ const configSchema = validation_1.default.object({
50
+ number: validation_1.default.union([validation_1.default.number(), validation_1.default.string()])
51
+ .enforceEnv('SOME_NUMERIC_ENV')
52
+ .transform(value => Number(value))
53
+ .pipe(validation_1.default.number()),
54
+ bool: validation_1.default.union([validation_1.default.string(), validation_1.default.boolean()])
55
+ .enforceEnv('SOME_BOOLEAN_ENV')
56
+ .transformBooleanString(),
57
+ });
64
58
  process.env['SOME_NUMERIC_ENV'] = '10';
65
59
  process.env['SOME_BOOLEAN_ENV'] = 'false';
66
- const config = { number: '1', bool: true };
67
- const transformed = loader['transform'](config, Config);
60
+ const config = { number: 1, bool: true };
61
+ const transformed = await loader['validate'](configSchema, config);
68
62
  (0, tests_1.expect)(transformed.number).toBe(10);
69
63
  (0, tests_1.expect)(transformed.bool).toBe(false);
70
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.test-suite.js","sourceRoot":"","sources":["../../src/tests/config-loader.test-suite.ts"],"names":[],"mappings":";;;;AACA,yDAA8C;AAE9C,wCAKsB;AAEtB,oDAAgD;AAChD,8CAA2C;AAGpC,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,iBAAS;IAEtC,AAAN,KAAK,CAAC,MAAM;QAClB,MAAM,MAAM,GAAG,IAAI,4BAAY,EAAE,CAAC;QAElC,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;YACrC;gBACC,CAAC,EAAE,GAAG;gBACN,CAAC,EAAE,GAAG;aACN;YACD;gBACC,CAAC,EAAE,IAAI;gBACP,CAAC,EAAE,GAAG;aACN;SACD,CAAC,CAAC;QAEH,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAGY,AAAN,KAAK,CAAC,SAAS;QACrB,MAAM,MAAM,GAAG,IAAI,4BAAY,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;YACrC;gBACC,CAAC,EAAE,GAAG;gBACN,CAAC,EAAE,GAAG;aACN;YACD;gBACC,CAAC,EAAE,IAAI;gBACP,CAAC,EAAE,GAAG;gBACN,IAAI,EAAE,IAAI;aACV;YACD;gBACC,CAAC,EAAE,KAAK;gBACR,CAAC,EAAE,KAAK;gBACR,CAAC,EAAE,KAAK;aACR;SACD,CAAC,CAAC;QAEH,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAGY,AAAN,KAAK,CAAC,UAAU;QACtB,MAAM,MAAM,GAAG,IAAI,4BAAY,EAAE,CAAC;QAElC,MAAM,MAAM;YAGJ,MAAM,CAAS;YAKf,IAAI,CAAU;SACrB;QANO;YAFN,IAAA,uBAAU,EAAC,kBAAkB,CAAC;YAC9B,IAAA,6BAAS,EAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;;8CAC1D;QAKf;YAHN,IAAA,uBAAU,EAAC,kBAAkB,CAAC;YAE9B,IAAA,6BAAS,EAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;;4CACnE;QAGtB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC;QAE1C,MAAM,MAAM,GAA4B,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAEpE,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAExD,IAAA,cAAM,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,IAAA,cAAM,EAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;CACD,CAAA;AAxEY,sDAAqB;AAEpB;IADZ,IAAA,YAAI,GAAE;;;;mDAkBN;AAGY;IADZ,IAAA,YAAI,GAAE;;;;sDAwBN;AAGY;IADZ,IAAA,YAAI,GAAE;;;;uDAwBN;gCAvEW,qBAAqB;IADjC,IAAA,gBAAQ,GAAE;GACE,qBAAqB,CAwEjC"}
1
+ {"version":3,"file":"config-loader.test-suite.js","sourceRoot":"","sources":["../../src/tests/config-loader.test-suite.ts"],"names":[],"mappings":";;;;AAAA,2EAAoC;AAEpC,wCAKsB;AAEtB,oDAAgD;AAGzC,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,iBAAS;IAEtC,AAAN,KAAK,CAAC,MAAM;QAClB,MAAM,MAAM,GAAG,IAAI,4BAAY,EAAE,CAAC;QAElC,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;YACrC;gBACC,CAAC,EAAE,GAAG;gBACN,CAAC,EAAE,GAAG;aACN;YACD;gBACC,CAAC,EAAE,IAAI;gBACP,CAAC,EAAE,GAAG;aACN;SACD,CAAC,CAAC;QAEH,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAGY,AAAN,KAAK,CAAC,SAAS;QACrB,MAAM,MAAM,GAAG,IAAI,4BAAY,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;YACrC;gBACC,CAAC,EAAE,GAAG;gBACN,CAAC,EAAE,GAAG;aACN;YACD;gBACC,CAAC,EAAE,IAAI;gBACP,CAAC,EAAE,GAAG;gBACN,IAAI,EAAE,IAAI;aACV;YACD;gBACC,CAAC,EAAE,KAAK;gBACR,CAAC,EAAE,KAAK;gBACR,CAAC,EAAE,KAAK;aACR;SACD,CAAC,CAAC;QAEH,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAA,cAAM,EAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAGY,AAAN,KAAK,CAAC,UAAU;QACtB,MAAM,MAAM,GAAG,IAAI,4BAAY,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,oBAAG,CAAC,MAAM,CAAC;YAC/B,MAAM,EAAE,oBAAG,CAAC,KAAK,CAAC,CAAC,oBAAG,CAAC,MAAM,EAAE,EAAE,oBAAG,CAAC,MAAM,EAAE,CAAC,CAAC;iBAC7C,UAAU,CAAC,kBAAkB,CAAC;iBAC9B,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;iBACjC,IAAI,CAAC,oBAAG,CAAC,MAAM,EAAE,CAAC;YACpB,IAAI,EAAE,oBAAG,CAAC,KAAK,CAAC,CAAC,oBAAG,CAAC,MAAM,EAAE,EAAE,oBAAG,CAAC,OAAO,EAAE,CAAC,CAAC;iBAC5C,UAAU,CAAC,kBAAkB,CAAC;iBAC9B,sBAAsB,EAAE;SAC1B,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC;QAE1C,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAEzC,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAEnE,IAAA,cAAM,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,IAAA,cAAM,EAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;CACD,CAAA;AAtEY,sDAAqB;AAEpB;IADZ,IAAA,YAAI,GAAE;;;;mDAkBN;AAGY;IADZ,IAAA,YAAI,GAAE;;;;sDAwBN;AAGY;IADZ,IAAA,YAAI,GAAE;;;;uDAsBN;gCArEW,qBAAqB;IADjC,IAAA,gBAAQ,GAAE;GACE,qBAAqB,CAsEjC"}
@@ -1,4 +1,4 @@
1
- /// <reference types="@hg-ts/types" />
1
+ import zod from '@hg-ts/validation';
2
2
  import { PathBuilderOptions } from './path-builder';
3
3
  export type ConfigLoaderOptions = PathBuilderOptions & {
4
4
  recursive?: boolean;
@@ -9,11 +9,10 @@ export declare class ConfigLoader {
9
9
  private readonly options;
10
10
  private readonly cacheMap;
11
11
  constructor(options?: ConfigLoaderOptions);
12
- load<ConfigType extends object>(ctor: Class<ConfigType>, name: string): Promise<ConfigType>;
12
+ load<ConfigType extends object>(schema: zod.Schema<ConfigType>, name: string): Promise<ConfigType>;
13
+ private validate;
13
14
  private loadRawConfig;
14
15
  private mergeConfigs;
15
- private transform;
16
- private validate;
17
16
  private loadConfigFile;
18
17
  }
19
18
  //# sourceMappingURL=config-loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":";AAOA,OAAO,EAAe,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEjE,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAOF,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgC;gBAEtC,OAAO,GAAE,mBAAwB;IAKvC,IAAI,CAAC,UAAU,SAAS,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;YAsB1F,aAAa;IAW3B,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,SAAS;YAIH,QAAQ;YAYR,cAAc;CAS5B"}
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAGA,OAAO,GAA8B,MAAM,mBAAmB,CAAC;AAG/D,OAAO,EAAe,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEjE,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAOF,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgC;gBAEtC,OAAO,GAAE,mBAAwB;IAKvC,IAAI,CAAC,UAAU,SAAS,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;YAoBjG,QAAQ;YAOR,aAAa;IAY3B,OAAO,CAAC,YAAY;YAeN,cAAc;CAS5B"}
@@ -1,7 +1,5 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import assert from 'node:assert/strict';
3
- import { validate } from 'class-validator';
4
- import { plainToInstance } from 'class-transformer';
5
3
  import { NoBaseConfigException } from './exceptions';
6
4
  import { PathBuilder } from './path-builder';
7
5
  export class ConfigLoader {
@@ -12,20 +10,22 @@ export class ConfigLoader {
12
10
  this.pathBuilder = new PathBuilder(options);
13
11
  this.options = this.pathBuilder.options;
14
12
  }
15
- async load(ctor, name) {
13
+ async load(schema, name) {
16
14
  if (this.options.cache && this.cacheMap.has(name)) {
17
15
  const cacheItem = this.cacheMap.get(name);
18
- assert.ok(cacheItem.ctor === ctor, `cached instance of config "${name}" has another dto class`);
16
+ assert.ok(cacheItem.schema === schema, `cached instance of config "${name}" has another schema`);
19
17
  return cacheItem.config;
20
18
  }
21
19
  const rawConfig = await this.loadRawConfig(name);
22
- const config = this.transform(rawConfig, ctor);
23
- await this.validate(config);
20
+ const config = await this.validate(schema, rawConfig);
24
21
  if (this.options.cache) {
25
- this.cacheMap.set(name, { ctor, config });
22
+ this.cacheMap.set(name, { schema, config });
26
23
  }
27
24
  return config;
28
25
  }
26
+ async validate(schema, config) {
27
+ return schema.parseAsync(config);
28
+ }
29
29
  async loadRawConfig(name) {
30
30
  const paths = this.pathBuilder.build(name);
31
31
  const configs = await Promise.all(paths.map(async (path) => this.loadConfigFile(path)));
@@ -48,15 +48,6 @@ export class ConfigLoader {
48
48
  };
49
49
  });
50
50
  }
51
- transform(rawConfig, ctor) {
52
- return plainToInstance(ctor, rawConfig);
53
- }
54
- async validate(config) {
55
- const validationErrors = await validate(config);
56
- if (validationErrors.length > 0) {
57
- throw new AggregateError(validationErrors, 'Config validation error');
58
- }
59
- }
60
51
  async loadConfigFile(path) {
61
52
  try {
62
53
  const content = await fs.readFile(path, { encoding: 'utf-8' });
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAIxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,WAAW,EAAsB,MAAM,gBAAgB,CAAC;AAYjE,MAAM,OAAO,YAAY;IACP,WAAW,CAAc;IACzB,OAAO,CAAsB;IAC7B,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEzD,YAAmB,UAA+B,EAAE;QACnD,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;IACzC,CAAC;IAEM,KAAK,CAAC,IAAI,CAA4B,MAA8B,EAAE,IAAY;QACxF,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YAClD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;YAE3C,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,KAAK,MAAM,EAAE,8BAA8B,IAAI,sBAAsB,CAAC,CAAC;YAEjG,OAAO,SAAS,CAAC,MAAoB,CAAC;SACtC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAEjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAEtD,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;YACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;SAC5C;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,QAAQ,CACrB,MAAkD,EAClD,MAAe;QAEf,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,IAAY;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE3C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEtF,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YAChB,MAAM,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC;SACtC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAEO,YAAY,CAAC,OAAkB;QACtC,OAAO,OAAO;aACZ,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC;aACjC,MAAM,CAAC,CAAC,MAAM,EAAqC,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC;aACjF,MAAM,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;YACxB,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;gBACtD,OAAO,MAAM,CAAC;aACd;YACD,OAAO;gBACN,GAAG,MAAM;gBACT,GAAG,IAAI;aACP,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,IAAY;QACxC,IAAI;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAE/D,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;SACtC;QAAC,OAAO,KAAc,EAAE;YACxB,OAAO,IAAI,CAAC;SACZ;IACF,CAAC;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.test-suite.d.ts","sourceRoot":"","sources":["../../src/tests/config-loader.test-suite.ts"],"names":[],"mappings":"AAGA,OAAO,EAIN,SAAS,EACT,MAAM,cAAc,CAAC;AAKtB,qBACa,qBAAsB,SAAQ,SAAS;IAEtC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBvB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAwBxC"}
1
+ {"version":3,"file":"config-loader.test-suite.d.ts","sourceRoot":"","sources":["../../src/tests/config-loader.test-suite.ts"],"names":[],"mappings":"AAEA,OAAO,EAIN,SAAS,EACT,MAAM,cAAc,CAAC;AAItB,qBACa,qBAAsB,SAAQ,SAAS;IAEtC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBvB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAsBxC"}
@@ -1,8 +1,7 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
- import { Transform } from 'class-transformer';
2
+ import zod from '@hg-ts/validation';
3
3
  import { Describe, expect, Test, TestSuite, } from '@hg-ts/tests';
4
4
  import { ConfigLoader } from '../config-loader';
5
- import { EnforceEnv } from '../decorators';
6
5
  let ConfigLoaderTestSuite = class ConfigLoaderTestSuite extends TestSuite {
7
6
  async simple() {
8
7
  const loader = new ConfigLoader();
@@ -44,24 +43,19 @@ let ConfigLoaderTestSuite = class ConfigLoaderTestSuite extends TestSuite {
44
43
  }
45
44
  async enforceEnv() {
46
45
  const loader = new ConfigLoader();
47
- class Config {
48
- number;
49
- bool;
50
- }
51
- __decorate([
52
- EnforceEnv('SOME_NUMERIC_ENV'),
53
- Transform(({ value }) => (Number.isNaN(Number(value)) ? value : Number(value))),
54
- __metadata("design:type", Number)
55
- ], Config.prototype, "number", void 0);
56
- __decorate([
57
- EnforceEnv('SOME_BOOLEAN_ENV'),
58
- Transform(({ value }) => (value === 'true' ? true : value === 'false' ? false : value)),
59
- __metadata("design:type", Boolean)
60
- ], Config.prototype, "bool", void 0);
46
+ const configSchema = zod.object({
47
+ number: zod.union([zod.number(), zod.string()])
48
+ .enforceEnv('SOME_NUMERIC_ENV')
49
+ .transform(value => Number(value))
50
+ .pipe(zod.number()),
51
+ bool: zod.union([zod.string(), zod.boolean()])
52
+ .enforceEnv('SOME_BOOLEAN_ENV')
53
+ .transformBooleanString(),
54
+ });
61
55
  process.env['SOME_NUMERIC_ENV'] = '10';
62
56
  process.env['SOME_BOOLEAN_ENV'] = 'false';
63
- const config = { number: '1', bool: true };
64
- const transformed = loader['transform'](config, Config);
57
+ const config = { number: 1, bool: true };
58
+ const transformed = await loader['validate'](configSchema, config);
65
59
  expect(transformed.number).toBe(10);
66
60
  expect(transformed.bool).toBe(false);
67
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.test-suite.js","sourceRoot":"","sources":["../../src/tests/config-loader.test-suite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config-loader.test-suite.js","sourceRoot":"","sources":["../../src/tests/config-loader.test-suite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ declare module 'zod' {
2
+ interface ZodSchema<Output = any> {
3
+ enforceEnv<T extends ZodSchema>(this: T, name: string): T;
4
+ }
5
+ }
6
+ export {};
7
+ //# sourceMappingURL=zod-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-extension.d.ts","sourceRoot":"","sources":["../src/zod-extension.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,KAAK,CAAC;IAEpB,UAAU,SAAS,CAAC,MAAM,GAAG,GAAG;QAC/B,UAAU,CAAC,CAAC,SAAS,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC;KAC1D;CACD"}
@@ -0,0 +1,6 @@
1
+ import zod from 'zod';
2
+ zod.Schema.prototype.enforceEnv = function enforceEnv(name) {
3
+ this.transform(value => process.env[name] ?? value);
4
+ return this;
5
+ };
6
+ //# sourceMappingURL=zod-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-extension.js","sourceRoot":"","sources":["../src/zod-extension.ts"],"names":[],"mappings":"AAAA,OAAO,GAAkB,MAAM,KAAK,CAAC;AAQrC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,GAAG,SAAS,UAAU,CAA+B,IAAY;IAC/F,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;IACpD,OAAO,IAAI,CAAC;AACb,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hg-ts/config-loader",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist-esm/index.js",
6
6
  "repository": "git@gitlab.com:hyper-graph/framework.git",
@@ -15,36 +15,33 @@
15
15
  "test:coverage": "hg test:coverage"
16
16
  },
17
17
  "devDependencies": {
18
- "@hg-ts-config/eslint-config": "0.1.13",
19
- "@hg-ts-config/typescript": "0.1.13",
20
- "@hg-ts/cli": "0.1.13",
21
- "@hg-ts/exception": "0.1.13",
22
- "@hg-ts/execution-mode": "0.1.13",
23
- "@hg-ts/tests": "0.1.13",
24
- "@hg-ts/types": "0.1.13",
18
+ "@hg-ts-config/eslint-config": "0.1.15",
19
+ "@hg-ts-config/nyc": "0.1.15",
20
+ "@hg-ts-config/typescript": "0.1.15",
21
+ "@hg-ts/cli": "0.1.15",
22
+ "@hg-ts/exception": "0.1.15",
23
+ "@hg-ts/execution-mode": "0.1.15",
24
+ "@hg-ts/tests": "0.1.15",
25
+ "@hg-ts/types": "0.1.15",
25
26
  "@types/node": "20.8.7",
26
27
  "@typescript-eslint/eslint-plugin": "6.8.0",
27
28
  "@typescript-eslint/parser": "6.8.0",
28
- "class-transformer": "0.5.1",
29
- "class-validator": "0.14.0",
30
29
  "eslint": "8.52.0",
31
30
  "mocha": "10.2.0",
32
31
  "mocha-junit-reporter": "2.2.1",
33
32
  "nyc": "15.1.0",
34
- "reflect-metadata": "0.1.13",
33
+ "reflect-metadata": "*",
35
34
  "tsc-watch": "6.0.4",
36
35
  "tslib": "2.6.2",
37
36
  "typescript": "5.2.2"
38
37
  },
39
38
  "peerDependencies": {
40
- "@hg-ts/exception": "*",
41
- "@hg-ts/execution-mode": "*",
42
- "class-transformer": "*",
43
- "class-validator": "*",
39
+ "@hg-ts/exception": "0.1.15",
40
+ "@hg-ts/execution-mode": "0.1.15",
44
41
  "reflect-metadata": "*",
45
42
  "tslib": "*"
46
43
  },
47
44
  "dependencies": {
48
- "@hg-ts-config/nyc": "0.1.13"
45
+ "@hg-ts/validation": "0.1.15"
49
46
  }
50
47
  }
@@ -1,8 +1,7 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import assert from 'node:assert/strict';
3
3
 
4
- import { validate } from 'class-validator';
5
- import { plainToInstance } from 'class-transformer';
4
+ import zod, { ZodSchema, ZodTypeDef } from '@hg-ts/validation';
6
5
 
7
6
  import { NoBaseConfigException } from './exceptions';
8
7
  import { PathBuilder, PathBuilderOptions } from './path-builder';
@@ -13,7 +12,7 @@ export type ConfigLoaderOptions = PathBuilderOptions & {
13
12
  };
14
13
 
15
14
  type CacheItem = {
16
- ctor: Class<object>;
15
+ schema: zod.Schema<object>;
17
16
  config: object;
18
17
  };
19
18
 
@@ -27,30 +26,36 @@ export class ConfigLoader {
27
26
  this.options = this.pathBuilder.options;
28
27
  }
29
28
 
30
- public async load<ConfigType extends object>(ctor: Class<ConfigType>, name: string): Promise<ConfigType> {
29
+ public async load<ConfigType extends object>(schema: zod.Schema<ConfigType>, name: string): Promise<ConfigType> {
31
30
  if (this.options.cache && this.cacheMap.has(name)) {
32
31
  const cacheItem = this.cacheMap.get(name)!;
33
32
 
34
- assert.ok(cacheItem.ctor === ctor, `cached instance of config "${name}" has another dto class`);
33
+ assert.ok(cacheItem.schema === schema, `cached instance of config "${name}" has another schema`);
35
34
 
36
35
  return cacheItem.config as ConfigType;
37
36
  }
38
37
 
39
38
  const rawConfig = await this.loadRawConfig(name);
40
39
 
41
- const config = this.transform(rawConfig, ctor);
42
-
43
- await this.validate(config);
40
+ const config = await this.validate(schema, rawConfig);
44
41
 
45
42
  if (this.options.cache) {
46
- this.cacheMap.set(name, { ctor, config });
43
+ this.cacheMap.set(name, { schema, config });
47
44
  }
48
45
 
49
46
  return config;
50
47
  }
51
48
 
49
+ private async validate<ConfigType>(
50
+ schema: ZodSchema<ConfigType, ZodTypeDef, unknown>,
51
+ config: unknown,
52
+ ): Promise<ConfigType> {
53
+ return schema.parseAsync(config);
54
+ }
55
+
52
56
  private async loadRawConfig(name: string): Promise<unknown> {
53
57
  const paths = this.pathBuilder.build(name);
58
+
54
59
  const configs = await Promise.all(paths.map(async path => this.loadConfigFile(path)));
55
60
 
56
61
  if (!configs[0]) {
@@ -75,22 +80,6 @@ export class ConfigLoader {
75
80
  });
76
81
  }
77
82
 
78
- private transform<ConfigType extends object>(rawConfig: unknown, ctor: Class<ConfigType>): ConfigType {
79
- return plainToInstance(ctor, rawConfig);
80
- }
81
-
82
- private async validate<ConfigType extends object>(config: ConfigType): Promise<void> {
83
- const validationErrors = await validate(config);
84
-
85
- if (validationErrors.length > 0) {
86
- /*
87
- * TODO: Use aggregate exception from @hg/exception
88
- * TODO: Map validateErrors to BaseException from @hg/exception
89
- */
90
- throw new AggregateError(validationErrors, 'Config validation error');
91
- }
92
- }
93
-
94
83
  private async loadConfigFile(path: string): Promise<unknown> {
95
84
  try {
96
85
  const content = await fs.readFile(path, { encoding: 'utf-8' });
@@ -1,5 +1,4 @@
1
- // eslint-disable-next-line max-classes-per-file
2
- import { Transform } from 'class-transformer';
1
+ import zod from '@hg-ts/validation';
3
2
 
4
3
  import {
5
4
  Describe,
@@ -9,7 +8,6 @@ import {
9
8
  } from '@hg-ts/tests';
10
9
 
11
10
  import { ConfigLoader } from '../config-loader';
12
- import { EnforceEnv } from '../decorators';
13
11
 
14
12
  @Describe()
15
13
  export class ConfigLoaderTestSuite extends TestSuite {
@@ -62,24 +60,22 @@ export class ConfigLoaderTestSuite extends TestSuite {
62
60
  @Test()
63
61
  public async enforceEnv(): Promise<void> {
64
62
  const loader = new ConfigLoader();
65
-
66
- class Config {
67
- @EnforceEnv('SOME_NUMERIC_ENV')
68
- @Transform(({ value }) => (Number.isNaN(Number(value)) ? value : Number(value)))
69
- public number: number;
70
-
71
- @EnforceEnv('SOME_BOOLEAN_ENV')
72
- // eslint-disable-next-line no-nested-ternary
73
- @Transform(({ value }) => (value === 'true' ? true : value === 'false' ? false : value))
74
- public bool: boolean;
75
- }
63
+ const configSchema = zod.object({
64
+ number: zod.union([zod.number(), zod.string()])
65
+ .enforceEnv('SOME_NUMERIC_ENV')
66
+ .transform(value => Number(value))
67
+ .pipe(zod.number()),
68
+ bool: zod.union([zod.string(), zod.boolean()])
69
+ .enforceEnv('SOME_BOOLEAN_ENV')
70
+ .transformBooleanString(),
71
+ });
76
72
 
77
73
  process.env['SOME_NUMERIC_ENV'] = '10';
78
74
  process.env['SOME_BOOLEAN_ENV'] = 'false';
79
75
 
80
- const config: Record<string, unknown> = { number: '1', bool: true };
76
+ const config = { number: 1, bool: true };
81
77
 
82
- const transformed = loader['transform'](config, Config);
78
+ const transformed = await loader['validate'](configSchema, config);
83
79
 
84
80
  expect(transformed.number).toBe(10);
85
81
  expect(transformed.bool).toBe(false);
@@ -1,2 +0,0 @@
1
- export declare function EnforceEnv(name: string): PropertyDecorator;
2
- //# sourceMappingURL=enforce-env.decorator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"enforce-env.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/enforce-env.decorator.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAE1D"}
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EnforceEnv = void 0;
4
- const class_transformer_1 = require("class-transformer");
5
- function EnforceEnv(name) {
6
- return (0, class_transformer_1.Transform)(({ value }) => process.env[name] ?? value);
7
- }
8
- exports.EnforceEnv = EnforceEnv;
9
- //# sourceMappingURL=enforce-env.decorator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"enforce-env.decorator.js","sourceRoot":"","sources":["../../src/decorators/enforce-env.decorator.ts"],"names":[],"mappings":";;;AAAA,yDAA8C;AAE9C,SAAgB,UAAU,CAAC,IAAY;IACtC,OAAO,IAAA,6BAAS,EAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;AAC7D,CAAC;AAFD,gCAEC"}
@@ -1,2 +0,0 @@
1
- export * from './enforce-env.decorator';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./enforce-env.decorator"), exports);
5
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;AAAA,kEAAwC"}
@@ -1,5 +0,0 @@
1
- import { Transform } from 'class-transformer';
2
-
3
- export function EnforceEnv(name: string): PropertyDecorator {
4
- return Transform(({ value }) => process.env[name] ?? value);
5
- }
@@ -1 +0,0 @@
1
- export * from './enforce-env.decorator';