@zokugun/artifact 0.5.2 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/bin/artifact +1 -1
  2. package/lib/cli.d.ts +1 -0
  3. package/lib/cli.js +12 -4
  4. package/lib/commands/add.d.ts +6 -0
  5. package/lib/commands/add.js +47 -36
  6. package/lib/commands/index.d.ts +4 -0
  7. package/lib/commands/index.js +9 -7
  8. package/lib/commands/list.d.ts +1 -0
  9. package/lib/commands/list.js +13 -8
  10. package/lib/commands/remove.d.ts +6 -0
  11. package/lib/commands/remove.js +79 -0
  12. package/lib/commands/update.d.ts +5 -0
  13. package/lib/commands/update.js +43 -39
  14. package/lib/compositors/compose.d.ts +7 -0
  15. package/lib/compositors/compose.js +13 -13
  16. package/lib/compositors/fork.d.ts +3 -0
  17. package/lib/compositors/fork.js +4 -4
  18. package/lib/compositors/index.d.ts +6 -0
  19. package/lib/compositors/index.js +12 -12
  20. package/lib/compositors/json.d.ts +2 -0
  21. package/lib/compositors/json.js +14 -12
  22. package/lib/compositors/map-sort.d.ts +2 -0
  23. package/lib/compositors/map-sort.js +2 -2
  24. package/lib/compositors/rc.d.ts +2 -0
  25. package/lib/compositors/rc.js +13 -10
  26. package/lib/compositors/yaml.d.ts +2 -0
  27. package/lib/compositors/yaml.js +8 -11
  28. package/lib/configs/index.d.ts +3 -0
  29. package/lib/configs/index.js +3 -2
  30. package/lib/configs/install/index.d.ts +3 -0
  31. package/lib/configs/install/index.js +6 -6
  32. package/lib/configs/install/read-install-config.d.ts +6 -0
  33. package/lib/configs/install/read-install-config.js +128 -81
  34. package/lib/configs/install/update-install-config.d.ts +2 -0
  35. package/lib/configs/install/write-install-config.d.ts +5 -0
  36. package/lib/configs/install/write-install-config.js +25 -10
  37. package/lib/configs/package/index.d.ts +1 -0
  38. package/lib/configs/package/index.js +2 -2
  39. package/lib/configs/package/read-package-config.d.ts +3 -0
  40. package/lib/configs/package/read-package-config.js +160 -40
  41. package/lib/configs/uninstall/index.d.ts +1 -0
  42. package/lib/configs/uninstall/index.js +5 -0
  43. package/lib/configs/uninstall/update-uninstall-config.d.ts +2 -0
  44. package/lib/configs/uninstall/update-uninstall-config.js +6 -0
  45. package/lib/configs/utils/constants.d.ts +11 -0
  46. package/lib/configs/utils/constants.js +24 -0
  47. package/lib/configs/utils/is-transform.d.ts +2 -0
  48. package/lib/configs/utils/is-transform.js +16 -0
  49. package/lib/configs/utils/merge-upsert-property.d.ts +3 -0
  50. package/lib/configs/utils/merge-upsert-property.js +78 -0
  51. package/lib/configs/utils/normalize-file-always.d.ts +3 -0
  52. package/lib/configs/utils/normalize-file-always.js +29 -0
  53. package/lib/configs/utils/normalize-file-uninstall.d.ts +3 -0
  54. package/lib/configs/utils/normalize-file-uninstall.js +32 -0
  55. package/lib/configs/utils/normalize-file-upsert.d.ts +3 -0
  56. package/lib/configs/utils/normalize-file-upsert.js +55 -0
  57. package/lib/journeys/commitlint/index.d.ts +2 -0
  58. package/lib/journeys/commitlint/index.js +15 -15
  59. package/lib/journeys/config.ts/index.d.ts +2 -0
  60. package/lib/journeys/config.ts/index.js +5 -5
  61. package/lib/journeys/default/index.d.ts +2 -0
  62. package/lib/journeys/default/index.js +11 -14
  63. package/lib/journeys/fixpack/index.d.ts +2 -0
  64. package/lib/journeys/fixpack/index.js +13 -13
  65. package/lib/journeys/gitignore/index.d.ts +2 -0
  66. package/lib/journeys/gitignore/index.js +5 -5
  67. package/lib/journeys/ignore/index.d.ts +2 -0
  68. package/lib/journeys/ignore/index.js +5 -5
  69. package/lib/journeys/index.d.ts +2 -0
  70. package/lib/journeys/index.js +20 -20
  71. package/lib/journeys/npmignore/index.d.ts +2 -0
  72. package/lib/journeys/npmignore/index.js +5 -5
  73. package/lib/journeys/package/index.d.ts +2 -0
  74. package/lib/journeys/package/index.js +27 -30
  75. package/lib/journeys/rc/index.d.ts +2 -0
  76. package/lib/journeys/rc/index.js +12 -12
  77. package/lib/journeys/tsconfig/index.d.ts +2 -0
  78. package/lib/journeys/tsconfig/index.js +13 -16
  79. package/lib/parsers/json.d.ts +2 -0
  80. package/lib/parsers/jsonc/index.d.ts +2 -0
  81. package/lib/parsers/jsonc/index.js +4 -4
  82. package/lib/parsers/jsonc/parse.d.ts +5 -0
  83. package/lib/parsers/jsonc/parse.js +1 -13
  84. package/lib/parsers/jsonc/stringify.d.ts +2 -0
  85. package/lib/parsers/jsonc/stringify.js +2 -2
  86. package/lib/parsers/jsonc/transform.d.ts +10 -0
  87. package/lib/parsers/yaml.d.ts +2 -0
  88. package/lib/routes/command.d.ts +4 -0
  89. package/lib/routes/command.js +10 -10
  90. package/lib/routes/index.d.ts +8 -0
  91. package/lib/routes/index.js +17 -15
  92. package/lib/routes/lines-concat.d.ts +4 -0
  93. package/lib/routes/lines-concat.js +7 -7
  94. package/lib/routes/list-concat.d.ts +4 -0
  95. package/lib/routes/list-concat.js +3 -7
  96. package/lib/routes/list-sort-concat.d.ts +4 -0
  97. package/lib/routes/list-sort-concat.js +1 -1
  98. package/lib/routes/map-concat.d.ts +4 -0
  99. package/lib/routes/map-concat.js +1 -1
  100. package/lib/routes/map-delete.d.ts +4 -0
  101. package/lib/routes/map-delete.js +32 -0
  102. package/lib/routes/overwrite.d.ts +4 -0
  103. package/lib/routes/overwrite.js +2 -2
  104. package/lib/routes/primitive.d.ts +4 -0
  105. package/lib/routes/primitive.js +3 -3
  106. package/lib/steps/apply-formatting.d.ts +8 -0
  107. package/lib/steps/apply-formatting.js +50 -25
  108. package/lib/steps/configure-branches.d.ts +3 -0
  109. package/lib/steps/configure-branches.js +8 -5
  110. package/lib/steps/configure-install-file-actions.d.ts +3 -0
  111. package/lib/steps/configure-install-file-actions.js +59 -94
  112. package/lib/steps/configure-uninstall-file-actions.d.ts +3 -0
  113. package/lib/steps/configure-uninstall-file-actions.js +57 -0
  114. package/lib/steps/configure-update-file-actions.d.ts +3 -0
  115. package/lib/steps/configure-update-file-actions.js +65 -102
  116. package/lib/steps/copy-binary-files.d.ts +3 -0
  117. package/lib/steps/copy-binary-files.js +24 -11
  118. package/lib/steps/execute-first-block.d.ts +3 -0
  119. package/lib/steps/execute-first-block.js +35 -14
  120. package/lib/steps/execute-next-block.d.ts +3 -0
  121. package/lib/steps/execute-next-block.js +8 -3
  122. package/lib/steps/index.d.ts +54 -0
  123. package/lib/steps/index.js +76 -54
  124. package/lib/steps/insert-final-new-line.d.ts +6 -0
  125. package/lib/steps/insert-final-new-line.js +13 -1
  126. package/lib/steps/merge-text-files.d.ts +3 -0
  127. package/lib/steps/merge-text-files.js +47 -28
  128. package/lib/steps/read-editor-config.d.ts +3 -0
  129. package/lib/steps/read-editor-config.js +21 -26
  130. package/lib/steps/read-files.d.ts +3 -0
  131. package/lib/steps/read-files.js +26 -10
  132. package/lib/steps/read-incoming-config.d.ts +3 -0
  133. package/lib/steps/read-incoming-config.js +7 -5
  134. package/lib/steps/read-incoming-package.d.ts +3 -0
  135. package/lib/steps/read-incoming-package.js +12 -7
  136. package/lib/steps/remove-files.d.ts +3 -0
  137. package/lib/steps/remove-files.js +10 -4
  138. package/lib/steps/rename-files.d.ts +3 -0
  139. package/lib/steps/rename-files.js +25 -0
  140. package/lib/steps/replace-templates.d.ts +3 -0
  141. package/lib/steps/replace-templates.js +19 -5
  142. package/lib/steps/transform-untouched-files.d.ts +3 -0
  143. package/lib/steps/transform-untouched-files.js +64 -0
  144. package/lib/steps/unmerge-text-files.d.ts +3 -0
  145. package/lib/steps/unmerge-text-files.js +64 -0
  146. package/lib/steps/validate-newer-package.d.ts +3 -0
  147. package/lib/steps/validate-newer-package.js +4 -2
  148. package/lib/steps/validate-not-present-package.d.ts +3 -0
  149. package/lib/steps/validate-not-present-package.js +7 -4
  150. package/lib/steps/validate-present-package.d.ts +3 -0
  151. package/lib/steps/validate-present-package.js +24 -0
  152. package/lib/steps/write-text-files.d.ts +3 -0
  153. package/lib/steps/write-text-files.js +16 -7
  154. package/lib/types/binary-file.d.ts +4 -0
  155. package/lib/types/command.d.ts +5 -0
  156. package/lib/types/config.d.ts +59 -0
  157. package/lib/types/context.d.ts +62 -0
  158. package/lib/types/context.js +4 -0
  159. package/lib/types/format.d.ts +14 -0
  160. package/lib/types/step.d.ts +3 -0
  161. package/lib/types/travel.d.ts +14 -0
  162. package/lib/utils/apply-transforms.d.ts +2 -0
  163. package/lib/utils/apply-transforms.js +48 -0
  164. package/lib/utils/build-journey-plan.d.ts +2 -0
  165. package/lib/utils/build-route.d.ts +3 -0
  166. package/lib/utils/build-route.js +92 -0
  167. package/lib/utils/build-travel-plan.d.ts +2 -0
  168. package/lib/utils/build-travel.d.ts +3 -0
  169. package/lib/utils/build-travel.js +32 -0
  170. package/lib/utils/command/dedupe-strings.d.ts +1 -0
  171. package/lib/utils/command/index.d.ts +8 -0
  172. package/lib/utils/command/index.js +14 -14
  173. package/lib/utils/command/join-command.d.ts +2 -0
  174. package/lib/utils/command/merge-and-chains.d.ts +1 -0
  175. package/lib/utils/command/merge-and-chains.js +21 -21
  176. package/lib/utils/command/merge-command-records.d.ts +2 -0
  177. package/lib/utils/command/merge-command-records.js +43 -22
  178. package/lib/utils/command/merge-flag-tokens.d.ts +1 -0
  179. package/lib/utils/command/merge-flag-tokens.js +1 -1
  180. package/lib/utils/command/merge-flags-as-string.d.ts +4 -0
  181. package/lib/utils/command/merge-flags-as-string.js +4 -4
  182. package/lib/utils/command/merge-or-segments.d.ts +1 -0
  183. package/lib/utils/command/merge-or-segments.js +28 -28
  184. package/lib/utils/command/merge-parts-by-prefix.d.ts +1 -0
  185. package/lib/utils/command/merge-parts-by-prefix.js +6 -6
  186. package/lib/utils/command/merge-semicolon-segments.d.ts +1 -0
  187. package/lib/utils/command/merge-semicolon-segments.js +35 -35
  188. package/lib/utils/command/merge-with-semicolon-mix.d.ts +1 -0
  189. package/lib/utils/command/merge-with-semicolon-mix.js +12 -12
  190. package/lib/utils/command/prefix-of-command.d.ts +1 -0
  191. package/lib/utils/command/prefix-of-command.js +2 -2
  192. package/lib/utils/command/split-chain.d.ts +1 -0
  193. package/lib/utils/command/split-command.d.ts +2 -0
  194. package/lib/utils/command/split-command.js +8 -8
  195. package/lib/utils/command/split-prefix-and-flags.d.ts +4 -0
  196. package/lib/utils/command/split-prefix-and-flags.js +5 -5
  197. package/lib/utils/command/split-segments.d.ts +1 -0
  198. package/lib/utils/detect-indent.d.ts +2 -0
  199. package/lib/utils/detect-indent.js +63 -0
  200. package/lib/utils/flow.d.ts +3 -0
  201. package/lib/utils/flow.js +12 -0
  202. package/lib/utils/get-format.d.ts +2 -0
  203. package/lib/utils/get-format.js +19 -0
  204. package/lib/utils/has-final-new-line.d.ts +1 -0
  205. package/lib/utils/has-final-new-line.js +7 -0
  206. package/lib/utils/read-buffer.d.ts +2 -0
  207. package/lib/utils/resolve-request.d.ts +3 -0
  208. package/lib/utils/resolve-request.js +4 -3
  209. package/lib/utils/template.d.ts +17 -0
  210. package/lib/utils/template.js +79 -57
  211. package/lib/utils/to-lines.d.ts +1 -0
  212. package/lib/utils/trim-final-newline.d.ts +1 -0
  213. package/lib/utils/try-json.d.ts +1 -0
  214. package/lib/utils/try-json.js +2 -2
  215. package/package.json +74 -51
  216. package/lib/types/text-file.js +0 -2
  217. package/lib/utils/dev-null.js +0 -7
@@ -1,21 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.splitCommand = splitCommand;
4
- const lodash_1 = require("lodash");
4
+ const lodash_es_1 = require("lodash-es");
5
5
  function splitCommand(command) {
6
6
  const result = {};
7
- const splitted = command.split(/([&|]{1,2}|;)/).map(lodash_1.trim);
7
+ const splitted = command.split(/([&|]{1,2}|;)/).map(lodash_es_1.trim);
8
8
  for (let i = 0; i < splitted.length; i++) {
9
9
  const command = splitted[i];
10
- const splittedSubcommand = command.split(/([\w-]+=\S+)\s/).filter(lodash_1.identity);
10
+ const splittedSubcommand = command.split(/([\w-]+=\S+)\s/).filter(lodash_es_1.identity);
11
11
  if (splittedSubcommand.length > 0) {
12
- const subcommandWithArgs = (0, lodash_1.last)(splittedSubcommand).split(' ');
13
- const subcommand = (0, lodash_1.head)(subcommandWithArgs).trim();
12
+ const subcommandWithArgs = (0, lodash_es_1.last)(splittedSubcommand).split(' ');
13
+ const subcommand = (0, lodash_es_1.head)(subcommandWithArgs).trim();
14
14
  const args = subcommandWithArgs.slice(1);
15
- const env = splittedSubcommand.slice(0, -1);
15
+ const environment = splittedSubcommand.slice(0, -1);
16
16
  const parsedSubcommand = {
17
- args: args.map(lodash_1.trim),
18
- env: env.map(lodash_1.trim),
17
+ args: args.map(lodash_es_1.trim),
18
+ env: environment.map(lodash_es_1.trim),
19
19
  separator: splitted[i + 1],
20
20
  };
21
21
  if (result[subcommand]) {
@@ -0,0 +1,4 @@
1
+ export declare function splitPrefixAndFlags(command: string): {
2
+ prefix: string;
3
+ flags: string[];
4
+ };
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.splitPrefixAndFlags = splitPrefixAndFlags;
4
4
  function splitPrefixAndFlags(command) {
5
5
  const tokens = command.split(/\s+/).filter(Boolean);
6
- let idx = tokens.findIndex((t) => t.startsWith('-'));
7
- if (idx === -1) {
8
- idx = tokens.length;
6
+ let index = tokens.findIndex((t) => t.startsWith('-'));
7
+ if (index === -1) {
8
+ index = tokens.length;
9
9
  }
10
- const prefix = tokens.slice(0, idx).join(' ');
11
- const rest = tokens.slice(idx);
10
+ const prefix = tokens.slice(0, index).join(' ');
11
+ const rest = tokens.slice(index);
12
12
  const flags = [];
13
13
  for (let i = 0; i < rest.length; i++) {
14
14
  const t = rest[i];
@@ -0,0 +1 @@
1
+ export declare function splitSegments(s: string): string[];
@@ -0,0 +1,2 @@
1
+ import { type Indent } from '../types/format.js';
2
+ export declare function detectIndent(text: string): Indent | undefined;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectIndent = detectIndent;
4
+ const format_js_1 = require("../types/format.js");
5
+ const INDENT_REGEX = /^(?:(\t+)|( +))/;
6
+ const LINE_SEPARATOR_REGEX = /\r\n|\r|\n/;
7
+ function detectIndent(text) {
8
+ const lines = text.split(LINE_SEPARATOR_REGEX);
9
+ const indentations = new Set();
10
+ let spaces = 0;
11
+ let tabs = 0;
12
+ for (const line of lines) {
13
+ const match = INDENT_REGEX.exec(line);
14
+ if (match) {
15
+ if (match[1]) {
16
+ tabs += 1;
17
+ }
18
+ else {
19
+ indentations.add(match[2].length);
20
+ spaces += 1;
21
+ }
22
+ }
23
+ }
24
+ if (tabs > spaces) {
25
+ return {
26
+ style: format_js_1.IndentStyle.TAB,
27
+ size: 1,
28
+ };
29
+ }
30
+ if (indentations.size === 0) {
31
+ return undefined;
32
+ }
33
+ const sorted = [...indentations].sort((a, b) => a - b);
34
+ const diffs = [];
35
+ for (let i = 1; i < sorted.length; i++) {
36
+ const d = sorted[i] - sorted[i - 1];
37
+ if (d > 0) {
38
+ diffs.push(d);
39
+ }
40
+ }
41
+ let size = sorted[0];
42
+ if (diffs.length > 0) {
43
+ size = diffs.shift();
44
+ for (const value of diffs) {
45
+ size = gcd(size, value);
46
+ }
47
+ }
48
+ if (!size || size === 0) {
49
+ size = sorted[0];
50
+ }
51
+ return {
52
+ style: format_js_1.IndentStyle.SPACE,
53
+ size,
54
+ };
55
+ }
56
+ function gcd(a, b) {
57
+ while (b !== 0) {
58
+ const t = a % b;
59
+ a = b;
60
+ b = t;
61
+ }
62
+ return Math.abs(a);
63
+ } // }}}
@@ -0,0 +1,3 @@
1
+ type AnyFn = (input: any) => unknown | Promise<unknown>;
2
+ export declare function flow<Args = unknown, Result = unknown>(...functions: AnyFn[]): (args: Args) => Promise<Result>;
3
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.flow = flow;
4
+ function flow(...functions) {
5
+ return async (args) => {
6
+ let result = args;
7
+ for (const fn of functions) {
8
+ result = await fn(result);
9
+ }
10
+ return result;
11
+ };
12
+ }
@@ -0,0 +1,2 @@
1
+ import type { Format } from '../types/format.js';
2
+ export declare function getFormat(name: string, formats: Format[]): Format | null;
@@ -0,0 +1,19 @@
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.getFormat = getFormat;
7
+ const fnmatch_1 = __importDefault(require("editorconfig/src/lib/fnmatch"));
8
+ function fnmatch(filepath, glob) {
9
+ const matchOptions = { matchBase: true, dot: true, noext: true };
10
+ return (0, fnmatch_1.default)(filepath, glob, matchOptions);
11
+ } // }}}
12
+ function getFormat(name, formats) {
13
+ for (const format of formats) {
14
+ if (fnmatch(name, format.glob)) {
15
+ return format;
16
+ }
17
+ }
18
+ return null;
19
+ }
@@ -0,0 +1 @@
1
+ export declare function hasFinalNewLine(text: string): boolean;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasFinalNewLine = hasFinalNewLine;
4
+ const FINAL_LINE_REGEX = /\r\n|\r|\n$/;
5
+ function hasFinalNewLine(text) {
6
+ return FINAL_LINE_REGEX.test(text);
7
+ }
@@ -0,0 +1,2 @@
1
+ import { Buffer } from 'buffer';
2
+ export declare function readBuffer(filepath: string, size: number, offset?: number): Promise<Buffer>;
@@ -0,0 +1,3 @@
1
+ import { type DResult } from '@zokugun/xtry';
2
+ import { type Request } from '../types/config.js';
3
+ export declare function resolveRequest(spec: string): DResult<Request>;
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.resolveRequest = resolveRequest;
7
+ const xtry_1 = require("@zokugun/xtry");
7
8
  const untildify_1 = __importDefault(require("untildify"));
8
9
  function resolveRequest(spec) {
9
10
  if (spec.startsWith('~')) {
@@ -32,11 +33,11 @@ function resolveRequest(spec) {
32
33
  if (spec.includes(':')) {
33
34
  const [name, variant] = spec.split(':');
34
35
  if (variant.length === 0) {
35
- throw new Error(`Missing variant in "${spec}"`);
36
+ return (0, xtry_1.err)(`Missing variant in "${spec}"`);
36
37
  }
37
- return { name, variant };
38
+ return (0, xtry_1.ok)({ name, variant });
38
39
  }
39
40
  else {
40
- return { name: spec };
41
+ return (0, xtry_1.ok)({ name: spec });
41
42
  }
42
43
  } // }}}
@@ -0,0 +1,17 @@
1
+ import { type DResult } from '@zokugun/xtry';
2
+ export declare class TemplateEngine {
3
+ private readonly basePath;
4
+ private readonly fileCache;
5
+ private readonly variables;
6
+ private readonly variableCache;
7
+ constructor(basePath: string, variables?: Record<string, string>);
8
+ render(template: string): DResult<string>;
9
+ private getValueByPath;
10
+ private parseFile;
11
+ private readConfigFile;
12
+ private resolveExpression;
13
+ private resolveVariable;
14
+ private splitPlaceholder;
15
+ private toDate;
16
+ }
17
+ export declare function unescapeCode(code: string): string;
@@ -39,92 +39,105 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.TemplateEngine = void 0;
40
40
  exports.unescapeCode = unescapeCode;
41
41
  const path_1 = __importDefault(require("path"));
42
+ const sync_1 = __importDefault(require("@zokugun/fs-extra-plus/sync"));
43
+ const xtry_1 = require("@zokugun/xtry");
42
44
  const dayjs_1 = __importDefault(require("dayjs"));
43
45
  const utc_1 = __importDefault(require("dayjs/plugin/utc"));
44
- const fs_extra_1 = __importDefault(require("fs-extra"));
45
- const lodash_1 = require("lodash");
46
- const YAML = __importStar(require("../parsers/yaml"));
47
- const try_json_1 = require("./try-json");
46
+ const lodash_es_1 = require("lodash-es");
47
+ const YAML = __importStar(require("../parsers/yaml.js"));
48
+ const try_json_js_1 = require("./try-json.js");
48
49
  dayjs_1.default.extend(utc_1.default);
50
+ const EXPRESSION_REGEX = /#\[\[(.*?)]]/g;
49
51
  const NEXT_PROPERTY_REGEX = /^(\w+?)((?=\.|$).*)$/;
50
52
  const PLACEHOLDER_REGEX = /^((?:[^/.]+(?:[^/]+\/)*\/)?\.?[^.]+(?:\.(?:json|ya?ml))?)\.(.*)$/;
51
- class TemplateError extends Error {
52
- constructor(message) {
53
- super(message);
54
- this.name = 'TemplateError';
55
- } // }}}
56
- }
57
53
  class TemplateEngine {
54
+ basePath;
55
+ fileCache = new Map();
56
+ variables;
57
+ variableCache = new Map();
58
58
  constructor(basePath, variables) {
59
- this.fileCache = new Map();
60
- this.variableCache = new Map();
61
59
  this.basePath = basePath;
62
60
  this.variables = variables ?? {};
63
61
  } // }}}
64
62
  render(template) {
65
- const pattern = /#\[\[(.*?)]]/g;
66
- return template.replace(pattern, (_, placeholder) => this.resolveExpression(placeholder));
63
+ let content = '';
64
+ let lastIndex = 0;
65
+ let match;
66
+ while ((match = EXPRESSION_REGEX.exec(template))) {
67
+ const result = this.resolveExpression(match[1]);
68
+ if (result.fails) {
69
+ return result;
70
+ }
71
+ content += template.slice(lastIndex, match.index) + result.value;
72
+ lastIndex = EXPRESSION_REGEX.lastIndex;
73
+ }
74
+ content += template.slice(lastIndex);
75
+ return (0, xtry_1.ok)(content);
67
76
  } // }}}
68
77
  getValueByPath(values, propertyPath) {
69
78
  let currentPath = propertyPath;
70
79
  let currentValue = values;
71
- // eslint-disable-next-line @typescript-eslint/ban-types
72
80
  let match;
73
81
  while ((match = NEXT_PROPERTY_REGEX.exec(currentPath))) {
74
- if (!(0, lodash_1.isPlainObject)(currentValue)) {
75
- throw new TemplateError(`Property path not found: ${propertyPath}`);
82
+ if (!(0, lodash_es_1.isPlainObject)(currentValue)) {
83
+ return (0, xtry_1.err)(`Property path not found: ${propertyPath}`);
76
84
  }
77
85
  currentValue = currentValue[match[1]];
78
- if ((0, lodash_1.isNil)(currentValue)) {
79
- throw new TemplateError(`Property not found: ${propertyPath}`);
86
+ if ((0, lodash_es_1.isNil)(currentValue)) {
87
+ return (0, xtry_1.err)(`Property not found: ${propertyPath}`);
80
88
  }
81
89
  currentPath = match[2];
82
90
  if (currentPath.length === 0) {
83
- return currentValue;
91
+ return (0, xtry_1.ok)(currentValue);
84
92
  }
85
93
  }
86
94
  // eslint-disable-next-line no-new-func
87
95
  const fn = new Function('it', `return it${unescapeCode(currentPath)};`);
88
- return fn(currentValue);
96
+ return (0, xtry_1.ok)(fn(currentValue));
89
97
  } // }}}
90
98
  parseFile(filename) {
91
- let content;
92
- try {
93
- content = fs_extra_1.default.readFileSync(filename, 'utf8');
94
- }
95
- catch {
96
- throw new TemplateError(`File not found: ${filename}`);
99
+ const result = sync_1.default.readFile(filename, 'utf8');
100
+ if (result.fails) {
101
+ return (0, xtry_1.err)(`TemplateError: File not found: ${filename}`);
97
102
  }
98
- const ext = path_1.default.extname(filename).toLowerCase();
103
+ const content = result.value;
104
+ const extension = path_1.default.extname(filename).toLowerCase();
99
105
  try {
100
- if (ext === '.json') {
101
- return JSON.parse(content);
106
+ if (extension === '.json') {
107
+ return (0, xtry_1.ok)(JSON.parse(content));
102
108
  }
103
- else if (ext === '.yaml' || ext === '.yml') {
104
- return YAML.parse(content);
109
+ else if (extension === '.yaml' || extension === '.yml') {
110
+ return (0, xtry_1.ok)(YAML.parse(content));
105
111
  }
106
112
  else {
107
- return (0, try_json_1.tryJson)(content) ?? YAML.parse(content);
113
+ return (0, xtry_1.ok)((0, try_json_js_1.tryJSON)(content) ?? YAML.parse(content));
108
114
  }
109
115
  }
110
116
  catch (parseError) {
111
- throw new TemplateError(`Failed to parse ${filename}: ${parseError.message}`);
117
+ return (0, xtry_1.err)(`Failed to parse ${filename}: ${parseError.message}`);
112
118
  }
113
119
  } // }}}
114
120
  readConfigFile(filename) {
115
121
  // Check cache first
116
122
  if (this.fileCache.has(filename)) {
117
- return this.fileCache.get(filename);
123
+ return (0, xtry_1.ok)(this.fileCache.get(filename));
118
124
  }
119
125
  const filePath = path_1.default.resolve(this.basePath, filename);
120
- const content = this.parseFile(filePath);
121
- this.fileCache.set(filename, content);
122
- return content;
126
+ const result = this.parseFile(filePath);
127
+ if (result.fails) {
128
+ return result;
129
+ }
130
+ this.fileCache.set(filename, result.value);
131
+ return result;
123
132
  } // }}}
124
133
  resolveExpression(expression) {
125
- const [name, propertyPath] = this.splitPlaceholder(expression);
134
+ const result = this.splitPlaceholder(expression);
135
+ if (result.fails) {
136
+ return result;
137
+ }
138
+ const { name, propertyPath } = result.value;
126
139
  if (!name || !propertyPath) {
127
- throw new TemplateError(`Invalid expression format: ${expression}. Expected format: #[[filename.property]]`);
140
+ return (0, xtry_1.err)(`Invalid expression format: ${expression}. Expected format: #[[filename.property]]`);
128
141
  }
129
142
  if (name === 'date') {
130
143
  return this.toDate(propertyPath);
@@ -133,48 +146,57 @@ class TemplateEngine {
133
146
  return this.resolveVariable(propertyPath);
134
147
  }
135
148
  else {
136
- const fileContent = this.readConfigFile(name);
137
- const value = this.getValueByPath(fileContent, propertyPath);
138
- if ((0, lodash_1.isNil)(value)) {
139
- throw new TemplateError(expression);
149
+ const readResult = this.readConfigFile(name);
150
+ if (readResult.fails) {
151
+ return readResult;
152
+ }
153
+ const getValueResult = this.getValueByPath(readResult.value, propertyPath);
154
+ if (getValueResult.fails) {
155
+ return getValueResult;
140
156
  }
141
- return String(value);
157
+ if ((0, lodash_es_1.isNil)(getValueResult.value)) {
158
+ return (0, xtry_1.err)(expression);
159
+ }
160
+ return (0, xtry_1.ok)(String(getValueResult.value));
142
161
  }
143
162
  } // }}}
144
163
  resolveVariable(name) {
145
164
  if (this.variableCache.has(name)) {
146
- return this.variableCache.get(name);
165
+ return (0, xtry_1.ok)(this.variableCache.get(name));
147
166
  }
148
167
  const expression = this.variables[name];
149
168
  if (typeof expression !== 'string' || expression.trim().length === 0) {
150
- throw new TemplateError(`Invalid variable: ${name}.`);
169
+ return (0, xtry_1.err)(`Invalid variable: ${name}.`);
170
+ }
171
+ const result = this.resolveExpression(expression);
172
+ if (result.fails) {
173
+ return result;
151
174
  }
152
- const content = this.resolveExpression(expression);
153
- this.variableCache.set(name, content);
154
- return content;
175
+ this.variableCache.set(name, result.value);
176
+ return result;
155
177
  } // }}}
156
178
  splitPlaceholder(placeholder) {
157
179
  const matches = PLACEHOLDER_REGEX.exec(placeholder);
158
180
  if (!matches) {
159
- throw new TemplateError(`Invalid expression format: ${placeholder}. Expected format: #[[filename.property]]`);
181
+ return (0, xtry_1.err)(`Invalid expression format: ${placeholder}. Expected format: #[[filename.property]]`);
160
182
  }
161
- const [, filename, propertyPath] = matches;
162
- return [filename, propertyPath];
183
+ const [, name, propertyPath] = matches;
184
+ return (0, xtry_1.ok)({ name, propertyPath });
163
185
  } // }}}
164
186
  toDate(format) {
165
187
  try {
166
188
  const now = (0, dayjs_1.default)().utc();
167
189
  if (format === 'utc') {
168
- return now.format('YYYY-MM-DD HH:mm:ss');
190
+ return (0, xtry_1.ok)(now.format('YYYY-MM-DD HH:mm:ss'));
169
191
  }
170
- return now.format(format);
192
+ return (0, xtry_1.ok)(now.format(format));
171
193
  }
172
194
  catch {
173
- throw new TemplateError(`Invalid date format: ${format}`);
195
+ return (0, xtry_1.err)(`Invalid date format: ${format}`);
174
196
  }
175
197
  } // }}}
176
198
  }
177
199
  exports.TemplateEngine = TemplateEngine;
178
200
  function unescapeCode(code) {
179
- return code.replace(/\\('|\\)/g, '$1').replace(/[\r\t\n]/g, ' ');
201
+ return code.replaceAll(/\\('|\\)/g, '$1').replaceAll(/[\r\t\n]/g, ' ');
180
202
  }
@@ -0,0 +1 @@
1
+ export declare function toLines(value: string): string[];
@@ -0,0 +1 @@
1
+ export declare function trimFinalNewLine(value: string): string;
@@ -0,0 +1 @@
1
+ export declare function tryJSON(value: string): Record<string, unknown> | undefined;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.tryJson = tryJson;
4
- function tryJson(value) {
3
+ exports.tryJSON = tryJSON;
4
+ function tryJSON(value) {
5
5
  try {
6
6
  return JSON.parse(value);
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zokugun/artifact",
3
3
  "description": "Boilerplate your project & keep your configurations up to date",
4
- "version": "0.5.2",
4
+ "version": "0.6.1",
5
5
  "author": {
6
6
  "name": "Baptiste Augrain",
7
7
  "email": "daiyam@zokugun.org"
@@ -13,76 +13,99 @@
13
13
  "url": "https://github.com/zokugun/artifact.git"
14
14
  },
15
15
  "bugs": {
16
- "url": "https://github.com/zokugun/artifact/issues"
16
+ "url": "https://github.com/zokugun/artifact/discussions/categories/issue-triage"
17
+ },
18
+ "engines": {
19
+ "node": ">=18.20"
17
20
  },
18
21
  "bin": {
19
22
  "artifact": "bin/artifact",
20
23
  "atf": "bin/artifact"
21
24
  },
22
25
  "scripts": {
23
- "compile": "tsc -p src",
26
+ "audit:fix": "npm audit fix --min-release-age=0",
27
+ "build": "npm run clean && npm run compile:src",
28
+ "ci:lint": "zizmor .",
29
+ "ci:lint:fix": "zizmor . --fix=all",
30
+ "clean": "rimraf .test lib",
31
+ "compile:src": "tsc -p src",
24
32
  "lint": "xo",
25
- "prepare": "husky install;",
26
- "prepublishOnly": "npm run compile",
33
+ "lint:all": "fixpack && npm run ci:lint && npm run lint",
34
+ "lint:fix": "xo --fix",
35
+ "prepack": "npm run build",
36
+ "prepare": "husky; fixpack || true",
27
37
  "release": "release-it",
28
38
  "test": "tsc -p test && mocha",
29
39
  "test:dev": "mocha",
30
40
  "test:watch": "tsc-watch -p src -p test --onSuccess 'mocha -g=\"\"'",
41
+ "update:artifacts": "artifact update",
42
+ "update:ci": "PINACT_MIN_AGE=7 pinact run",
43
+ "update:deps": "taze",
44
+ "watch:build": "tsc-watch -p src --onSuccess 'npm run build'",
31
45
  "watch:src": "tsc-watch -p src",
32
46
  "watch:test": "tsc-watch -p test"
33
47
  },
34
48
  "dependencies": {
35
- "@zokugun/cli-utils": "^0.2.0",
36
- "@zokugun/configdotts-merge": "^0.2.0",
37
- "ansi-colors": "^4.1.1",
38
- "dayjs": "^1.11.13",
39
- "detect-indent": "^6.1.0",
40
- "editorconfig": "^0.15.3",
41
- "fs-extra": "^10.0.0",
42
- "globby": "^11.0.4",
43
- "istextorbinary": "^6.0.0",
44
- "jsonc-parser": "^3.0.0",
45
- "lodash": "^4.18.1",
46
- "micromatch": "^4.0.8",
47
- "npm": "^7.23.0",
48
- "ora": "^5.4.1",
49
- "pacote": "^13.0.5",
50
- "semver": "^7.7.4",
51
- "tempy": "^1.0.1",
52
- "typescript": "^5.9.2",
53
- "untildify": "^4.0.0",
49
+ "@zokugun/cli-utils": "0.3.1",
50
+ "@zokugun/configdotts-merge": "0.2.1",
51
+ "@zokugun/fs-extra-plus": "0.3.7",
52
+ "@zokugun/is-it-type": "0.8.1",
53
+ "@zokugun/xtry": "0.11.4",
54
+ "dayjs": "1.11.20",
55
+ "editorconfig": "0.15.3",
56
+ "globby": "11.1.0",
57
+ "istextorbinary": "6.0.0",
58
+ "jq-wasm": "1.1.0-jq-1.8.1",
59
+ "jsonc-parser": "3.3.1",
60
+ "lodash-es": "4.18.1",
61
+ "micromatch": "4.0.8",
62
+ "pacote": "21.5.0",
63
+ "semver": "7.7.4",
64
+ "tempy": "1.0.1",
65
+ "untildify": "4.0.0",
54
66
  "yaml": "2.8.3"
55
67
  },
56
68
  "devDependencies": {
57
- "@commitlint/cli": "^16.2.3",
58
- "@commitlint/config-conventional": "^16.2.1",
59
- "@types/chai": "^4.2.17",
60
- "@types/chai-as-promised": "^7.1.4",
61
- "@types/fs-extra": "^9.0.12",
62
- "@types/lodash": "^4.14.172",
63
- "@types/micromatch": "^4.0.2",
64
- "@types/mocha": "^9.0.0",
69
+ "@commitlint/cli": "19.8.1",
70
+ "@commitlint/config-conventional": "19.8.1",
71
+ "@types/chai": "4.3.20",
72
+ "@types/chai-as-promised": "7.1.8",
73
+ "@types/lodash-es": "4.17.12",
74
+ "@types/micromatch": "4.0.10",
75
+ "@types/mocha": "9.1.1",
65
76
  "@types/node": "20.19.39",
66
- "@types/npm": "^7.19.0",
67
- "@types/pacote": "^11.1.1",
68
- "@types/semver": "^7.3.8",
69
- "@types/universalify": "^1.0.0",
70
- "camelcase": "^6.2.0",
71
- "chai": "^4.3.4",
72
- "chai-as-promised": "^7.1.1",
77
+ "@types/npm": "7.19.3",
78
+ "@types/pacote": "11.1.8",
79
+ "@types/semver": "7.7.1",
80
+ "@types/universalify": "1.0.3",
81
+ "camelcase": "6.3.0",
82
+ "chai": "4.5.0",
83
+ "chai-as-promised": "7.1.2",
73
84
  "eslint": "8.11.0",
74
- "eslint-plugin-chai-friendly": "^0.7.2",
75
- "fixpack": "^4.0.0",
76
- "husky": "^7.0.1",
77
- "lint-staged": "^12.3.6",
78
- "memfs": "^3.2.4",
79
- "mocha": "^9.1.1",
80
- "release-it": "^14.11.3",
81
- "rewiremock": "^3.14.3",
82
- "source-map-support": "^0.5.20",
83
- "tsc-watch": "^4.5.0",
84
- "universalify": "^2.0.0",
85
- "xo": "^0.48.0"
85
+ "eslint-plugin-chai-friendly": "0.7.4",
86
+ "fixpack": "4.0.0",
87
+ "husky": "9.1.7",
88
+ "lint-staged": "16.4.0",
89
+ "memfs": "3.6.0",
90
+ "mocha": "9.2.2",
91
+ "release-it": "20.0.0",
92
+ "rewiremock": "3.14.6",
93
+ "source-map-support": "0.5.21",
94
+ "taze": "19.11.0",
95
+ "tsc-watch": "7.2.0",
96
+ "typescript": "5.9.3",
97
+ "universalify": "2.0.1",
98
+ "xo": "0.60.0"
99
+ },
100
+ "overrides": {
101
+ "mocha": {
102
+ "diff": "5.2.2",
103
+ "glob": "8.1.0",
104
+ "js-yaml": "4.1.1",
105
+ "minimatch": "4.2.6",
106
+ "nanoid": "3.3.11",
107
+ "serialize-javascript": "7.0.5"
108
+ }
86
109
  },
87
110
  "keywords": [
88
111
  "artifact",
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createDevNull = createDevNull;
4
- const fs_1 = require("fs");
5
- function createDevNull() {
6
- return (0, fs_1.createWriteStream)('/dev/null');
7
- }