@taqueria/plugin-ligo 0.28.5 → 0.28.6

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/compile-all.ts CHANGED
@@ -5,25 +5,129 @@ import { join } from 'path';
5
5
  import { CompileAllOpts as Opts, CompileOpts, getInputFilenameAbsPath } from './common';
6
6
  import { compileContractWithStorageAndParameter, TableRow } from './compile';
7
7
 
8
- const isMainContract = (parsedArgs: Opts, contactFilename: string): Promise<boolean> =>
9
- readFile(getInputFilenameAbsPath(parsedArgs, contactFilename), 'utf8')
10
- .then(data => /(const|let|function)\s+main/.test(data));
8
+ const isMainContract = async (parsedArgs: Opts, contractFilename: string): Promise<boolean> => {
9
+ const fileContent = await readFile(getInputFilenameAbsPath(parsedArgs, contractFilename), 'utf8');
10
+ const entryOrMainFunctionRegex = /@entry|((const|let|function)\s+main)/g;
11
+ return entryOrMainFunctionRegex.test(fileContent);
12
+ };
13
+
14
+ // Helper function to parse includes from a LIGO file
15
+ const parseIncludes = async (parsedArgs: Opts, contractFilename: string): Promise<string[]> => {
16
+ const fileContent = await readFile(getInputFilenameAbsPath(parsedArgs, contractFilename), 'utf8');
17
+ const includeRegex = /#include\s+"([^"]+\.m?ligo)"/g;
18
+ let match;
19
+ const includes: string[] = [];
20
+
21
+ while ((match = includeRegex.exec(fileContent)) !== null) {
22
+ includes.push(match[1]);
23
+ }
24
+
25
+ return includes;
26
+ };
27
+
28
+ // Helper function to build the dependency graph
29
+ const buildDependencyGraph = async (
30
+ parsedArgs: Opts,
31
+ contractFilenames: string[],
32
+ ): Promise<Map<string, Set<string>>> => {
33
+ const graph = new Map<string, Set<string>>();
34
+
35
+ for (const filename of contractFilenames) {
36
+ const includes = await parseIncludes(parsedArgs, filename);
37
+ graph.set(filename, new Set(includes));
38
+ }
39
+
40
+ return graph;
41
+ };
42
+
43
+ const visit = (
44
+ node: string,
45
+ graph: Map<string, Set<string>>,
46
+ visited: Set<string>,
47
+ stack: Set<string>,
48
+ ): [boolean, Set<string>] => {
49
+ if (stack.has(node)) return [true, visited]; // Circular dependency detected
50
+
51
+ if (!visited.has(node)) {
52
+ const newVisited = new Set(visited).add(node);
53
+ const newStack = new Set(stack).add(node);
54
+
55
+ const [circular, updatedVisited] = Array.from(graph.get(node) || []).reduce<[boolean, Set<string>]>(
56
+ ([circularFound, vSet], dependency) => {
57
+ const [result, v] = visit(dependency, graph, vSet, newStack);
58
+ return [circularFound || result, v];
59
+ },
60
+ [false, newVisited],
61
+ );
62
+
63
+ if (!circular) return [false, updatedVisited];
64
+ }
65
+
66
+ return [false, visited];
67
+ };
68
+
69
+ const detectCircularDependencies = (
70
+ graph: Map<string, Set<string>>,
71
+ ): { safeFiles: string[]; circularFiles: string[] } => {
72
+ const { safeFiles, circularFiles, visited } = Array.from(graph.keys()).reduce<{
73
+ safeFiles: string[];
74
+ circularFiles: string[];
75
+ visited: Set<string>;
76
+ }>(
77
+ (acc, filename) => {
78
+ const [isCircular, updatedVisited] = visit(
79
+ filename,
80
+ graph,
81
+ acc.visited,
82
+ new Set<string>(),
83
+ );
84
+ if (isCircular) {
85
+ acc.circularFiles.push(filename);
86
+ } else {
87
+ acc.safeFiles.push(filename);
88
+ }
89
+ acc.visited = updatedVisited;
90
+ return acc;
91
+ },
92
+ { safeFiles: [], circularFiles: [], visited: new Set<string>() },
93
+ );
94
+
95
+ return { safeFiles, circularFiles };
96
+ };
11
97
 
12
98
  const compileAll = async (parsedArgs: Opts): Promise<void> => {
13
99
  let p: Promise<TableRow[]>[] = [];
14
100
 
15
101
  const contractFilenames = await glob(
16
102
  ['**/*.ligo', '**/*.religo', '**/*.mligo', '**/*.jsligo'],
17
- { cwd: join(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? 'contracts'), absolute: false },
103
+ {
104
+ cwd: join(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? 'contracts'),
105
+ absolute: false,
106
+ },
18
107
  );
19
108
 
20
- for (const filename of contractFilenames) {
109
+ const dependencyGraph = await buildDependencyGraph(parsedArgs, contractFilenames);
110
+ const { safeFiles, circularFiles } = detectCircularDependencies(dependencyGraph);
111
+
112
+ for (const filename of safeFiles) {
21
113
  if (await isMainContract(parsedArgs, filename)) {
22
114
  p.push(compileContractWithStorageAndParameter(parsedArgs as CompileOpts, filename));
23
115
  }
24
116
  }
25
117
 
26
- return Promise.all(p).then(tables => tables.flat()).then(sendJsonRes).catch(err => sendErr(err, false));
118
+ return Promise.all(p)
119
+ .then(tables => tables.flat())
120
+ .then(table => {
121
+ if (circularFiles.length > 0) {
122
+ console.warn(
123
+ 'Warning: Circular dependencies detected in the following files. They have been skipped:',
124
+ );
125
+ console.warn(circularFiles.join(', '));
126
+ }
127
+ return table;
128
+ })
129
+ .then(sendJsonRes)
130
+ .catch(err => sendErr(err, false));
27
131
  };
28
132
 
29
133
  export default compileAll;
package/compile.ts CHANGED
@@ -28,6 +28,15 @@ const isParameterListFile = (sourceFile: string): boolean =>
28
28
  const isContractFile = (sourceFile: string): boolean =>
29
29
  isLIGOFile(sourceFile) && !isStorageListFile(sourceFile) && !isParameterListFile(sourceFile);
30
30
 
31
+ const getModuleName = async (parsedArgs: Opts, sourceFile: string): Promise<string | undefined> => {
32
+ const fileContent = await readFile(getInputFilenameAbsPath(parsedArgs, sourceFile), 'utf8');
33
+ if (fileContent.includes('@entry') && fileContent.includes('module')) {
34
+ const match = fileContent.match(/module ([^\s]+)/);
35
+ return match ? match[1] : undefined;
36
+ }
37
+ return undefined;
38
+ };
39
+
31
40
  const extractExt = (path: string): string => {
32
41
  const matchResult = path.match(/\.(ligo|religo|mligo|jsligo)$/);
33
42
  return matchResult ? matchResult[0] : '';
@@ -68,7 +77,7 @@ const getOutputExprFilename = (parsedArgs: Opts, sourceFile: string, exprKind: E
68
77
  return join(getArtifactsDir(parsedArgs), `${outputFile}`);
69
78
  };
70
79
 
71
- const getCompileContractCmd = (parsedArgs: Opts, sourceFile: string): string => {
80
+ const getCompileContractCmd = async (parsedArgs: Opts, sourceFile: string): Promise<string> => {
72
81
  const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
73
82
  if (!projectDir) throw `No project directory provided`;
74
83
  const baseCmd =
@@ -76,7 +85,9 @@ const getCompileContractCmd = (parsedArgs: Opts, sourceFile: string): string =>
76
85
  const inputFile = getInputFilenameRelPath(parsedArgs, sourceFile);
77
86
  const outputFile = `-o ${getOutputContractFilename(parsedArgs, sourceFile)}`;
78
87
  const flags = isOutputFormatJSON(parsedArgs) ? ' --michelson-format json ' : '';
79
- const cmd = `${baseCmd} ${inputFile} ${outputFile} ${flags}`;
88
+ const moduleName = await getModuleName(parsedArgs, sourceFile);
89
+ const entryFlag = moduleName ? `-m ${moduleName}` : '';
90
+ const cmd = `${baseCmd} ${inputFile} ${outputFile} ${flags}${entryFlag}`;
80
91
  return cmd;
81
92
  };
82
93
 
@@ -93,24 +104,24 @@ const getCompileExprCmd = (parsedArgs: Opts, sourceFile: string, exprKind: ExprK
93
104
  return cmd;
94
105
  };
95
106
 
96
- const compileContract = (parsedArgs: Opts, sourceFile: string): Promise<TableRow> =>
97
- getArch()
98
- .then(() => getCompileContractCmd(parsedArgs, sourceFile))
99
- .then(execCmd)
100
- .then(({ stderr }) => {
101
- if (stderr.length > 0) sendWarn(stderr);
102
- return {
103
- contract: sourceFile,
104
- artifact: getOutputContractFilename(parsedArgs, sourceFile),
105
- };
106
- })
107
- .catch(err => {
108
- emitExternalError(err, sourceFile);
109
- return {
110
- contract: sourceFile,
111
- artifact: COMPILE_ERR_MSG,
112
- };
113
- });
107
+ const compileContract = async (parsedArgs: Opts, sourceFile: string): Promise<TableRow> => {
108
+ try {
109
+ await getArch();
110
+ const cmd = await getCompileContractCmd(parsedArgs, sourceFile);
111
+ const { stderr } = await execCmd(cmd);
112
+ if (stderr.length > 0) sendWarn(stderr);
113
+ return {
114
+ contract: sourceFile,
115
+ artifact: getOutputContractFilename(parsedArgs, sourceFile),
116
+ };
117
+ } catch (err) {
118
+ emitExternalError(err, sourceFile);
119
+ return {
120
+ contract: sourceFile,
121
+ artifact: COMPILE_ERR_MSG,
122
+ };
123
+ }
124
+ };
114
125
 
115
126
  const compileExpr = (parsedArgs: Opts, sourceFile: string, exprKind: ExprKind) =>
116
127
  (exprName: string): Promise<TableRow> =>
@@ -119,9 +130,10 @@ const compileExpr = (parsedArgs: Opts, sourceFile: string, exprKind: ExprKind) =
119
130
  .then(execCmd)
120
131
  .then(({ stderr }) => {
121
132
  if (stderr.length > 0) sendWarn(stderr);
133
+ const artifactName = getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName);
122
134
  return {
123
135
  contract: sourceFile,
124
- artifact: getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName),
136
+ artifact: artifactName,
125
137
  };
126
138
  })
127
139
  .catch(err => {
@@ -152,9 +164,15 @@ const compileExprs = (parsedArgs: Opts, sourceFile: string, exprKind: ExprKind):
152
164
  emitExternalError(err, sourceFile);
153
165
  return [{
154
166
  contract: sourceFile,
155
- artifact: `No ${isStorageKind(exprKind) ? 'storage' : 'parameter'} values compiled`,
167
+ artifact: `No ${isStorageKind(exprKind) ? 'storage' : 'parameter'} expressions compiled`,
156
168
  }];
157
169
  })
170
+ .then(results =>
171
+ results.length > 0 ? results : [{
172
+ contract: sourceFile,
173
+ artifact: `No ${isStorageKind(exprKind) ? 'storage' : 'parameter'} expressions found`,
174
+ }]
175
+ )
158
176
  .then(mergeArtifactsOutput(sourceFile));
159
177
 
160
178
  // TODO: Just for backwards compatibility. Can be deleted in the future.
package/index.js CHANGED
@@ -23,7 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  ));
24
24
 
25
25
  // index.ts
26
- var import_node_sdk8 = require("@taqueria/node-sdk");
26
+ var import_node_sdk9 = require("@taqueria/node-sdk");
27
27
 
28
28
  // createContract.ts
29
29
  var import_node_sdk = require("@taqueria/node-sdk");
@@ -175,7 +175,7 @@ var createContract = (args) => {
175
175
  var createContract_default = createContract;
176
176
 
177
177
  // main.ts
178
- var import_node_sdk7 = require("@taqueria/node-sdk");
178
+ var import_node_sdk8 = require("@taqueria/node-sdk");
179
179
 
180
180
  // common.ts
181
181
  var import_node_sdk2 = require("@taqueria/node-sdk");
@@ -203,6 +203,14 @@ var isLIGOFile = (sourceFile) => /.+\.(ligo|religo|mligo|jsligo)$/.test(sourceFi
203
203
  var isStorageListFile = (sourceFile) => /.+\.(storageList|storages)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
204
204
  var isParameterListFile = (sourceFile) => /.+\.(parameterList|parameters)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
205
205
  var isContractFile = (sourceFile) => isLIGOFile(sourceFile) && !isStorageListFile(sourceFile) && !isParameterListFile(sourceFile);
206
+ var getModuleName = async (parsedArgs, sourceFile) => {
207
+ const fileContent = await (0, import_promises2.readFile)(getInputFilenameAbsPath(parsedArgs, sourceFile), "utf8");
208
+ if (fileContent.includes("@entry") && fileContent.includes("module")) {
209
+ const match = fileContent.match(/module ([^\s]+)/);
210
+ return match ? match[1] : void 0;
211
+ }
212
+ return void 0;
213
+ };
206
214
  var extractExt = (path) => {
207
215
  const matchResult = path.match(/\.(ligo|religo|mligo|jsligo)$/);
208
216
  return matchResult ? matchResult[0] : "";
@@ -230,7 +238,7 @@ var getOutputExprFilename = (parsedArgs, sourceFile, exprKind, exprName) => {
230
238
  const outputFile = exprKind === "default_storage" ? `${contractName}.default_storage${ext}` : `${contractName}.${exprKind}.${exprName}${ext}`;
231
239
  return (0, import_path2.join)((0, import_node_sdk3.getArtifactsDir)(parsedArgs), `${outputFile}`);
232
240
  };
233
- var getCompileContractCmd = (parsedArgs, sourceFile) => {
241
+ var getCompileContractCmd = async (parsedArgs, sourceFile) => {
234
242
  const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
235
243
  if (!projectDir)
236
244
  throw `No project directory provided`;
@@ -238,7 +246,9 @@ var getCompileContractCmd = (parsedArgs, sourceFile) => {
238
246
  const inputFile = getInputFilenameRelPath(parsedArgs, sourceFile);
239
247
  const outputFile = `-o ${getOutputContractFilename(parsedArgs, sourceFile)}`;
240
248
  const flags = isOutputFormatJSON(parsedArgs) ? " --michelson-format json " : "";
241
- const cmd = `${baseCmd} ${inputFile} ${outputFile} ${flags}`;
249
+ const moduleName = await getModuleName(parsedArgs, sourceFile);
250
+ const entryFlag = moduleName ? `-m ${moduleName}` : "";
251
+ const cmd = `${baseCmd} ${inputFile} ${outputFile} ${flags}${entryFlag}`;
242
252
  return cmd;
243
253
  };
244
254
  var getCompileExprCmd = (parsedArgs, sourceFile, exprKind, exprName) => {
@@ -253,26 +263,32 @@ var getCompileExprCmd = (parsedArgs, sourceFile, exprKind, exprName) => {
253
263
  const cmd = `${baseCmd} ${inputFile} ${exprName} ${outputFile} ${flags}`;
254
264
  return cmd;
255
265
  };
256
- var compileContract = (parsedArgs, sourceFile) => (0, import_node_sdk3.getArch)().then(() => getCompileContractCmd(parsedArgs, sourceFile)).then(import_node_sdk3.execCmd).then(({ stderr }) => {
257
- if (stderr.length > 0)
258
- (0, import_node_sdk3.sendWarn)(stderr);
259
- return {
260
- contract: sourceFile,
261
- artifact: getOutputContractFilename(parsedArgs, sourceFile)
262
- };
263
- }).catch((err) => {
264
- emitExternalError(err, sourceFile);
265
- return {
266
- contract: sourceFile,
267
- artifact: COMPILE_ERR_MSG
268
- };
269
- });
266
+ var compileContract = async (parsedArgs, sourceFile) => {
267
+ try {
268
+ await (0, import_node_sdk3.getArch)();
269
+ const cmd = await getCompileContractCmd(parsedArgs, sourceFile);
270
+ const { stderr } = await (0, import_node_sdk3.execCmd)(cmd);
271
+ if (stderr.length > 0)
272
+ (0, import_node_sdk3.sendWarn)(stderr);
273
+ return {
274
+ contract: sourceFile,
275
+ artifact: getOutputContractFilename(parsedArgs, sourceFile)
276
+ };
277
+ } catch (err) {
278
+ emitExternalError(err, sourceFile);
279
+ return {
280
+ contract: sourceFile,
281
+ artifact: COMPILE_ERR_MSG
282
+ };
283
+ }
284
+ };
270
285
  var compileExpr = (parsedArgs, sourceFile, exprKind) => (exprName) => (0, import_node_sdk3.getArch)().then(() => getCompileExprCmd(parsedArgs, sourceFile, exprKind, exprName)).then(import_node_sdk3.execCmd).then(({ stderr }) => {
271
286
  if (stderr.length > 0)
272
287
  (0, import_node_sdk3.sendWarn)(stderr);
288
+ const artifactName = getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName);
273
289
  return {
274
290
  contract: sourceFile,
275
- artifact: getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName)
291
+ artifact: artifactName
276
292
  };
277
293
  }).catch((err) => {
278
294
  emitExternalError(err, sourceFile);
@@ -296,9 +312,14 @@ var compileExprs = (parsedArgs, sourceFile, exprKind) => getExprNames(parsedArgs
296
312
  emitExternalError(err, sourceFile);
297
313
  return [{
298
314
  contract: sourceFile,
299
- artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} values compiled`
315
+ artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} expressions compiled`
300
316
  }];
301
- }).then(mergeArtifactsOutput(sourceFile));
317
+ }).then(
318
+ (results) => results.length > 0 ? results : [{
319
+ contract: sourceFile,
320
+ artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} expressions found`
321
+ }]
322
+ ).then(mergeArtifactsOutput(sourceFile));
302
323
  var tryLegacyStorageNamingConvention = (parsedArgs, sourceFile) => {
303
324
  const storageListFile = `${removeExt(sourceFile)}.storages${extractExt(sourceFile)}`;
304
325
  const storageListFilename = getInputFilenameAbsPath(parsedArgs, storageListFile);
@@ -418,24 +439,100 @@ var import_node_sdk4 = require("@taqueria/node-sdk");
418
439
  var import_fast_glob = __toESM(require("fast-glob"));
419
440
  var import_promises3 = require("fs/promises");
420
441
  var import_path3 = require("path");
421
- var isMainContract = (parsedArgs, contactFilename) => (0, import_promises3.readFile)(getInputFilenameAbsPath(parsedArgs, contactFilename), "utf8").then((data) => /(const|let|function)\s+main/.test(data));
442
+ var isMainContract = async (parsedArgs, contractFilename) => {
443
+ const fileContent = await (0, import_promises3.readFile)(getInputFilenameAbsPath(parsedArgs, contractFilename), "utf8");
444
+ const entryOrMainFunctionRegex = /@entry|((const|let|function)\s+main)/g;
445
+ return entryOrMainFunctionRegex.test(fileContent);
446
+ };
447
+ var parseIncludes = async (parsedArgs, contractFilename) => {
448
+ const fileContent = await (0, import_promises3.readFile)(getInputFilenameAbsPath(parsedArgs, contractFilename), "utf8");
449
+ const includeRegex = /#include\s+"([^"]+\.m?ligo)"/g;
450
+ let match;
451
+ const includes = [];
452
+ while ((match = includeRegex.exec(fileContent)) !== null) {
453
+ includes.push(match[1]);
454
+ }
455
+ return includes;
456
+ };
457
+ var buildDependencyGraph = async (parsedArgs, contractFilenames) => {
458
+ const graph = /* @__PURE__ */ new Map();
459
+ for (const filename of contractFilenames) {
460
+ const includes = await parseIncludes(parsedArgs, filename);
461
+ graph.set(filename, new Set(includes));
462
+ }
463
+ return graph;
464
+ };
465
+ var visit = (node, graph, visited, stack) => {
466
+ if (stack.has(node))
467
+ return [true, visited];
468
+ if (!visited.has(node)) {
469
+ const newVisited = new Set(visited).add(node);
470
+ const newStack = new Set(stack).add(node);
471
+ const [circular, updatedVisited] = Array.from(graph.get(node) || []).reduce(
472
+ ([circularFound, vSet], dependency) => {
473
+ const [result, v] = visit(dependency, graph, vSet, newStack);
474
+ return [circularFound || result, v];
475
+ },
476
+ [false, newVisited]
477
+ );
478
+ if (!circular)
479
+ return [false, updatedVisited];
480
+ }
481
+ return [false, visited];
482
+ };
483
+ var detectCircularDependencies = (graph) => {
484
+ const { safeFiles, circularFiles, visited } = Array.from(graph.keys()).reduce(
485
+ (acc, filename) => {
486
+ const [isCircular, updatedVisited] = visit(
487
+ filename,
488
+ graph,
489
+ acc.visited,
490
+ /* @__PURE__ */ new Set()
491
+ );
492
+ if (isCircular) {
493
+ acc.circularFiles.push(filename);
494
+ } else {
495
+ acc.safeFiles.push(filename);
496
+ }
497
+ acc.visited = updatedVisited;
498
+ return acc;
499
+ },
500
+ { safeFiles: [], circularFiles: [], visited: /* @__PURE__ */ new Set() }
501
+ );
502
+ return { safeFiles, circularFiles };
503
+ };
422
504
  var compileAll = async (parsedArgs) => {
423
505
  let p = [];
424
506
  const contractFilenames = await (0, import_fast_glob.default)(
425
507
  ["**/*.ligo", "**/*.religo", "**/*.mligo", "**/*.jsligo"],
426
- { cwd: (0, import_path3.join)(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? "contracts"), absolute: false }
508
+ {
509
+ cwd: (0, import_path3.join)(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? "contracts"),
510
+ absolute: false
511
+ }
427
512
  );
428
- for (const filename of contractFilenames) {
513
+ const dependencyGraph = await buildDependencyGraph(parsedArgs, contractFilenames);
514
+ const { safeFiles, circularFiles } = detectCircularDependencies(dependencyGraph);
515
+ for (const filename of safeFiles) {
429
516
  if (await isMainContract(parsedArgs, filename)) {
430
517
  p.push(compileContractWithStorageAndParameter(parsedArgs, filename));
431
518
  }
432
519
  }
433
- return Promise.all(p).then((tables) => tables.flat()).then(import_node_sdk4.sendJsonRes).catch((err) => (0, import_node_sdk4.sendErr)(err, false));
520
+ return Promise.all(p).then((tables) => tables.flat()).then((table) => {
521
+ if (circularFiles.length > 0) {
522
+ console.warn(
523
+ "Warning: Circular dependencies detected in the following files. They have been skipped:"
524
+ );
525
+ console.warn(circularFiles.join(", "));
526
+ }
527
+ return table;
528
+ }).then(import_node_sdk4.sendJsonRes).catch((err) => (0, import_node_sdk4.sendErr)(err, false));
434
529
  };
435
530
  var compile_all_default = compileAll;
436
531
 
437
532
  // ligo.ts
438
533
  var import_node_sdk5 = require("@taqueria/node-sdk");
534
+ var import_node_sdk6 = require("@taqueria/node-sdk");
535
+ var import_path4 = require("path");
439
536
  var getArbitraryLigoCmd = (parsedArgs, uid, gid, userArgs) => {
440
537
  const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
441
538
  if (!projectDir)
@@ -463,7 +560,15 @@ var getArbitraryLigoCmd = (parsedArgs, uid, gid, userArgs) => {
463
560
  envVars
464
561
  ];
465
562
  };
466
- var runArbitraryLigoCmd = (parsedArgs, cmd) => (0, import_node_sdk5.getArch)().then(async () => {
563
+ var ensureEsyExists = async (parsedArgs) => {
564
+ const esyJsonPath = (0, import_path4.join)(parsedArgs.projectDir, "esy.json");
565
+ try {
566
+ return await (0, import_node_sdk6.readJsonFile)(esyJsonPath);
567
+ } catch {
568
+ return await (0, import_node_sdk6.writeJsonFile)(esyJsonPath)({});
569
+ }
570
+ };
571
+ var runArbitraryLigoCmd = (parsedArgs, cmd) => ensureEsyExists(parsedArgs).then(import_node_sdk5.getArch).then(async () => {
467
572
  const uid = await (0, import_node_sdk5.execCmd)("id -u");
468
573
  const gid = await (0, import_node_sdk5.execCmd)("id -g");
469
574
  return [uid.stdout.trim(), gid.stdout.trim()];
@@ -477,7 +582,7 @@ var ligo = (parsedArgs) => {
477
582
  var ligo_default = ligo;
478
583
 
479
584
  // test.ts
480
- var import_node_sdk6 = require("@taqueria/node-sdk");
585
+ var import_node_sdk7 = require("@taqueria/node-sdk");
481
586
  var getTestContractCmd = (parsedArgs, sourceFile) => {
482
587
  const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
483
588
  if (!projectDir)
@@ -487,9 +592,9 @@ var getTestContractCmd = (parsedArgs, sourceFile) => {
487
592
  const cmd = `${baseCmd} ${inputFile}`;
488
593
  return cmd;
489
594
  };
490
- var testContract = (parsedArgs, sourceFile) => (0, import_node_sdk6.getArch)().then(() => getTestContractCmd(parsedArgs, sourceFile)).then(import_node_sdk6.execCmd).then(({ stdout, stderr }) => {
595
+ var testContract = (parsedArgs, sourceFile) => (0, import_node_sdk7.getArch)().then(() => getTestContractCmd(parsedArgs, sourceFile)).then(import_node_sdk7.execCmd).then(({ stdout, stderr }) => {
491
596
  if (stderr.length > 0)
492
- (0, import_node_sdk6.sendWarn)(stderr);
597
+ (0, import_node_sdk7.sendWarn)(stderr);
493
598
  const result = "\u{1F389} All tests passed \u{1F389}";
494
599
  return {
495
600
  contract: sourceFile,
@@ -506,9 +611,9 @@ ${result}` : result
506
611
  var test = (parsedArgs) => {
507
612
  const sourceFile = parsedArgs.sourceFile;
508
613
  if (!sourceFile)
509
- return (0, import_node_sdk6.sendAsyncErr)(`No source file provided`);
510
- return testContract(parsedArgs, sourceFile).then((result) => [result]).then(import_node_sdk6.sendJsonRes).catch(
511
- (err) => (0, import_node_sdk6.sendAsyncErr)(err, false)
614
+ return (0, import_node_sdk7.sendAsyncErr)(`No source file provided`);
615
+ return testContract(parsedArgs, sourceFile).then((result) => [result]).then(import_node_sdk7.sendJsonRes).catch(
616
+ (err) => (0, import_node_sdk7.sendAsyncErr)(err, false)
512
617
  );
513
618
  };
514
619
  var test_default = test;
@@ -526,25 +631,25 @@ var main = (parsedArgs) => {
526
631
  case "test":
527
632
  return test_default(parsedArgs);
528
633
  case "get-image":
529
- return (0, import_node_sdk7.sendAsyncRes)(getLigoDockerImage());
634
+ return (0, import_node_sdk8.sendAsyncRes)(getLigoDockerImage());
530
635
  default:
531
- return (0, import_node_sdk7.sendAsyncErr)(`${unsafeOpts.task} is not an understood task by the LIGO plugin`);
636
+ return (0, import_node_sdk8.sendAsyncErr)(`${unsafeOpts.task} is not an understood task by the LIGO plugin`);
532
637
  }
533
638
  };
534
639
  var main_default = main;
535
640
 
536
641
  // index.ts
537
- import_node_sdk8.Plugin.create((i18n) => ({
642
+ import_node_sdk9.Plugin.create((i18n) => ({
538
643
  schema: "1.0",
539
644
  version: "0.1",
540
645
  alias: "ligo",
541
646
  tasks: [
542
- import_node_sdk8.Task.create({
647
+ import_node_sdk9.Task.create({
543
648
  task: "ligo",
544
649
  command: "ligo",
545
650
  description: "This task allows you to run arbitrary LIGO native commands. Note that they might not benefit from the abstractions provided by Taqueria",
546
651
  options: [
547
- import_node_sdk8.Option.create({
652
+ import_node_sdk9.Option.create({
548
653
  shortFlag: "c",
549
654
  flag: "command",
550
655
  type: "string",
@@ -555,13 +660,13 @@ import_node_sdk8.Plugin.create((i18n) => ({
555
660
  handler: "proxy",
556
661
  encoding: "none"
557
662
  }),
558
- import_node_sdk8.Task.create({
663
+ import_node_sdk9.Task.create({
559
664
  task: "compile",
560
665
  command: "compile <sourceFile>",
561
666
  aliases: ["c", "compile-ligo"],
562
667
  description: "Compile a smart contract written in a LIGO syntax to Michelson code, along with its associated storage/parameter list files if they are found",
563
668
  options: [
564
- import_node_sdk8.Option.create({
669
+ import_node_sdk9.Option.create({
565
670
  flag: "json",
566
671
  boolean: true,
567
672
  description: "Emit JSON-encoded Michelson"
@@ -570,12 +675,12 @@ import_node_sdk8.Plugin.create((i18n) => ({
570
675
  handler: "proxy",
571
676
  encoding: "json"
572
677
  }),
573
- import_node_sdk8.Task.create({
678
+ import_node_sdk9.Task.create({
574
679
  task: "compile-all",
575
680
  command: "compile-all",
576
681
  description: "Compile all main smart contracts written in a LIGO syntax to Michelson code, along with their associated storage/parameter list files if they are found",
577
682
  options: [
578
- import_node_sdk8.Option.create({
683
+ import_node_sdk9.Option.create({
579
684
  flag: "json",
580
685
  boolean: true,
581
686
  description: "Emit JSON-encoded Michelson"
@@ -584,14 +689,14 @@ import_node_sdk8.Plugin.create((i18n) => ({
584
689
  handler: "proxy",
585
690
  encoding: "json"
586
691
  }),
587
- import_node_sdk8.Task.create({
692
+ import_node_sdk9.Task.create({
588
693
  task: "test",
589
694
  command: "test <sourceFile>",
590
695
  description: "Test a smart contract written in LIGO",
591
696
  handler: "proxy",
592
697
  encoding: "json"
593
698
  }),
594
- import_node_sdk8.Task.create({
699
+ import_node_sdk9.Task.create({
595
700
  task: "get-image",
596
701
  command: "get-image",
597
702
  description: "Gets the name of the image to be used",
@@ -600,19 +705,19 @@ import_node_sdk8.Plugin.create((i18n) => ({
600
705
  })
601
706
  ],
602
707
  templates: [
603
- import_node_sdk8.Template.create({
708
+ import_node_sdk9.Template.create({
604
709
  template: "contract",
605
710
  command: "contract <sourceFileName>",
606
711
  description: "Create a LIGO contract with boilerplate code",
607
712
  positionals: [
608
- import_node_sdk8.PositionalArg.create({
713
+ import_node_sdk9.PositionalArg.create({
609
714
  placeholder: "sourceFileName",
610
715
  type: "string",
611
716
  description: "The name of the LIGO contract to generate"
612
717
  })
613
718
  ],
614
719
  options: [
615
- import_node_sdk8.Option.create({
720
+ import_node_sdk9.Option.create({
616
721
  shortFlag: "s",
617
722
  flag: "syntax",
618
723
  type: "string",