@buenos_andres/compact-builder 0.5.3
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 +38 -0
- package/README.md +71 -0
- package/dist/Builder.d.ts +95 -0
- package/dist/Builder.js +236 -0
- package/dist/Builder.js.map +1 -0
- package/dist/Compiler.d.ts +120 -0
- package/dist/Compiler.js +267 -0
- package/dist/Compiler.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/services/CompilerService.d.ts +47 -0
- package/dist/services/CompilerService.js +100 -0
- package/dist/services/CompilerService.js.map +1 -0
- package/dist/services/EnvironmentValidator.d.ts +56 -0
- package/dist/services/EnvironmentValidator.js +82 -0
- package/dist/services/EnvironmentValidator.js.map +1 -0
- package/dist/services/FileDiscovery.d.ts +33 -0
- package/dist/services/FileDiscovery.js +76 -0
- package/dist/services/FileDiscovery.js.map +1 -0
- package/dist/services/UIService.d.ts +43 -0
- package/dist/services/UIService.js +70 -0
- package/dist/services/UIService.js.map +1 -0
- package/dist/types/errors.d.ts +75 -0
- package/dist/types/errors.js +74 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/options.d.ts +128 -0
- package/dist/types/options.js +22 -0
- package/dist/types/options.js.map +1 -0
- package/dist/utils.d.ts +43 -0
- package/dist/utils.js +61 -0
- package/dist/utils.js.map +1 -0
- package/package.json +51 -0
package/dist/Compiler.js
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import { CompilerService } from "./services/CompilerService.js";
|
|
7
|
+
import { EnvironmentValidator } from "./services/EnvironmentValidator.js";
|
|
8
|
+
import { FileDiscovery } from "./services/FileDiscovery.js";
|
|
9
|
+
import { UIService } from "./services/UIService.js";
|
|
10
|
+
import { CompilationError, DirectoryNotFoundError, isPromisifiedChildProcessError, } from "./types/errors.js";
|
|
11
|
+
import { DEFAULT_OUT_DIR, DEFAULT_SRC_DIR, } from "./types/options.js";
|
|
12
|
+
// Re-export public types and services so consumers keep importing them
|
|
13
|
+
// from './Compiler.js' regardless of the internal file layout.
|
|
14
|
+
// biome-ignore lint/performance/noBarrelFile: package entrypoint
|
|
15
|
+
export { CompilerService } from "./services/CompilerService.js";
|
|
16
|
+
export { EnvironmentValidator } from "./services/EnvironmentValidator.js";
|
|
17
|
+
export { FileDiscovery } from "./services/FileDiscovery.js";
|
|
18
|
+
export { UIService } from "./services/UIService.js";
|
|
19
|
+
/**
|
|
20
|
+
* Main compiler class that orchestrates the compilation process.
|
|
21
|
+
* Coordinates environment validation, file discovery, and compilation services
|
|
22
|
+
* to provide a complete .compact file compilation solution.
|
|
23
|
+
*
|
|
24
|
+
* Features:
|
|
25
|
+
* - Dependency injection for testability
|
|
26
|
+
* - Structured error propagation with custom error types
|
|
27
|
+
* - Progress reporting and user feedback
|
|
28
|
+
* - Support for compiler flags and toolchain versions
|
|
29
|
+
* - Environment variable integration
|
|
30
|
+
* - Configurable artifact output structure (flattened or hierarchical)
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Basic usage with options object (flattened artifacts by default)
|
|
35
|
+
* const compiler = new CompactCompiler({
|
|
36
|
+
* flags: '--skip-zk',
|
|
37
|
+
* targetDir: 'security',
|
|
38
|
+
* version: '0.26.0',
|
|
39
|
+
* });
|
|
40
|
+
* await compiler.compile();
|
|
41
|
+
*
|
|
42
|
+
* // Factory method usage
|
|
43
|
+
* const compiler = CompactCompiler.fromArgs(['--dir', 'security', '--skip-zk']);
|
|
44
|
+
* await compiler.compile();
|
|
45
|
+
*
|
|
46
|
+
* // With hierarchical artifacts structure
|
|
47
|
+
* const compiler = CompactCompiler.fromArgs(['--hierarchical', '--skip-zk']);
|
|
48
|
+
* await compiler.compile();
|
|
49
|
+
*
|
|
50
|
+
* // With environment variables
|
|
51
|
+
* process.env.SKIP_ZK = 'true';
|
|
52
|
+
* const compiler = CompactCompiler.fromArgs(['--dir', 'token']);
|
|
53
|
+
* await compiler.compile();
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export class CompactCompiler {
|
|
57
|
+
/** Environment validation service */
|
|
58
|
+
environmentValidator;
|
|
59
|
+
/** File discovery service */
|
|
60
|
+
fileDiscovery;
|
|
61
|
+
/** Compilation execution service */
|
|
62
|
+
compilerService;
|
|
63
|
+
/** Compiler options */
|
|
64
|
+
options;
|
|
65
|
+
/**
|
|
66
|
+
* Creates a new CompactCompiler instance with specified configuration.
|
|
67
|
+
*
|
|
68
|
+
* @param options - Compiler configuration options
|
|
69
|
+
* @param execFn - Optional custom exec function for dependency injection
|
|
70
|
+
*/
|
|
71
|
+
constructor(options = {}, execFn) {
|
|
72
|
+
this.options = {
|
|
73
|
+
flags: (options.flags ?? '').trim(),
|
|
74
|
+
targetDir: options.targetDir,
|
|
75
|
+
version: options.version,
|
|
76
|
+
hierarchical: options.hierarchical ?? false,
|
|
77
|
+
srcDir: options.srcDir ?? DEFAULT_SRC_DIR,
|
|
78
|
+
outDir: options.outDir ?? DEFAULT_OUT_DIR,
|
|
79
|
+
exclude: options.exclude ?? [],
|
|
80
|
+
};
|
|
81
|
+
this.environmentValidator = new EnvironmentValidator(execFn);
|
|
82
|
+
this.fileDiscovery = new FileDiscovery(this.options.srcDir, this.options.exclude);
|
|
83
|
+
this.compilerService = new CompilerService(execFn, {
|
|
84
|
+
hierarchical: this.options.hierarchical,
|
|
85
|
+
srcDir: this.options.srcDir,
|
|
86
|
+
outDir: this.options.outDir,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parses command-line arguments into a CompilerOptions object.
|
|
91
|
+
*
|
|
92
|
+
* Supported argument patterns:
|
|
93
|
+
* - `--dir <directory>` - Target specific subdirectory within srcDir
|
|
94
|
+
* - `--src <directory>` - Source directory containing .compact files (default: 'src')
|
|
95
|
+
* - `--out <directory>` - Output directory for artifacts (default: 'artifacts')
|
|
96
|
+
* - `--hierarchical` - Preserve source directory structure in artifacts output
|
|
97
|
+
* - `--exclude <pattern>` - Skip `.compact` files matching the glob pattern (repeatable)
|
|
98
|
+
* - `+<version>` - Use specific toolchain version
|
|
99
|
+
* - Other arguments - Treated as compiler flags
|
|
100
|
+
* - `SKIP_ZK=true` environment variable - Adds --skip-zk flag
|
|
101
|
+
*
|
|
102
|
+
* @param args - Array of command-line arguments
|
|
103
|
+
* @param env - Environment variables (defaults to process.env)
|
|
104
|
+
* @returns Parsed CompilerOptions object
|
|
105
|
+
* @throws {Error} If --dir, --src, --out, or --exclude is provided without a value
|
|
106
|
+
*/
|
|
107
|
+
static parseArgs(args, env = process.env) {
|
|
108
|
+
const options = {
|
|
109
|
+
hierarchical: false,
|
|
110
|
+
};
|
|
111
|
+
const flags = [];
|
|
112
|
+
if (env.SKIP_ZK === 'true') {
|
|
113
|
+
flags.push('--skip-zk');
|
|
114
|
+
}
|
|
115
|
+
for (let i = 0; i < args.length; i++) {
|
|
116
|
+
if (args[i] === '--dir') {
|
|
117
|
+
const valueExists = i + 1 < args.length && !args[i + 1].startsWith('--');
|
|
118
|
+
if (valueExists) {
|
|
119
|
+
options.targetDir = args[i + 1];
|
|
120
|
+
i++;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
throw new Error('--dir flag requires a directory name');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else if (args[i] === '--src') {
|
|
127
|
+
const valueExists = i + 1 < args.length && !args[i + 1].startsWith('--');
|
|
128
|
+
if (valueExists) {
|
|
129
|
+
options.srcDir = args[i + 1];
|
|
130
|
+
i++;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
throw new Error('--src flag requires a directory path');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if (args[i] === '--out') {
|
|
137
|
+
const valueExists = i + 1 < args.length && !args[i + 1].startsWith('--');
|
|
138
|
+
if (valueExists) {
|
|
139
|
+
options.outDir = args[i + 1];
|
|
140
|
+
i++;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
throw new Error('--out flag requires a directory path');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (args[i] === '--hierarchical') {
|
|
147
|
+
options.hierarchical = true;
|
|
148
|
+
}
|
|
149
|
+
else if (args[i] === '--exclude') {
|
|
150
|
+
const valueExists = i + 1 < args.length && !args[i + 1].startsWith('--');
|
|
151
|
+
if (valueExists) {
|
|
152
|
+
options.exclude ??= [];
|
|
153
|
+
options.exclude.push(args[i + 1]);
|
|
154
|
+
i++;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
throw new Error('--exclude flag requires a pattern');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else if (args[i].startsWith('+')) {
|
|
161
|
+
options.version = args[i].slice(1);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
// Forward flags in original order, no dedup — repeatable flags
|
|
165
|
+
// (e.g. `--define x=1 --define y=2`) must be preserved as given.
|
|
166
|
+
flags.push(args[i]);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
options.flags = flags.join(' ');
|
|
170
|
+
return options;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Factory method to create a CompactCompiler from command-line arguments.
|
|
174
|
+
* See {@link CompactCompiler.parseArgs} for the supported argument shapes.
|
|
175
|
+
*
|
|
176
|
+
* @param args - Array of command-line arguments
|
|
177
|
+
* @param env - Environment variables (defaults to process.env)
|
|
178
|
+
* @returns New CompactCompiler instance configured from arguments
|
|
179
|
+
* @throws {Error} If --dir, --src, --out, or --exclude is provided without a value
|
|
180
|
+
*/
|
|
181
|
+
static fromArgs(args, env = process.env) {
|
|
182
|
+
const options = CompactCompiler.parseArgs(args, env);
|
|
183
|
+
return new CompactCompiler(options);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Validates the compilation environment and displays version information.
|
|
187
|
+
*
|
|
188
|
+
* @throws {CompactCliNotFoundError} If Compact CLI is not available in PATH
|
|
189
|
+
* @throws {Error} If version retrieval or other validation steps fail
|
|
190
|
+
*/
|
|
191
|
+
async validateEnvironment() {
|
|
192
|
+
const { devToolsVersion, toolchainVersion } = await this.environmentValidator.validate(this.options.version);
|
|
193
|
+
UIService.displayEnvInfo(devToolsVersion, toolchainVersion, this.options.targetDir, this.options.version);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Main compilation method that orchestrates the entire compilation process.
|
|
197
|
+
*
|
|
198
|
+
* @throws {CompactCliNotFoundError} If Compact CLI is not available
|
|
199
|
+
* @throws {DirectoryNotFoundError} If target directory doesn't exist
|
|
200
|
+
* @throws {CompilationError} If any file compilation fails
|
|
201
|
+
*/
|
|
202
|
+
async compile() {
|
|
203
|
+
await this.validateEnvironment();
|
|
204
|
+
const searchDir = this.options.targetDir
|
|
205
|
+
? join(this.options.srcDir, this.options.targetDir)
|
|
206
|
+
: this.options.srcDir;
|
|
207
|
+
// Validate target directory exists
|
|
208
|
+
if (this.options.targetDir && !existsSync(searchDir)) {
|
|
209
|
+
throw new DirectoryNotFoundError(`Target directory ${searchDir} does not exist`, searchDir);
|
|
210
|
+
}
|
|
211
|
+
const compactFiles = await this.fileDiscovery.getCompactFiles(searchDir);
|
|
212
|
+
if (compactFiles.length === 0) {
|
|
213
|
+
UIService.showNoFiles(this.options.targetDir);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
UIService.showCompilationStart(compactFiles.length, this.options.targetDir);
|
|
217
|
+
for (const [index, file] of compactFiles.entries()) {
|
|
218
|
+
await this.compileFile(file, index, compactFiles.length);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Compiles a single file with progress reporting and error handling.
|
|
223
|
+
*
|
|
224
|
+
* @param file - Relative path to the .compact file
|
|
225
|
+
* @param index - Current file index (0-based) for progress tracking
|
|
226
|
+
* @param total - Total number of files being compiled
|
|
227
|
+
* @throws {CompilationError} If compilation fails
|
|
228
|
+
*/
|
|
229
|
+
async compileFile(file, index, total) {
|
|
230
|
+
const step = `[${index + 1}/${total}]`;
|
|
231
|
+
const spinner = ora(chalk.blue(`[COMPILE] ${step} Compiling ${file}`)).start();
|
|
232
|
+
try {
|
|
233
|
+
const result = await this.compilerService.compileFile(file, this.options.flags, this.options.version);
|
|
234
|
+
spinner.succeed(chalk.green(`[COMPILE] ${step} Compiled ${file}`));
|
|
235
|
+
// Filter out compactc version output from compact compile
|
|
236
|
+
const filteredOutput = result.stdout.split('\n').slice(1).join('\n');
|
|
237
|
+
if (filteredOutput) {
|
|
238
|
+
UIService.printOutput(filteredOutput, chalk.cyan);
|
|
239
|
+
}
|
|
240
|
+
UIService.printOutput(result.stderr, chalk.yellow);
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
spinner.fail(chalk.red(`[COMPILE] ${step} Failed ${file}`));
|
|
244
|
+
// CompilationError wraps the underlying child-process error in `.cause`.
|
|
245
|
+
// The previous guard `isPromisifiedChildProcessError(error)` on a
|
|
246
|
+
// CompilationError instance was unreachable — unwrap via `.cause` to
|
|
247
|
+
// surface compactc's stdout/stderr to the user.
|
|
248
|
+
const execError = error instanceof CompilationError ? error.cause : error;
|
|
249
|
+
if (isPromisifiedChildProcessError(execError)) {
|
|
250
|
+
// Filter out compactc version output from compact compile
|
|
251
|
+
const filteredOutput = execError.stdout.split('\n').slice(1).join('\n');
|
|
252
|
+
if (filteredOutput) {
|
|
253
|
+
UIService.printOutput(filteredOutput, chalk.cyan);
|
|
254
|
+
}
|
|
255
|
+
UIService.printOutput(execError.stderr, chalk.red);
|
|
256
|
+
}
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* For testing - returns the resolved options object
|
|
262
|
+
*/
|
|
263
|
+
get testOptions() {
|
|
264
|
+
return this.options;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=Compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Compiler.js","sourceRoot":"","sources":["../src/Compiler.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { BuilderOnlyOptions, BuilderOptions } from './Builder.js';
|
|
2
|
+
export { CompactBuilder } from './Builder.js';
|
|
3
|
+
export type { CompilerOptions, CompilerServiceOptions, ExecFunction, } from './Compiler.js';
|
|
4
|
+
export { CompactCompiler, CompilerService, EnvironmentValidator, FileDiscovery, UIService, } from './Compiler.js';
|
|
5
|
+
export type { PromisifiedChildProcessError } from './types/errors.js';
|
|
6
|
+
export { CompactCliNotFoundError, CompilationError, DirectoryNotFoundError, isPromisifiedChildProcessError, } from './types/errors.js';
|
|
7
|
+
export type { BuildStep } from './types/options.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// biome-ignore lint/performance/noBarrelFile: package entrypoint
|
|
2
|
+
export { CompactBuilder } from './Builder.js';
|
|
3
|
+
export { CompactCompiler, CompilerService, EnvironmentValidator, FileDiscovery, UIService, } from './Compiler.js';
|
|
4
|
+
export { CompactCliNotFoundError, CompilationError, DirectoryNotFoundError, isPromisifiedChildProcessError, } from './types/errors.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,iEAAiE;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAM9C,OAAO,EACL,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,SAAS,GACV,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type CompilerServiceOptions, type ExecFunction } from '../types/options.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Service responsible for compiling individual .compact files.
|
|
4
|
+
* Builds argv arrays and invokes the Compact CLI via `child_process.execFile`
|
|
5
|
+
* (no shell), so user-supplied values cannot inject extra commands.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const compiler = new CompilerService();
|
|
10
|
+
* const result = await compiler.compileFile(
|
|
11
|
+
* 'contracts/Token.compact',
|
|
12
|
+
* '--skip-zk --verbose',
|
|
13
|
+
* '0.26.0'
|
|
14
|
+
* );
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare class CompilerService {
|
|
18
|
+
private execFn;
|
|
19
|
+
private options;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new CompilerService instance.
|
|
22
|
+
*
|
|
23
|
+
* @param execFn - Function to invoke the Compact CLI binary (defaults to
|
|
24
|
+
* a promisified `child_process.execFile` — argv array, no shell).
|
|
25
|
+
* @param options - Compiler service options
|
|
26
|
+
*/
|
|
27
|
+
constructor(execFn?: ExecFunction, options?: CompilerServiceOptions);
|
|
28
|
+
/**
|
|
29
|
+
* Compiles a single .compact file using the Compact CLI.
|
|
30
|
+
* Builds the argv array (no shell interpolation) and invokes the binary.
|
|
31
|
+
*
|
|
32
|
+
* By default, uses flattened output structure where all artifacts go to `<outDir>/<ContractName>/`.
|
|
33
|
+
* When `hierarchical` is true, preserves source directory structure: `<outDir>/<subdir>/<ContractName>/`.
|
|
34
|
+
*
|
|
35
|
+
* @param file - Relative path to the .compact file from srcDir
|
|
36
|
+
* @param flags - Space-separated compiler flags (e.g., '--skip-zk --verbose').
|
|
37
|
+
* Tokenized via `shell-quote` so quoted whitespace is preserved
|
|
38
|
+
* and shell operators (`;`, `&&`, …) cannot inject commands.
|
|
39
|
+
* @param version - Optional specific toolchain version to use
|
|
40
|
+
* @returns Promise resolving to compilation output (stdout/stderr)
|
|
41
|
+
* @throws {CompilationError} If compilation fails for any reason
|
|
42
|
+
*/
|
|
43
|
+
compileFile(file: string, flags: string, version?: string): Promise<{
|
|
44
|
+
stdout: string;
|
|
45
|
+
stderr: string;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { execFile as execFileCallback } from 'node:child_process';
|
|
2
|
+
import { basename, dirname, join } from 'node:path';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import { parse as parseShellArgs } from 'shell-quote';
|
|
5
|
+
import { CompilationError } from "../types/errors.js";
|
|
6
|
+
import { DEFAULT_OUT_DIR, DEFAULT_SRC_DIR, } from "../types/options.js";
|
|
7
|
+
const defaultExecFn = (file, args) => promisify(execFileCallback)(file, [...args]);
|
|
8
|
+
/**
|
|
9
|
+
* Tokenizes a user-supplied `flags` string into discrete argv entries using
|
|
10
|
+
* `shell-quote` (the same rules a shell would apply for splitting). Any
|
|
11
|
+
* non-string tokens (e.g. operators like `;`, `&&`) are filtered out so they
|
|
12
|
+
* cannot leak into argv as data — defense in depth against command injection
|
|
13
|
+
* via the `flags` option.
|
|
14
|
+
*/
|
|
15
|
+
function tokenizeFlags(flags) {
|
|
16
|
+
if (!flags) {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
return parseShellArgs(flags).filter((token) => typeof token === 'string');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Service responsible for compiling individual .compact files.
|
|
23
|
+
* Builds argv arrays and invokes the Compact CLI via `child_process.execFile`
|
|
24
|
+
* (no shell), so user-supplied values cannot inject extra commands.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const compiler = new CompilerService();
|
|
29
|
+
* const result = await compiler.compileFile(
|
|
30
|
+
* 'contracts/Token.compact',
|
|
31
|
+
* '--skip-zk --verbose',
|
|
32
|
+
* '0.26.0'
|
|
33
|
+
* );
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export class CompilerService {
|
|
37
|
+
execFn;
|
|
38
|
+
options;
|
|
39
|
+
/**
|
|
40
|
+
* Creates a new CompilerService instance.
|
|
41
|
+
*
|
|
42
|
+
* @param execFn - Function to invoke the Compact CLI binary (defaults to
|
|
43
|
+
* a promisified `child_process.execFile` — argv array, no shell).
|
|
44
|
+
* @param options - Compiler service options
|
|
45
|
+
*/
|
|
46
|
+
constructor(execFn = defaultExecFn, options = {}) {
|
|
47
|
+
this.execFn = execFn;
|
|
48
|
+
this.options = {
|
|
49
|
+
hierarchical: options.hierarchical ?? false,
|
|
50
|
+
srcDir: options.srcDir ?? DEFAULT_SRC_DIR,
|
|
51
|
+
outDir: options.outDir ?? DEFAULT_OUT_DIR,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Compiles a single .compact file using the Compact CLI.
|
|
56
|
+
* Builds the argv array (no shell interpolation) and invokes the binary.
|
|
57
|
+
*
|
|
58
|
+
* By default, uses flattened output structure where all artifacts go to `<outDir>/<ContractName>/`.
|
|
59
|
+
* When `hierarchical` is true, preserves source directory structure: `<outDir>/<subdir>/<ContractName>/`.
|
|
60
|
+
*
|
|
61
|
+
* @param file - Relative path to the .compact file from srcDir
|
|
62
|
+
* @param flags - Space-separated compiler flags (e.g., '--skip-zk --verbose').
|
|
63
|
+
* Tokenized via `shell-quote` so quoted whitespace is preserved
|
|
64
|
+
* and shell operators (`;`, `&&`, …) cannot inject commands.
|
|
65
|
+
* @param version - Optional specific toolchain version to use
|
|
66
|
+
* @returns Promise resolving to compilation output (stdout/stderr)
|
|
67
|
+
* @throws {CompilationError} If compilation fails for any reason
|
|
68
|
+
*/
|
|
69
|
+
async compileFile(file, flags, version) {
|
|
70
|
+
const inputPath = join(this.options.srcDir, file);
|
|
71
|
+
const fileDir = dirname(file);
|
|
72
|
+
const fileName = basename(file, '.compact');
|
|
73
|
+
// Flattened (default): <outDir>/<ContractName>/
|
|
74
|
+
// Hierarchical: <outDir>/<subdir>/<ContractName>/
|
|
75
|
+
const outputDir = this.options.hierarchical && fileDir !== '.'
|
|
76
|
+
? join(this.options.outDir, fileDir, fileName)
|
|
77
|
+
: join(this.options.outDir, fileName);
|
|
78
|
+
const args = [
|
|
79
|
+
'compile',
|
|
80
|
+
...(version ? [`+${version}`] : []),
|
|
81
|
+
...tokenizeFlags(flags),
|
|
82
|
+
inputPath,
|
|
83
|
+
outputDir,
|
|
84
|
+
];
|
|
85
|
+
try {
|
|
86
|
+
return await this.execFn('compact', args);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
let message;
|
|
90
|
+
if (error instanceof Error) {
|
|
91
|
+
message = error.message;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
message = String(error); // fallback for strings, objects, numbers, etc.
|
|
95
|
+
}
|
|
96
|
+
throw new CompilationError(`Failed to compile ${file}: ${message}`, file, error);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=CompilerService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompilerService.js","sourceRoot":"","sources":["../../src/services/CompilerService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ExecFunction } from '../types/options.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Service responsible for validating the Compact CLI environment.
|
|
4
|
+
* Checks CLI availability, retrieves version information, and ensures
|
|
5
|
+
* the toolchain is properly configured before compilation.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const validator = new EnvironmentValidator();
|
|
10
|
+
* await validator.validate('0.26.0');
|
|
11
|
+
* const version = await validator.getDevToolsVersion();
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare class EnvironmentValidator {
|
|
15
|
+
private execFn;
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new EnvironmentValidator instance.
|
|
18
|
+
*
|
|
19
|
+
* @param execFn - Function to execute the Compact CLI binary (defaults to
|
|
20
|
+
* a promisified `child_process.execFile` — argv array, no shell).
|
|
21
|
+
*/
|
|
22
|
+
constructor(execFn?: ExecFunction);
|
|
23
|
+
/**
|
|
24
|
+
* Checks if the Compact CLI is available in the system PATH.
|
|
25
|
+
*
|
|
26
|
+
* @returns Promise resolving to true if CLI is available, false otherwise
|
|
27
|
+
*/
|
|
28
|
+
checkCompactAvailable(): Promise<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* Retrieves the version of the Compact developer tools.
|
|
31
|
+
*
|
|
32
|
+
* @returns Promise resolving to the version string
|
|
33
|
+
* @throws {Error} If the CLI is not available or command fails
|
|
34
|
+
*/
|
|
35
|
+
getDevToolsVersion(): Promise<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Retrieves the version of the Compact toolchain/compiler.
|
|
38
|
+
*
|
|
39
|
+
* @param version - Optional specific toolchain version to query
|
|
40
|
+
* @returns Promise resolving to the toolchain version string
|
|
41
|
+
* @throws {Error} If the CLI is not available or command fails
|
|
42
|
+
*/
|
|
43
|
+
getToolchainVersion(version?: string): Promise<string>;
|
|
44
|
+
/**
|
|
45
|
+
* Validates the entire Compact environment and ensures it's ready for compilation.
|
|
46
|
+
* Checks CLI availability and retrieves version information.
|
|
47
|
+
*
|
|
48
|
+
* @param version - Optional specific toolchain version to validate
|
|
49
|
+
* @throws {CompactCliNotFoundError} If the Compact CLI is not available
|
|
50
|
+
* @throws {Error} If version commands fail
|
|
51
|
+
*/
|
|
52
|
+
validate(version?: string): Promise<{
|
|
53
|
+
devToolsVersion: string;
|
|
54
|
+
toolchainVersion: string;
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { execFile as execFileCallback } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import { CompactCliNotFoundError } from "../types/errors.js";
|
|
4
|
+
const defaultExecFn = (file, args) => promisify(execFileCallback)(file, [...args]);
|
|
5
|
+
/**
|
|
6
|
+
* Service responsible for validating the Compact CLI environment.
|
|
7
|
+
* Checks CLI availability, retrieves version information, and ensures
|
|
8
|
+
* the toolchain is properly configured before compilation.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const validator = new EnvironmentValidator();
|
|
13
|
+
* await validator.validate('0.26.0');
|
|
14
|
+
* const version = await validator.getDevToolsVersion();
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export class EnvironmentValidator {
|
|
18
|
+
execFn;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a new EnvironmentValidator instance.
|
|
21
|
+
*
|
|
22
|
+
* @param execFn - Function to execute the Compact CLI binary (defaults to
|
|
23
|
+
* a promisified `child_process.execFile` — argv array, no shell).
|
|
24
|
+
*/
|
|
25
|
+
constructor(execFn = defaultExecFn) {
|
|
26
|
+
this.execFn = execFn;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Checks if the Compact CLI is available in the system PATH.
|
|
30
|
+
*
|
|
31
|
+
* @returns Promise resolving to true if CLI is available, false otherwise
|
|
32
|
+
*/
|
|
33
|
+
async checkCompactAvailable() {
|
|
34
|
+
try {
|
|
35
|
+
await this.execFn('compact', ['--version']);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves the version of the Compact developer tools.
|
|
44
|
+
*
|
|
45
|
+
* @returns Promise resolving to the version string
|
|
46
|
+
* @throws {Error} If the CLI is not available or command fails
|
|
47
|
+
*/
|
|
48
|
+
async getDevToolsVersion() {
|
|
49
|
+
const { stdout } = await this.execFn('compact', ['--version']);
|
|
50
|
+
return stdout.trim();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Retrieves the version of the Compact toolchain/compiler.
|
|
54
|
+
*
|
|
55
|
+
* @param version - Optional specific toolchain version to query
|
|
56
|
+
* @returns Promise resolving to the toolchain version string
|
|
57
|
+
* @throws {Error} If the CLI is not available or command fails
|
|
58
|
+
*/
|
|
59
|
+
async getToolchainVersion(version) {
|
|
60
|
+
const args = ['compile', ...(version ? [`+${version}`] : []), '--version'];
|
|
61
|
+
const { stdout } = await this.execFn('compact', args);
|
|
62
|
+
return stdout.trim();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Validates the entire Compact environment and ensures it's ready for compilation.
|
|
66
|
+
* Checks CLI availability and retrieves version information.
|
|
67
|
+
*
|
|
68
|
+
* @param version - Optional specific toolchain version to validate
|
|
69
|
+
* @throws {CompactCliNotFoundError} If the Compact CLI is not available
|
|
70
|
+
* @throws {Error} If version commands fail
|
|
71
|
+
*/
|
|
72
|
+
async validate(version) {
|
|
73
|
+
const isAvailable = await this.checkCompactAvailable();
|
|
74
|
+
if (!isAvailable) {
|
|
75
|
+
throw new CompactCliNotFoundError("'compact' CLI not found in PATH. Please install the Compact developer tools.");
|
|
76
|
+
}
|
|
77
|
+
const devToolsVersion = await this.getDevToolsVersion();
|
|
78
|
+
const toolchainVersion = await this.getToolchainVersion(version);
|
|
79
|
+
return { devToolsVersion, toolchainVersion };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=EnvironmentValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvironmentValidator.js","sourceRoot":"","sources":["../../src/services/EnvironmentValidator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAG7D,MAAM,aAAa,GAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CACjD,SAAS,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,oBAAoB;IACvB,MAAM,CAAe;IAE7B;;;;;OAKG;IACH,YAAY,SAAuB,aAAa;QAC9C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,kBAAkB;QACtB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QAC/D,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,mBAAmB,CAAC,OAAgB;QACxC,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;QAC3E,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACtD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,CACZ,OAAgB;QAEhB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACvD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,uBAAuB,CAC/B,8EAA8E,CAC/E,CAAC;QACJ,CAAC;QAED,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxD,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAEjE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service responsible for discovering .compact files in the source directory.
|
|
3
|
+
* Recursively scans directories and filters for .compact file extensions,
|
|
4
|
+
* applying user-supplied exclude patterns.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const discovery = new FileDiscovery('src', ['Mock*']);
|
|
9
|
+
* const files = await discovery.getCompactFiles('src/security');
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export declare class FileDiscovery {
|
|
13
|
+
private srcDir;
|
|
14
|
+
private excludes;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new FileDiscovery instance.
|
|
17
|
+
*
|
|
18
|
+
* @param srcDir - Base source directory for relative path calculation (default: 'src')
|
|
19
|
+
* @param excludes - Glob-style patterns of `.compact` files to skip.
|
|
20
|
+
* Patterns containing `/` match against the full path
|
|
21
|
+
* (as `find <srcDir>` would emit it); others match against
|
|
22
|
+
* the filename only. Default: `[]`.
|
|
23
|
+
*/
|
|
24
|
+
constructor(srcDir?: string, excludes?: readonly string[]);
|
|
25
|
+
/**
|
|
26
|
+
* Recursively discovers all .compact files in a directory.
|
|
27
|
+
* Returns relative paths from the srcDir for consistent processing.
|
|
28
|
+
*
|
|
29
|
+
* @param dir - Directory path to search (relative or absolute)
|
|
30
|
+
* @returns Promise resolving to array of relative file paths
|
|
31
|
+
*/
|
|
32
|
+
getCompactFiles(dir: string): Promise<string[]>;
|
|
33
|
+
}
|