depflow 3.0.0-dev.1 → 3.0.0-dev.11

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 (165) hide show
  1. package/README.md +108 -43
  2. package/dist/builder/Builder.d.ts +279 -0
  3. package/dist/builder/Builder.js +391 -0
  4. package/dist/builder/Builder.js.map +1 -0
  5. package/dist/cli/CLI.d.ts +157 -0
  6. package/dist/cli/CLI.js +214 -0
  7. package/dist/cli/CLI.js.map +1 -0
  8. package/dist/cli/DepFLowCLI.d.ts +93 -0
  9. package/dist/cli/DepFLowCLI.js +413 -0
  10. package/dist/cli/DepFLowCLI.js.map +1 -0
  11. package/dist/cli/Flags.d.ts +106 -0
  12. package/dist/cli/Flags.js +125 -0
  13. package/dist/cli/Flags.js.map +1 -0
  14. package/dist/cli/bin.js +68 -0
  15. package/dist/cli/bin.js.map +1 -0
  16. package/dist/config/Config.d.ts +690 -0
  17. package/dist/config/Config.js +45 -0
  18. package/dist/config/Config.js.map +1 -0
  19. package/dist/config/ImportMap.d.ts +60 -0
  20. package/dist/config/ImportMap.js +66 -0
  21. package/dist/config/ImportMap.js.map +1 -0
  22. package/dist/config/JsonSchema.d.ts +12 -0
  23. package/dist/config/JsonSchema.js +26 -0
  24. package/dist/config/JsonSchema.js.map +1 -0
  25. package/dist/config/Settings.d.ts +201 -0
  26. package/dist/config/Settings.js +191 -0
  27. package/dist/config/Settings.js.map +1 -0
  28. package/dist/config/TSConfig.d.ts +73 -0
  29. package/dist/config/TSConfig.js +73 -0
  30. package/dist/config/TSConfig.js.map +1 -0
  31. package/dist/config/codecs/JsonCodec.d.ts +30 -0
  32. package/dist/config/codecs/JsonCodec.js +31 -0
  33. package/dist/config/codecs/JsonCodec.js.map +1 -0
  34. package/dist/config/codecs/YamlCodec.d.ts +62 -0
  35. package/dist/config/codecs/YamlCodec.js +89 -0
  36. package/dist/config/codecs/YamlCodec.js.map +1 -0
  37. package/dist/dependency/DepUtils.d.ts +50 -0
  38. package/dist/dependency/DepUtils.js +71 -0
  39. package/dist/dependency/DepUtils.js.map +1 -0
  40. package/dist/dependency/Dependency.d.ts +81 -0
  41. package/dist/dependency/Dependency.js +71 -0
  42. package/dist/dependency/Dependency.js.map +1 -0
  43. package/dist/dependency/Git.d.ts +75 -0
  44. package/dist/dependency/Git.js +97 -0
  45. package/dist/dependency/Git.js.map +1 -0
  46. package/dist/dependency/GitDependency.d.ts +30 -0
  47. package/dist/dependency/GitDependency.js +79 -0
  48. package/dist/dependency/GitDependency.js.map +1 -0
  49. package/dist/dependency/NpmDependency.d.ts +27 -0
  50. package/dist/dependency/NpmDependency.js +91 -0
  51. package/dist/dependency/NpmDependency.js.map +1 -0
  52. package/dist/resolve/AliasCompiler.d.ts +45 -0
  53. package/dist/resolve/AliasCompiler.js +84 -0
  54. package/dist/resolve/AliasCompiler.js.map +1 -0
  55. package/{build/support/PathResolver → dist/resolve}/PathResolver.d.ts +26 -9
  56. package/dist/resolve/PathResolver.js +133 -0
  57. package/dist/resolve/PathResolver.js.map +1 -0
  58. package/dist/resolve/PathRewriter.d.ts +24 -0
  59. package/{build/support/PathResolver → dist/resolve}/PathRewriter.js +21 -11
  60. package/dist/resolve/PathRewriter.js.map +1 -0
  61. package/dist/schema/Config/Builder.d.ts +496 -0
  62. package/dist/schema/Config/Builder.js +78 -0
  63. package/dist/schema/Config/Builder.js.map +1 -0
  64. package/dist/schema/Config/Config.d.ts +673 -0
  65. package/dist/schema/Config/Config.js +62 -0
  66. package/dist/schema/Config/Config.js.map +1 -0
  67. package/dist/schema/Config/Dependency.d.ts +878 -0
  68. package/dist/schema/Config/Dependency.js +80 -0
  69. package/dist/schema/Config/Dependency.js.map +1 -0
  70. package/dist/schema/Config/Extractor.d.ts +157 -0
  71. package/dist/schema/Config/Extractor.js +43 -0
  72. package/dist/schema/Config/Extractor.js.map +1 -0
  73. package/dist/schema/Config/Resolver.d.ts +87 -0
  74. package/dist/schema/Config/Resolver.js +43 -0
  75. package/dist/schema/Config/Resolver.js.map +1 -0
  76. package/dist/schema/Config/Transform.d.ts +90 -0
  77. package/dist/schema/Config/Transform.js +51 -0
  78. package/dist/schema/Config/Transform.js.map +1 -0
  79. package/dist/schema/Defaults.d.ts +20 -0
  80. package/dist/schema/Defaults.js +24 -0
  81. package/dist/schema/Defaults.js.map +1 -0
  82. package/dist/schema/ImportMap.d.ts +30 -0
  83. package/dist/schema/ImportMap.js +28 -0
  84. package/dist/schema/ImportMap.js.map +1 -0
  85. package/dist/schema/TSConfig.d.ts +70 -0
  86. package/dist/schema/TSConfig.js +39 -0
  87. package/dist/schema/TSConfig.js.map +1 -0
  88. package/dist/schema/schema.d.ts +38 -0
  89. package/dist/schema/schema.js +40 -0
  90. package/dist/schema/schema.js.map +1 -0
  91. package/dist/task/Command.d.ts +287 -0
  92. package/dist/task/Command.js +404 -0
  93. package/dist/task/Command.js.map +1 -0
  94. package/dist/task/Group.d.ts +15 -0
  95. package/dist/task/Group.js +29 -0
  96. package/dist/task/Group.js.map +1 -0
  97. package/dist/task/OutputPolicy.d.ts +262 -0
  98. package/dist/task/OutputPolicy.js +364 -0
  99. package/dist/task/OutputPolicy.js.map +1 -0
  100. package/dist/task/Task.d.ts +210 -0
  101. package/dist/task/Task.js +312 -0
  102. package/dist/task/Task.js.map +1 -0
  103. package/package.json +16 -14
  104. package/.gitignore +0 -7
  105. package/build/cli/DepFLowCLI.d.ts +0 -15
  106. package/build/cli/DepFLowCLI.js +0 -223
  107. package/build/cli/DepFLowCLI.js.map +0 -1
  108. package/build/cli/bin.js +0 -41
  109. package/build/cli/bin.js.map +0 -1
  110. package/build/config/Config.d.ts +0 -28
  111. package/build/config/Config.js +0 -46
  112. package/build/config/Config.js.map +0 -1
  113. package/build/config/ImportMap.d.ts +0 -37
  114. package/build/config/ImportMap.js +0 -82
  115. package/build/config/ImportMap.js.map +0 -1
  116. package/build/config/Tsconfig.d.ts +0 -57
  117. package/build/config/Tsconfig.js +0 -100
  118. package/build/config/Tsconfig.js.map +0 -1
  119. package/build/config/schemas.d.ts +0 -1194
  120. package/build/config/schemas.js +0 -66
  121. package/build/config/schemas.js.map +0 -1
  122. package/build/support/Async.d.ts +0 -22
  123. package/build/support/Async.js +0 -62
  124. package/build/support/Async.js.map +0 -1
  125. package/build/support/Builder/Builder.d.ts +0 -36
  126. package/build/support/Builder/Builder.js +0 -89
  127. package/build/support/Builder/Builder.js.map +0 -1
  128. package/build/support/Dependency/Dependency.d.ts +0 -38
  129. package/build/support/Dependency/Dependency.js +0 -14
  130. package/build/support/Dependency/Dependency.js.map +0 -1
  131. package/build/support/Dependency/GitDependency.d.ts +0 -20
  132. package/build/support/Dependency/GitDependency.js +0 -67
  133. package/build/support/Dependency/GitDependency.js.map +0 -1
  134. package/build/support/Dependency/NpmDependency.d.ts +0 -18
  135. package/build/support/Dependency/NpmDependency.js +0 -65
  136. package/build/support/Dependency/NpmDependency.js.map +0 -1
  137. package/build/support/Dependency/Resolver.d.ts +0 -7
  138. package/build/support/Dependency/Resolver.js +0 -4
  139. package/build/support/Dependency/Resolver.js.map +0 -1
  140. package/build/support/Git.d.ts +0 -53
  141. package/build/support/Git.js +0 -86
  142. package/build/support/Git.js.map +0 -1
  143. package/build/support/PathResolver/AliasCompiler.d.ts +0 -25
  144. package/build/support/PathResolver/AliasCompiler.js +0 -39
  145. package/build/support/PathResolver/AliasCompiler.js.map +0 -1
  146. package/build/support/PathResolver/PathResolver.js +0 -104
  147. package/build/support/PathResolver/PathResolver.js.map +0 -1
  148. package/build/support/PathResolver/PathRewriter.d.ts +0 -18
  149. package/build/support/PathResolver/PathRewriter.js.map +0 -1
  150. package/build/support/PathResolver/Utils.d.ts +0 -36
  151. package/build/support/PathResolver/Utils.js +0 -45
  152. package/build/support/PathResolver/Utils.js.map +0 -1
  153. package/build/support/Task/Command.d.ts +0 -49
  154. package/build/support/Task/Command.js +0 -100
  155. package/build/support/Task/Command.js.map +0 -1
  156. package/build/support/Task/Task.d.ts +0 -84
  157. package/build/support/Task/Task.js +0 -145
  158. package/build/support/Task/Task.js.map +0 -1
  159. package/build/support/Utils.d.ts +0 -40
  160. package/build/support/Utils.js +0 -138
  161. package/build/support/Utils.js.map +0 -1
  162. package/build/support/Validator.d.ts +0 -22
  163. package/build/support/Validator.js +0 -28
  164. package/build/support/Validator.js.map +0 -1
  165. /package/{build → dist}/cli/bin.d.ts +0 -0
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @author NetFeez <netfeez.dev@gmail.com>.
3
+ * @description Depflow main configuration store, persisted as JSON or YAML with generated comments.
4
+ * @license Apache-2.0
5
+ */
6
+ import { Path } from '@netfeez/common-node';
7
+ import schema from '../schema/schema.js';
8
+ import Settings from './Settings.js';
9
+ import JsonSchema from './JsonSchema.js';
10
+ import JsonCodec from './codecs/JsonCodec.js';
11
+ import YamlCodec from './codecs/YamlCodec.js';
12
+ export class Config extends Settings {
13
+ static schema = schema.Config;
14
+ /**
15
+ * The formats of the config file, in resolution order.
16
+ *
17
+ * The YAML one carries the header of a generated file; the comments of each key come from the
18
+ * descriptions of the schema, on their own.
19
+ * @returns The JSON codec and the YAML codec of the config.
20
+ */
21
+ static get codecs() {
22
+ return [
23
+ new JsonCodec(),
24
+ new YamlCodec(schema.Config, {
25
+ header: [
26
+ '# Depflow Configuration File',
27
+ '# You can use the Red Hat extension for JSON schema validation in VSCode: "$schema: .depflow/schema.json"',
28
+ '', ''
29
+ ]
30
+ })
31
+ ];
32
+ }
33
+ /**
34
+ * Saves the config and refreshes the editor JSON Schema under the project `.depflow` directory.
35
+ * @param path - The path to save the config file to.
36
+ * @returns A promise that resolves when the config and the editor schema have been written.
37
+ **/
38
+ async save(path = this.path) {
39
+ const dir = Path.dirname(path);
40
+ await super.save(path);
41
+ await JsonSchema.write(dir);
42
+ }
43
+ }
44
+ export default Config;
45
+ //# sourceMappingURL=Config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Config.js","sourceRoot":"","sources":["../../src/config/Config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAG5C,OAAO,MAAM,MAAM,qBAAqB,CAAC;AACzC,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,SAAS,MAAM,uBAAuB,CAAC;AAC9C,OAAO,SAAS,MAAM,uBAAuB,CAAC;AAE9C,MAAM,OAAO,MAAO,SAAQ,QAAwC;IACtD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAExC;;;;;;OAMG;IACO,MAAM,KAAc,MAAM;QAChC,OAAO;YACH,IAAI,SAAS,EAAE;YACf,IAAI,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE;gBACzB,MAAM,EAAE;oBACJ,8BAA8B;oBAC9B,2GAA2G;oBAC3G,EAAE,EAAE,EAAE;iBACT;aACJ,CAAC;SACL,CAAC;IACN,CAAC;IAED;;;;QAII;IACY,KAAK,CAAC,IAAI,CAAC,IAAI,GAAW,IAAI,CAAC,IAAK;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,MAAM,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;CACJ;AAID,eAAe,MAAM,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @author NetFeez <netfeez.dev@gmail.com>.
3
+ * @description Updates and persists the import map file from compiled path aliases.
4
+ * @license Apache-2.0
5
+ */
6
+ import { Logger } from '@netfeez/vterm';
7
+ import schema from '../schema/schema.js';
8
+ import Settings from './Settings.js';
9
+ import type AliasCompiler from '../resolve/AliasCompiler.js';
10
+ export declare class ImportMap extends Settings<typeof schema.ImportMap> {
11
+ protected static schema: import("@netfeez/schema").Schema<{
12
+ readonly type: "object";
13
+ readonly additional: true;
14
+ readonly default: {};
15
+ readonly keys: {
16
+ readonly imports: {
17
+ readonly type: "object";
18
+ readonly additional: true;
19
+ readonly default: {};
20
+ readonly description: "Mapping of bare specifiers to their resolved URLs or paths.";
21
+ };
22
+ readonly scopes: {
23
+ readonly type: "object";
24
+ readonly additional: true;
25
+ readonly default: {};
26
+ readonly description: "Scope-based mappings of bare specifiers to their resolved URLs or paths.";
27
+ };
28
+ };
29
+ readonly description: "Structure of an import map file.";
30
+ }>;
31
+ protected logger: Logger;
32
+ constructor(data: ImportMap.Data, options?: ImportMap.Options);
33
+ /**
34
+ * The formats of the import map file: JSON only, so it never reaches a YAML parser.
35
+ * @returns The JSON codec of the file.
36
+ */
37
+ protected static get codecs(): readonly Settings.AnyCodec[];
38
+ /**
39
+ * Updates the import map data based on the provided compiled aliases.
40
+ * It constructs an "imports" section where each alias is mapped to its target path.
41
+ * @param aliases - An array of compiled aliases.
42
+ * @param mode - The resolution mode ('local' or 'cdn').
43
+ */
44
+ updateImports(aliases: AliasCompiler.CompiledAlias[], mode: 'local' | 'cdn'): void;
45
+ /**
46
+ * Saves the current import map data to a file.
47
+ * It ensures that the directory for the file exists, converts the data to a JSON string with proper formatting, and writes it to the file system using the File.write method.
48
+ * The method also includes logging to inform users when the save operation is successful.
49
+ * @param path - The path to the import map file to save.
50
+ * @returns A promise that resolves when the save operation is complete, or rejects if an error occurs during the process.
51
+ */
52
+ save(path?: string): Promise<void>;
53
+ }
54
+ export declare namespace ImportMap {
55
+ type Data = schema.ImportMap.Root;
56
+ interface Options extends Settings.Options {
57
+ logger?: Logger;
58
+ }
59
+ }
60
+ export default ImportMap;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @author NetFeez <netfeez.dev@gmail.com>.
3
+ * @description Updates and persists the import map file from compiled path aliases.
4
+ * @license Apache-2.0
5
+ */
6
+ import { Logger } from '@netfeez/vterm';
7
+ import { Path } from '@netfeez/common-node';
8
+ import schema from '../schema/schema.js';
9
+ import Settings from './Settings.js';
10
+ import JsonCodec from './codecs/JsonCodec.js';
11
+ export class ImportMap extends Settings {
12
+ static schema = schema.ImportMap;
13
+ logger;
14
+ constructor(data, options = {}) {
15
+ super(data, options);
16
+ this.logger = options.logger || new Logger({ name: 'IMP-MAP' });
17
+ }
18
+ /**
19
+ * The formats of the import map file: JSON only, so it never reaches a YAML parser.
20
+ * @returns The JSON codec of the file.
21
+ */
22
+ static get codecs() { return [new JsonCodec()]; }
23
+ /**
24
+ * Updates the import map data based on the provided compiled aliases.
25
+ * It constructs an "imports" section where each alias is mapped to its target path.
26
+ * @param aliases - An array of compiled aliases.
27
+ * @param mode - The resolution mode ('local' or 'cdn').
28
+ */
29
+ updateImports(aliases, mode) {
30
+ if (!this.data.imports)
31
+ this.data.imports = {};
32
+ const projectRoot = Path.dirname(this.path);
33
+ for (const aliasObj of aliases) {
34
+ const key = aliasObj.isWildcard ? `${aliasObj.alias}/` : aliasObj.alias;
35
+ let target = mode === 'cdn' && aliasObj.targets.cdn
36
+ ? aliasObj.targets.cdn
37
+ : aliasObj.targets.local;
38
+ if (target === aliasObj.targets.local) {
39
+ target = Path.diff(projectRoot, target);
40
+ target = target.startsWith('.') ? target : `./${target}`;
41
+ target = Path.normalize(target);
42
+ }
43
+ if (aliasObj.isWildcard) {
44
+ if (!target.endsWith('/'))
45
+ target += '/';
46
+ }
47
+ this.data.imports[key] = target;
48
+ }
49
+ }
50
+ /**
51
+ * Saves the current import map data to a file.
52
+ * It ensures that the directory for the file exists, converts the data to a JSON string with proper formatting, and writes it to the file system using the File.write method.
53
+ * The method also includes logging to inform users when the save operation is successful.
54
+ * @param path - The path to the import map file to save.
55
+ * @returns A promise that resolves when the save operation is complete, or rejects if an error occurs during the process.
56
+ */
57
+ async save(path = this.path) {
58
+ await super.save(path);
59
+ if (path !== this.path)
60
+ this.path = path;
61
+ const filename = Path.fileName(path);
62
+ this.logger.log(`&C2Saved file &C4${filename}`);
63
+ }
64
+ }
65
+ export default ImportMap;
66
+ //# sourceMappingURL=ImportMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImportMap.js","sourceRoot":"","sources":["../../src/config/ImportMap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5C,OAAO,MAAM,MAAM,qBAAqB,CAAC;AACzC,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,SAAS,MAAM,uBAAuB,CAAC;AAI9C,MAAM,OAAO,SAAU,SAAQ,QAAiC;IAClD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC;IACjC,MAAM,CAAS;IAEzB,YAAY,IAAoB,EAAE,OAAO,GAAsB,EAAE;QAC7D,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACpE,CAAC;IAED;;;OAGG;IACO,MAAM,KAAc,MAAM,KAAmC,OAAO,CAAE,IAAI,SAAS,EAAE,CAAE,CAAC,CAAC,CAAC;IAEpG;;;;;OAKG;IACI,aAAa,CAAC,OAAsC,EAAE,IAAqB;QAC9E,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAE/C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,CAAC,CAAC;QAE7C,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YAExE,IAAI,MAAM,GAAG,IAAI,KAAK,KAAK,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG;gBAC/C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG;gBACtB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC;YAE7B,IAAI,MAAM,KAAK,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBACpC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;gBACxC,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;gBACzD,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;YACD,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;gBACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;oBAAE,MAAM,IAAI,GAAG,CAAC;YAC7C,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACpC,CAAC;IACL,CAAC;IACD;;;;;;OAMG;IACI,KAAK,CAAC,IAAI,CAAC,IAAI,GAAW,IAAI,CAAC,IAAK;QACvC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,oBAAoB,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;CACJ;AASD,eAAe,SAAS,CAAC"}
@@ -0,0 +1,12 @@
1
+ export declare namespace JsonSchema {
2
+ /**
3
+ * Writes the configuration JSON Schema to `<projectRoot>/.depflow/schema.json`.
4
+ * Editors and tools use the file to validate and autocomplete the config.
5
+ * Effectively replaces the pre-dispatch write that used to run on every CLI
6
+ * invocation with a write anchored to the project that owns the config.
7
+ * @param projectRoot - Absolute path of the directory containing the config file.
8
+ * @returns A promise that resolves when the schema file has been written.
9
+ **/
10
+ function write(projectRoot: string): Promise<void>;
11
+ }
12
+ export default JsonSchema;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @author NetFeez <netfeez.dev@gmail.com>.
3
+ * @description Keeps the editor JSON Schema of the depflow configuration in sync under the project flow directory.
4
+ * @license Apache-2.0
5
+ */
6
+ import { File, Path } from '@netfeez/common-node';
7
+ import schema from '../schema/schema.js';
8
+ export var JsonSchema;
9
+ (function (JsonSchema) {
10
+ /**
11
+ * Writes the configuration JSON Schema to `<projectRoot>/.depflow/schema.json`.
12
+ * Editors and tools use the file to validate and autocomplete the config.
13
+ * Effectively replaces the pre-dispatch write that used to run on every CLI
14
+ * invocation with a write anchored to the project that owns the config.
15
+ * @param projectRoot - Absolute path of the directory containing the config file.
16
+ * @returns A promise that resolves when the schema file has been written.
17
+ **/
18
+ async function write(projectRoot) {
19
+ const path = Path.join(projectRoot, '.depflow', 'schema.json');
20
+ await File.ensureDir(Path.dirname(path));
21
+ await File.write(path, JSON.stringify(schema.Config.jsonSchema));
22
+ }
23
+ JsonSchema.write = write;
24
+ })(JsonSchema || (JsonSchema = {}));
25
+ export default JsonSchema;
26
+ //# sourceMappingURL=JsonSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonSchema.js","sourceRoot":"","sources":["../../src/config/JsonSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,MAAM,MAAM,qBAAqB,CAAC;AAEzC,MAAM,KAAW,UAAU,CAc1B;AAdD,WAAiB,UAAU;IACvB;;;;;;;QAOI;IACG,KAAK,UAAU,KAAK,CAAC,WAAmB;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;QAC/D,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IACrE,CAAC;IAJqB,WAAA,KAAK,QAI1B,CAAA;AACL,CAAC,EAdgB,UAAU,KAAV,UAAU,QAc1B;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * @author NetFeez <netfeez.dev@gmail.com>.
3
+ * @description Abstract schema-backed config store with flattened property access, whose file format lives in a codec that owns the document it preserves.
4
+ * @license Apache-2.0
5
+ */
6
+ import { Flatten } from '@netfeez/common';
7
+ import Schema, { Definition } from '@netfeez/schema';
8
+ export declare abstract class Settings<S extends Schema<Definition.Object>, TDocument = never> {
9
+ /** The schema describing and validating the config. */
10
+ protected static schema: Schema<any>;
11
+ /**
12
+ * The formats this config can be persisted in, in resolution order.
13
+ *
14
+ * Declaring the formats is what replaces the implicit "every config is JSON and YAML": a class
15
+ * that only needs JSON declares only the JSON codec and never reaches a YAML parser.
16
+ * @returns The codecs of the class, empty when it declares no format at all.
17
+ *
18
+ * @remarks The types are widened because a static cannot see the type parameters of its class.
19
+ * {@link Settings.codec} is the narrowing seam, named {@link Settings.AnyCodec} on purpose.
20
+ */
21
+ protected static get codecs(): readonly Settings.AnyCodec[];
22
+ protected vData: Settings.Data<S>;
23
+ protected props: Flatten.Document;
24
+ protected document: TDocument | null;
25
+ protected path: string | null;
26
+ /** The formats of the class this instance was built from, the only way it reaches them. **/
27
+ protected formats: Settings.Formats;
28
+ /**
29
+ * Creates the config store.
30
+ * @param data - The processed data to store.
31
+ * @param options - Additional options for the config store.
32
+ */
33
+ constructor(data: Settings.Data<S>, options?: Settings.Options<TDocument>);
34
+ get data(): Settings.Data<S>;
35
+ set data(value: Settings.Data<S>);
36
+ /**
37
+ * Gets a config property by its path.
38
+ * @param path - The path to the config property.
39
+ * @returns The value of the config property at the specified path.
40
+ */
41
+ get<TKey extends keyof Settings.Props<S>>(path: TKey): Settings.Props<S>[TKey];
42
+ set<TKey extends keyof Settings.Props<S>>(path: TKey, value: Settings.Props<S>[TKey]): void;
43
+ merge(partial: Settings.DeepPartial<Settings.Data<S>>): void;
44
+ /**
45
+ * Saves the config to the given path, in the format of its extension.
46
+ *
47
+ * The document the config was loaded with is handed to the codec, so untouched keys, comments
48
+ * and formatting survive the round trip. When the config is saved into another format than it
49
+ * was loaded from (`json-to-yaml`), there is no document of that format yet, so the codec
50
+ * creates one from the data and the file is written as if it had always been in that format.
51
+ * @param path - The path to save the config file to, defaulting to the path it was loaded from.
52
+ * @returns A promise that resolves when the config is saved.
53
+ * @throws { Error} When no path is given, or the class declares no format for the extension.
54
+ */
55
+ save(path?: string): Promise<void>;
56
+ /**
57
+ * Loads a config from the given path, creating it with defaults when missing.
58
+ *
59
+ * The file is read as plain text and nothing more: the codec of the extension decides what that
60
+ * text means and hands back both the data and the document the format preserves. A file holding
61
+ * no document at all (missing, blank, or holding nothing but comments) decodes to nothing, and
62
+ * the config is then built from the defaults the schema resolves, seeded into a fresh document.
63
+ * @param this - The concrete Settings subclass constructor.
64
+ * @param path - The path to the config file.
65
+ * @param options - Options for loading the config.
66
+ * @returns A promise that resolves with the loaded config.
67
+ * @throws { Error} When the class declares no format for the extension of the path.
68
+ */
69
+ static load<C extends Settings<any, any>>(this: Settings.Ctor<C>, path: string, options?: Settings.LoadOptions): Promise<C>;
70
+ /**
71
+ * Validates the data of a file against the schema, filling in the defaults of whatever is
72
+ * absent, so that a partial file yields a complete config.
73
+ * @param data - The data read from the file.
74
+ * @returns The data of the config, ready to be stored.
75
+ *
76
+ * @remarks The return type is widened because a static cannot see the type parameters of its
77
+ * class. {@link Settings.Ctor} is where a caller of {@link load} gets it back, as the data of
78
+ * the subclass it asked for.
79
+ */
80
+ static parse(data: unknown): Settings.Data<any>;
81
+ /**
82
+ * The codec this class declares for a file extension.
83
+ * @param extension - The lower-cased file extension, including the leading dot.
84
+ * @returns The codec that reads and writes that extension, or `null` when the class declares no
85
+ * format for it.
86
+ *
87
+ * @remarks The types are widened because a static cannot see the type parameters of its class,
88
+ * as in {@link codecs}.
89
+ */
90
+ static codec(extension: string): Settings.AnyCodec | null;
91
+ /**
92
+ * The codec of a path, as declared by the class it is asked for.
93
+ * @param formats - The formats of the class, either its static side or a loaded config.
94
+ * @param path - The path the config is read from or written to.
95
+ * @returns The codec of the extension of the path.
96
+ * @throws { Error } When no format is declared for that extension.
97
+ */
98
+ private static require;
99
+ /**
100
+ * The lower-cased extension of a path, the form formats are selected by.
101
+ * @param path - The path to get the extension of.
102
+ * @returns The lower-cased extension of the path, including the leading dot.
103
+ */
104
+ private static extension;
105
+ /**
106
+ * Checks if a value is a non-null object (not an array).
107
+ * @param value - The value to check.
108
+ * @returns `true` if the value is a non-null object, `false` otherwise.
109
+ */
110
+ private static isObject;
111
+ /**
112
+ * Merges two objects deeply, recursively merging their properties.
113
+ * @param target - The object to merge into.
114
+ * @param source - The object to merge from.
115
+ * @returns The merged object.
116
+ */
117
+ private static deepMerge;
118
+ }
119
+ export declare namespace Settings {
120
+ type DeepPartial<T> = T extends object ? {
121
+ [K in keyof T]?: DeepPartial<T[K]>;
122
+ } : T;
123
+ type Data<S extends Schema<any>> = S['infer'];
124
+ type Props<S extends Schema<any>> = Flatten.Object<Extract<S['infer'], Flatten.Document>>;
125
+ interface Options<TDocument = never> {
126
+ /** The document the format of the file preserves, carried across loads and saves. */
127
+ document?: TDocument | null;
128
+ path?: string | null;
129
+ }
130
+ interface LoadOptions {
131
+ logger?: Logger;
132
+ create?: boolean;
133
+ }
134
+ interface Logger {
135
+ log(...args: any[]): void;
136
+ warn?(...args: any[]): void;
137
+ error(...args: any[]): void;
138
+ }
139
+ /**
140
+ * A codec with both of its types widened, which is what a static can name: the statics of a
141
+ * class cannot see the type parameters of that class, so this is the shape a codec is looked up
142
+ * and carried in, and the only widening in the design.
143
+ */
144
+ type AnyCodec = Settings.Codec<any, any>;
145
+ /**
146
+ * The formats of a class, as far as a caller needs them: the codec of an extension, or `null`
147
+ * when the class declares no format for it.
148
+ *
149
+ * This is what a config keeps of its own class (its formats) and what a static side exposes
150
+ * ({@link Settings.Ctor}), so both resolve a format the same way.
151
+ */
152
+ interface Formats {
153
+ codec(extension: string): Settings.AnyCodec | null;
154
+ }
155
+ /**
156
+ * What a concrete subclass must expose for {@link load} to build it: its constructor, the
157
+ * schema behind {@link parse}, and the formats it declares.
158
+ */
159
+ interface Ctor<C extends Settings<any, any>> extends Settings.Formats {
160
+ new (data: any, options?: Settings.Options<any>): C;
161
+ parse(data: unknown): Settings.Data<any>;
162
+ }
163
+ /**
164
+ * A bidirectional text format: it reads the text of a config file, writes it back, and carries
165
+ * the document of that file — whatever the format keeps around the values — from one to the other.
166
+ *
167
+ * @typeParam TDocument - The document the format preserves; `null` for a format that keeps
168
+ * nothing beyond the data, whose document is the data itself.
169
+ * @typeParam TData - The data the format renders.
170
+ */
171
+ interface Codec<TDocument, TData> {
172
+ /** The lower-cased file extensions this codec is selected by, including the leading dot. */
173
+ readonly extensions: readonly string[];
174
+ /**
175
+ * Parses the text of a file into the data it holds and the document that holds it.
176
+ * @param text - The text of the file.
177
+ * @returns The data and the document, or `null` when the text holds no document at all.
178
+ */
179
+ decode(text: string): Settings.Decoded<TDocument> | null;
180
+ /**
181
+ * Creates the document of a file that does not exist yet, holding the given data.
182
+ * @param data - The data to hold in the new document.
183
+ * @returns The new document.
184
+ */
185
+ create(data: TData): TDocument;
186
+ /**
187
+ * Renders the data through the document, keeping whatever the format preserves.
188
+ * @param data - The data to render.
189
+ * @param document - The document the data is rendered through.
190
+ * @returns The text of the file.
191
+ */
192
+ encode(data: TData, document: TDocument): string;
193
+ }
194
+ interface Decoded<TDocument> {
195
+ /** The data the file holds, before the schema validates it. */
196
+ data: unknown;
197
+ /** The document the file is written through, and written back from. */
198
+ document: TDocument;
199
+ }
200
+ }
201
+ export default Settings;
@@ -0,0 +1,191 @@
1
+ /**
2
+ * @author NetFeez <netfeez.dev@gmail.com>.
3
+ * @description Abstract schema-backed config store with flattened property access, whose file format lives in a codec that owns the document it preserves.
4
+ * @license Apache-2.0
5
+ */
6
+ import { File, Path } from '@netfeez/common-node';
7
+ import { Flatten } from '@netfeez/common';
8
+ export class Settings {
9
+ /** The schema describing and validating the config. */
10
+ static schema;
11
+ /**
12
+ * The formats this config can be persisted in, in resolution order.
13
+ *
14
+ * Declaring the formats is what replaces the implicit "every config is JSON and YAML": a class
15
+ * that only needs JSON declares only the JSON codec and never reaches a YAML parser.
16
+ * @returns The codecs of the class, empty when it declares no format at all.
17
+ *
18
+ * @remarks The types are widened because a static cannot see the type parameters of its class.
19
+ * {@link Settings.codec} is the narrowing seam, named {@link Settings.AnyCodec} on purpose.
20
+ */
21
+ static get codecs() { return []; }
22
+ vData;
23
+ props;
24
+ document;
25
+ path;
26
+ /** The formats of the class this instance was built from, the only way it reaches them. **/
27
+ formats;
28
+ /**
29
+ * Creates the config store.
30
+ * @param data - The processed data to store.
31
+ * @param options - Additional options for the config store.
32
+ */
33
+ constructor(data, options = {}) {
34
+ this.formats = new.target;
35
+ this.vData = data;
36
+ this.props = Flatten.object(this.vData);
37
+ this.document = options.document ?? null;
38
+ this.path = options.path ?? null;
39
+ }
40
+ get data() { return this.vData; }
41
+ set data(value) {
42
+ this.vData = value;
43
+ this.props = Flatten.object(this.vData);
44
+ }
45
+ /**
46
+ * Gets a config property by its path.
47
+ * @param path - The path to the config property.
48
+ * @returns The value of the config property at the specified path.
49
+ */
50
+ get(path) {
51
+ return this.props[path];
52
+ }
53
+ set(path, value) {
54
+ this.props[path] = value;
55
+ this.vData = Flatten.unObject(this.props);
56
+ }
57
+ merge(partial) {
58
+ this.vData = Settings.deepMerge(this.vData, partial);
59
+ this.props = Flatten.object(this.vData);
60
+ }
61
+ /**
62
+ * Saves the config to the given path, in the format of its extension.
63
+ *
64
+ * The document the config was loaded with is handed to the codec, so untouched keys, comments
65
+ * and formatting survive the round trip. When the config is saved into another format than it
66
+ * was loaded from (`json-to-yaml`), there is no document of that format yet, so the codec
67
+ * creates one from the data and the file is written as if it had always been in that format.
68
+ * @param path - The path to save the config file to, defaulting to the path it was loaded from.
69
+ * @returns A promise that resolves when the config is saved.
70
+ * @throws { Error} When no path is given, or the class declares no format for the extension.
71
+ */
72
+ async save(path = this.path) {
73
+ if (!path)
74
+ throw new Error('No path specified for saving the config.');
75
+ const codec = Settings.require(this.formats, path);
76
+ await File.ensureDir(Path.dirname(path));
77
+ await File.write(path, codec.encode(this.vData, this.document ?? codec.create(this.vData)), 'utf-8');
78
+ }
79
+ /**
80
+ * Loads a config from the given path, creating it with defaults when missing.
81
+ *
82
+ * The file is read as plain text and nothing more: the codec of the extension decides what that
83
+ * text means and hands back both the data and the document the format preserves. A file holding
84
+ * no document at all (missing, blank, or holding nothing but comments) decodes to nothing, and
85
+ * the config is then built from the defaults the schema resolves, seeded into a fresh document.
86
+ * @param this - The concrete Settings subclass constructor.
87
+ * @param path - The path to the config file.
88
+ * @param options - Options for loading the config.
89
+ * @returns A promise that resolves with the loaded config.
90
+ * @throws { Error} When the class declares no format for the extension of the path.
91
+ */
92
+ static async load(path, options = {}) {
93
+ const logger = options.logger;
94
+ const codec = Settings.require(this, path);
95
+ if (logger)
96
+ logger.log(`loading config from &C6[${path}]`);
97
+ const text = await File.exists(path) ? await File.read(path, 'utf-8') : null;
98
+ if (text === null && logger)
99
+ logger.log(`config file &C6[${path}]&R does not exist, creating it`);
100
+ try {
101
+ const source = text === null ? null : codec.decode(text);
102
+ const data = this.parse(source === null ? {} : source.data);
103
+ const config = new this(data, { document: source?.document ?? codec.create(data), path });
104
+ if (text === null) {
105
+ if (options.create)
106
+ await config.save();
107
+ if (logger)
108
+ logger.log(`config file &C6[${path}]&R &C2was created successfully`);
109
+ }
110
+ return config;
111
+ }
112
+ catch (error) {
113
+ if (logger)
114
+ logger.error(`config file &C6[${path}]&R &C1could not be loaded`);
115
+ throw error;
116
+ }
117
+ }
118
+ /**
119
+ * Validates the data of a file against the schema, filling in the defaults of whatever is
120
+ * absent, so that a partial file yields a complete config.
121
+ * @param data - The data read from the file.
122
+ * @returns The data of the config, ready to be stored.
123
+ *
124
+ * @remarks The return type is widened because a static cannot see the type parameters of its
125
+ * class. {@link Settings.Ctor} is where a caller of {@link load} gets it back, as the data of
126
+ * the subclass it asked for.
127
+ */
128
+ static parse(data) { return this.schema.processUnknown(data); }
129
+ /**
130
+ * The codec this class declares for a file extension.
131
+ * @param extension - The lower-cased file extension, including the leading dot.
132
+ * @returns The codec that reads and writes that extension, or `null` when the class declares no
133
+ * format for it.
134
+ *
135
+ * @remarks The types are widened because a static cannot see the type parameters of its class,
136
+ * as in {@link codecs}.
137
+ */
138
+ static codec(extension) {
139
+ return this.codecs.find(candidate => candidate.extensions.includes(extension)) ?? null;
140
+ }
141
+ /**
142
+ * The codec of a path, as declared by the class it is asked for.
143
+ * @param formats - The formats of the class, either its static side or a loaded config.
144
+ * @param path - The path the config is read from or written to.
145
+ * @returns The codec of the extension of the path.
146
+ * @throws { Error } When no format is declared for that extension.
147
+ */
148
+ static require(formats, path) {
149
+ const extension = Settings.extension(path);
150
+ const codec = formats.codec(extension);
151
+ if (!codec)
152
+ throw new Error(`Unsupported config file extension: ${extension}`);
153
+ return codec;
154
+ }
155
+ /**
156
+ * The lower-cased extension of a path, the form formats are selected by.
157
+ * @param path - The path to get the extension of.
158
+ * @returns The lower-cased extension of the path, including the leading dot.
159
+ */
160
+ static extension(path) { return Path.extName(path).toLowerCase(); }
161
+ /**
162
+ * Checks if a value is a non-null object (not an array).
163
+ * @param value - The value to check.
164
+ * @returns `true` if the value is a non-null object, `false` otherwise.
165
+ */
166
+ static isObject(value) {
167
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
168
+ }
169
+ /**
170
+ * Merges two objects deeply, recursively merging their properties.
171
+ * @param target - The object to merge into.
172
+ * @param source - The object to merge from.
173
+ * @returns The merged object.
174
+ */
175
+ static deepMerge(target, source) {
176
+ if (!Settings.isObject(target) || !Settings.isObject(source))
177
+ return source;
178
+ const result = { ...target };
179
+ for (const key of Object.keys(source)) {
180
+ if (source[key] === undefined)
181
+ continue;
182
+ if (Settings.isObject(result[key]) && Settings.isObject(source[key]))
183
+ result[key] = Settings.deepMerge(result[key], source[key]);
184
+ else
185
+ result[key] = source[key];
186
+ }
187
+ return result;
188
+ }
189
+ }
190
+ export default Settings;
191
+ //# sourceMappingURL=Settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Settings.js","sourceRoot":"","sources":["../../src/config/Settings.ts"],"names":[],"mappings":"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"}