@0xsequence/catapult 1.3.17 → 1.5.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 (232) hide show
  1. package/README.md +276 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +1 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/index.d.ts +1 -0
  6. package/dist/commands/index.d.ts.map +1 -1
  7. package/dist/commands/index.js +1 -0
  8. package/dist/commands/index.js.map +1 -1
  9. package/dist/commands/list.d.ts.map +1 -1
  10. package/dist/commands/list.js +12 -0
  11. package/dist/commands/list.js.map +1 -1
  12. package/dist/commands/provenance.d.ts +3 -0
  13. package/dist/commands/provenance.d.ts.map +1 -0
  14. package/dist/commands/provenance.js +138 -0
  15. package/dist/commands/provenance.js.map +1 -0
  16. package/dist/lib/__tests__/deployer.spec.js +118 -1
  17. package/dist/lib/__tests__/deployer.spec.js.map +1 -1
  18. package/dist/lib/__tests__/network-loader.spec.js.map +1 -1
  19. package/dist/lib/__tests__/provenance.spec.d.ts +2 -0
  20. package/dist/lib/__tests__/provenance.spec.d.ts.map +1 -0
  21. package/dist/lib/__tests__/provenance.spec.js +205 -0
  22. package/dist/lib/__tests__/provenance.spec.js.map +1 -0
  23. package/dist/lib/contracts/__tests__/repository.spec.js +243 -0
  24. package/dist/lib/contracts/__tests__/repository.spec.js.map +1 -1
  25. package/dist/lib/contracts/repository.d.ts +9 -1
  26. package/dist/lib/contracts/repository.d.ts.map +1 -1
  27. package/dist/lib/contracts/repository.js +93 -7
  28. package/dist/lib/contracts/repository.js.map +1 -1
  29. package/dist/lib/core/__tests__/assert-action.spec.d.ts +2 -0
  30. package/dist/lib/core/__tests__/assert-action.spec.d.ts.map +1 -0
  31. package/dist/lib/core/__tests__/assert-action.spec.js +377 -0
  32. package/dist/lib/core/__tests__/assert-action.spec.js.map +1 -0
  33. package/dist/lib/core/__tests__/engine.spec.js +80 -0
  34. package/dist/lib/core/__tests__/engine.spec.js.map +1 -1
  35. package/dist/lib/core/__tests__/loader.spec.js +29 -0
  36. package/dist/lib/core/__tests__/loader.spec.js.map +1 -1
  37. package/dist/lib/core/__tests__/resolver.spec.js +405 -0
  38. package/dist/lib/core/__tests__/resolver.spec.js.map +1 -1
  39. package/dist/lib/core/__tests__/sign-actions.spec.d.ts +2 -0
  40. package/dist/lib/core/__tests__/sign-actions.spec.d.ts.map +1 -0
  41. package/dist/lib/core/__tests__/sign-actions.spec.js +128 -0
  42. package/dist/lib/core/__tests__/sign-actions.spec.js.map +1 -0
  43. package/dist/lib/core/__tests__/signer.spec.d.ts +2 -0
  44. package/dist/lib/core/__tests__/signer.spec.d.ts.map +1 -0
  45. package/dist/lib/core/__tests__/signer.spec.js +40 -0
  46. package/dist/lib/core/__tests__/signer.spec.js.map +1 -0
  47. package/dist/lib/core/context.d.ts +3 -2
  48. package/dist/lib/core/context.d.ts.map +1 -1
  49. package/dist/lib/core/context.js +3 -2
  50. package/dist/lib/core/context.js.map +1 -1
  51. package/dist/lib/core/engine.d.ts +4 -0
  52. package/dist/lib/core/engine.d.ts.map +1 -1
  53. package/dist/lib/core/engine.js +206 -0
  54. package/dist/lib/core/engine.js.map +1 -1
  55. package/dist/lib/core/loader.d.ts +1 -0
  56. package/dist/lib/core/loader.d.ts.map +1 -1
  57. package/dist/lib/core/loader.js +6 -1
  58. package/dist/lib/core/loader.js.map +1 -1
  59. package/dist/lib/core/resolver.d.ts +2 -0
  60. package/dist/lib/core/resolver.d.ts.map +1 -1
  61. package/dist/lib/core/resolver.js +89 -0
  62. package/dist/lib/core/resolver.js.map +1 -1
  63. package/dist/lib/core/signer.d.ts +7 -0
  64. package/dist/lib/core/signer.d.ts.map +1 -0
  65. package/dist/lib/core/signer.js +60 -0
  66. package/dist/lib/core/signer.js.map +1 -0
  67. package/dist/lib/deployer.d.ts.map +1 -1
  68. package/dist/lib/deployer.js +21 -4
  69. package/dist/lib/deployer.js.map +1 -1
  70. package/dist/lib/index.d.ts +1 -0
  71. package/dist/lib/index.d.ts.map +1 -1
  72. package/dist/lib/index.js +1 -0
  73. package/dist/lib/index.js.map +1 -1
  74. package/dist/lib/parsers/__tests__/job.spec.js +77 -0
  75. package/dist/lib/parsers/__tests__/job.spec.js.map +1 -1
  76. package/dist/lib/parsers/__tests__/source.spec.d.ts +2 -0
  77. package/dist/lib/parsers/__tests__/source.spec.d.ts.map +1 -0
  78. package/dist/lib/parsers/__tests__/source.spec.js +158 -0
  79. package/dist/lib/parsers/__tests__/source.spec.js.map +1 -0
  80. package/dist/lib/parsers/index.d.ts +1 -0
  81. package/dist/lib/parsers/index.d.ts.map +1 -1
  82. package/dist/lib/parsers/index.js +1 -0
  83. package/dist/lib/parsers/index.js.map +1 -1
  84. package/dist/lib/parsers/job.d.ts.map +1 -1
  85. package/dist/lib/parsers/job.js +11 -0
  86. package/dist/lib/parsers/job.js.map +1 -1
  87. package/dist/lib/parsers/source.d.ts +4 -0
  88. package/dist/lib/parsers/source.d.ts.map +1 -0
  89. package/dist/lib/parsers/source.js +107 -0
  90. package/dist/lib/parsers/source.js.map +1 -0
  91. package/dist/lib/provenance.d.ts +34 -0
  92. package/dist/lib/provenance.d.ts.map +1 -0
  93. package/dist/lib/provenance.js +694 -0
  94. package/dist/lib/provenance.js.map +1 -0
  95. package/dist/lib/types/actions.d.ts +42 -2
  96. package/dist/lib/types/actions.d.ts.map +1 -1
  97. package/dist/lib/types/actions.js +4 -0
  98. package/dist/lib/types/actions.js.map +1 -1
  99. package/dist/lib/types/contracts.d.ts +3 -0
  100. package/dist/lib/types/contracts.d.ts.map +1 -1
  101. package/dist/lib/types/definitions.d.ts +1 -0
  102. package/dist/lib/types/definitions.d.ts.map +1 -1
  103. package/dist/lib/types/index.d.ts +1 -0
  104. package/dist/lib/types/index.d.ts.map +1 -1
  105. package/dist/lib/types/index.js +1 -0
  106. package/dist/lib/types/index.js.map +1 -1
  107. package/dist/lib/types/source.d.ts +26 -0
  108. package/dist/lib/types/source.d.ts.map +1 -0
  109. package/dist/lib/types/source.js +3 -0
  110. package/dist/lib/types/source.js.map +1 -0
  111. package/dist/lib/types/values.d.ts +33 -1
  112. package/dist/lib/types/values.d.ts.map +1 -1
  113. package/package.json +4 -1
  114. package/.eslintrc.json +0 -29
  115. package/.github/workflows/ci.yml +0 -181
  116. package/CONCEPT.md +0 -24
  117. package/contracts/checked-call.huff +0 -65
  118. package/eslint.config.js +0 -48
  119. package/examples/jobs/guards-v1.yaml +0 -17
  120. package/examples/jobs/sequence-seq-0001-patch.yaml +0 -59
  121. package/examples/jobs/sequence-v1.yaml +0 -59
  122. package/examples/templates/sequence-factory-v1.yaml +0 -56
  123. package/jest.config.js +0 -25
  124. package/src/cli.ts +0 -17
  125. package/src/commands/common.ts +0 -61
  126. package/src/commands/dry.ts +0 -209
  127. package/src/commands/etherscan.ts +0 -360
  128. package/src/commands/index.ts +0 -5
  129. package/src/commands/list.ts +0 -249
  130. package/src/commands/run.ts +0 -146
  131. package/src/commands/utils.ts +0 -215
  132. package/src/index.ts +0 -67
  133. package/src/lib/__tests__/deployer-events.spec.ts +0 -338
  134. package/src/lib/__tests__/deployer.spec.ts +0 -2093
  135. package/src/lib/__tests__/network-loader.spec.ts +0 -150
  136. package/src/lib/__tests__/network-selection.spec.ts +0 -41
  137. package/src/lib/__tests__/network-utils.spec.ts +0 -230
  138. package/src/lib/artifacts/__tests__/fixtures/contract1.json +0 -19
  139. package/src/lib/artifacts/__tests__/fixtures/contract2.json +0 -19
  140. package/src/lib/artifacts/__tests__/fixtures/duplicate-name.json +0 -19
  141. package/src/lib/artifacts/__tests__/fixtures/nested/nested-contract.json +0 -18
  142. package/src/lib/artifacts/__tests__/fixtures/not-an-artifact.json +0 -8
  143. package/src/lib/artifacts/__tests__/fixtures/readme.txt +0 -2
  144. package/src/lib/contracts/__tests__/repository.spec.ts +0 -344
  145. package/src/lib/contracts/repository.ts +0 -313
  146. package/src/lib/core/__tests__/context.spec.ts +0 -37
  147. package/src/lib/core/__tests__/engine.spec.ts +0 -1889
  148. package/src/lib/core/__tests__/graph.spec.ts +0 -125
  149. package/src/lib/core/__tests__/json-integration.spec.ts +0 -425
  150. package/src/lib/core/__tests__/loader.spec.ts +0 -334
  151. package/src/lib/core/__tests__/multi-platform-verification.spec.ts +0 -406
  152. package/src/lib/core/__tests__/resolver.spec.ts +0 -2053
  153. package/src/lib/core/__tests__/static-action.spec.ts +0 -172
  154. package/src/lib/core/context.ts +0 -127
  155. package/src/lib/core/engine.ts +0 -1782
  156. package/src/lib/core/graph.ts +0 -252
  157. package/src/lib/core/loader.ts +0 -247
  158. package/src/lib/core/resolver.ts +0 -757
  159. package/src/lib/deployer.ts +0 -981
  160. package/src/lib/events/__tests__/event-system.spec.ts +0 -392
  161. package/src/lib/events/cli-adapter.ts +0 -369
  162. package/src/lib/events/emitter.ts +0 -62
  163. package/src/lib/events/index.ts +0 -3
  164. package/src/lib/events/types.ts +0 -520
  165. package/src/lib/index.ts +0 -14
  166. package/src/lib/network-loader.ts +0 -90
  167. package/src/lib/network-selection.ts +0 -73
  168. package/src/lib/network-utils.ts +0 -64
  169. package/src/lib/parsers/__tests__/buildinfo.spec.ts +0 -122
  170. package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-bytecode-buildinfo.json +0 -62
  171. package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-json.txt +0 -2
  172. package/src/lib/parsers/__tests__/fixtures/buildinfo/multi-contract-buildinfo.json +0 -89
  173. package/src/lib/parsers/__tests__/fixtures/buildinfo/no-contracts-buildinfo.json +0 -17
  174. package/src/lib/parsers/__tests__/fixtures/buildinfo/simple-buildinfo.json +0 -63
  175. package/src/lib/parsers/__tests__/fixtures/buildinfo/wrong-format.json +0 -4
  176. package/src/lib/parsers/__tests__/job.spec.ts +0 -358
  177. package/src/lib/parsers/__tests__/template.spec.ts +0 -111
  178. package/src/lib/parsers/artifact/__tests__/artifact.spec.ts +0 -117
  179. package/src/lib/parsers/artifact/__tests__/fixtures/empty-bytecode.json +0 -5
  180. package/src/lib/parsers/artifact/__tests__/fixtures/hardhat-artifact.json +0 -67
  181. package/src/lib/parsers/artifact/__tests__/fixtures/invalid-bytecode.json +0 -5
  182. package/src/lib/parsers/artifact/__tests__/fixtures/invalid-json.txt +0 -11
  183. package/src/lib/parsers/artifact/__tests__/fixtures/minimal-artifact.json +0 -5
  184. package/src/lib/parsers/artifact/__tests__/fixtures/missing-abi.json +0 -4
  185. package/src/lib/parsers/artifact/__tests__/fixtures/missing-bytecode.json +0 -11
  186. package/src/lib/parsers/artifact/__tests__/fixtures/missing-contract-name.json +0 -11
  187. package/src/lib/parsers/artifact/__tests__/fixtures/simple-artifact.json +0 -40
  188. package/src/lib/parsers/artifact/__tests__/fixtures/wrong-types.json +0 -7
  189. package/src/lib/parsers/artifact/foundry-1.2.ts +0 -72
  190. package/src/lib/parsers/artifact/index.ts +0 -27
  191. package/src/lib/parsers/artifact/types.ts +0 -9
  192. package/src/lib/parsers/buildinfo.ts +0 -127
  193. package/src/lib/parsers/constants.ts +0 -56
  194. package/src/lib/parsers/index.ts +0 -5
  195. package/src/lib/parsers/job.ts +0 -148
  196. package/src/lib/parsers/template.ts +0 -135
  197. package/src/lib/std/templates/arachnid-deterministic-deployment-proxy.yaml +0 -68
  198. package/src/lib/std/templates/assured-deployment.yaml +0 -46
  199. package/src/lib/std/templates/era-evm-predeploy.yaml +0 -35
  200. package/src/lib/std/templates/erc-2470.yaml +0 -70
  201. package/src/lib/std/templates/min-balance.yaml +0 -35
  202. package/src/lib/std/templates/nano-universal-deployer.yaml +0 -61
  203. package/src/lib/std/templates/raw-erc-2470.yaml +0 -62
  204. package/src/lib/std/templates/raw-nano-universal-deployer.yaml +0 -54
  205. package/src/lib/std/templates/raw-sequence-universal-deployer-2.yaml +0 -52
  206. package/src/lib/std/templates/sequence-universal-deployer-2.yaml +0 -61
  207. package/src/lib/types/__tests__/json-request-action.spec.ts +0 -243
  208. package/src/lib/types/__tests__/read-json-value.spec.ts +0 -278
  209. package/src/lib/types/__tests__/resolve-json-value.spec.ts +0 -769
  210. package/src/lib/types/actions.ts +0 -127
  211. package/src/lib/types/artifacts.ts +0 -21
  212. package/src/lib/types/buildinfo.ts +0 -116
  213. package/src/lib/types/conditions.ts +0 -50
  214. package/src/lib/types/contracts.ts +0 -23
  215. package/src/lib/types/definitions.ts +0 -70
  216. package/src/lib/types/index.ts +0 -8
  217. package/src/lib/types/network.ts +0 -33
  218. package/src/lib/types/project.ts +0 -9
  219. package/src/lib/types/task.ts +0 -9
  220. package/src/lib/types/values.ts +0 -150
  221. package/src/lib/utils/assertion.ts +0 -24
  222. package/src/lib/utils/validation.ts +0 -116
  223. package/src/lib/validation/contract-references.ts +0 -210
  224. package/src/lib/validation/index.ts +0 -1
  225. package/src/lib/verification/__tests__/etherscan.spec.ts +0 -710
  226. package/src/lib/verification/__tests__/sourcify.spec.ts +0 -288
  227. package/src/lib/verification/etherscan.ts +0 -547
  228. package/src/lib/verification/sourcify.ts +0 -248
  229. package/test_validation/artifacts/TestContract.json +0 -9
  230. package/test_validation/jobs/test-missing.yaml +0 -16
  231. package/test_validation/networks.yaml +0 -3
  232. package/tsconfig.json +0 -36
@@ -0,0 +1,694 @@
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.collectSourceProvenanceEntries = collectSourceProvenanceEntries;
37
+ exports.verifySourceProvenance = verifySourceProvenance;
38
+ exports.generateBuildInfoFromSourceProvenance = generateBuildInfoFromSourceProvenance;
39
+ const fs = __importStar(require("fs/promises"));
40
+ const os = __importStar(require("os"));
41
+ const path = __importStar(require("path"));
42
+ const child_process_1 = require("child_process");
43
+ const util_1 = require("util");
44
+ const graph_1 = require("./core/graph");
45
+ const loader_1 = require("./core/loader");
46
+ const source_1 = require("./parsers/source");
47
+ const buildinfo_1 = require("./parsers/buildinfo");
48
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
49
+ const IGNORED_DIRS = new Set(['node_modules', 'dist', '.git', '.idea', '.vscode']);
50
+ const COMMAND_MAX_BUFFER = 20 * 1024 * 1024;
51
+ const BUILD_INFO_ID_PLACEHOLDER = '<build-info-id>';
52
+ const BUILD_INFO_BASE_PATH_PLACEHOLDER = '<build-info-base-path>';
53
+ const CATAPULT_CHECKOUT_PATH_PATTERN = /(?:[A-Za-z]:)?[/\\](?:[^/\\]+[/\\])*catapult-provenance-[^/\\]+[/\\]repo(?=[/\\]|$)/g;
54
+ async function collectSourceProvenanceEntries(projectRoot, options = {}) {
55
+ const absoluteProjectRoot = path.resolve(projectRoot);
56
+ const sourceFiles = await findSourceFiles(absoluteProjectRoot);
57
+ const warnings = [];
58
+ const entries = [];
59
+ for (const sourceFilePath of sourceFiles) {
60
+ let sourceDocument;
61
+ try {
62
+ const content = await fs.readFile(sourceFilePath, 'utf-8');
63
+ sourceDocument = (0, source_1.parseSourceDocument)(content);
64
+ }
65
+ catch (error) {
66
+ warnings.push(`Skipping source provenance file ${sourceFilePath}: ${formatError(error)}`);
67
+ continue;
68
+ }
69
+ if (!sourceDocument) {
70
+ continue;
71
+ }
72
+ for (const warning of sourceDocument.warnings || []) {
73
+ warnings.push(`Skipping source provenance entry ${sourceFilePath}: ${warning}`);
74
+ }
75
+ const sourceDir = path.dirname(sourceFilePath);
76
+ for (const [buildInfoRef, provenance] of Object.entries(sourceDocument.build_info)) {
77
+ const buildInfoPath = path.resolve(sourceDir, buildInfoRef);
78
+ if (!(0, buildinfo_1.isBuildInfoFile)(buildInfoPath)) {
79
+ warnings.push(`Skipping source provenance entry ${sourceFilePath}: "${buildInfoRef}" does not point to a build-info JSON file.`);
80
+ continue;
81
+ }
82
+ entries.push({
83
+ sourceDocumentPath: sourceFilePath,
84
+ buildInfoRef,
85
+ buildInfoPath,
86
+ provenance
87
+ });
88
+ }
89
+ }
90
+ if (options.jobs && options.jobs.length > 0) {
91
+ return {
92
+ entries: await filterEntriesByJobs(absoluteProjectRoot, entries, options),
93
+ warnings
94
+ };
95
+ }
96
+ return { entries, warnings };
97
+ }
98
+ async function verifySourceProvenance(projectRoot, options = {}) {
99
+ const collected = await collectSourceProvenanceEntries(projectRoot, options);
100
+ const buildCache = new Map();
101
+ const results = [];
102
+ try {
103
+ for (const entry of collected.entries) {
104
+ results.push(await verifySourceProvenanceEntry(entry, buildCache));
105
+ }
106
+ }
107
+ finally {
108
+ await cleanupBuildCache(buildCache);
109
+ }
110
+ return {
111
+ ...collected,
112
+ results
113
+ };
114
+ }
115
+ async function generateBuildInfoFromSourceProvenance(projectRoot, options = {}) {
116
+ const collected = await collectSourceProvenanceEntries(projectRoot, options);
117
+ const buildCache = new Map();
118
+ const results = [];
119
+ try {
120
+ for (const entry of collected.entries) {
121
+ results.push(await generateBuildInfoForEntry(entry, buildCache, options.force === true));
122
+ }
123
+ }
124
+ finally {
125
+ await cleanupBuildCache(buildCache);
126
+ }
127
+ return {
128
+ ...collected,
129
+ results
130
+ };
131
+ }
132
+ async function verifySourceProvenanceEntry(entry, buildCache) {
133
+ try {
134
+ await assertPathExists(entry.buildInfoPath);
135
+ const buildOutput = await getBuildOutput(entry, buildCache);
136
+ const generated = await selectGeneratedBuildInfo(entry, buildOutput.candidates);
137
+ const comparison = await compareJsonFiles(entry.buildInfoPath, generated);
138
+ if (!comparison.matches) {
139
+ return {
140
+ entry,
141
+ status: 'failed',
142
+ message: `Committed build-info does not match generated ${generated.relativePath}.${comparison.difference ? ` First difference: ${comparison.difference}.` : ''}`,
143
+ generatedBuildInfoPath: generated.filePath
144
+ };
145
+ }
146
+ return {
147
+ entry,
148
+ status: 'verified',
149
+ message: `Matches generated ${generated.relativePath} at ${shortCommit(buildOutput.head)}.`,
150
+ generatedBuildInfoPath: generated.filePath
151
+ };
152
+ }
153
+ catch (error) {
154
+ return {
155
+ entry,
156
+ status: 'failed',
157
+ message: formatError(error)
158
+ };
159
+ }
160
+ }
161
+ async function generateBuildInfoForEntry(entry, buildCache, force) {
162
+ try {
163
+ if (!force && await pathExists(entry.buildInfoPath)) {
164
+ return {
165
+ entry,
166
+ status: 'skipped',
167
+ message: 'Build-info already exists. Use --force to overwrite it.'
168
+ };
169
+ }
170
+ const buildOutput = await getBuildOutput(entry, buildCache);
171
+ const generated = await selectGeneratedBuildInfo(entry, buildOutput.candidates);
172
+ await fs.mkdir(path.dirname(entry.buildInfoPath), { recursive: true });
173
+ await fs.writeFile(entry.buildInfoPath, generated.content);
174
+ return {
175
+ entry,
176
+ status: 'generated',
177
+ message: `Wrote build-info from generated ${generated.relativePath} at ${shortCommit(buildOutput.head)}.`,
178
+ generatedBuildInfoPath: generated.filePath
179
+ };
180
+ }
181
+ catch (error) {
182
+ return {
183
+ entry,
184
+ status: 'failed',
185
+ message: formatError(error)
186
+ };
187
+ }
188
+ }
189
+ async function getBuildOutput(entry, buildCache) {
190
+ const key = buildCacheKey(entry.provenance);
191
+ if (!buildCache.has(key)) {
192
+ buildCache.set(key, buildFromSourceProvenance(entry.provenance));
193
+ }
194
+ return buildCache.get(key);
195
+ }
196
+ async function buildFromSourceProvenance(provenance) {
197
+ if (!provenance.build) {
198
+ throw new Error('source provenance is missing a build command.');
199
+ }
200
+ if (!provenance.commit && !provenance.ref) {
201
+ throw new Error('source provenance must include either commit or ref.');
202
+ }
203
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'catapult-provenance-'));
204
+ const checkoutDir = path.join(tempDir, 'repo');
205
+ try {
206
+ await runGit(['clone', '--', provenance.repo, checkoutDir]);
207
+ if (provenance.ref) {
208
+ const refHead = await gitCommitForRevision(provenance.ref, checkoutDir);
209
+ if (provenance.commit && !commitMatches(refHead, provenance.commit)) {
210
+ throw new Error(`ref "${provenance.ref}" resolves to ${refHead}, not ${provenance.commit}.`);
211
+ }
212
+ await checkoutGitCommit(refHead, checkoutDir);
213
+ }
214
+ else if (provenance.commit) {
215
+ const commitHead = await gitCommitForRevision(provenance.commit, checkoutDir);
216
+ await checkoutGitCommit(commitHead, checkoutDir);
217
+ }
218
+ const head = await gitStdout(['rev-parse', 'HEAD'], checkoutDir);
219
+ await runBuild(provenance.build, checkoutDir, provenance.image);
220
+ const candidates = await findBuildInfoCandidates(checkoutDir);
221
+ if (candidates.length === 0) {
222
+ throw new Error('build command did not produce any build-info JSON files.');
223
+ }
224
+ return {
225
+ tempDir,
226
+ checkoutDir,
227
+ head,
228
+ candidates
229
+ };
230
+ }
231
+ catch (error) {
232
+ await fs.rm(tempDir, { recursive: true, force: true });
233
+ throw error;
234
+ }
235
+ }
236
+ async function cleanupBuildCache(buildCache) {
237
+ const seen = new Set();
238
+ for (const buildOutputPromise of buildCache.values()) {
239
+ try {
240
+ const buildOutput = await buildOutputPromise;
241
+ if (!seen.has(buildOutput.tempDir)) {
242
+ seen.add(buildOutput.tempDir);
243
+ await fs.rm(buildOutput.tempDir, { recursive: true, force: true });
244
+ }
245
+ }
246
+ catch {
247
+ }
248
+ }
249
+ }
250
+ async function findBuildInfoCandidates(root) {
251
+ const files = await findJsonFiles(root);
252
+ const candidates = [];
253
+ for (const filePath of files) {
254
+ if (!(0, buildinfo_1.isBuildInfoFile)(filePath)) {
255
+ continue;
256
+ }
257
+ try {
258
+ const content = await fs.readFile(filePath, 'utf-8');
259
+ const json = JSON.parse(content);
260
+ candidates.push({
261
+ filePath,
262
+ relativePath: path.relative(root, filePath),
263
+ content,
264
+ json,
265
+ id: getJsonId(json)
266
+ });
267
+ }
268
+ catch {
269
+ }
270
+ }
271
+ return candidates;
272
+ }
273
+ async function selectGeneratedBuildInfo(entry, candidates) {
274
+ if (candidates.length === 0) {
275
+ throw new Error('build command did not produce any build-info JSON files.');
276
+ }
277
+ const existingJson = await readJsonIfExists(entry.buildInfoPath);
278
+ const existingId = getJsonId(existingJson);
279
+ const selectionIssues = [];
280
+ if (existingId) {
281
+ const idMatches = candidates.filter(candidate => candidate.id === existingId);
282
+ if (idMatches.length === 1) {
283
+ return idMatches[0];
284
+ }
285
+ if (idMatches.length > 1) {
286
+ selectionIssues.push(`${idMatches.length} candidates share id "${existingId}"`);
287
+ }
288
+ }
289
+ const targetBaseName = path.basename(entry.buildInfoPath);
290
+ const nameMatches = candidates.filter(candidate => path.basename(candidate.filePath) === targetBaseName);
291
+ if (nameMatches.length === 1) {
292
+ return nameMatches[0];
293
+ }
294
+ if (nameMatches.length > 1) {
295
+ selectionIssues.push(`${nameMatches.length} candidates are named "${targetBaseName}"`);
296
+ }
297
+ if (candidates.length === 1) {
298
+ return candidates[0];
299
+ }
300
+ throw new Error(`Generated ${candidates.length} build-info files and could not select one for "${entry.buildInfoRef}". ` +
301
+ `${selectionIssues.length > 0 ? `${selectionIssues.join('; ')}. ` : ''}` +
302
+ `Use a build command that emits one file or names the file "${targetBaseName}".`);
303
+ }
304
+ async function compareJsonFiles(existingPath, generated) {
305
+ const existingRaw = await fs.readFile(existingPath, 'utf-8');
306
+ const existingJson = JSON.parse(existingRaw);
307
+ const normalizedExisting = sortJson(normalizeBuildInfoJson(existingJson));
308
+ const normalizedGenerated = sortJson(normalizeBuildInfoJson(generated.json));
309
+ if (JSON.stringify(normalizedExisting) === JSON.stringify(normalizedGenerated)) {
310
+ return { matches: true };
311
+ }
312
+ return {
313
+ matches: false,
314
+ difference: findFirstJsonDifference(normalizedExisting, normalizedGenerated)
315
+ };
316
+ }
317
+ async function filterEntriesByJobs(projectRoot, entries, options) {
318
+ const loader = new loader_1.ProjectLoader(projectRoot, {
319
+ loadStdTemplates: options.loadStdTemplates,
320
+ loadContracts: false
321
+ });
322
+ await loader.load();
323
+ const graph = new graph_1.DependencyGraph(loader.jobs, loader.templates);
324
+ const selectedJobs = selectJobNames(loader.jobs, graph, options.jobs || [], options.includeDependencies === true);
325
+ const scopeRoots = selectedJobs.flatMap(jobName => {
326
+ const job = loader.jobs.get(jobName);
327
+ return job ? jobScopeRoots(projectRoot, job) : [];
328
+ });
329
+ return entries.filter(entry => scopeRoots.some(root => isPathWithin(root, entry.sourceDocumentPath) || isPathWithin(root, entry.buildInfoPath)));
330
+ }
331
+ function selectJobNames(jobs, graph, patterns, includeDependencies) {
332
+ const allJobNames = Array.from(jobs.keys());
333
+ const requested = new Set();
334
+ for (const pattern of patterns) {
335
+ const matches = isPattern(pattern)
336
+ ? allJobNames.filter(jobName => patternToRegex(pattern).test(jobName))
337
+ : allJobNames.filter(jobName => jobName === pattern);
338
+ if (matches.length === 0) {
339
+ throw new Error(`Job "${pattern}" not found in project.`);
340
+ }
341
+ matches.forEach(match => requested.add(match));
342
+ }
343
+ const selected = new Set(requested);
344
+ if (includeDependencies) {
345
+ for (const jobName of requested) {
346
+ graph.getDependencies(jobName).forEach(dep => selected.add(dep));
347
+ }
348
+ }
349
+ return graph.getExecutionOrder().filter(jobName => selected.has(jobName));
350
+ }
351
+ function jobScopeRoots(projectRoot, job) {
352
+ if (!job._path) {
353
+ return [];
354
+ }
355
+ const jobsRoot = path.resolve(projectRoot, 'jobs');
356
+ const jobPath = path.resolve(job._path);
357
+ const jobDir = path.dirname(jobPath);
358
+ const jobBaseDir = path.join(jobDir, path.basename(jobPath, path.extname(jobPath)));
359
+ if (path.normalize(jobDir) === path.normalize(jobsRoot)) {
360
+ return [jobBaseDir];
361
+ }
362
+ return Array.from(new Set([jobDir, jobBaseDir]));
363
+ }
364
+ async function findSourceFiles(root) {
365
+ const results = [];
366
+ await walk(root, async (filePath, direntName) => {
367
+ if (direntName === 'source.yaml' || direntName === 'source.yml') {
368
+ results.push(filePath);
369
+ }
370
+ });
371
+ return results.sort();
372
+ }
373
+ async function findJsonFiles(root) {
374
+ const results = [];
375
+ await walk(root, async (filePath, direntName) => {
376
+ if (direntName.endsWith('.json')) {
377
+ results.push(filePath);
378
+ }
379
+ });
380
+ return results.sort();
381
+ }
382
+ async function walk(root, onFile) {
383
+ let dirents;
384
+ try {
385
+ dirents = await fs.readdir(root, { withFileTypes: true });
386
+ }
387
+ catch {
388
+ return;
389
+ }
390
+ for (const dirent of dirents) {
391
+ const fullPath = path.resolve(root, dirent.name);
392
+ if (dirent.isDirectory()) {
393
+ if (!IGNORED_DIRS.has(dirent.name)) {
394
+ await walk(fullPath, onFile);
395
+ }
396
+ }
397
+ else if (dirent.isFile()) {
398
+ await onFile(fullPath, dirent.name);
399
+ }
400
+ }
401
+ }
402
+ async function runGit(args, cwd) {
403
+ try {
404
+ await execFileAsync('git', args, { cwd, maxBuffer: COMMAND_MAX_BUFFER });
405
+ }
406
+ catch (error) {
407
+ throw new Error(`git ${args.join(' ')} failed: ${commandErrorMessage(error)}`);
408
+ }
409
+ }
410
+ async function gitStdout(args, cwd) {
411
+ try {
412
+ const result = await execFileAsync('git', args, { cwd, maxBuffer: COMMAND_MAX_BUFFER });
413
+ return String(result.stdout).trim();
414
+ }
415
+ catch (error) {
416
+ throw new Error(`git ${args.join(' ')} failed: ${commandErrorMessage(error)}`);
417
+ }
418
+ }
419
+ async function gitCommitForRevision(revision, cwd) {
420
+ return gitStdout(['rev-parse', '--verify', '--end-of-options', `${revision}^{commit}`], cwd);
421
+ }
422
+ async function checkoutGitCommit(commit, cwd) {
423
+ await runGit(['checkout', '--detach', commit], cwd);
424
+ }
425
+ async function runBuild(command, cwd, image) {
426
+ if (image) {
427
+ await runDockerBuild(command, cwd, image);
428
+ }
429
+ else {
430
+ await runShell(command, cwd);
431
+ }
432
+ }
433
+ const CONTAINER_WORKDIR = '/workspace';
434
+ async function runDockerBuild(command, cwd, image) {
435
+ const args = [
436
+ 'run',
437
+ '--rm',
438
+ '-v',
439
+ `${cwd}:${CONTAINER_WORKDIR}`,
440
+ '-w',
441
+ CONTAINER_WORKDIR,
442
+ '-e',
443
+ `HOME=${CONTAINER_WORKDIR}`
444
+ ];
445
+ const uid = typeof process.getuid === 'function' ? process.getuid() : undefined;
446
+ const gid = typeof process.getgid === 'function' ? process.getgid() : undefined;
447
+ if (uid !== undefined && gid !== undefined) {
448
+ args.push('--user', `${uid}:${gid}`);
449
+ }
450
+ args.push('--entrypoint', 'sh', image, '-c', command);
451
+ await new Promise((resolve, reject) => {
452
+ const child = (0, child_process_1.spawn)('docker', args, {
453
+ cwd,
454
+ env: process.env,
455
+ stdio: 'inherit'
456
+ });
457
+ child.on('error', error => {
458
+ reject(new Error(`failed to start docker for image "${image}" (is Docker installed and running?): ${error.message}`));
459
+ });
460
+ child.on('exit', (code, signal) => {
461
+ if (code === 0) {
462
+ resolve();
463
+ }
464
+ else if (signal) {
465
+ reject(new Error(`build command failed: terminated by ${signal}`));
466
+ }
467
+ else {
468
+ reject(new Error(`build command failed: exited with code ${code}`));
469
+ }
470
+ });
471
+ });
472
+ }
473
+ async function runShell(command, cwd) {
474
+ await new Promise((resolve, reject) => {
475
+ const child = (0, child_process_1.spawn)(command, {
476
+ cwd,
477
+ env: process.env,
478
+ shell: true,
479
+ stdio: 'inherit'
480
+ });
481
+ child.on('error', error => {
482
+ reject(new Error(`build command failed to start: ${error.message}`));
483
+ });
484
+ child.on('exit', (code, signal) => {
485
+ if (code === 0) {
486
+ resolve();
487
+ }
488
+ else if (signal) {
489
+ reject(new Error(`build command failed: terminated by ${signal}`));
490
+ }
491
+ else {
492
+ reject(new Error(`build command failed: exited with code ${code}`));
493
+ }
494
+ });
495
+ });
496
+ }
497
+ async function assertPathExists(filePath) {
498
+ if (!await pathExists(filePath)) {
499
+ throw new Error(`build-info file does not exist: ${filePath}`);
500
+ }
501
+ }
502
+ async function pathExists(filePath) {
503
+ try {
504
+ await fs.access(filePath);
505
+ return true;
506
+ }
507
+ catch {
508
+ return false;
509
+ }
510
+ }
511
+ async function readJsonIfExists(filePath) {
512
+ try {
513
+ const content = await fs.readFile(filePath, 'utf-8');
514
+ return JSON.parse(content);
515
+ }
516
+ catch {
517
+ return undefined;
518
+ }
519
+ }
520
+ function getJsonId(value) {
521
+ if (value && typeof value === 'object' && 'id' in value) {
522
+ const id = value.id;
523
+ return typeof id === 'string' ? id : undefined;
524
+ }
525
+ return undefined;
526
+ }
527
+ function buildCacheKey(provenance) {
528
+ return JSON.stringify({
529
+ repo: provenance.repo,
530
+ ref: provenance.ref,
531
+ commit: provenance.commit,
532
+ build: provenance.build,
533
+ image: provenance.image
534
+ });
535
+ }
536
+ function normalizeBuildInfoJson(value) {
537
+ return normalizeBuildInfoValue(value, [], getBuildInfoBasePath(value));
538
+ }
539
+ function normalizeBuildInfoValue(value, pathSegments, basePath) {
540
+ if (pathSegments.length === 1 && pathSegments[0] === 'id') {
541
+ return BUILD_INFO_ID_PLACEHOLDER;
542
+ }
543
+ if (typeof value === 'string') {
544
+ return normalizeBuildInfoString(value, basePath);
545
+ }
546
+ if (Array.isArray(value)) {
547
+ return value.map((item, index) => normalizeBuildInfoValue(item, [...pathSegments, String(index)], basePath));
548
+ }
549
+ if (value && typeof value === 'object') {
550
+ const objectValue = value;
551
+ return Object.fromEntries(Object.entries(objectValue).map(([key, item]) => [
552
+ normalizeBuildInfoString(key, basePath),
553
+ normalizeBuildInfoValue(item, [...pathSegments, key], basePath)
554
+ ]));
555
+ }
556
+ return value;
557
+ }
558
+ function normalizeBuildInfoString(value, basePath) {
559
+ let normalized = value;
560
+ const basePathPattern = basePath && isAbsolutePath(basePath) ? pathPrefixPattern(basePath) : undefined;
561
+ if (basePathPattern) {
562
+ normalized = normalized.replace(basePathPattern, BUILD_INFO_BASE_PATH_PLACEHOLDER);
563
+ }
564
+ return normalized.replace(CATAPULT_CHECKOUT_PATH_PATTERN, BUILD_INFO_BASE_PATH_PLACEHOLDER);
565
+ }
566
+ function getBuildInfoBasePath(value) {
567
+ if (!value || typeof value !== 'object') {
568
+ return undefined;
569
+ }
570
+ const input = value.input;
571
+ if (!input || typeof input !== 'object') {
572
+ return undefined;
573
+ }
574
+ const basePath = input.basePath;
575
+ return typeof basePath === 'string' && basePath.length > 0 ? basePath : undefined;
576
+ }
577
+ function pathPrefixPattern(value) {
578
+ const hasLeadingSeparator = /^[\\/]/.test(value);
579
+ const trimmed = value.replace(/^[\\/]+/, '').replace(/[\\/]+$/, '');
580
+ const segments = trimmed.split(/[\\/]+/).filter(Boolean);
581
+ if (segments.length === 0) {
582
+ return undefined;
583
+ }
584
+ const source = `${hasLeadingSeparator ? '[/\\\\]+' : ''}${segments.map(escapeRegex).join('[/\\\\]+')}`;
585
+ return new RegExp(`${source}(?=[/\\\\]|$)`, 'g');
586
+ }
587
+ function escapeRegex(value) {
588
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
589
+ }
590
+ function isAbsolutePath(value) {
591
+ return path.posix.isAbsolute(value) || path.win32.isAbsolute(value);
592
+ }
593
+ function findFirstJsonDifference(existing, generated, location = '$') {
594
+ if (Object.is(existing, generated)) {
595
+ return '';
596
+ }
597
+ if (Array.isArray(existing) || Array.isArray(generated)) {
598
+ if (!Array.isArray(existing) || !Array.isArray(generated)) {
599
+ return `${location} type differs: committed ${jsonType(existing)}, generated ${jsonType(generated)}`;
600
+ }
601
+ if (existing.length !== generated.length) {
602
+ return `${location} length differs: committed ${existing.length}, generated ${generated.length}`;
603
+ }
604
+ for (let i = 0; i < existing.length; i++) {
605
+ const difference = findFirstJsonDifference(existing[i], generated[i], `${location}[${i}]`);
606
+ if (difference) {
607
+ return difference;
608
+ }
609
+ }
610
+ return '';
611
+ }
612
+ if (isRecord(existing) || isRecord(generated)) {
613
+ if (!isRecord(existing) || !isRecord(generated)) {
614
+ return `${location} type differs: committed ${jsonType(existing)}, generated ${jsonType(generated)}`;
615
+ }
616
+ const keys = Array.from(new Set([...Object.keys(existing), ...Object.keys(generated)])).sort();
617
+ for (const key of keys) {
618
+ const nextLocation = jsonPath(location, key);
619
+ if (!(key in existing)) {
620
+ return `${nextLocation} is missing from committed build-info`;
621
+ }
622
+ if (!(key in generated)) {
623
+ return `${nextLocation} is missing from generated build-info`;
624
+ }
625
+ const difference = findFirstJsonDifference(existing[key], generated[key], nextLocation);
626
+ if (difference) {
627
+ return difference;
628
+ }
629
+ }
630
+ return '';
631
+ }
632
+ return `${location} differs: committed ${formatJsonScalar(existing)}, generated ${formatJsonScalar(generated)}`;
633
+ }
634
+ function isRecord(value) {
635
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
636
+ }
637
+ function jsonPath(location, key) {
638
+ return /^[A-Za-z_$][\w$]*$/.test(key) ? `${location}.${key}` : `${location}[${JSON.stringify(key)}]`;
639
+ }
640
+ function jsonType(value) {
641
+ if (Array.isArray(value)) {
642
+ return 'array';
643
+ }
644
+ if (value === null) {
645
+ return 'null';
646
+ }
647
+ return typeof value;
648
+ }
649
+ function formatJsonScalar(value) {
650
+ const formatted = JSON.stringify(value);
651
+ return formatted && formatted.length > 120 ? `${formatted.slice(0, 117)}...` : formatted ?? String(value);
652
+ }
653
+ function sortJson(value) {
654
+ if (Array.isArray(value)) {
655
+ return value.map(sortJson);
656
+ }
657
+ if (value && typeof value === 'object') {
658
+ const objectValue = value;
659
+ return Object.fromEntries(Object.keys(objectValue).sort().map(key => [key, sortJson(objectValue[key])]));
660
+ }
661
+ return value;
662
+ }
663
+ function isPathWithin(root, candidate) {
664
+ const relative = path.relative(path.resolve(root), path.resolve(candidate));
665
+ return relative === '' || (!!relative && !relative.startsWith('..') && !path.isAbsolute(relative));
666
+ }
667
+ function isPattern(value) {
668
+ return /[*?]/.test(value);
669
+ }
670
+ function patternToRegex(pattern) {
671
+ const escaped = pattern.replace(/[-\\^$+?.()|[\]{}]/g, '\\$&')
672
+ .replace(/\*/g, '.*')
673
+ .replace(/\?/g, '.');
674
+ return new RegExp(`^${escaped}$`);
675
+ }
676
+ function commitMatches(actual, expected) {
677
+ return actual === expected || actual.startsWith(expected);
678
+ }
679
+ function shortCommit(commit) {
680
+ return commit.slice(0, 12);
681
+ }
682
+ function commandErrorMessage(error) {
683
+ if (error && typeof error === 'object') {
684
+ const maybe = error;
685
+ const stderr = maybe.stderr ? String(maybe.stderr).trim() : '';
686
+ const stdout = maybe.stdout ? String(maybe.stdout).trim() : '';
687
+ return stderr || stdout || maybe.message || String(error);
688
+ }
689
+ return String(error);
690
+ }
691
+ function formatError(error) {
692
+ return error instanceof Error ? error.message : String(error);
693
+ }
694
+ //# sourceMappingURL=provenance.js.map