@layerzerolabs/evm-sdks-build 3.0.14 → 3.0.16
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.
- package/CHANGELOG.md +12 -0
- package/README.md +107 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +18 -5
- package/dist/index.d.ts +18 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# @layerzerolabs/evm-sdks-build
|
|
2
|
+
|
|
3
|
+
The EVM SDKs Build Tools package provides a set of utilities and tools for building and managing EVM-based SDKs. It includes functions for copying files, populating directories, and managing concurrency with semaphores.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **File Management**: Copy files from source packages to target directories.
|
|
8
|
+
- **Directory Population**: Populate directories with specified files.
|
|
9
|
+
- **Concurrency Control**: Manage concurrent operations with semaphores.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
To install the EVM SDKs Build Tools package, you can use npm or yarn:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install @layerzerolabs/evm-sdks-build
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
or
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
yarn add @layerzerolabs/evm-sdks-build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### File Management
|
|
28
|
+
|
|
29
|
+
Asynchronously copies files from source packages to a target root directory based on the provided directory structure.
|
|
30
|
+
|
|
31
|
+
- packageFiles: An object mapping package names to their directory structures.
|
|
32
|
+
- callerRootFile: The absolute path to the root file of the caller.
|
|
33
|
+
- Returns: A promise that resolves when the operation is complete.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { copyPackageFiles, PackageFiles } from "@layerzerolabs/evm-sdks-build";
|
|
37
|
+
|
|
38
|
+
const packageFiles: PackageFiles = {
|
|
39
|
+
"@layerzerolabs/package1": ["file1.js", "file2.js"],
|
|
40
|
+
"@layerzerolabs/package2": {
|
|
41
|
+
dir1: ["file3.js"],
|
|
42
|
+
dir2: ["file4.js", "file5.js"],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const callerRootFile = __filename;
|
|
47
|
+
|
|
48
|
+
copyPackageFiles(packageFiles, callerRootFile).then(() => {
|
|
49
|
+
console.log("Files copied successfully.");
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Directory Population
|
|
54
|
+
|
|
55
|
+
Populates the target directory with files from the specified source packages.
|
|
56
|
+
|
|
57
|
+
- copyTargets: An object mapping source packages to their respective file patterns.
|
|
58
|
+
- callerRootFile: The absolute path to the root file of the caller.
|
|
59
|
+
- Returns: A promise that resolves when the operation is complete.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { populate, CopyTargets } from "@layerzerolabs/evm-sdks-build";
|
|
63
|
+
|
|
64
|
+
const copyTargets: CopyTargets = {
|
|
65
|
+
"@layerzerolabs/package1": {
|
|
66
|
+
artifacts: ["**/*.json"],
|
|
67
|
+
deployments: ["**/*.json"],
|
|
68
|
+
},
|
|
69
|
+
"@layerzerolabs/package2": {
|
|
70
|
+
"artifacts-tron": ["**/*.json"],
|
|
71
|
+
"artifacts-zk": ["**/*.json"],
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const callerRootFile = __filename;
|
|
76
|
+
|
|
77
|
+
populate(copyTargets, callerRootFile).then(() => {
|
|
78
|
+
console.log("Directories populated successfully.");
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Concurrency Control
|
|
83
|
+
|
|
84
|
+
Semaphore for controlling access to a resource by multiple processes.
|
|
85
|
+
|
|
86
|
+
- constructor(max: number): Initializes the semaphore with a maximum number of concurrent locks.
|
|
87
|
+
- acquire(): Acquires a lock on the semaphore.
|
|
88
|
+
- release(): Releases a lock on the semaphore.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { Semaphore } from '@layerzerolabs/evm-sdks-build'
|
|
92
|
+
|
|
93
|
+
const semaphore = new Semaphore(3)
|
|
94
|
+
|
|
95
|
+
async function task(id: number) {
|
|
96
|
+
await semaphore.acquire()
|
|
97
|
+
console.log(`Task ${id} acquired semaphore.`)
|
|
98
|
+
// Simulate async work
|
|
99
|
+
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|
100
|
+
console.log(`Task ${id} releasing semaphore.`)
|
|
101
|
+
semaphore.release()
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
for (let i = 1 i <= 5 i++) {
|
|
105
|
+
task(i)
|
|
106
|
+
}
|
|
107
|
+
```
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/populate.ts","../src/errors.ts","../src/semaphore.ts","../src/copyFiles.ts"],"names":["mkdir","path","copyFile","createRequire","glob"],"mappings":"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","sourcesContent":["import { copyFile, mkdir } from 'fs/promises'\nimport { createRequire } from 'module'\nimport path from 'path'\n\nimport { glob } from 'glob'\n\ntype AllowedFiles = 'artifacts' | 'deployments' | 'artifacts-tron' | 'artifacts-zk'\n\nexport type SrcFiles = { [key in AllowedFiles]?: readonly string[] }\nexport interface CopyTargets {\n [key: string]: SrcFiles\n}\n\nexport async function populate(copyTargets: CopyTargets, callerRootFile: string): Promise<void> {\n const callerRootDir = path.dirname(callerRootFile)\n for (const [srcPackage, srcFiles] of Object.entries(copyTargets)) {\n const srcDir = path.dirname(createRequire(callerRootFile).resolve(`${srcPackage}/package.json`))\n for (const [filePath, patterns] of Object.entries(srcFiles)) {\n const files = await glob(patterns.map((p) => path.join(srcDir, filePath, p)))\n let count = 0\n for (const file of files) {\n const relativePath = path.relative(srcDir, file)\n const destPath = path.join(callerRootDir, relativePath)\n await mkdir(path.dirname(destPath), { recursive: true })\n await copyFile(file, destPath)\n count++\n }\n console.log(`Copied ${count} ${filePath} from ${srcPackage}`)\n }\n }\n}\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises'\nimport path from 'path'\n\nimport { utils } from 'ethers'\n\nimport { Semaphore } from './semaphore'\n\nconst { ErrorFragment, FormatTypes, Interface } = utils\n\n/**\n * Asynchronously reads a JSON file from a given file path.\n * @param filePath - The path to the JSON file.\n * @returns A promise that resolves to the parsed JSON data.\n */\nasync function readJSONFile(filePath: string): Promise<any> {\n const data = await readFile(filePath, { encoding: 'utf8' })\n return JSON.parse(data)\n}\n\n/**\n * Processes ABI errors in parallel, controlled by a semaphore, and populates error collections.\n * @param filePath - The file path to read.\n * @param semaphore - Semaphore instance for concurrency control.\n * @param errors - Object to collect full errors and error selectors.\n */\nasync function parallelProcess(\n filePath: string,\n semaphore: Semaphore,\n errors: { full: Set<string>; selector: { [key: string]: string } }\n): Promise<void> {\n await semaphore.acquire()\n try {\n const { abi } = await readJSONFile(filePath)\n if (abi === undefined || !Array.isArray(abi)) return\n abi.filter(({ type }) => type === 'error').forEach((obj) => {\n const frag = ErrorFragment.from(obj)\n errors.full.add(frag.format(FormatTypes.full))\n errors.selector[Interface.getSighash(frag)] = frag.format(FormatTypes.sighash)\n })\n } finally {\n semaphore.release()\n }\n}\n\n/**\n * Populates error information from ABI files in parallel.\n * @param callerRootFile - The root file path to start the search for ABI files.\n * @param destPath - The path relative to root to copy the files in.\n * @param maxConcurrent - Maximum number of concurrent file processing operations.\n */\nexport async function populateErrors(\n callerRootFile: string,\n destPath = 'src/errors',\n maxConcurrent = 50\n): Promise<void> {\n // Determining the directory paths from the caller's root file\n const callerRootDir = path.dirname(callerRootFile)\n const callerArtifactsPath = path.join(callerRootDir, 'artifacts')\n\n // Reading and filtering artifacts to process only JSON files\n const files = await readdir(callerArtifactsPath, { recursive: true })\n const jsonFiles = files.filter((file) => path.extname(file).toLowerCase() === '.json')\n\n const semaphore = new Semaphore(maxConcurrent)\n const errors = { full: new Set<string>(), selector: {} }\n\n // Parallel processing of files using the semaphore for concurrency control\n const filePromises = jsonFiles.map(async (file) =>\n parallelProcess(path.join(callerArtifactsPath, file), semaphore, errors)\n )\n await Promise.all(filePromises)\n\n // Sorting and organizing errors for output\n const { full, selector } = errors\n let sorter = new Intl.Collator('en', { caseFirst: 'upper', numeric: true })\n const sortedErrors = [...full].sort(sorter.compare)\n sorter = new Intl.Collator('en', { caseFirst: 'upper', numeric: false })\n const sortedSelectors = Object.fromEntries(Object.entries(selector).sort(([a], [b]) => sorter.compare(a, b)))\n const errorDir = path.join(callerRootDir, destPath)\n // Writing errors to files in the error directory\n await mkdir(errorDir, { recursive: true })\n await writeFile(path.join(errorDir, 'errors.json'), JSON.stringify(sortedErrors, null, 2))\n console.log(`Generated abi for ${sortedErrors.length} errors`)\n await writeFile(path.join(errorDir, 'errorSelectors.json'), JSON.stringify(sortedSelectors, null, 2))\n}\n","/**\n * Semaphore class for controlling access to a resource by multiple processes.\n * It maintains a counter and a queue for managing access.\n */\nexport class Semaphore {\n private counter = 0\n private queue: (() => void)[] = []\n constructor(private max: number) {}\n\n /**\n * Acquires a lock on the semaphore. If the semaphore is at its maximum,\n * the function will wait until it can acquire the lock.\n * @returns A promise that resolves when the lock has been acquired.\n */\n public async acquire(): Promise<void> {\n if (this.counter >= this.max) {\n await new Promise<void>((resolve) => this.queue.push(resolve))\n }\n this.counter++\n }\n\n /**\n * Releases a lock on the semaphore.\n */\n public release(): void {\n if (this.counter == 0) return\n this.counter--\n const resolve = this.queue.shift() ?? ((): undefined => undefined)\n resolve()\n }\n}\n","import { copyFile, mkdir } from 'fs/promises'\nimport { createRequire } from 'module'\nimport path from 'path'\n\nimport { glob } from 'glob'\n\ntype Package = string\ntype File = string\ntype Directory = (File | NestedDirectory)[]\ninterface NestedDirectory {\n [key: string]: Directory | NestedDirectory\n}\nexport interface PackageFiles {\n [key: Package]: NestedDirectory | Directory\n}\n\n/**\n * Recursively traverses a directory structure to build paths to leaf nodes.\n * @param node - A directory structure represented as a string (for files), an array (for directories), or an object (for nested directories).\n * @returns An array of strings, each representing a path from the root to a leaf node.\n */\nexport const buildPaths = (node: NestedDirectory | Directory | File): string[] => {\n // base case, we're at a leaf node, return the filename\n if (typeof node === 'string') return [node]\n\n const paths: string[] = []\n // If the current node is an array, recursively process each file / nested dir\n if (Array.isArray(node)) {\n for (const contract of node) {\n paths.push(...buildPaths(contract))\n }\n } else {\n // Current node is a nested directory. Recursively process each entry.\n for (const [parent, child] of Object.entries(node)) {\n const children = buildPaths(child)\n children.forEach((path) => paths.push(`${parent}/${path}`))\n }\n }\n return paths\n}\n\n/**\n * Asynchronously copies files from source packages to a target root directory based on the provided directory structure.\n * This function iterates over each source package, resolves all file paths,\n * and copies each file to the corresponding location within the caller's root directory.\n *\n * @param packageFiles - An object mapping package names to their directory structures,\n * where each directory structure defines the files and nested directories to be copied.\n * @param callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.\n */\nexport async function copyPackageFiles(packageFiles: PackageFiles, callerRootFile: string): Promise<void> {\n const callerRootDir = path.dirname(callerRootFile)\n for (const [srcPackage, srcFiles] of Object.entries(packageFiles)) {\n const allPaths = buildPaths(srcFiles)\n const srcDir = path.dirname(createRequire(callerRootFile).resolve(`${srcPackage}/package.json`))\n let count = 0\n for (const uniquePath of allPaths) {\n const files = await glob(path.join(srcDir, uniquePath))\n for (const file of files) {\n const relativePath = path.relative(srcDir, file)\n const destPath = path.join(callerRootDir, relativePath)\n await mkdir(path.dirname(destPath), { recursive: true })\n await copyFile(file, destPath)\n count++\n }\n }\n console.log(`Copied ${count} files from ${srcPackage}`)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/populate.ts","../src/errors.ts","../src/semaphore.ts","../src/copyFiles.ts"],"names":["mkdir","path","copyFile","createRequire","glob"],"mappings":"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","sourcesContent":["import { copyFile, mkdir } from 'fs/promises'\nimport { createRequire } from 'module'\nimport path from 'path'\n\nimport { glob } from 'glob'\n\ntype AllowedFiles = 'artifacts' | 'deployments' | 'artifacts-tron' | 'artifacts-zk'\n\nexport type SrcFiles = { [key in AllowedFiles]?: readonly string[] }\nexport interface CopyTargets {\n [key: string]: SrcFiles\n}\n\n/**\n * Populates the target directory with files from the specified source packages.\n * This function copies files from the source packages to the target directory based on the provided patterns.\n *\n * @param {CopyTargets} copyTargets - An object mapping source packages to their respective file patterns.\n * @param {string} callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n */\nexport async function populate(copyTargets: CopyTargets, callerRootFile: string): Promise<void> {\n const callerRootDir = path.dirname(callerRootFile)\n for (const [srcPackage, srcFiles] of Object.entries(copyTargets)) {\n const srcDir = path.dirname(createRequire(callerRootFile).resolve(`${srcPackage}/package.json`))\n for (const [filePath, patterns] of Object.entries(srcFiles)) {\n const files = await glob(patterns.map((p) => path.join(srcDir, filePath, p)))\n let count = 0\n for (const file of files) {\n const relativePath = path.relative(srcDir, file)\n const destPath = path.join(callerRootDir, relativePath)\n await mkdir(path.dirname(destPath), { recursive: true })\n await copyFile(file, destPath)\n count++\n }\n console.log(`Copied ${count} ${filePath} from ${srcPackage}`)\n }\n }\n}\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises'\nimport path from 'path'\n\nimport { utils } from 'ethers'\n\nimport { Semaphore } from './semaphore'\n\nconst { ErrorFragment, FormatTypes, Interface } = utils\n\n/**\n * Asynchronously reads a JSON file from a given file path.\n * @param filePath - The path to the JSON file.\n * @returns {Promise<any>} A promise that resolves to the parsed JSON data.\n */\nasync function readJSONFile(filePath: string): Promise<any> {\n const data = await readFile(filePath, { encoding: 'utf8' })\n return JSON.parse(data)\n}\n\n/**\n * Processes ABI errors in parallel, controlled by a semaphore, and populates error collections.\n * @param {string} filePath - The file path to read.\n * @param {Semaphore} semaphore - Semaphore instance for concurrency control.\n * @param {Object} errors - Object to collect full errors and error selectors.\n * @param {Set<string>} errors.full - Set to collect full error definitions.\n * @param {Object.<string, string>} errors.selector - Object to collect error selectors.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n */\nasync function parallelProcess(\n filePath: string,\n semaphore: Semaphore,\n errors: { full: Set<string>; selector: { [key: string]: string } }\n): Promise<void> {\n await semaphore.acquire()\n try {\n const { abi } = await readJSONFile(filePath)\n if (abi === undefined || !Array.isArray(abi)) return\n abi.filter(({ type }) => type === 'error').forEach((obj) => {\n const frag = ErrorFragment.from(obj)\n errors.full.add(frag.format(FormatTypes.full))\n errors.selector[Interface.getSighash(frag)] = frag.format(FormatTypes.sighash)\n })\n } finally {\n semaphore.release()\n }\n}\n\n/**\n * Populates error information from ABI files in parallel.\n * This function reads ABI files, processes them to extract error information,\n * and writes the combined and sorted errors to JSON files.\n *\n * @param {string} callerRootFile - The root file path to start the search for ABI files.\n * @param {string} [destPath='src/errors'] - The path relative to root to copy the files in.\n * @param {number} [maxConcurrent=50] - Maximum number of concurrent file processing operations.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n */\nexport async function populateErrors(\n callerRootFile: string,\n destPath = 'src/errors',\n maxConcurrent = 50\n): Promise<void> {\n // Determining the directory paths from the caller's root file\n const callerRootDir = path.dirname(callerRootFile)\n const callerArtifactsPath = path.join(callerRootDir, 'artifacts')\n\n // Reading and filtering artifacts to process only JSON files\n const files = await readdir(callerArtifactsPath, { recursive: true })\n const jsonFiles = files.filter((file) => path.extname(file).toLowerCase() === '.json')\n\n const semaphore = new Semaphore(maxConcurrent)\n const errors = { full: new Set<string>(), selector: {} }\n\n // Parallel processing of files using the semaphore for concurrency control\n const filePromises = jsonFiles.map(async (file) =>\n parallelProcess(path.join(callerArtifactsPath, file), semaphore, errors)\n )\n await Promise.all(filePromises)\n\n // Sorting and organizing errors for output\n const { full, selector } = errors\n let sorter = new Intl.Collator('en', { caseFirst: 'upper', numeric: true })\n const sortedErrors = [...full].sort(sorter.compare)\n sorter = new Intl.Collator('en', { caseFirst: 'upper', numeric: false })\n const sortedSelectors = Object.fromEntries(Object.entries(selector).sort(([a], [b]) => sorter.compare(a, b)))\n const errorDir = path.join(callerRootDir, destPath)\n // Writing errors to files in the error directory\n await mkdir(errorDir, { recursive: true })\n await writeFile(path.join(errorDir, 'errors.json'), JSON.stringify(sortedErrors, null, 2))\n console.log(`Generated abi for ${sortedErrors.length} errors`)\n await writeFile(path.join(errorDir, 'errorSelectors.json'), JSON.stringify(sortedSelectors, null, 2))\n}\n","/**\n * Semaphore class for controlling access to a resource by multiple processes.\n * It maintains a counter and a queue for managing access.\n */\nexport class Semaphore {\n private counter = 0\n private queue: (() => void)[] = []\n constructor(private max: number) {}\n\n /**\n * Acquires a lock on the semaphore. If the semaphore is at its maximum,\n * the function will wait until it can acquire the lock.\n * @returns A promise that resolves when the lock has been acquired.\n */\n public async acquire(): Promise<void> {\n if (this.counter >= this.max) {\n await new Promise<void>((resolve) => this.queue.push(resolve))\n }\n this.counter++\n }\n\n /**\n * Releases a lock on the semaphore.\n */\n public release(): void {\n if (this.counter == 0) return\n this.counter--\n const resolve = this.queue.shift() ?? ((): undefined => undefined)\n resolve()\n }\n}\n","import { copyFile, mkdir } from 'fs/promises'\nimport { createRequire } from 'module'\nimport path from 'path'\n\nimport { glob } from 'glob'\n\ntype Package = string\ntype File = string\ntype Directory = (File | NestedDirectory)[]\ninterface NestedDirectory {\n [key: string]: Directory | NestedDirectory\n}\nexport interface PackageFiles {\n [key: Package]: NestedDirectory | Directory\n}\n\n/**\n * Recursively traverses a directory structure to build paths to leaf nodes.\n * @param node - A directory structure represented as a string (for files), an array (for directories), or an object (for nested directories).\n * @returns {string[]} An array of strings, each representing a path from the root to a leaf node.\n */\nexport const buildPaths = (node: NestedDirectory | Directory | File): string[] => {\n // base case, we're at a leaf node, return the filename\n if (typeof node === 'string') return [node]\n\n const paths: string[] = []\n // If the current node is an array, recursively process each file / nested dir\n if (Array.isArray(node)) {\n for (const contract of node) {\n paths.push(...buildPaths(contract))\n }\n } else {\n // Current node is a nested directory. Recursively process each entry.\n for (const [parent, child] of Object.entries(node)) {\n const children = buildPaths(child)\n children.forEach((path) => paths.push(`${parent}/${path}`))\n }\n }\n return paths\n}\n\n/**\n * Asynchronously copies files from source packages to a target root directory based on the provided directory structure.\n * This function iterates over each source package, resolves all file paths,\n * and copies each file to the corresponding location within the caller's root directory.\n *\n * @param {PackageFiles} packageFiles - An object mapping package names to their directory structures,\n * where each directory structure defines the files and nested directories to be copied.\n * @param {string} callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n */\nexport async function copyPackageFiles(packageFiles: PackageFiles, callerRootFile: string): Promise<void> {\n const callerRootDir = path.dirname(callerRootFile)\n for (const [srcPackage, srcFiles] of Object.entries(packageFiles)) {\n const allPaths = buildPaths(srcFiles)\n const srcDir = path.dirname(createRequire(callerRootFile).resolve(`${srcPackage}/package.json`))\n let count = 0\n for (const uniquePath of allPaths) {\n const files = await glob(path.join(srcDir, uniquePath))\n for (const file of files) {\n const relativePath = path.relative(srcDir, file)\n const destPath = path.join(callerRootDir, relativePath)\n await mkdir(path.dirname(destPath), { recursive: true })\n await copyFile(file, destPath)\n count++\n }\n }\n console.log(`Copied ${count} files from ${srcPackage}`)\n }\n}\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -5,13 +5,25 @@ type SrcFiles = {
|
|
|
5
5
|
interface CopyTargets {
|
|
6
6
|
[key: string]: SrcFiles;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Populates the target directory with files from the specified source packages.
|
|
10
|
+
* This function copies files from the source packages to the target directory based on the provided patterns.
|
|
11
|
+
*
|
|
12
|
+
* @param {CopyTargets} copyTargets - An object mapping source packages to their respective file patterns.
|
|
13
|
+
* @param {string} callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.
|
|
14
|
+
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
15
|
+
*/
|
|
8
16
|
declare function populate(copyTargets: CopyTargets, callerRootFile: string): Promise<void>;
|
|
9
17
|
|
|
10
18
|
/**
|
|
11
19
|
* Populates error information from ABI files in parallel.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
20
|
+
* This function reads ABI files, processes them to extract error information,
|
|
21
|
+
* and writes the combined and sorted errors to JSON files.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} callerRootFile - The root file path to start the search for ABI files.
|
|
24
|
+
* @param {string} [destPath='src/errors'] - The path relative to root to copy the files in.
|
|
25
|
+
* @param {number} [maxConcurrent=50] - Maximum number of concurrent file processing operations.
|
|
26
|
+
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
15
27
|
*/
|
|
16
28
|
declare function populateErrors(callerRootFile: string, destPath?: string, maxConcurrent?: number): Promise<void>;
|
|
17
29
|
|
|
@@ -49,9 +61,10 @@ interface PackageFiles {
|
|
|
49
61
|
* This function iterates over each source package, resolves all file paths,
|
|
50
62
|
* and copies each file to the corresponding location within the caller's root directory.
|
|
51
63
|
*
|
|
52
|
-
* @param packageFiles - An object mapping package names to their directory structures,
|
|
64
|
+
* @param {PackageFiles} packageFiles - An object mapping package names to their directory structures,
|
|
53
65
|
* where each directory structure defines the files and nested directories to be copied.
|
|
54
|
-
* @param callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.
|
|
66
|
+
* @param {string} callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.
|
|
67
|
+
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
55
68
|
*/
|
|
56
69
|
declare function copyPackageFiles(packageFiles: PackageFiles, callerRootFile: string): Promise<void>;
|
|
57
70
|
|
package/dist/index.d.ts
CHANGED
|
@@ -5,13 +5,25 @@ type SrcFiles = {
|
|
|
5
5
|
interface CopyTargets {
|
|
6
6
|
[key: string]: SrcFiles;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Populates the target directory with files from the specified source packages.
|
|
10
|
+
* This function copies files from the source packages to the target directory based on the provided patterns.
|
|
11
|
+
*
|
|
12
|
+
* @param {CopyTargets} copyTargets - An object mapping source packages to their respective file patterns.
|
|
13
|
+
* @param {string} callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.
|
|
14
|
+
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
15
|
+
*/
|
|
8
16
|
declare function populate(copyTargets: CopyTargets, callerRootFile: string): Promise<void>;
|
|
9
17
|
|
|
10
18
|
/**
|
|
11
19
|
* Populates error information from ABI files in parallel.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
20
|
+
* This function reads ABI files, processes them to extract error information,
|
|
21
|
+
* and writes the combined and sorted errors to JSON files.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} callerRootFile - The root file path to start the search for ABI files.
|
|
24
|
+
* @param {string} [destPath='src/errors'] - The path relative to root to copy the files in.
|
|
25
|
+
* @param {number} [maxConcurrent=50] - Maximum number of concurrent file processing operations.
|
|
26
|
+
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
15
27
|
*/
|
|
16
28
|
declare function populateErrors(callerRootFile: string, destPath?: string, maxConcurrent?: number): Promise<void>;
|
|
17
29
|
|
|
@@ -49,9 +61,10 @@ interface PackageFiles {
|
|
|
49
61
|
* This function iterates over each source package, resolves all file paths,
|
|
50
62
|
* and copies each file to the corresponding location within the caller's root directory.
|
|
51
63
|
*
|
|
52
|
-
* @param packageFiles - An object mapping package names to their directory structures,
|
|
64
|
+
* @param {PackageFiles} packageFiles - An object mapping package names to their directory structures,
|
|
53
65
|
* where each directory structure defines the files and nested directories to be copied.
|
|
54
|
-
* @param callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.
|
|
66
|
+
* @param {string} callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.
|
|
67
|
+
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
55
68
|
*/
|
|
56
69
|
declare function copyPackageFiles(packageFiles: PackageFiles, callerRootFile: string): Promise<void>;
|
|
57
70
|
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/populate.ts","../src/errors.ts","../src/semaphore.ts","../src/copyFiles.ts"],"names":["mkdir","path","copyFile","createRequire","glob"],"mappings":"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","sourcesContent":["import { copyFile, mkdir } from 'fs/promises'\nimport { createRequire } from 'module'\nimport path from 'path'\n\nimport { glob } from 'glob'\n\ntype AllowedFiles = 'artifacts' | 'deployments' | 'artifacts-tron' | 'artifacts-zk'\n\nexport type SrcFiles = { [key in AllowedFiles]?: readonly string[] }\nexport interface CopyTargets {\n [key: string]: SrcFiles\n}\n\nexport async function populate(copyTargets: CopyTargets, callerRootFile: string): Promise<void> {\n const callerRootDir = path.dirname(callerRootFile)\n for (const [srcPackage, srcFiles] of Object.entries(copyTargets)) {\n const srcDir = path.dirname(createRequire(callerRootFile).resolve(`${srcPackage}/package.json`))\n for (const [filePath, patterns] of Object.entries(srcFiles)) {\n const files = await glob(patterns.map((p) => path.join(srcDir, filePath, p)))\n let count = 0\n for (const file of files) {\n const relativePath = path.relative(srcDir, file)\n const destPath = path.join(callerRootDir, relativePath)\n await mkdir(path.dirname(destPath), { recursive: true })\n await copyFile(file, destPath)\n count++\n }\n console.log(`Copied ${count} ${filePath} from ${srcPackage}`)\n }\n }\n}\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises'\nimport path from 'path'\n\nimport { utils } from 'ethers'\n\nimport { Semaphore } from './semaphore'\n\nconst { ErrorFragment, FormatTypes, Interface } = utils\n\n/**\n * Asynchronously reads a JSON file from a given file path.\n * @param filePath - The path to the JSON file.\n * @returns A promise that resolves to the parsed JSON data.\n */\nasync function readJSONFile(filePath: string): Promise<any> {\n const data = await readFile(filePath, { encoding: 'utf8' })\n return JSON.parse(data)\n}\n\n/**\n * Processes ABI errors in parallel, controlled by a semaphore, and populates error collections.\n * @param filePath - The file path to read.\n * @param semaphore - Semaphore instance for concurrency control.\n * @param errors - Object to collect full errors and error selectors.\n */\nasync function parallelProcess(\n filePath: string,\n semaphore: Semaphore,\n errors: { full: Set<string>; selector: { [key: string]: string } }\n): Promise<void> {\n await semaphore.acquire()\n try {\n const { abi } = await readJSONFile(filePath)\n if (abi === undefined || !Array.isArray(abi)) return\n abi.filter(({ type }) => type === 'error').forEach((obj) => {\n const frag = ErrorFragment.from(obj)\n errors.full.add(frag.format(FormatTypes.full))\n errors.selector[Interface.getSighash(frag)] = frag.format(FormatTypes.sighash)\n })\n } finally {\n semaphore.release()\n }\n}\n\n/**\n * Populates error information from ABI files in parallel.\n * @param callerRootFile - The root file path to start the search for ABI files.\n * @param destPath - The path relative to root to copy the files in.\n * @param maxConcurrent - Maximum number of concurrent file processing operations.\n */\nexport async function populateErrors(\n callerRootFile: string,\n destPath = 'src/errors',\n maxConcurrent = 50\n): Promise<void> {\n // Determining the directory paths from the caller's root file\n const callerRootDir = path.dirname(callerRootFile)\n const callerArtifactsPath = path.join(callerRootDir, 'artifacts')\n\n // Reading and filtering artifacts to process only JSON files\n const files = await readdir(callerArtifactsPath, { recursive: true })\n const jsonFiles = files.filter((file) => path.extname(file).toLowerCase() === '.json')\n\n const semaphore = new Semaphore(maxConcurrent)\n const errors = { full: new Set<string>(), selector: {} }\n\n // Parallel processing of files using the semaphore for concurrency control\n const filePromises = jsonFiles.map(async (file) =>\n parallelProcess(path.join(callerArtifactsPath, file), semaphore, errors)\n )\n await Promise.all(filePromises)\n\n // Sorting and organizing errors for output\n const { full, selector } = errors\n let sorter = new Intl.Collator('en', { caseFirst: 'upper', numeric: true })\n const sortedErrors = [...full].sort(sorter.compare)\n sorter = new Intl.Collator('en', { caseFirst: 'upper', numeric: false })\n const sortedSelectors = Object.fromEntries(Object.entries(selector).sort(([a], [b]) => sorter.compare(a, b)))\n const errorDir = path.join(callerRootDir, destPath)\n // Writing errors to files in the error directory\n await mkdir(errorDir, { recursive: true })\n await writeFile(path.join(errorDir, 'errors.json'), JSON.stringify(sortedErrors, null, 2))\n console.log(`Generated abi for ${sortedErrors.length} errors`)\n await writeFile(path.join(errorDir, 'errorSelectors.json'), JSON.stringify(sortedSelectors, null, 2))\n}\n","/**\n * Semaphore class for controlling access to a resource by multiple processes.\n * It maintains a counter and a queue for managing access.\n */\nexport class Semaphore {\n private counter = 0\n private queue: (() => void)[] = []\n constructor(private max: number) {}\n\n /**\n * Acquires a lock on the semaphore. If the semaphore is at its maximum,\n * the function will wait until it can acquire the lock.\n * @returns A promise that resolves when the lock has been acquired.\n */\n public async acquire(): Promise<void> {\n if (this.counter >= this.max) {\n await new Promise<void>((resolve) => this.queue.push(resolve))\n }\n this.counter++\n }\n\n /**\n * Releases a lock on the semaphore.\n */\n public release(): void {\n if (this.counter == 0) return\n this.counter--\n const resolve = this.queue.shift() ?? ((): undefined => undefined)\n resolve()\n }\n}\n","import { copyFile, mkdir } from 'fs/promises'\nimport { createRequire } from 'module'\nimport path from 'path'\n\nimport { glob } from 'glob'\n\ntype Package = string\ntype File = string\ntype Directory = (File | NestedDirectory)[]\ninterface NestedDirectory {\n [key: string]: Directory | NestedDirectory\n}\nexport interface PackageFiles {\n [key: Package]: NestedDirectory | Directory\n}\n\n/**\n * Recursively traverses a directory structure to build paths to leaf nodes.\n * @param node - A directory structure represented as a string (for files), an array (for directories), or an object (for nested directories).\n * @returns An array of strings, each representing a path from the root to a leaf node.\n */\nexport const buildPaths = (node: NestedDirectory | Directory | File): string[] => {\n // base case, we're at a leaf node, return the filename\n if (typeof node === 'string') return [node]\n\n const paths: string[] = []\n // If the current node is an array, recursively process each file / nested dir\n if (Array.isArray(node)) {\n for (const contract of node) {\n paths.push(...buildPaths(contract))\n }\n } else {\n // Current node is a nested directory. Recursively process each entry.\n for (const [parent, child] of Object.entries(node)) {\n const children = buildPaths(child)\n children.forEach((path) => paths.push(`${parent}/${path}`))\n }\n }\n return paths\n}\n\n/**\n * Asynchronously copies files from source packages to a target root directory based on the provided directory structure.\n * This function iterates over each source package, resolves all file paths,\n * and copies each file to the corresponding location within the caller's root directory.\n *\n * @param packageFiles - An object mapping package names to their directory structures,\n * where each directory structure defines the files and nested directories to be copied.\n * @param callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.\n */\nexport async function copyPackageFiles(packageFiles: PackageFiles, callerRootFile: string): Promise<void> {\n const callerRootDir = path.dirname(callerRootFile)\n for (const [srcPackage, srcFiles] of Object.entries(packageFiles)) {\n const allPaths = buildPaths(srcFiles)\n const srcDir = path.dirname(createRequire(callerRootFile).resolve(`${srcPackage}/package.json`))\n let count = 0\n for (const uniquePath of allPaths) {\n const files = await glob(path.join(srcDir, uniquePath))\n for (const file of files) {\n const relativePath = path.relative(srcDir, file)\n const destPath = path.join(callerRootDir, relativePath)\n await mkdir(path.dirname(destPath), { recursive: true })\n await copyFile(file, destPath)\n count++\n }\n }\n console.log(`Copied ${count} files from ${srcPackage}`)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/populate.ts","../src/errors.ts","../src/semaphore.ts","../src/copyFiles.ts"],"names":["mkdir","path","copyFile","createRequire","glob"],"mappings":"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","sourcesContent":["import { copyFile, mkdir } from 'fs/promises'\nimport { createRequire } from 'module'\nimport path from 'path'\n\nimport { glob } from 'glob'\n\ntype AllowedFiles = 'artifacts' | 'deployments' | 'artifacts-tron' | 'artifacts-zk'\n\nexport type SrcFiles = { [key in AllowedFiles]?: readonly string[] }\nexport interface CopyTargets {\n [key: string]: SrcFiles\n}\n\n/**\n * Populates the target directory with files from the specified source packages.\n * This function copies files from the source packages to the target directory based on the provided patterns.\n *\n * @param {CopyTargets} copyTargets - An object mapping source packages to their respective file patterns.\n * @param {string} callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n */\nexport async function populate(copyTargets: CopyTargets, callerRootFile: string): Promise<void> {\n const callerRootDir = path.dirname(callerRootFile)\n for (const [srcPackage, srcFiles] of Object.entries(copyTargets)) {\n const srcDir = path.dirname(createRequire(callerRootFile).resolve(`${srcPackage}/package.json`))\n for (const [filePath, patterns] of Object.entries(srcFiles)) {\n const files = await glob(patterns.map((p) => path.join(srcDir, filePath, p)))\n let count = 0\n for (const file of files) {\n const relativePath = path.relative(srcDir, file)\n const destPath = path.join(callerRootDir, relativePath)\n await mkdir(path.dirname(destPath), { recursive: true })\n await copyFile(file, destPath)\n count++\n }\n console.log(`Copied ${count} ${filePath} from ${srcPackage}`)\n }\n }\n}\n","import { mkdir, readFile, readdir, writeFile } from 'fs/promises'\nimport path from 'path'\n\nimport { utils } from 'ethers'\n\nimport { Semaphore } from './semaphore'\n\nconst { ErrorFragment, FormatTypes, Interface } = utils\n\n/**\n * Asynchronously reads a JSON file from a given file path.\n * @param filePath - The path to the JSON file.\n * @returns {Promise<any>} A promise that resolves to the parsed JSON data.\n */\nasync function readJSONFile(filePath: string): Promise<any> {\n const data = await readFile(filePath, { encoding: 'utf8' })\n return JSON.parse(data)\n}\n\n/**\n * Processes ABI errors in parallel, controlled by a semaphore, and populates error collections.\n * @param {string} filePath - The file path to read.\n * @param {Semaphore} semaphore - Semaphore instance for concurrency control.\n * @param {Object} errors - Object to collect full errors and error selectors.\n * @param {Set<string>} errors.full - Set to collect full error definitions.\n * @param {Object.<string, string>} errors.selector - Object to collect error selectors.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n */\nasync function parallelProcess(\n filePath: string,\n semaphore: Semaphore,\n errors: { full: Set<string>; selector: { [key: string]: string } }\n): Promise<void> {\n await semaphore.acquire()\n try {\n const { abi } = await readJSONFile(filePath)\n if (abi === undefined || !Array.isArray(abi)) return\n abi.filter(({ type }) => type === 'error').forEach((obj) => {\n const frag = ErrorFragment.from(obj)\n errors.full.add(frag.format(FormatTypes.full))\n errors.selector[Interface.getSighash(frag)] = frag.format(FormatTypes.sighash)\n })\n } finally {\n semaphore.release()\n }\n}\n\n/**\n * Populates error information from ABI files in parallel.\n * This function reads ABI files, processes them to extract error information,\n * and writes the combined and sorted errors to JSON files.\n *\n * @param {string} callerRootFile - The root file path to start the search for ABI files.\n * @param {string} [destPath='src/errors'] - The path relative to root to copy the files in.\n * @param {number} [maxConcurrent=50] - Maximum number of concurrent file processing operations.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n */\nexport async function populateErrors(\n callerRootFile: string,\n destPath = 'src/errors',\n maxConcurrent = 50\n): Promise<void> {\n // Determining the directory paths from the caller's root file\n const callerRootDir = path.dirname(callerRootFile)\n const callerArtifactsPath = path.join(callerRootDir, 'artifacts')\n\n // Reading and filtering artifacts to process only JSON files\n const files = await readdir(callerArtifactsPath, { recursive: true })\n const jsonFiles = files.filter((file) => path.extname(file).toLowerCase() === '.json')\n\n const semaphore = new Semaphore(maxConcurrent)\n const errors = { full: new Set<string>(), selector: {} }\n\n // Parallel processing of files using the semaphore for concurrency control\n const filePromises = jsonFiles.map(async (file) =>\n parallelProcess(path.join(callerArtifactsPath, file), semaphore, errors)\n )\n await Promise.all(filePromises)\n\n // Sorting and organizing errors for output\n const { full, selector } = errors\n let sorter = new Intl.Collator('en', { caseFirst: 'upper', numeric: true })\n const sortedErrors = [...full].sort(sorter.compare)\n sorter = new Intl.Collator('en', { caseFirst: 'upper', numeric: false })\n const sortedSelectors = Object.fromEntries(Object.entries(selector).sort(([a], [b]) => sorter.compare(a, b)))\n const errorDir = path.join(callerRootDir, destPath)\n // Writing errors to files in the error directory\n await mkdir(errorDir, { recursive: true })\n await writeFile(path.join(errorDir, 'errors.json'), JSON.stringify(sortedErrors, null, 2))\n console.log(`Generated abi for ${sortedErrors.length} errors`)\n await writeFile(path.join(errorDir, 'errorSelectors.json'), JSON.stringify(sortedSelectors, null, 2))\n}\n","/**\n * Semaphore class for controlling access to a resource by multiple processes.\n * It maintains a counter and a queue for managing access.\n */\nexport class Semaphore {\n private counter = 0\n private queue: (() => void)[] = []\n constructor(private max: number) {}\n\n /**\n * Acquires a lock on the semaphore. If the semaphore is at its maximum,\n * the function will wait until it can acquire the lock.\n * @returns A promise that resolves when the lock has been acquired.\n */\n public async acquire(): Promise<void> {\n if (this.counter >= this.max) {\n await new Promise<void>((resolve) => this.queue.push(resolve))\n }\n this.counter++\n }\n\n /**\n * Releases a lock on the semaphore.\n */\n public release(): void {\n if (this.counter == 0) return\n this.counter--\n const resolve = this.queue.shift() ?? ((): undefined => undefined)\n resolve()\n }\n}\n","import { copyFile, mkdir } from 'fs/promises'\nimport { createRequire } from 'module'\nimport path from 'path'\n\nimport { glob } from 'glob'\n\ntype Package = string\ntype File = string\ntype Directory = (File | NestedDirectory)[]\ninterface NestedDirectory {\n [key: string]: Directory | NestedDirectory\n}\nexport interface PackageFiles {\n [key: Package]: NestedDirectory | Directory\n}\n\n/**\n * Recursively traverses a directory structure to build paths to leaf nodes.\n * @param node - A directory structure represented as a string (for files), an array (for directories), or an object (for nested directories).\n * @returns {string[]} An array of strings, each representing a path from the root to a leaf node.\n */\nexport const buildPaths = (node: NestedDirectory | Directory | File): string[] => {\n // base case, we're at a leaf node, return the filename\n if (typeof node === 'string') return [node]\n\n const paths: string[] = []\n // If the current node is an array, recursively process each file / nested dir\n if (Array.isArray(node)) {\n for (const contract of node) {\n paths.push(...buildPaths(contract))\n }\n } else {\n // Current node is a nested directory. Recursively process each entry.\n for (const [parent, child] of Object.entries(node)) {\n const children = buildPaths(child)\n children.forEach((path) => paths.push(`${parent}/${path}`))\n }\n }\n return paths\n}\n\n/**\n * Asynchronously copies files from source packages to a target root directory based on the provided directory structure.\n * This function iterates over each source package, resolves all file paths,\n * and copies each file to the corresponding location within the caller's root directory.\n *\n * @param {PackageFiles} packageFiles - An object mapping package names to their directory structures,\n * where each directory structure defines the files and nested directories to be copied.\n * @param {string} callerRootFile - The absolute path to the root file of the caller, used to determine the root directory into which the files will be copied.\n * @returns {Promise<void>} A promise that resolves when the operation is complete.\n */\nexport async function copyPackageFiles(packageFiles: PackageFiles, callerRootFile: string): Promise<void> {\n const callerRootDir = path.dirname(callerRootFile)\n for (const [srcPackage, srcFiles] of Object.entries(packageFiles)) {\n const allPaths = buildPaths(srcFiles)\n const srcDir = path.dirname(createRequire(callerRootFile).resolve(`${srcPackage}/package.json`))\n let count = 0\n for (const uniquePath of allPaths) {\n const files = await glob(path.join(srcDir, uniquePath))\n for (const file of files) {\n const relativePath = path.relative(srcDir, file)\n const destPath = path.join(callerRootDir, relativePath)\n await mkdir(path.dirname(destPath), { recursive: true })\n await copyFile(file, destPath)\n count++\n }\n }\n console.log(`Copied ${count} files from ${srcPackage}`)\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layerzerolabs/evm-sdks-build",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.16",
|
|
4
4
|
"license": "BUSL-1.1",
|
|
5
5
|
"exports": {
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"glob": "^10.3.10"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@layerzerolabs/tsup-config-next": "^3.0.
|
|
28
|
-
"@layerzerolabs/typescript-config-next": "^3.0.
|
|
27
|
+
"@layerzerolabs/tsup-config-next": "^3.0.16",
|
|
28
|
+
"@layerzerolabs/typescript-config-next": "^3.0.16",
|
|
29
29
|
"@types/glob": "^8.1.0",
|
|
30
30
|
"@types/jest": "^29.5.10",
|
|
31
31
|
"@types/node": "^20.10.5",
|