@udondan/avanti 0.12.1 → 0.14.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 (85) hide show
  1. package/README.md +341 -271
  2. package/dist/cli.js +2 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/diff.d.ts.map +1 -1
  5. package/dist/commands/diff.js +117 -26
  6. package/dist/commands/diff.js.map +1 -1
  7. package/dist/commands/lock.d.ts +3 -0
  8. package/dist/commands/lock.d.ts.map +1 -0
  9. package/dist/commands/lock.js +112 -0
  10. package/dist/commands/lock.js.map +1 -0
  11. package/dist/commands/log.js +48 -9
  12. package/dist/commands/log.js.map +1 -1
  13. package/dist/commands/pull.d.ts.map +1 -1
  14. package/dist/commands/pull.js +260 -43
  15. package/dist/commands/pull.js.map +1 -1
  16. package/dist/commands/reset.js +18 -9
  17. package/dist/commands/reset.js.map +1 -1
  18. package/dist/commands/revert.js +18 -9
  19. package/dist/commands/revert.js.map +1 -1
  20. package/dist/config-writeback.d.ts +12 -0
  21. package/dist/config-writeback.d.ts.map +1 -0
  22. package/dist/config-writeback.js +209 -0
  23. package/dist/config-writeback.js.map +1 -0
  24. package/dist/config.d.ts +1 -0
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +139 -65
  27. package/dist/config.js.map +1 -1
  28. package/dist/diff.js +22 -13
  29. package/dist/diff.js.map +1 -1
  30. package/dist/fetch.d.ts +0 -1
  31. package/dist/fetch.d.ts.map +1 -1
  32. package/dist/fetch.js +2 -2
  33. package/dist/fetch.js.map +1 -1
  34. package/dist/history.d.ts +8 -1
  35. package/dist/history.d.ts.map +1 -1
  36. package/dist/history.js +22 -10
  37. package/dist/history.js.map +1 -1
  38. package/dist/processors/json.js +2 -3
  39. package/dist/processors/json.js.map +1 -1
  40. package/dist/processors/post.js +1 -2
  41. package/dist/processors/post.js.map +1 -1
  42. package/dist/processors/replace.js +1 -2
  43. package/dist/processors/replace.js.map +1 -1
  44. package/dist/processors/yaml.js +2 -3
  45. package/dist/processors/yaml.js.map +1 -1
  46. package/dist/prompt.js +18 -9
  47. package/dist/prompt.js.map +1 -1
  48. package/dist/sha.d.ts +2 -0
  49. package/dist/sha.d.ts.map +1 -0
  50. package/dist/sha.js +41 -0
  51. package/dist/sha.js.map +1 -0
  52. package/dist/sources/bitbucket.js +18 -9
  53. package/dist/sources/bitbucket.js.map +1 -1
  54. package/dist/sources/exec.js +1 -2
  55. package/dist/sources/exec.js.map +1 -1
  56. package/dist/sources/git.js +18 -9
  57. package/dist/sources/git.js.map +1 -1
  58. package/dist/sources/github.js +18 -9
  59. package/dist/sources/github.js.map +1 -1
  60. package/dist/sources/gitlab.js +18 -9
  61. package/dist/sources/gitlab.js.map +1 -1
  62. package/dist/sources/http.d.ts +3 -0
  63. package/dist/sources/http.d.ts.map +1 -1
  64. package/dist/sources/http.js +24 -12
  65. package/dist/sources/http.js.map +1 -1
  66. package/dist/sources/index.d.ts +11 -1
  67. package/dist/sources/index.d.ts.map +1 -1
  68. package/dist/sources/index.js +287 -41
  69. package/dist/sources/index.js.map +1 -1
  70. package/dist/sources/local.d.ts +2 -1
  71. package/dist/sources/local.d.ts.map +1 -1
  72. package/dist/sources/local.js +21 -10
  73. package/dist/sources/local.js.map +1 -1
  74. package/dist/sources/s3.js +18 -9
  75. package/dist/sources/s3.js.map +1 -1
  76. package/dist/sources/vault.js +18 -9
  77. package/dist/sources/vault.js.map +1 -1
  78. package/dist/types.d.ts +27 -3
  79. package/dist/types.d.ts.map +1 -1
  80. package/dist/variables.js +4 -4
  81. package/dist/variables.js.map +1 -1
  82. package/dist/writer.d.ts.map +1 -1
  83. package/dist/writer.js +37 -12
  84. package/dist/writer.js.map +1 -1
  85. package/package.json +10 -9
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.applyUpdatedShas = applyUpdatedShas;
37
+ exports.writeUpdatedShas = writeUpdatedShas;
38
+ const fs = __importStar(require("fs"));
39
+ const yaml_1 = require("yaml");
40
+ const writer_1 = require("./writer");
41
+ /**
42
+ * Applies updated SHA values into a parsed YAML config string in-place,
43
+ * preserving comments. Returns the new content, or null if no updates matched.
44
+ */
45
+ function applyUpdatedShas(raw, updates) {
46
+ if (updates.size === 0)
47
+ return null;
48
+ const doc = (0, yaml_1.parseDocument)(raw);
49
+ const filesNode = doc.get('files', true);
50
+ if (!(0, yaml_1.isMap)(filesNode))
51
+ return null;
52
+ let changed = false;
53
+ filesNode.items.forEach((pair) => {
54
+ if (!pair || typeof pair !== 'object')
55
+ return;
56
+ const p = pair;
57
+ const targetKey = p.key != null && (0, yaml_1.isScalar)(p.key) ? String(p.key.value) : null;
58
+ if (!targetKey)
59
+ return;
60
+ const entryNode = p.value;
61
+ if (!entryNode?.get)
62
+ return;
63
+ const srcNode = entryNode.get('src', true);
64
+ if (!srcNode)
65
+ return;
66
+ // inSeq=true → src is a sequence; shaPath includes the numeric srcIdx.
67
+ // inSeq=false → src is a single map; omit the index so the path matches.
68
+ const processSrcItem = (item, srcIdx, inSeq) => {
69
+ if (!item || typeof item !== 'object')
70
+ return;
71
+ const n = item;
72
+ if (!n.get)
73
+ return;
74
+ const srcBase = inSeq
75
+ ? ['files', targetKey, 'src', srcIdx]
76
+ : ['files', targetKey, 'src'];
77
+ let label = null;
78
+ let shaPath = null;
79
+ if (n.get('github')) {
80
+ const gh = n.get('github');
81
+ if (gh?.get) {
82
+ const repo = gh.get('repo');
83
+ const file = gh.get('file');
84
+ const ref = gh.get('ref');
85
+ if (repo && file) {
86
+ label = `github:${repo}:${file}${ref ? `@${ref}` : ''}`;
87
+ shaPath = [...srcBase, 'github', 'sha'];
88
+ }
89
+ }
90
+ }
91
+ else if (n.get('gitlab')) {
92
+ const gl = n.get('gitlab');
93
+ if (gl?.get) {
94
+ const project = gl.get('project');
95
+ const file = gl.get('file');
96
+ const ref = gl.get('ref');
97
+ if (project && file) {
98
+ label = `gitlab:${project}:${file}${ref ? `@${ref}` : ''}`;
99
+ shaPath = [...srcBase, 'gitlab', 'sha'];
100
+ }
101
+ }
102
+ }
103
+ else if (n.get('bitbucket')) {
104
+ const bb = n.get('bitbucket');
105
+ if (bb?.get) {
106
+ const ws = bb.get('workspace');
107
+ const repo = bb.get('repo');
108
+ const file = bb.get('file');
109
+ const ref = bb.get('ref');
110
+ if (ws && repo && file) {
111
+ label = `bitbucket:${ws}/${repo}:${file}${ref ? `@${ref}` : ''}`;
112
+ shaPath = [...srcBase, 'bitbucket', 'sha'];
113
+ }
114
+ }
115
+ }
116
+ else if (n.get('git')) {
117
+ const gt = n.get('git');
118
+ if (gt?.get) {
119
+ const repo = gt.get('repo');
120
+ const file = gt.get('file');
121
+ const ref = gt.get('ref');
122
+ if (repo && file) {
123
+ label = `git:${repo}:${file}${ref ? `@${ref}` : ''}`;
124
+ shaPath = [...srcBase, 'git', 'sha'];
125
+ }
126
+ }
127
+ }
128
+ else if (n.get('exec') !== undefined) {
129
+ const cmd = n.get('exec');
130
+ if (cmd) {
131
+ label = `exec:${cmd}`;
132
+ shaPath = [...srcBase, 'sha'];
133
+ }
134
+ }
135
+ else if (n.get('s3') !== undefined) {
136
+ const s3 = n.get('s3');
137
+ if (s3) {
138
+ label = `s3:${s3}`;
139
+ shaPath = [...srcBase, 'sha'];
140
+ }
141
+ }
142
+ else if (n.get('vault')) {
143
+ const vt = n.get('vault');
144
+ if (vt?.get) {
145
+ const p = vt.get('path');
146
+ const field = vt.get('field');
147
+ if (p) {
148
+ label = `vault:${p}${field ? `#${field}` : ''}`;
149
+ shaPath = [...srcBase, 'vault', 'sha'];
150
+ }
151
+ }
152
+ }
153
+ else if (n.get('http') !== undefined) {
154
+ const url = n.get('http');
155
+ if (url) {
156
+ label = `http:${url}`;
157
+ shaPath = [...srcBase, 'sha'];
158
+ }
159
+ }
160
+ else if (n.get('path') !== undefined) {
161
+ const p = n.get('path');
162
+ if (p) {
163
+ label = `path:${p}`;
164
+ shaPath = [...srcBase, 'sha'];
165
+ }
166
+ }
167
+ else if (n.get('url') !== undefined) {
168
+ const u = n.get('url');
169
+ if (u) {
170
+ label = `url:${u}`;
171
+ shaPath = [...srcBase, 'sha'];
172
+ }
173
+ }
174
+ if (label && shaPath && updates.has(label)) {
175
+ const newSha = updates.get(label);
176
+ if (doc.getIn(shaPath) !== newSha) {
177
+ doc.setIn(shaPath, newSha);
178
+ changed = true;
179
+ }
180
+ }
181
+ };
182
+ if ((0, yaml_1.isSeq)(srcNode)) {
183
+ srcNode.items.forEach((item, idx) => {
184
+ processSrcItem(item, idx, true);
185
+ });
186
+ }
187
+ else {
188
+ processSrcItem(srcNode, 0, false);
189
+ }
190
+ });
191
+ return changed ? doc.toString() : null;
192
+ }
193
+ /**
194
+ * Writes updated SHA values into the config YAML file in-place, preserving comments.
195
+ * Returns true if the file was actually modified, false if no labels matched or all
196
+ * values were already up to date.
197
+ */
198
+ function writeUpdatedShas(configPath, updates) {
199
+ if (updates.size === 0)
200
+ return false;
201
+ const raw = fs.readFileSync(configPath, 'utf8');
202
+ const newContent = applyUpdatedShas(raw, updates);
203
+ if (newContent !== null) {
204
+ (0, writer_1.atomicWrite)([{ targetPath: configPath, content: newContent }]);
205
+ return true;
206
+ }
207
+ return false;
208
+ }
209
+ //# sourceMappingURL=config-writeback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-writeback.js","sourceRoot":"","sources":["../src/config-writeback.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { AvantiConfig } from './types';
2
+ export declare const SELF_KEY = "$self";
2
3
  export declare function isRemoteConfigSpec(s: string): boolean;
3
4
  export declare function normalizeConfigKey(spec: string): string;
4
5
  export declare function resolveConfigPath(explicit?: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,YAAY,EAab,MAAM,SAAS,CAAC;AAajB,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAOrD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB3D;AAwFD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAsFhE;AAED,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAQ1E"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,YAAY,EAgBb,MAAM,SAAS,CAAC;AAMjB,eAAO,MAAM,QAAQ,UAAU,CAAC;AAShC,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAOrD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB3D;AAwFD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAmFhE;AAED,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAQ1E"}
package/dist/config.js CHANGED
@@ -15,15 +15,30 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.loadConfig = exports.parseConfigContent = exports.resolveConfigPath = exports.normalizeConfigKey = exports.isRemoteConfigSpec = void 0;
36
+ exports.SELF_KEY = void 0;
37
+ exports.isRemoteConfigSpec = isRemoteConfigSpec;
38
+ exports.normalizeConfigKey = normalizeConfigKey;
39
+ exports.resolveConfigPath = resolveConfigPath;
40
+ exports.parseConfigContent = parseConfigContent;
41
+ exports.loadConfig = loadConfig;
27
42
  const fs = __importStar(require("fs"));
28
43
  const path = __importStar(require("path"));
29
44
  const yaml = __importStar(require("js-yaml"));
@@ -31,6 +46,7 @@ const variables_1 = require("./variables");
31
46
  const http_1 = require("./sources/http");
32
47
  const github_1 = require("./sources/github");
33
48
  const gitlab_1 = require("./sources/gitlab");
49
+ exports.SELF_KEY = '$self';
34
50
  const CONFIG_CANDIDATES = [
35
51
  '.avanti.yml',
36
52
  '.avanti.yaml',
@@ -43,7 +59,6 @@ function isRemoteConfigSpec(s) {
43
59
  s.startsWith('github:') ||
44
60
  s.startsWith('gitlab:'));
45
61
  }
46
- exports.isRemoteConfigSpec = isRemoteConfigSpec;
47
62
  function normalizeConfigKey(spec) {
48
63
  if (spec.startsWith('github:') || spec.startsWith('gitlab:')) {
49
64
  const atIdx = spec.lastIndexOf('@');
@@ -52,7 +67,6 @@ function normalizeConfigKey(spec) {
52
67
  }
53
68
  return spec;
54
69
  }
55
- exports.normalizeConfigKey = normalizeConfigKey;
56
70
  function resolveConfigPath(explicit) {
57
71
  if (explicit) {
58
72
  if (isRemoteConfigSpec(explicit))
@@ -69,7 +83,6 @@ function resolveConfigPath(explicit) {
69
83
  }
70
84
  return path.resolve(cwd, CONFIG_CANDIDATES[0]);
71
85
  }
72
- exports.resolveConfigPath = resolveConfigPath;
73
86
  // Parses github:owner/repo:path/to/file.yml[@ref]
74
87
  function parseGitHubSpec(spec) {
75
88
  const body = spec.slice('github:'.length);
@@ -106,7 +119,7 @@ function parseGitLabSpec(spec) {
106
119
  }
107
120
  async function fetchConfigContent(spec) {
108
121
  if (spec.startsWith('http://') || spec.startsWith('https://')) {
109
- return (0, http_1.fetchHttp)(spec);
122
+ return await (0, http_1.fetchHttp)(spec);
110
123
  }
111
124
  if (spec.startsWith('github:')) {
112
125
  const { repo, file, ref } = parseGitHubSpec(spec);
@@ -143,43 +156,35 @@ function parseConfigContent(content) {
143
156
  throw new Error('Config must be a YAML object');
144
157
  }
145
158
  const obj = raw;
146
- if (!Array.isArray(obj['files'])) {
147
- throw new Error('Config must have a "files" array');
159
+ if (!obj['files'] ||
160
+ typeof obj['files'] !== 'object' ||
161
+ Array.isArray(obj['files'])) {
162
+ throw new Error('Config must have a "files" map');
148
163
  }
149
164
  const variables = parseVariables(obj['variables']);
150
- const files = obj['files'].map((entry, i) => {
165
+ const filesRaw = obj['files'];
166
+ const files = Object.create(null);
167
+ for (const [target, entry] of Object.entries(filesRaw)) {
151
168
  if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
152
- throw new Error(`files[${i}]: must be an object`);
169
+ throw new Error(`files["${target}"]: must be an object`);
153
170
  }
154
171
  const e = entry;
155
172
  if (e['src'] === undefined || e['src'] === null) {
156
- throw new Error(`files[${i}]: "src" is required`);
173
+ throw new Error(`files["${target}"]: "src" is required`);
157
174
  }
158
175
  const src = Array.isArray(e['src'])
159
- ? e['src'].map((item, j) => parseSingleSrc(item, i, j))
160
- : parseSingleSrc(e['src'], i, undefined);
161
- // list src must have an explicit target
162
- if (Array.isArray(src) && !e['target']) {
163
- throw new Error(`files[${i}]: "target" is required when "src" is a list`);
164
- }
165
- // exec/raw sources must have a target
166
- if (!Array.isArray(src) &&
167
- (isExecSrc(src) || isRawSrc(src)) &&
168
- !e['target']) {
169
- throw new Error(`files[${i}]: "target" is required for exec/raw sources`);
170
- }
171
- const fileEntry = { src };
172
- if (typeof e['target'] === 'string')
173
- fileEntry.target = e['target'];
176
+ ? e['src'].map((item, j) => parseSingleSrc(item, target, j))
177
+ : parseSingleSrc(e['src'], target, undefined);
178
+ const fileEntry = { src, target };
174
179
  if (typeof e['mode'] === 'string')
175
180
  fileEntry.mode = e['mode'];
176
181
  if (typeof e['post'] === 'string')
177
182
  fileEntry.post = e['post'];
178
183
  if (e['replace'] !== undefined) {
179
184
  if (!Array.isArray(e['replace'])) {
180
- throw new Error(`files[${i}]: "replace" must be an array`);
185
+ throw new Error(`files["${target}"]: "replace" must be an array`);
181
186
  }
182
- fileEntry.replace = e['replace'].map((r, j) => parseReplaceRule(r, i, j));
187
+ fileEntry.replace = e['replace'].map((r, j) => parseReplaceRule(r, target, j));
183
188
  }
184
189
  if (e['json'] !== undefined) {
185
190
  const rawJson = e['json'];
@@ -187,7 +192,7 @@ function parseConfigContent(content) {
187
192
  fileEntry.json = rawJson;
188
193
  }
189
194
  else {
190
- fileEntry.json = parseJsonMergeOptions(rawJson, i);
195
+ fileEntry.json = parseJsonMergeOptions(rawJson, target);
191
196
  }
192
197
  }
193
198
  if (e['yaml'] !== undefined) {
@@ -196,14 +201,13 @@ function parseConfigContent(content) {
196
201
  fileEntry.yaml = rawYaml;
197
202
  }
198
203
  else {
199
- fileEntry.yaml = parseYamlMergeOptions(rawYaml, i);
204
+ fileEntry.yaml = parseYamlMergeOptions(rawYaml, target);
200
205
  }
201
206
  }
202
- return fileEntry;
203
- });
207
+ files[target] = fileEntry;
208
+ }
204
209
  return { variables, files };
205
210
  }
206
- exports.parseConfigContent = parseConfigContent;
207
211
  async function loadConfig(configPath) {
208
212
  try {
209
213
  const content = await fetchConfigContent(configPath);
@@ -214,7 +218,6 @@ async function loadConfig(configPath) {
214
218
  throw new Error(`Failed to parse config file: ${msg}`, { cause: err });
215
219
  }
216
220
  }
217
- exports.loadConfig = loadConfig;
218
221
  function parseVariables(raw) {
219
222
  if (raw === undefined || raw === null)
220
223
  return {};
@@ -232,21 +235,89 @@ function parseVariables(raw) {
232
235
  (0, variables_1.validateVariables)(vars);
233
236
  return vars;
234
237
  }
235
- function parseSingleSrc(raw, i, j) {
236
- const loc = j !== undefined ? `files[${i}].src[${j}]` : `files[${i}].src`;
238
+ function parseSha(value, loc) {
239
+ if (value === undefined || value === null)
240
+ return undefined;
241
+ if (typeof value !== 'string') {
242
+ throw new Error(`${loc}.sha: must be a string, got ${typeof value}`);
243
+ }
244
+ const normalized = value.toLowerCase();
245
+ if (!/^[0-9a-f]{64}$/.test(normalized)) {
246
+ throw new Error(`${loc}.sha: expected 64 hex characters, got "${value}"`);
247
+ }
248
+ return normalized;
249
+ }
250
+ function parseSingleSrc(raw, target, j) {
251
+ const loc = j !== undefined ? `files["${target}"].src[${j}]` : `files["${target}"].src`;
237
252
  // Plain string → http/https URL or local path
238
253
  if (typeof raw === 'string') {
239
254
  return raw;
240
255
  }
241
256
  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
242
- throw new Error(`${loc}: must be a string or a map with one of: exec, gitlab, github, bitbucket, git, s3, vault`);
257
+ throw new Error(`${loc}: must be a string or a map with one of: exec, gitlab, github, bitbucket, git, s3, vault, http, raw`);
243
258
  }
244
259
  const obj = raw;
260
+ if ('path' in obj) {
261
+ if (typeof obj['path'] !== 'string' || !obj['path']) {
262
+ throw new Error(`${loc}.path: must be a non-empty string`);
263
+ }
264
+ const result = { path: obj['path'] };
265
+ if (obj['optional'] !== undefined) {
266
+ if (typeof obj['optional'] !== 'boolean') {
267
+ throw new Error(`${loc}.optional: must be a boolean`);
268
+ }
269
+ result.optional = obj['optional'];
270
+ }
271
+ const pathSha = parseSha(obj['sha'], loc);
272
+ if (pathSha !== undefined)
273
+ result.sha = pathSha;
274
+ return result;
275
+ }
276
+ if ('url' in obj) {
277
+ if (typeof obj['url'] !== 'string' || !obj['url']) {
278
+ throw new Error(`${loc}.url: must be a non-empty string (http/https URL)`);
279
+ }
280
+ if (!obj['url'].includes('$') &&
281
+ !obj['url'].startsWith('http://') &&
282
+ !obj['url'].startsWith('https://')) {
283
+ throw new Error(`${loc}.url: must start with http:// or https://, got "${obj['url']}"`);
284
+ }
285
+ const result = { url: obj['url'] };
286
+ if (obj['optional'] !== undefined) {
287
+ if (typeof obj['optional'] !== 'boolean') {
288
+ throw new Error(`${loc}.optional: must be a boolean`);
289
+ }
290
+ result.optional = obj['optional'];
291
+ }
292
+ const urlSha = parseSha(obj['sha'], loc);
293
+ if (urlSha !== undefined)
294
+ result.sha = urlSha;
295
+ return result;
296
+ }
297
+ if ('http' in obj) {
298
+ if (typeof obj['http'] !== 'string' || !obj['http']) {
299
+ throw new Error(`${loc}.http: must be a non-empty string (http/https URL)`);
300
+ }
301
+ if (!obj['http'].includes('$') &&
302
+ !obj['http'].startsWith('http://') &&
303
+ !obj['http'].startsWith('https://')) {
304
+ throw new Error(`${loc}.http: must start with http:// or https://, got "${obj['http']}"`);
305
+ }
306
+ const result = { http: obj['http'] };
307
+ const httpSha = parseSha(obj['sha'], loc);
308
+ if (httpSha !== undefined)
309
+ result.sha = httpSha;
310
+ return result;
311
+ }
245
312
  if ('exec' in obj) {
246
313
  if (typeof obj['exec'] !== 'string' || !obj['exec']) {
247
314
  throw new Error(`${loc}.exec: must be a non-empty string`);
248
315
  }
249
- return { exec: obj['exec'] };
316
+ const result = { exec: obj['exec'] };
317
+ const execSha = parseSha(obj['sha'], loc);
318
+ if (execSha !== undefined)
319
+ result.sha = execSha;
320
+ return result;
250
321
  }
251
322
  if ('gitlab' in obj) {
252
323
  const gl = obj['gitlab'];
@@ -265,6 +336,7 @@ function parseSingleSrc(raw, i, j) {
265
336
  project: g['project'],
266
337
  file: g['file'],
267
338
  ref: typeof g['ref'] === 'string' ? g['ref'] : undefined,
339
+ sha: parseSha(g['sha'], `${loc}.gitlab`),
268
340
  },
269
341
  };
270
342
  }
@@ -291,6 +363,7 @@ function parseSingleSrc(raw, i, j) {
291
363
  repo: g['repo'],
292
364
  file: g['file'],
293
365
  ref: typeof g['ref'] === 'string' ? g['ref'] : undefined,
366
+ sha: parseSha(g['sha'], `${loc}.github`),
294
367
  },
295
368
  };
296
369
  }
@@ -315,6 +388,7 @@ function parseSingleSrc(raw, i, j) {
315
388
  repo: b['repo'],
316
389
  file: b['file'],
317
390
  ref: typeof b['ref'] === 'string' ? b['ref'] : undefined,
391
+ sha: parseSha(b['sha'], `${loc}.bitbucket`),
318
392
  },
319
393
  };
320
394
  }
@@ -335,6 +409,7 @@ function parseSingleSrc(raw, i, j) {
335
409
  repo: gt['repo'],
336
410
  file: gt['file'],
337
411
  ref: typeof gt['ref'] === 'string' ? gt['ref'] : undefined,
412
+ sha: parseSha(gt['sha'], `${loc}.git`),
338
413
  },
339
414
  };
340
415
  }
@@ -342,7 +417,11 @@ function parseSingleSrc(raw, i, j) {
342
417
  if (typeof obj['s3'] !== 'string' || !obj['s3']) {
343
418
  throw new Error(`${loc}.s3: must be a non-empty string (s3:// URI)`);
344
419
  }
345
- return { s3: obj['s3'] };
420
+ const result = { s3: obj['s3'] };
421
+ const s3Sha = parseSha(obj['sha'], loc);
422
+ if (s3Sha !== undefined)
423
+ result.sha = s3Sha;
424
+ return result;
346
425
  }
347
426
  if ('vault' in obj) {
348
427
  const v = obj['vault'];
@@ -357,59 +436,54 @@ function parseSingleSrc(raw, i, j) {
357
436
  vault: {
358
437
  path: vt['path'],
359
438
  field: typeof vt['field'] === 'string' ? vt['field'] : undefined,
439
+ sha: parseSha(vt['sha'], `${loc}.vault`),
360
440
  },
361
441
  };
362
442
  }
363
- throw new Error(`${loc}: unknown source type. Must be a string or map with exec/gitlab/github/bitbucket/git/s3/vault/raw`);
364
- }
365
- function isExecSrc(src) {
366
- return typeof src === 'object' && 'exec' in src;
367
- }
368
- function isRawSrc(src) {
369
- return typeof src === 'object' && 'raw' in src;
443
+ throw new Error(`${loc}: unknown source type. Must be a string or map with exec/gitlab/github/bitbucket/git/s3/vault/http/url/path/raw`);
370
444
  }
371
- function parseMergeOptions(raw, i, kind, conflictValues, arrayValues, objectValues) {
445
+ function parseMergeOptions(raw, target, kind, conflictValues, arrayValues, objectValues) {
372
446
  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
373
- throw new Error(`files[${i}]: "${kind}" must be an object`);
447
+ throw new Error(`files["${target}"]: "${kind}" must be an object`);
374
448
  }
375
449
  const obj = raw;
376
450
  const opts = {};
377
451
  if (obj['conflicts'] !== undefined) {
378
452
  if (!conflictValues.includes(obj['conflicts'])) {
379
- throw new Error(`files[${i}].${kind}.conflicts: must be one of ${conflictValues.join(', ')}`);
453
+ throw new Error(`files["${target}"].${kind}.conflicts: must be one of ${conflictValues.join(', ')}`);
380
454
  }
381
455
  opts.conflicts = obj['conflicts'];
382
456
  }
383
457
  if (obj['arrays'] !== undefined) {
384
458
  if (!arrayValues.includes(obj['arrays'])) {
385
- throw new Error(`files[${i}].${kind}.arrays: must be one of ${arrayValues.join(', ')}`);
459
+ throw new Error(`files["${target}"].${kind}.arrays: must be one of ${arrayValues.join(', ')}`);
386
460
  }
387
461
  opts.arrays = obj['arrays'];
388
462
  }
389
463
  if (obj['objects'] !== undefined) {
390
464
  if (!objectValues.includes(obj['objects'])) {
391
- throw new Error(`files[${i}].${kind}.objects: must be one of ${objectValues.join(', ')}`);
465
+ throw new Error(`files["${target}"].${kind}.objects: must be one of ${objectValues.join(', ')}`);
392
466
  }
393
467
  opts.objects = obj['objects'];
394
468
  }
395
469
  return opts;
396
470
  }
397
- function parseJsonMergeOptions(raw, i) {
398
- return parseMergeOptions(raw, i, 'json', ['abort', 'first_wins', 'last_wins'], ['replace', 'concat'], ['replace', 'merge']);
471
+ function parseJsonMergeOptions(raw, target) {
472
+ return parseMergeOptions(raw, target, 'json', ['abort', 'first_wins', 'last_wins'], ['replace', 'concat'], ['replace', 'merge']);
399
473
  }
400
- function parseYamlMergeOptions(raw, i) {
401
- return parseMergeOptions(raw, i, 'yaml', ['abort', 'first_wins', 'last_wins'], ['replace', 'concat'], ['replace', 'merge']);
474
+ function parseYamlMergeOptions(raw, target) {
475
+ return parseMergeOptions(raw, target, 'yaml', ['abort', 'first_wins', 'last_wins'], ['replace', 'concat'], ['replace', 'merge']);
402
476
  }
403
- function parseReplaceRule(r, i, j) {
477
+ function parseReplaceRule(r, target, j) {
404
478
  if (!r || typeof r !== 'object' || Array.isArray(r)) {
405
- throw new Error(`files[${i}].replace[${j}]: must be an object`);
479
+ throw new Error(`files["${target}"].replace[${j}]: must be an object`);
406
480
  }
407
481
  const rule = r;
408
482
  if (typeof rule['from'] !== 'string') {
409
- throw new Error(`files[${i}].replace[${j}]: "from" must be a string`);
483
+ throw new Error(`files["${target}"].replace[${j}]: "from" must be a string`);
410
484
  }
411
485
  if (typeof rule['to'] !== 'string') {
412
- throw new Error(`files[${i}].replace[${j}]: "to" must be a string`);
486
+ throw new Error(`files["${target}"].replace[${j}]: "to" must be a string`);
413
487
  }
414
488
  return { from: rule['from'], to: rule['to'] };
415
489
  }