@zokugun/artifact 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/lib/commands/add.js +67 -37
  2. package/lib/commands/list.js +2 -2
  3. package/lib/commands/outdated.js +2 -2
  4. package/lib/commands/remove.js +12 -18
  5. package/lib/commands/update.js +36 -21
  6. package/lib/compositors/codec.d.ts +3 -0
  7. package/lib/compositors/codec.js +46 -0
  8. package/lib/compositors/compose.d.ts +1 -0
  9. package/lib/compositors/compose.js +4 -0
  10. package/lib/compositors/index.d.ts +1 -0
  11. package/lib/compositors/index.js +3 -1
  12. package/lib/compositors/json.js +3 -66
  13. package/lib/compositors/rc.js +3 -56
  14. package/lib/compositors/yaml.js +24 -3
  15. package/lib/configs/install/read-install-config.d.ts +2 -5
  16. package/lib/configs/install/read-install-config.js +20 -18
  17. package/lib/configs/install/write-install-config.d.ts +2 -2
  18. package/lib/configs/install/write-install-config.js +2 -1
  19. package/lib/configs/package/read-package-config.d.ts +2 -1
  20. package/lib/configs/package/read-package-config.js +96 -10
  21. package/lib/configs/utils/constants.d.ts +2 -2
  22. package/lib/configs/utils/constants.js +2 -2
  23. package/lib/configs/utils/merge-upsert-property.js +0 -8
  24. package/lib/configs/utils/normalize-file-always.js +5 -0
  25. package/lib/configs/utils/normalize-file-upsert.d.ts +2 -1
  26. package/lib/configs/utils/normalize-file-upsert.js +12 -5
  27. package/lib/journeys/commitlint/index.d.ts +1 -1
  28. package/lib/journeys/config.ts/index.d.ts +1 -1
  29. package/lib/journeys/config.ts/index.js +2 -6
  30. package/lib/journeys/default/index.d.ts +1 -1
  31. package/lib/journeys/gitignore/index.d.ts +1 -1
  32. package/lib/journeys/ignore/index.d.ts +1 -1
  33. package/lib/journeys/index.d.ts +2 -2
  34. package/lib/journeys/index.js +9 -11
  35. package/lib/journeys/npmignore/index.d.ts +1 -1
  36. package/lib/journeys/package/index.d.ts +1 -1
  37. package/lib/journeys/rc/index.d.ts +1 -1
  38. package/lib/journeys/tsconfig/index.d.ts +1 -1
  39. package/lib/parsers/index.d.ts +4 -0
  40. package/lib/parsers/index.js +41 -0
  41. package/lib/parsers/json.d.ts +4 -2
  42. package/lib/parsers/json.js +7 -2
  43. package/lib/parsers/jsonc/parse.d.ts +2 -5
  44. package/lib/parsers/jsonc/parse.js +8 -6
  45. package/lib/parsers/to-format.d.ts +2 -0
  46. package/lib/parsers/to-format.js +50 -0
  47. package/lib/parsers/yaml.d.ts +4 -2
  48. package/lib/parsers/yaml.js +7 -2
  49. package/lib/routes/command.js +7 -0
  50. package/lib/routes/index.d.ts +4 -3
  51. package/lib/routes/index.js +9 -7
  52. package/lib/routes/{list-sort-concat.d.ts → list-concat-after.d.ts} +1 -1
  53. package/lib/routes/{list-sort-concat.js → list-concat-after.js} +2 -2
  54. package/lib/routes/merge-dot-js.d.ts +2 -0
  55. package/lib/routes/merge-dot-js.js +8 -0
  56. package/lib/steps/configure-install-file-actions.js +1 -20
  57. package/lib/steps/configure-update-file-actions.js +1 -20
  58. package/lib/steps/execute-first-block.js +1 -1
  59. package/lib/steps/index.d.ts +0 -2
  60. package/lib/steps/index.js +4 -3
  61. package/lib/steps/merge-text-files.d.ts +1 -1
  62. package/lib/steps/merge-text-files.js +6 -2
  63. package/lib/steps/read-files.d.ts +1 -1
  64. package/lib/steps/read-files.js +56 -42
  65. package/lib/steps/read-incoming-config.js +1 -1
  66. package/lib/steps/remove-files.d.ts +1 -1
  67. package/lib/steps/remove-files.js +3 -2
  68. package/lib/steps/rename-files.d.ts +1 -1
  69. package/lib/steps/rename-files.js +3 -2
  70. package/lib/steps/validate-newer-package.d.ts +1 -1
  71. package/lib/steps/validate-newer-package.js +13 -2
  72. package/lib/types/config.d.ts +11 -7
  73. package/lib/types/context.d.ts +23 -3
  74. package/lib/types/context.js +6 -0
  75. package/lib/types/travel.d.ts +1 -0
  76. package/lib/utils/build-journey-plan.d.ts +2 -2
  77. package/lib/utils/build-route.d.ts +1 -1
  78. package/lib/utils/build-route.js +50 -19
  79. package/lib/utils/build-travel-plan.js +1 -0
  80. package/lib/utils/command/merge-and-chains.js +1 -1
  81. package/lib/utils/command/merge-command-records.js +1 -1
  82. package/lib/utils/command/merge-parts-by-prefix.js +12 -1
  83. package/lib/utils/command/merge-semicolon-segments.js +161 -4
  84. package/lib/utils/fnmatch.d.ts +1 -0
  85. package/lib/utils/fnmatch.js +11 -0
  86. package/lib/utils/get-format.js +2 -9
  87. package/lib/utils/load-package.d.ts +6 -0
  88. package/lib/utils/load-package.js +26 -0
  89. package/lib/utils/template.js +1 -3
  90. package/package.json +128 -127
  91. package/lib/journeys/fixpack/index.d.ts +0 -2
  92. package/lib/journeys/fixpack/index.js +0 -16
  93. package/lib/steps/validate-not-present-package.d.ts +0 -3
  94. package/lib/steps/validate-not-present-package.js +0 -24
  95. package/lib/utils/try-json.d.ts +0 -1
  96. package/lib/utils/try-json.js +0 -11
@@ -1,9 +1,10 @@
1
1
  import { type Primitive } from '@zokugun/is-it-type';
2
- import { type AsyncDResult } from '@zokugun/xtry';
2
+ import { type DResult, type AsyncDResult } from '@zokugun/xtry';
3
+ import { type Transform } from '../parsers/jsonc/transform.js';
3
4
  import { type BinaryFile } from './binary-file.js';
4
5
  import { type Request, type InstallConfig, type PackageConfig, type ArtifactResult, type PackageManifest, type FileTransform } from './config.js';
5
6
  import { type Indent, type Format } from './format.js';
6
- import { type Journey } from './travel.js';
7
+ import { type JourneyPlan, type Route, type Journey } from './travel.js';
7
8
  export type ExistingAction = 'merge' | 'overwrite' | 'skip';
8
9
  export type MissingAction = 'continue' | 'skip';
9
10
  export type RenameAction = {
@@ -17,6 +18,7 @@ export type Context = {
17
18
  config: InstallConfig;
18
19
  filters: (file: string) => string[] | undefined;
19
20
  formats: Format[];
21
+ global: Global;
20
22
  incomingName?: string;
21
23
  incomingVersion?: string;
22
24
  incomingVariant?: string;
@@ -25,6 +27,7 @@ export type Context = {
25
27
  incomingPackage?: PackageManifest;
26
28
  incomingPath: string;
27
29
  mergedTextFiles: TextFile[];
30
+ mode: Mode;
28
31
  onExisting: (file: string) => ExistingAction;
29
32
  onMissing: (file: string) => MissingAction;
30
33
  options: Options;
@@ -39,7 +42,16 @@ export type Context = {
39
42
  transformedFiles: TextFile[];
40
43
  transforms: (file: string) => FileTransform[] | undefined;
41
44
  };
42
- export type MainFlow = (targetPath: string, incomingPath: string, request: Request, config: InstallConfig, options: Options) => AsyncDResult<Context | undefined>;
45
+ export declare enum Mode {
46
+ Default = 0,
47
+ Overwritten = 1
48
+ }
49
+ export type Global = {
50
+ journeys: Record<string, JourneyPlan>;
51
+ overwrittenTextFiles: string[];
52
+ routes: Record<string, Route<any>>;
53
+ };
54
+ export type MainFlow = (targetPath: string, incomingPath: string, request: Request, config: InstallConfig, global: Global, options: Options) => AsyncDResult<Context | undefined>;
43
55
  export type CommonFlow = (name: string, version: string, variant: string | undefined, branch: string | undefined, incomingPath: string, commonContext: Context) => AsyncDResult<Context | undefined>;
44
56
  export type Options = {
45
57
  force: boolean;
@@ -62,3 +74,11 @@ export type TextFile = {
62
74
  mode?: number;
63
75
  name: string;
64
76
  };
77
+ export type ParseResult = DResult<{
78
+ data: Record<string, unknown>;
79
+ transform?: Transform;
80
+ }>;
81
+ export type Codec = {
82
+ parse: (data: string) => ParseResult;
83
+ stringify: (data: Record<string, unknown>, transform?: Transform) => string;
84
+ };
@@ -1,2 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Mode = void 0;
4
+ var Mode;
5
+ (function (Mode) {
6
+ Mode[Mode["Default"] = 0] = "Default";
7
+ Mode[Mode["Overwritten"] = 1] = "Overwritten";
8
+ })(Mode || (exports.Mode = Mode = {}));
@@ -12,3 +12,4 @@ export type Journey = {
12
12
  alias?: string;
13
13
  travel: Route<string>;
14
14
  };
15
+ export type JourneyPlan = (basename: string) => Journey | undefined;
@@ -1,2 +1,2 @@
1
- import { type Journey, type TravelPlan } from '../types/travel.js';
2
- export declare function buildJourneyPlan(plan: TravelPlan, alias?: string): (basename: string) => Journey | undefined;
1
+ import { type JourneyPlan, type TravelPlan } from '../types/travel.js';
2
+ export declare function buildJourneyPlan(plan: TravelPlan, alias?: string): JourneyPlan;
@@ -1,3 +1,3 @@
1
1
  import { type DResult } from '@zokugun/xtry';
2
2
  import { type Route } from '../types/travel.js';
3
- export declare function buildRoute(route: any): DResult<Route<any>>;
3
+ export declare function buildRoute(route: unknown): DResult<Route<any>>;
@@ -18,43 +18,54 @@ function buildRoute(route) {
18
18
  result = (0, index_js_1.mapSort)(result);
19
19
  }
20
20
  else {
21
- return (0, xtry_1.err)('Can\'t build route');
21
+ return (0, xtry_1.err)(`Cannot build route "${JSON.stringify(route)}"`);
22
22
  }
23
23
  }
24
24
  return (0, xtry_1.ok)(result);
25
25
  }
26
26
  else if ((0, is_it_type_1.isRecord)(route)) {
27
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
28
- const { compose: rtCompose, fork: rtFork, mapSort: rtMapSort } = route;
29
- if (rtCompose) {
27
+ if ((0, is_it_type_1.isRecord)(route.compose)) {
30
28
  const map = {};
31
- for (const [name, route] of Object.entries(rtCompose)) {
32
- const result = buildRoute(route);
33
- if (result.fails) {
34
- return result;
29
+ const entries = Object.entries(route.compose);
30
+ for (const [name, route] of entries) {
31
+ if (name === '$$ignore' || name === '$$remove') {
32
+ map[name] = route;
33
+ }
34
+ else {
35
+ const result = buildRoute(route);
36
+ if (result.fails) {
37
+ return result;
38
+ }
39
+ map[name] = result.value;
35
40
  }
36
- map[name] = result.value;
37
41
  }
38
42
  return (0, xtry_1.ok)((0, index_js_1.compose)(map));
39
43
  }
40
- else if (rtFork) {
44
+ else if ((0, is_it_type_1.isRecord)(route.fork)) {
41
45
  const map = [];
42
- if (rtFork.array) {
43
- const result = buildRoute(rtFork.array);
46
+ if (route.fork.array) {
47
+ const result = buildRoute(route.fork.array);
44
48
  if (result.fails) {
45
49
  return result;
46
50
  }
47
51
  map.push([Array.isArray, result.value]);
48
52
  }
49
- if (rtFork.object) {
50
- const result = buildRoute(rtFork.object);
53
+ if (route.fork.object) {
54
+ const result = buildRoute(route.fork.object);
51
55
  if (result.fails) {
52
56
  return result;
53
57
  }
54
58
  map.push([is_it_type_1.isRecord, result.value]);
55
59
  }
56
- if (rtFork.default) {
57
- const result = buildRoute(rtFork.default);
60
+ if (route.fork.default) {
61
+ const result = buildRoute(route.fork.default);
62
+ if (result.fails) {
63
+ return result;
64
+ }
65
+ map.push(result.value);
66
+ }
67
+ else if (route.fork.$$default) {
68
+ const result = buildRoute(route.fork.$$default);
58
69
  if (result.fails) {
59
70
  return result;
60
71
  }
@@ -62,13 +73,27 @@ function buildRoute(route) {
62
73
  }
63
74
  return (0, xtry_1.ok)((0, fork_js_1.fork)(...map));
64
75
  }
65
- else if (rtMapSort) {
66
- const result = buildRoute(rtMapSort);
76
+ else if (route.json) {
77
+ const result = buildRoute(route.json);
78
+ if (result.fails) {
79
+ return result;
80
+ }
81
+ return (0, xtry_1.ok)((0, index_js_1.json)(result.value));
82
+ }
83
+ else if (route.mapSort) {
84
+ const result = buildRoute(route.mapSort);
67
85
  if (result.fails) {
68
86
  return result;
69
87
  }
70
88
  return (0, xtry_1.ok)((0, index_js_1.mapSort)(result.value));
71
89
  }
90
+ else if (route.yaml) {
91
+ const result = buildRoute(route.yaml);
92
+ if (result.fails) {
93
+ return result;
94
+ }
95
+ return (0, xtry_1.ok)((0, index_js_1.yaml)(result.value));
96
+ }
72
97
  }
73
98
  else if (route === 'command') {
74
99
  return (0, xtry_1.ok)(index_js_2.command);
@@ -79,14 +104,20 @@ function buildRoute(route) {
79
104
  else if (route === 'listConcat') {
80
105
  return (0, xtry_1.ok)(index_js_2.listConcat);
81
106
  }
107
+ else if (route === 'listConcatAfter') {
108
+ return (0, xtry_1.ok)(index_js_2.listConcatAfter);
109
+ }
82
110
  else if (route === 'mapConcat') {
83
111
  return (0, xtry_1.ok)(index_js_2.mapConcat);
84
112
  }
113
+ else if (route === 'mergeDotJs') {
114
+ return (0, xtry_1.ok)(index_js_2.mergeDotJs);
115
+ }
85
116
  else if (route === 'overwrite') {
86
117
  return (0, xtry_1.ok)(index_js_2.overwrite);
87
118
  }
88
119
  else if (route === 'primitive') {
89
120
  return (0, xtry_1.ok)(index_js_2.primitive);
90
121
  }
91
- return (0, xtry_1.err)('Can\'t build route');
122
+ return (0, xtry_1.err)(`Cannot build route "${JSON.stringify(route)}"`);
92
123
  } // }}}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildTravelPlan = buildTravelPlan;
4
+ // import { fnmatch } from './fnmatch.js';
4
5
  function buildTravelPlan(...mappers) {
5
6
  return (basename) => {
6
7
  const mapper = mappers.find((mapper) => {
@@ -23,7 +23,7 @@ function mergeAndChains(current, incoming) {
23
23
  if (!positionalMatch) {
24
24
  // Merge by matching prefixes across current segments, append unmatched incoming segments.
25
25
  const merged = (0, merge_parts_by_prefix_js_1.mergePartsByPrefix)(currentAnd, incomingAnd);
26
- return merged.join('; ');
26
+ return merged.join(' && ');
27
27
  }
28
28
  // Positional merge: iterate positions, merge flags when prefixes equal, otherwise
29
29
  // decide ordering: if incoming's semicolon tail contains current segment, prefer incoming in chain and move current to tail;
@@ -25,7 +25,7 @@ async function mergeCommandRecords(currentCommand, incomingCommand, currentStrin
25
25
  };
26
26
  const currentPrefix = getPrefix(currentInstance.args);
27
27
  const incomingPrefix = getPrefix(instance.args);
28
- const shouldMerge = currentPrefix && incomingPrefix && currentPrefix === incomingPrefix && (hasFlags(currentInstance.args) || hasFlags(instance.args) || (currentInstance.env.length > 0) || (instance.env.length > 0));
28
+ const shouldMerge = (currentPrefix === incomingPrefix) && (hasFlags(currentInstance.args) || hasFlags(instance.args) || (currentInstance.env.length > 0) || (instance.env.length > 0));
29
29
  if (shouldMerge) {
30
30
  // replace with merged instance
31
31
  result[name][index] = {
@@ -5,6 +5,8 @@ const merge_flag_tokens_js_1 = require("./merge-flag-tokens.js");
5
5
  const split_prefix_and_flags_js_1 = require("./split-prefix-and-flags.js");
6
6
  function mergePartsByPrefix(currentParts, incomingParts) {
7
7
  const result = [...currentParts];
8
+ // Track the index of the last position where we merged or inserted an incoming part
9
+ let lastIndex = null;
8
10
  for (const incomingPart of incomingParts) {
9
11
  const incomingPrefix = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(incomingPart);
10
12
  let merged = false;
@@ -14,11 +16,20 @@ function mergePartsByPrefix(currentParts, incomingParts) {
14
16
  const mergedFlags = (0, merge_flag_tokens_js_1.mergeFlagTokens)(currentPrefix.flags, incomingPrefix.flags);
15
17
  result[k] = currentPrefix.prefix + (mergedFlags.length > 0 ? ' ' + mergedFlags.join(' ') : '');
16
18
  merged = true;
19
+ lastIndex = k;
17
20
  break;
18
21
  }
19
22
  }
20
23
  if (!merged) {
21
- result.push(incomingPart);
24
+ // If we previously merged or inserted, place the new incoming part immediately after that position
25
+ if (lastIndex === null) {
26
+ result.push(incomingPart);
27
+ lastIndex = result.length - 1;
28
+ }
29
+ else {
30
+ result.splice(lastIndex + 1, 0, incomingPart);
31
+ lastIndex += 1;
32
+ }
22
33
  }
23
34
  }
24
35
  return result;
@@ -11,7 +11,13 @@ const split_segments_js_1 = require("./split-segments.js");
11
11
  function mergeSemicolonSegments(current, incoming) {
12
12
  let currentSegments = (0, split_segments_js_1.splitSegments)(current);
13
13
  const incomingSegments = (0, split_segments_js_1.splitSegments)(incoming);
14
- for (const incomingSegment of incomingSegments) {
14
+ // Pre-scan incoming segments to find which ones match existing current segments by prefix
15
+ const initialMatchedIndices = incomingSegments.map((seg) => {
16
+ const p = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(seg).prefix;
17
+ return currentSegments.findIndex((cs) => (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(cs).prefix === p);
18
+ });
19
+ for (let incomingIndex = 0; incomingIndex < incomingSegments.length; incomingIndex++) {
20
+ const incomingSegment = incomingSegments[incomingIndex];
15
21
  // If the incoming segment is itself a chain (&& or ||), merge subparts accordingly
16
22
  if (incomingSegment.includes('||')) {
17
23
  const incomingParts = incomingSegment.split('||').map((s) => s.trim()).filter(Boolean);
@@ -38,7 +44,58 @@ function mergeSemicolonSegments(current, incoming) {
38
44
  }
39
45
  }
40
46
  if (!mergedIntoCurrent) {
41
- currentSegments.push(incomingSegment);
47
+ // Determine insertion position based on matched incoming segments context
48
+ let previousMatch = -1;
49
+ for (let j = incomingIndex - 1; j >= 0; j--) {
50
+ const mi = initialMatchedIndices[j];
51
+ if (mi >= 0) {
52
+ const pref = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(incomingSegments[j]).prefix;
53
+ const pos = currentSegments.findIndex((cs) => (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(cs).prefix === pref);
54
+ if (pos !== -1) {
55
+ previousMatch = pos;
56
+ break;
57
+ }
58
+ }
59
+ }
60
+ let nextMatch = -1;
61
+ for (let j = incomingIndex + 1; j < incomingSegments.length; j++) {
62
+ const mi = initialMatchedIndices[j];
63
+ if (mi >= 0) {
64
+ const pref = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(incomingSegments[j]).prefix;
65
+ const pos = currentSegments.findIndex((cs) => (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(cs).prefix === pref);
66
+ if (pos !== -1) {
67
+ nextMatch = pos;
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ const incomingBase = ((0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(incomingSegment).prefix || incomingSegment).split(' ')[0];
73
+ let basePos = null;
74
+ for (let k = currentSegments.length - 1; k >= 0; k--) {
75
+ const cp = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(currentSegments[k]).prefix || currentSegments[k];
76
+ const cpBase = cp.split(' ')[0];
77
+ if (cpBase === incomingBase) {
78
+ basePos = k;
79
+ break;
80
+ }
81
+ }
82
+ let insertPos;
83
+ if ((previousMatch >= 0) && (nextMatch >= 0)) {
84
+ insertPos = previousMatch + 1;
85
+ }
86
+ else if ((basePos !== null) && (nextMatch < 0)) {
87
+ insertPos = basePos + 1;
88
+ }
89
+ else if (previousMatch >= 0) {
90
+ insertPos = previousMatch + 1;
91
+ }
92
+ else if (nextMatch >= 0) {
93
+ insertPos = nextMatch + 1;
94
+ }
95
+ else {
96
+ insertPos = currentSegments.length;
97
+ }
98
+ currentSegments.splice(insertPos, 0, incomingSegment);
42
99
  }
43
100
  continue;
44
101
  }
@@ -95,7 +152,57 @@ function mergeSemicolonSegments(current, incoming) {
95
152
  }
96
153
  }
97
154
  if (!mergedIntoCurrent) {
98
- currentSegments.push(incomingSegment);
155
+ let previousMatch = -1;
156
+ for (let j = incomingIndex - 1; j >= 0; j--) {
157
+ const mi = initialMatchedIndices[j];
158
+ if (mi >= 0) {
159
+ const pref = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(incomingSegments[j]).prefix;
160
+ const pos = currentSegments.findIndex((cs) => (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(cs).prefix === pref);
161
+ if (pos !== -1) {
162
+ previousMatch = pos;
163
+ break;
164
+ }
165
+ }
166
+ }
167
+ let nextMatch = -1;
168
+ for (let j = incomingIndex + 1; j < incomingSegments.length; j++) {
169
+ const mi = initialMatchedIndices[j];
170
+ if (mi >= 0) {
171
+ const pref = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(incomingSegments[j]).prefix;
172
+ const pos = currentSegments.findIndex((cs) => (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(cs).prefix === pref);
173
+ if (pos !== -1) {
174
+ nextMatch = pos;
175
+ break;
176
+ }
177
+ }
178
+ }
179
+ const incomingBase = ((0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(incomingSegment).prefix || incomingSegment).split(' ')[0];
180
+ let basePos = null;
181
+ for (let k = currentSegments.length - 1; k >= 0; k--) {
182
+ const cp = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(currentSegments[k]).prefix || currentSegments[k];
183
+ const cpBase = cp.split(' ')[0];
184
+ if (cpBase === incomingBase) {
185
+ basePos = k;
186
+ break;
187
+ }
188
+ }
189
+ let insertPos;
190
+ if ((previousMatch >= 0) && (nextMatch >= 0)) {
191
+ insertPos = previousMatch + 1;
192
+ }
193
+ else if ((basePos !== null) && (nextMatch < 0)) {
194
+ insertPos = basePos + 1;
195
+ }
196
+ else if (previousMatch >= 0) {
197
+ insertPos = previousMatch + 1;
198
+ }
199
+ else if (nextMatch >= 0) {
200
+ insertPos = nextMatch + 1;
201
+ }
202
+ else {
203
+ insertPos = currentSegments.length;
204
+ }
205
+ currentSegments.splice(insertPos, 0, incomingSegment);
99
206
  }
100
207
  continue;
101
208
  }
@@ -110,7 +217,57 @@ function mergeSemicolonSegments(current, incoming) {
110
217
  }
111
218
  }
112
219
  if (!matched) {
113
- currentSegments.push(incomingSegment);
220
+ let previousMatch = -1;
221
+ for (let j = incomingIndex - 1; j >= 0; j--) {
222
+ const mi = initialMatchedIndices[j];
223
+ if (mi >= 0) {
224
+ const pref = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(incomingSegments[j]).prefix;
225
+ const pos = currentSegments.findIndex((cs) => (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(cs).prefix === pref);
226
+ if (pos !== -1) {
227
+ previousMatch = pos;
228
+ break;
229
+ }
230
+ }
231
+ }
232
+ let nextMatch = -1;
233
+ for (let j = incomingIndex + 1; j < incomingSegments.length; j++) {
234
+ const mi = initialMatchedIndices[j];
235
+ if (mi >= 0) {
236
+ const pref = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(incomingSegments[j]).prefix;
237
+ const pos = currentSegments.findIndex((cs) => (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(cs).prefix === pref);
238
+ if (pos !== -1) {
239
+ nextMatch = pos;
240
+ break;
241
+ }
242
+ }
243
+ }
244
+ const incomingBase = (incomingPartsObject.prefix || incomingSegment).split(' ')[0];
245
+ let basePos = null;
246
+ for (let k = currentSegments.length - 1; k >= 0; k--) {
247
+ const cp = (0, split_prefix_and_flags_js_1.splitPrefixAndFlags)(currentSegments[k]).prefix || currentSegments[k];
248
+ const cpBase = cp.split(' ')[0];
249
+ if (cpBase === incomingBase) {
250
+ basePos = k;
251
+ break;
252
+ }
253
+ }
254
+ let insertPos;
255
+ if ((previousMatch >= 0) && (nextMatch >= 0)) {
256
+ insertPos = previousMatch + 1;
257
+ }
258
+ else if ((basePos !== null) && (nextMatch < 0)) {
259
+ insertPos = basePos + 1;
260
+ }
261
+ else if (previousMatch >= 0) {
262
+ insertPos = previousMatch + 1;
263
+ }
264
+ else if (nextMatch >= 0) {
265
+ insertPos = nextMatch + 1;
266
+ }
267
+ else {
268
+ insertPos = currentSegments.length;
269
+ }
270
+ currentSegments.splice(insertPos, 0, incomingSegment);
114
271
  }
115
272
  }
116
273
  // Deduplicate top-level semicolon segments by prefix, preserving first occurrence
@@ -0,0 +1 @@
1
+ export declare function fnmatch(filepath: string, glob: string): boolean;
@@ -0,0 +1,11 @@
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.fnmatch = fnmatch;
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
+ } // }}}
@@ -1,17 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  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
- } // }}}
4
+ const fnmatch_js_1 = require("./fnmatch.js");
12
5
  function getFormat(name, formats) {
13
6
  for (const format of formats) {
14
- if (fnmatch(name, format.glob)) {
7
+ if ((0, fnmatch_js_1.fnmatch)(name, format.glob)) {
15
8
  return format;
16
9
  }
17
10
  }
@@ -0,0 +1,6 @@
1
+ import { type Spinner } from '@zokugun/cli-utils/logger';
2
+ export declare function loadPackage(spec: string, spinner: Spinner, options: {
3
+ force?: boolean;
4
+ skip?: boolean;
5
+ verbose?: boolean;
6
+ }): Promise<string | null>;
@@ -0,0 +1,26 @@
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.loadPackage = loadPackage;
7
+ const cli_utils_1 = require("@zokugun/cli-utils");
8
+ const pacote_1 = __importDefault(require("pacote"));
9
+ const tempy_1 = __importDefault(require("tempy"));
10
+ async function loadPackage(spec, spinner, options) {
11
+ const dir = tempy_1.default.directory();
12
+ const pkgResult = await pacote_1.default.extract(spec, dir);
13
+ if (!pkgResult.resolved) {
14
+ if (options.force || options.skip) {
15
+ spinner.fail();
16
+ if (options.verbose) {
17
+ cli_utils_1.logger.warn(`The artifact '${spec}' couldn't be found, skipping...`);
18
+ }
19
+ return null;
20
+ }
21
+ else {
22
+ cli_utils_1.logger.fatal(pkgResult.from);
23
+ }
24
+ }
25
+ return dir;
26
+ }
@@ -46,7 +46,6 @@ const utc_1 = __importDefault(require("dayjs/plugin/utc"));
46
46
  const git_url_parse_1 = __importDefault(require("git-url-parse"));
47
47
  const lodash_es_1 = require("lodash-es");
48
48
  const YAML = __importStar(require("../parsers/yaml.js"));
49
- const try_json_js_1 = require("./try-json.js");
50
49
  dayjs_1.default.extend(utc_1.default);
51
50
  const EXPRESSION_REGEX = /#\[\[(.*?)]]/g;
52
51
  const PATH_PROPERTY_REGEX = /^(\w+?)(?:\.|$)(.*)$/;
@@ -157,7 +156,7 @@ class TemplateEngine {
157
156
  return (0, xtry_1.ok)(YAML.parse(content));
158
157
  }
159
158
  else {
160
- return (0, xtry_1.ok)((0, try_json_js_1.tryJSON)(content) ?? YAML.parse(content));
159
+ return (0, xtry_1.ok)(JSON.parse(content) ?? YAML.parse(content));
161
160
  }
162
161
  }
163
162
  catch (parseError) {
@@ -197,7 +196,6 @@ class TemplateEngine {
197
196
  if (readResult.fails) {
198
197
  return readResult;
199
198
  }
200
- // const getValueResult = this.getValueByPath(readResult.value, propertyPath);
201
199
  const evalResult = this.evaluateExpression(propertyPath, readResult.value);
202
200
  if (evalResult.fails) {
203
201
  return evalResult;