@0xsequence/catapult 1.4.0 → 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 (163) hide show
  1. package/README.md +27 -0
  2. package/dist/lib/__tests__/network-loader.spec.js.map +1 -1
  3. package/dist/lib/core/__tests__/resolver.spec.js +22 -0
  4. package/dist/lib/core/__tests__/resolver.spec.js.map +1 -1
  5. package/dist/lib/core/__tests__/sign-actions.spec.d.ts +2 -0
  6. package/dist/lib/core/__tests__/sign-actions.spec.d.ts.map +1 -0
  7. package/dist/lib/core/__tests__/sign-actions.spec.js +128 -0
  8. package/dist/lib/core/__tests__/sign-actions.spec.js.map +1 -0
  9. package/dist/lib/core/__tests__/signer.spec.d.ts +2 -0
  10. package/dist/lib/core/__tests__/signer.spec.d.ts.map +1 -0
  11. package/dist/lib/core/__tests__/signer.spec.js +40 -0
  12. package/dist/lib/core/__tests__/signer.spec.js.map +1 -0
  13. package/dist/lib/core/context.d.ts +3 -2
  14. package/dist/lib/core/context.d.ts.map +1 -1
  15. package/dist/lib/core/context.js +3 -2
  16. package/dist/lib/core/context.js.map +1 -1
  17. package/dist/lib/core/engine.d.ts +4 -0
  18. package/dist/lib/core/engine.d.ts.map +1 -1
  19. package/dist/lib/core/engine.js +173 -0
  20. package/dist/lib/core/engine.js.map +1 -1
  21. package/dist/lib/core/signer.d.ts +7 -0
  22. package/dist/lib/core/signer.d.ts.map +1 -0
  23. package/dist/lib/core/signer.js +60 -0
  24. package/dist/lib/core/signer.js.map +1 -0
  25. package/dist/lib/parsers/__tests__/source.spec.js +37 -0
  26. package/dist/lib/parsers/__tests__/source.spec.js.map +1 -1
  27. package/dist/lib/parsers/source.js +1 -1
  28. package/dist/lib/parsers/source.js.map +1 -1
  29. package/dist/lib/provenance.js +51 -2
  30. package/dist/lib/provenance.js.map +1 -1
  31. package/dist/lib/types/actions.d.ts +26 -2
  32. package/dist/lib/types/actions.d.ts.map +1 -1
  33. package/dist/lib/types/actions.js +3 -0
  34. package/dist/lib/types/actions.js.map +1 -1
  35. package/dist/lib/types/source.d.ts +2 -0
  36. package/dist/lib/types/source.d.ts.map +1 -1
  37. package/package.json +4 -1
  38. package/.eslintrc.json +0 -29
  39. package/.github/workflows/ci.yml +0 -181
  40. package/CONCEPT.md +0 -24
  41. package/contracts/checked-call.huff +0 -65
  42. package/eslint.config.js +0 -48
  43. package/examples/jobs/guards-v1.yaml +0 -17
  44. package/examples/jobs/sequence-seq-0001-patch.yaml +0 -59
  45. package/examples/jobs/sequence-v1.yaml +0 -59
  46. package/examples/templates/sequence-factory-v1.yaml +0 -56
  47. package/jest.config.js +0 -25
  48. package/src/cli.ts +0 -18
  49. package/src/commands/common.ts +0 -61
  50. package/src/commands/dry.ts +0 -209
  51. package/src/commands/etherscan.ts +0 -360
  52. package/src/commands/index.ts +0 -6
  53. package/src/commands/list.ts +0 -262
  54. package/src/commands/provenance.ts +0 -120
  55. package/src/commands/run.ts +0 -146
  56. package/src/commands/utils.ts +0 -215
  57. package/src/index.ts +0 -67
  58. package/src/lib/__tests__/deployer-events.spec.ts +0 -338
  59. package/src/lib/__tests__/deployer.spec.ts +0 -2269
  60. package/src/lib/__tests__/network-loader.spec.ts +0 -150
  61. package/src/lib/__tests__/network-selection.spec.ts +0 -41
  62. package/src/lib/__tests__/network-utils.spec.ts +0 -230
  63. package/src/lib/__tests__/provenance.spec.ts +0 -208
  64. package/src/lib/artifacts/__tests__/fixtures/contract1.json +0 -19
  65. package/src/lib/artifacts/__tests__/fixtures/contract2.json +0 -19
  66. package/src/lib/artifacts/__tests__/fixtures/duplicate-name.json +0 -19
  67. package/src/lib/artifacts/__tests__/fixtures/nested/nested-contract.json +0 -18
  68. package/src/lib/artifacts/__tests__/fixtures/not-an-artifact.json +0 -8
  69. package/src/lib/artifacts/__tests__/fixtures/readme.txt +0 -2
  70. package/src/lib/contracts/__tests__/repository.spec.ts +0 -612
  71. package/src/lib/contracts/repository.ts +0 -411
  72. package/src/lib/core/__tests__/assert-action.spec.ts +0 -474
  73. package/src/lib/core/__tests__/context.spec.ts +0 -37
  74. package/src/lib/core/__tests__/engine.spec.ts +0 -2005
  75. package/src/lib/core/__tests__/graph.spec.ts +0 -125
  76. package/src/lib/core/__tests__/json-integration.spec.ts +0 -425
  77. package/src/lib/core/__tests__/loader.spec.ts +0 -367
  78. package/src/lib/core/__tests__/multi-platform-verification.spec.ts +0 -406
  79. package/src/lib/core/__tests__/resolver.spec.ts +0 -2496
  80. package/src/lib/core/__tests__/static-action.spec.ts +0 -172
  81. package/src/lib/core/context.ts +0 -127
  82. package/src/lib/core/engine.ts +0 -1834
  83. package/src/lib/core/graph.ts +0 -252
  84. package/src/lib/core/loader.ts +0 -253
  85. package/src/lib/core/resolver.ts +0 -873
  86. package/src/lib/deployer.ts +0 -1005
  87. package/src/lib/events/__tests__/event-system.spec.ts +0 -392
  88. package/src/lib/events/cli-adapter.ts +0 -369
  89. package/src/lib/events/emitter.ts +0 -62
  90. package/src/lib/events/index.ts +0 -3
  91. package/src/lib/events/types.ts +0 -520
  92. package/src/lib/index.ts +0 -17
  93. package/src/lib/network-loader.ts +0 -90
  94. package/src/lib/network-selection.ts +0 -73
  95. package/src/lib/network-utils.ts +0 -64
  96. package/src/lib/parsers/__tests__/buildinfo.spec.ts +0 -122
  97. package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-bytecode-buildinfo.json +0 -62
  98. package/src/lib/parsers/__tests__/fixtures/buildinfo/invalid-json.txt +0 -2
  99. package/src/lib/parsers/__tests__/fixtures/buildinfo/multi-contract-buildinfo.json +0 -89
  100. package/src/lib/parsers/__tests__/fixtures/buildinfo/no-contracts-buildinfo.json +0 -17
  101. package/src/lib/parsers/__tests__/fixtures/buildinfo/simple-buildinfo.json +0 -63
  102. package/src/lib/parsers/__tests__/fixtures/buildinfo/wrong-format.json +0 -4
  103. package/src/lib/parsers/__tests__/job.spec.ts +0 -439
  104. package/src/lib/parsers/__tests__/source.spec.ts +0 -134
  105. package/src/lib/parsers/__tests__/template.spec.ts +0 -111
  106. package/src/lib/parsers/artifact/__tests__/artifact.spec.ts +0 -117
  107. package/src/lib/parsers/artifact/__tests__/fixtures/empty-bytecode.json +0 -5
  108. package/src/lib/parsers/artifact/__tests__/fixtures/hardhat-artifact.json +0 -67
  109. package/src/lib/parsers/artifact/__tests__/fixtures/invalid-bytecode.json +0 -5
  110. package/src/lib/parsers/artifact/__tests__/fixtures/invalid-json.txt +0 -11
  111. package/src/lib/parsers/artifact/__tests__/fixtures/minimal-artifact.json +0 -5
  112. package/src/lib/parsers/artifact/__tests__/fixtures/missing-abi.json +0 -4
  113. package/src/lib/parsers/artifact/__tests__/fixtures/missing-bytecode.json +0 -11
  114. package/src/lib/parsers/artifact/__tests__/fixtures/missing-contract-name.json +0 -11
  115. package/src/lib/parsers/artifact/__tests__/fixtures/simple-artifact.json +0 -40
  116. package/src/lib/parsers/artifact/__tests__/fixtures/wrong-types.json +0 -7
  117. package/src/lib/parsers/artifact/foundry-1.2.ts +0 -72
  118. package/src/lib/parsers/artifact/index.ts +0 -27
  119. package/src/lib/parsers/artifact/types.ts +0 -9
  120. package/src/lib/parsers/buildinfo.ts +0 -127
  121. package/src/lib/parsers/constants.ts +0 -56
  122. package/src/lib/parsers/index.ts +0 -6
  123. package/src/lib/parsers/job.ts +0 -160
  124. package/src/lib/parsers/source.ts +0 -129
  125. package/src/lib/parsers/template.ts +0 -135
  126. package/src/lib/provenance.ts +0 -785
  127. package/src/lib/std/templates/arachnid-deterministic-deployment-proxy.yaml +0 -68
  128. package/src/lib/std/templates/assured-deployment.yaml +0 -46
  129. package/src/lib/std/templates/era-evm-predeploy.yaml +0 -35
  130. package/src/lib/std/templates/erc-2470.yaml +0 -70
  131. package/src/lib/std/templates/min-balance.yaml +0 -35
  132. package/src/lib/std/templates/nano-universal-deployer.yaml +0 -61
  133. package/src/lib/std/templates/raw-erc-2470.yaml +0 -62
  134. package/src/lib/std/templates/raw-nano-universal-deployer.yaml +0 -54
  135. package/src/lib/std/templates/raw-sequence-universal-deployer-2.yaml +0 -52
  136. package/src/lib/std/templates/sequence-universal-deployer-2.yaml +0 -61
  137. package/src/lib/types/__tests__/json-request-action.spec.ts +0 -243
  138. package/src/lib/types/__tests__/read-json-value.spec.ts +0 -278
  139. package/src/lib/types/__tests__/resolve-json-value.spec.ts +0 -769
  140. package/src/lib/types/actions.ts +0 -148
  141. package/src/lib/types/artifacts.ts +0 -21
  142. package/src/lib/types/buildinfo.ts +0 -116
  143. package/src/lib/types/conditions.ts +0 -50
  144. package/src/lib/types/contracts.ts +0 -26
  145. package/src/lib/types/definitions.ts +0 -77
  146. package/src/lib/types/index.ts +0 -9
  147. package/src/lib/types/network.ts +0 -33
  148. package/src/lib/types/project.ts +0 -9
  149. package/src/lib/types/source.ts +0 -26
  150. package/src/lib/types/task.ts +0 -9
  151. package/src/lib/types/values.ts +0 -221
  152. package/src/lib/utils/assertion.ts +0 -24
  153. package/src/lib/utils/validation.ts +0 -116
  154. package/src/lib/validation/contract-references.ts +0 -210
  155. package/src/lib/validation/index.ts +0 -1
  156. package/src/lib/verification/__tests__/etherscan.spec.ts +0 -710
  157. package/src/lib/verification/__tests__/sourcify.spec.ts +0 -288
  158. package/src/lib/verification/etherscan.ts +0 -547
  159. package/src/lib/verification/sourcify.ts +0 -248
  160. package/test_validation/artifacts/TestContract.json +0 -9
  161. package/test_validation/jobs/test-missing.yaml +0 -16
  162. package/test_validation/networks.yaml +0 -3
  163. package/tsconfig.json +0 -36
@@ -1,411 +0,0 @@
1
- import * as fs from 'fs/promises'
2
- import * as path from 'path'
3
- import { createHash } from 'crypto'
4
- import { Contract } from '../types/contracts'
5
- import { BuildInfoSourceProvenance, SourceProvenance } from '../types/source'
6
- import { parseArtifact } from '../parsers/artifact'
7
- import { parseBuildInfo, isBuildInfoFile } from '../parsers/buildinfo'
8
- import { mergeSourceProvenance, parseSourceDocument } from '../parsers/source'
9
-
10
- export class ContractRepository {
11
- private contracts: Map<string, Contract> = new Map()
12
- private referenceMap: Map<string, string[]> = new Map()
13
- private ambiguousReferences: Set<string> = new Set()
14
- private sourceProvenanceByBuildInfoPath: Map<string, BuildInfoSourceProvenance> = new Map()
15
-
16
- /**
17
- * Main entry point that orchestrates the discovery and hydration process
18
- */
19
- public async loadFrom(projectRoot: string): Promise<void> {
20
- const files = await this.findProjectFiles(projectRoot)
21
-
22
- await this.loadSourceProvenanceFiles(files.sourceFiles)
23
-
24
- for (const filePath of files.contractFiles) {
25
- try {
26
- const content = await fs.readFile(filePath, 'utf-8')
27
- await this.parseAndHydrateFromFile(content, filePath)
28
- } catch (error) {
29
- // Silently ignore files that can't be read or parsed
30
- }
31
- }
32
-
33
- this.disambiguateReferences()
34
- }
35
-
36
- /**
37
- * Parse a file as both artifact and build-info, then hydrate contracts
38
- */
39
- private async parseAndHydrateFromFile(content: string, filePath: string): Promise<void> {
40
- // Try parsing as build-info file first
41
- if (isBuildInfoFile(filePath)) {
42
- const extractedContracts = parseBuildInfo(content, filePath)
43
- if (extractedContracts) {
44
- for (const extracted of extractedContracts) {
45
- const sourceProvenance = this.getSourceProvenance(filePath, extracted.fullyQualifiedName)
46
- this.hydrateContract({
47
- creationCode: extracted.bytecode,
48
- runtimeBytecode: extracted.deployedBytecode,
49
- abi: extracted.abi,
50
- sourceName: extracted.sourceName,
51
- contractName: extracted.contractName,
52
- source: extracted.source,
53
- compiler: extracted.compiler,
54
- buildInfoId: extracted.buildInfoId,
55
- sourceProvenance,
56
- }, filePath)
57
- }
58
- return
59
- }
60
- }
61
-
62
- // Try parsing as regular artifact
63
- const parsed = parseArtifact(content, filePath)
64
- if (parsed) {
65
- this.hydrateContract({
66
- creationCode: parsed.bytecode,
67
- runtimeBytecode: parsed.deployedBytecode,
68
- abi: parsed.abi,
69
- sourceName: parsed.sourceName,
70
- contractName: parsed.contractName,
71
- source: parsed.source,
72
- compiler: parsed.compiler,
73
- }, filePath)
74
- }
75
- }
76
-
77
- /**
78
- * Hydrates a contract object with data from a source file
79
- */
80
- private hydrateContract(data: {
81
- creationCode: string
82
- runtimeBytecode?: string
83
- abi?: any[]
84
- sourceName?: string
85
- contractName?: string
86
- source?: string
87
- compiler?: any
88
- buildInfoId?: string
89
- sourceProvenance?: SourceProvenance
90
- }, sourceFilePath: string): void {
91
- // Validate that we have creation code for hashing (but allow empty string)
92
- if (data.creationCode === null || data.creationCode === undefined) {
93
- throw new Error(`Cannot hydrate contract from ${sourceFilePath}: missing creation code`)
94
- }
95
-
96
- // Calculate unique hash based on creation code
97
- const uniqueHash = createHash('sha256').update(data.creationCode).digest('hex')
98
-
99
- // Get existing contract or create new one
100
- let contract = this.contracts.get(uniqueHash)
101
- if (!contract) {
102
- contract = {
103
- uniqueHash,
104
- creationCode: data.creationCode,
105
- _sources: new Set<string>(),
106
- _sourceProvenance: new Map<string, SourceProvenance>()
107
- }
108
- this.contracts.set(uniqueHash, contract)
109
- }
110
-
111
- // Add source file to tracking
112
- contract._sources.add(sourceFilePath)
113
-
114
- // Hydrate with new information - prefer more complete information
115
- // For build-info sources, prefer their data over artifact data
116
- const isFromBuildInfo = sourceFilePath.includes('/build-info/')
117
-
118
- if (data.runtimeBytecode && (!contract.runtimeBytecode || isFromBuildInfo)) {
119
- contract.runtimeBytecode = data.runtimeBytecode
120
- }
121
- if (data.abi && (!contract.abi || contract.abi.length === 0 || isFromBuildInfo)) {
122
- contract.abi = data.abi
123
- }
124
- if (data.sourceName && (!contract.sourceName || isFromBuildInfo)) {
125
- contract.sourceName = data.sourceName
126
- }
127
- if (data.contractName && (!contract.contractName || isFromBuildInfo)) {
128
- contract.contractName = data.contractName
129
- }
130
- if (data.source && (!contract.source || isFromBuildInfo)) {
131
- contract.source = data.source
132
- }
133
- if (data.compiler && (!contract.compiler || isFromBuildInfo)) {
134
- contract.compiler = data.compiler
135
- }
136
- if (data.buildInfoId && !contract.buildInfoId) {
137
- contract.buildInfoId = data.buildInfoId
138
- }
139
- if (data.sourceProvenance) {
140
- if (!contract._sourceProvenance) {
141
- contract._sourceProvenance = new Map<string, SourceProvenance>()
142
- }
143
- contract._sourceProvenance.set(sourceFilePath, data.sourceProvenance)
144
-
145
- contract.sourceProvenance = this.selectPreferredSourceProvenance(contract._sourceProvenance)
146
- }
147
- }
148
-
149
- private getSourceProvenance(buildInfoPath: string, fullyQualifiedName: string): SourceProvenance | undefined {
150
- const provenance = this.sourceProvenanceByBuildInfoPath.get(buildInfoPath)
151
- if (!provenance) {
152
- return undefined
153
- }
154
-
155
- return mergeSourceProvenance(provenance, provenance.contracts?.[fullyQualifiedName])
156
- }
157
-
158
- private selectPreferredSourceProvenance(sourceProvenance: Map<string, SourceProvenance>): SourceProvenance | undefined {
159
- const firstEntry = Array.from(sourceProvenance.entries()).sort(([a], [b]) => a.localeCompare(b))[0]
160
- return firstEntry?.[1]
161
- }
162
-
163
- /**
164
- * Builds reference maps and identifies ambiguous references
165
- */
166
- public disambiguateReferences(): void {
167
- this.referenceMap.clear()
168
- this.ambiguousReferences.clear()
169
-
170
- // Build reference map
171
- for (const contract of this.contracts.values()) {
172
- const references: string[] = []
173
-
174
- // Add contract name reference
175
- if (contract.contractName) {
176
- references.push(contract.contractName)
177
- }
178
-
179
- // Add sourceName:contractName reference
180
- if (contract.sourceName && contract.contractName) {
181
- references.push(`${contract.sourceName}:${contract.contractName}`)
182
- }
183
-
184
- // Add file paths from sources (excluding build-info files since they can contain multiple contracts)
185
- for (const sourcePath of contract._sources) {
186
- // Skip build-info files as they legitimately contain multiple contracts
187
- if (!isBuildInfoFile(sourcePath)) {
188
- references.push(sourcePath)
189
-
190
- // Add relative paths (both forward and backward variants)
191
- const relativePath = path.relative(process.cwd(), sourcePath)
192
- if (relativePath !== sourcePath) {
193
- references.push(relativePath)
194
- }
195
- }
196
- }
197
-
198
- // For each reference, add the contract's uniqueHash to the reference map
199
- for (const ref of references) {
200
- if (!this.referenceMap.has(ref)) {
201
- this.referenceMap.set(ref, [])
202
- }
203
- if (!this.referenceMap.get(ref)!.includes(contract.uniqueHash)) {
204
- this.referenceMap.get(ref)!.push(contract.uniqueHash)
205
- }
206
- }
207
- }
208
-
209
- // Identify ambiguous references
210
- for (const [reference, hashes] of this.referenceMap.entries()) {
211
- if (hashes.length > 1) {
212
- this.ambiguousReferences.add(reference)
213
- }
214
- }
215
- }
216
-
217
- /**
218
- * Lookup a contract by reference
219
- * @param reference The contract reference string
220
- * @param contextPath Optional file path context for resolving relative paths
221
- */
222
- public lookup(reference: string, contextPath?: string): Contract | null {
223
- let resolvedReference = reference
224
-
225
- // Handle relative path resolution if contextPath is provided
226
- if (contextPath && (reference.startsWith('./') || reference.startsWith('../'))) {
227
- resolvedReference = path.resolve(path.dirname(contextPath), reference)
228
- }
229
-
230
- // Handle build-info file:contract references (e.g., "./build-info/file.json:ContractName")
231
- if (resolvedReference.includes(':')) {
232
- const colonIndex = resolvedReference.lastIndexOf(':')
233
- const filePath = resolvedReference.substring(0, colonIndex)
234
- const contractName = resolvedReference.substring(colonIndex + 1)
235
-
236
- // Check if this looks like a build-info file reference
237
- if (isBuildInfoFile(filePath)) {
238
- // Find contract that came from this specific file with this specific contract name
239
- for (const contract of this.contracts.values()) {
240
- if (contract.contractName === contractName && contract._sources.has(filePath)) {
241
- return contract
242
- }
243
- }
244
- // If not found, return null (will be handled by the error in resolver)
245
- return null
246
- }
247
- }
248
-
249
- // Check if reference is ambiguous
250
- if (this.ambiguousReferences.has(resolvedReference)) {
251
- const hashes = this.referenceMap.get(resolvedReference) || []
252
- const conflictingSources = hashes.map(hash => {
253
- const contract = this.contracts.get(hash)
254
- return contract ? Array.from(contract._sources).join(', ') : 'unknown'
255
- })
256
- throw new Error(`Ambiguous contract reference "${resolvedReference}". Found in multiple contracts: ${conflictingSources.join(' | ')}`)
257
- }
258
-
259
- // Check if it's a direct unique hash
260
- if (this.contracts.has(resolvedReference)) {
261
- return this.contracts.get(resolvedReference)!
262
- }
263
-
264
- // Look up in reference map
265
- const hashes = this.referenceMap.get(resolvedReference)
266
- if (hashes && hashes.length === 1) {
267
- return this.contracts.get(hashes[0]) || null
268
- }
269
-
270
- return null
271
- }
272
-
273
- /**
274
- * Get all contracts in the repository
275
- */
276
- public getAll(): Contract[] {
277
- return Array.from(this.contracts.values())
278
- }
279
-
280
- /**
281
- * Get all ambiguous references
282
- */
283
- public getAmbiguousReferences(): string[] {
284
- return Array.from(this.ambiguousReferences)
285
- }
286
-
287
- /**
288
- * Add a contract directly to the repository (for testing purposes)
289
- * @param contractData - Contract data in the old Artifact format for compatibility
290
- */
291
- public addForTesting(contractData: {
292
- contractName: string
293
- abi: any[]
294
- bytecode: string
295
- deployedBytecode?: string
296
- sourceName?: string
297
- source?: string
298
- compiler?: any
299
- buildInfoId?: string
300
- sourceProvenance?: SourceProvenance
301
- _path: string
302
- _hash: string
303
- }): void {
304
- this.hydrateContract({
305
- creationCode: contractData.bytecode,
306
- runtimeBytecode: contractData.deployedBytecode,
307
- abi: contractData.abi,
308
- sourceName: contractData.sourceName,
309
- contractName: contractData.contractName,
310
- source: contractData.source,
311
- compiler: contractData.compiler,
312
- buildInfoId: contractData.buildInfoId,
313
- sourceProvenance: contractData.sourceProvenance,
314
- }, contractData._path)
315
-
316
- // For testing, immediately disambiguate references after adding
317
- this.disambiguateReferences()
318
- }
319
-
320
- private async findProjectFiles(
321
- dir: string,
322
- ignoreDirs: Set<string> = new Set(['node_modules', 'dist', '.git', '.idea', '.vscode'])
323
- ): Promise<{ contractFiles: string[]; sourceFiles: string[] }> {
324
- const results: { contractFiles: string[]; sourceFiles: string[] } = {
325
- contractFiles: [],
326
- sourceFiles: []
327
- }
328
- try {
329
- const list = await fs.readdir(dir, { withFileTypes: true })
330
-
331
- for (const dirent of list) {
332
- const fullPath = path.resolve(dir, dirent.name)
333
- if (dirent.isDirectory()) {
334
- if (!ignoreDirs.has(dirent.name)) {
335
- const childResults = await this.findProjectFiles(fullPath, ignoreDirs)
336
- results.contractFiles.push(...childResults.contractFiles)
337
- results.sourceFiles.push(...childResults.sourceFiles)
338
- }
339
- } else if (dirent.isFile() && dirent.name.endsWith('.json')) {
340
- results.contractFiles.push(fullPath)
341
- } else if (dirent.isFile() && (dirent.name === 'source.yaml' || dirent.name === 'source.yml')) {
342
- results.sourceFiles.push(fullPath)
343
- }
344
- }
345
- } catch (err) {
346
- // Ignore errors from trying to read directories we don't have access to
347
- }
348
- return results
349
- }
350
-
351
- private async loadSourceProvenanceFiles(sourceFiles: string[]): Promise<void> {
352
- this.sourceProvenanceByBuildInfoPath.clear()
353
-
354
- for (const sourceFilePath of sourceFiles) {
355
- let sourceDocument
356
- try {
357
- const content = await fs.readFile(sourceFilePath, 'utf-8')
358
- sourceDocument = parseSourceDocument(content)
359
- } catch (error) {
360
- this.warnSourceProvenance(`Skipping source provenance file ${sourceFilePath}: ${error instanceof Error ? error.message : String(error)}`)
361
- continue
362
- }
363
-
364
- if (!sourceDocument) {
365
- continue
366
- }
367
-
368
- for (const warning of sourceDocument.warnings || []) {
369
- this.warnSourceProvenance(`Skipping source provenance entry ${sourceFilePath}: ${warning}`)
370
- }
371
-
372
- const sourceDir = path.dirname(sourceFilePath)
373
- for (const [buildInfoRef, provenance] of Object.entries(sourceDocument.build_info)) {
374
- const buildInfoPath = path.resolve(sourceDir, buildInfoRef)
375
- if (!isBuildInfoFile(buildInfoPath)) {
376
- this.warnSourceProvenance(`Skipping source provenance entry ${sourceFilePath}: "${buildInfoRef}" does not point to a build-info JSON file.`)
377
- continue
378
- }
379
-
380
- if (!await this.pathExists(buildInfoPath)) {
381
- this.warnSourceProvenance(`Skipping source provenance entry ${sourceFilePath}: build-info file "${buildInfoRef}" does not exist.`)
382
- continue
383
- }
384
-
385
- if (this.sourceProvenanceByBuildInfoPath.has(buildInfoPath)) {
386
- this.warnSourceProvenance(`Skipping source provenance entry ${sourceFilePath}: duplicate provenance for build-info file "${buildInfoRef}".`)
387
- continue
388
- }
389
-
390
- this.sourceProvenanceByBuildInfoPath.set(buildInfoPath, {
391
- ...provenance,
392
- sourceDocumentPath: sourceFilePath,
393
- buildInfoPath
394
- })
395
- }
396
- }
397
- }
398
-
399
- private async pathExists(filePath: string): Promise<boolean> {
400
- try {
401
- await fs.access(filePath)
402
- return true
403
- } catch {
404
- return false
405
- }
406
- }
407
-
408
- private warnSourceProvenance(message: string): void {
409
- console.warn(message)
410
- }
411
- }