@taqueria/plugin-ligo 0.28.4 → 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/common.ts CHANGED
@@ -25,7 +25,7 @@ export type IntersectionOpts = LigoOpts & CompileOpts & CompileAllOpts & TestOpt
25
25
  type UnionOpts = LigoOpts | CompileOpts | CompileAllOpts | TestOpts;
26
26
 
27
27
  // Should point to the latest stable version, so it needs to be updated as part of our release process.
28
- const LIGO_DEFAULT_IMAGE = 'ligolang/ligo:0.57.0';
28
+ const LIGO_DEFAULT_IMAGE = 'ligolang/ligo:0.63.2';
29
29
 
30
30
  const LIGO_IMAGE_ENV_VAR = 'TAQ_LIGO_IMAGE';
31
31
 
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.d.ts CHANGED
@@ -1 +1,2 @@
1
1
 
2
+ export { }
package/index.js CHANGED
@@ -14,12 +14,16 @@ var __copyProps = (to, from, except, desc) => {
14
14
  return to;
15
15
  };
16
16
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
17
21
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
18
22
  mod
19
23
  ));
20
24
 
21
25
  // index.ts
22
- var import_node_sdk8 = require("@taqueria/node-sdk");
26
+ var import_node_sdk9 = require("@taqueria/node-sdk");
23
27
 
24
28
  // createContract.ts
25
29
  var import_node_sdk = require("@taqueria/node-sdk");
@@ -171,12 +175,12 @@ var createContract = (args) => {
171
175
  var createContract_default = createContract;
172
176
 
173
177
  // main.ts
174
- var import_node_sdk7 = require("@taqueria/node-sdk");
178
+ var import_node_sdk8 = require("@taqueria/node-sdk");
175
179
 
176
180
  // common.ts
177
181
  var import_node_sdk2 = require("@taqueria/node-sdk");
178
182
  var import_path = require("path");
179
- var LIGO_DEFAULT_IMAGE = "ligolang/ligo:0.57.0";
183
+ var LIGO_DEFAULT_IMAGE = "ligolang/ligo:0.63.2";
180
184
  var LIGO_IMAGE_ENV_VAR = "TAQ_LIGO_IMAGE";
181
185
  var getLigoDockerImage = () => (0, import_node_sdk2.getDockerImage)(LIGO_DEFAULT_IMAGE, LIGO_IMAGE_ENV_VAR);
182
186
  var getInputFilenameAbsPath = (parsedArgs, sourceFile) => (0, import_path.join)(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? "contracts", sourceFile);
@@ -199,6 +203,14 @@ var isLIGOFile = (sourceFile) => /.+\.(ligo|religo|mligo|jsligo)$/.test(sourceFi
199
203
  var isStorageListFile = (sourceFile) => /.+\.(storageList|storages)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
200
204
  var isParameterListFile = (sourceFile) => /.+\.(parameterList|parameters)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
201
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
+ };
202
214
  var extractExt = (path) => {
203
215
  const matchResult = path.match(/\.(ligo|religo|mligo|jsligo)$/);
204
216
  return matchResult ? matchResult[0] : "";
@@ -226,7 +238,7 @@ var getOutputExprFilename = (parsedArgs, sourceFile, exprKind, exprName) => {
226
238
  const outputFile = exprKind === "default_storage" ? `${contractName}.default_storage${ext}` : `${contractName}.${exprKind}.${exprName}${ext}`;
227
239
  return (0, import_path2.join)((0, import_node_sdk3.getArtifactsDir)(parsedArgs), `${outputFile}`);
228
240
  };
229
- var getCompileContractCmd = (parsedArgs, sourceFile) => {
241
+ var getCompileContractCmd = async (parsedArgs, sourceFile) => {
230
242
  const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
231
243
  if (!projectDir)
232
244
  throw `No project directory provided`;
@@ -234,7 +246,9 @@ var getCompileContractCmd = (parsedArgs, sourceFile) => {
234
246
  const inputFile = getInputFilenameRelPath(parsedArgs, sourceFile);
235
247
  const outputFile = `-o ${getOutputContractFilename(parsedArgs, sourceFile)}`;
236
248
  const flags = isOutputFormatJSON(parsedArgs) ? " --michelson-format json " : "";
237
- 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}`;
238
252
  return cmd;
239
253
  };
240
254
  var getCompileExprCmd = (parsedArgs, sourceFile, exprKind, exprName) => {
@@ -249,26 +263,32 @@ var getCompileExprCmd = (parsedArgs, sourceFile, exprKind, exprName) => {
249
263
  const cmd = `${baseCmd} ${inputFile} ${exprName} ${outputFile} ${flags}`;
250
264
  return cmd;
251
265
  };
252
- var compileContract = (parsedArgs, sourceFile) => (0, import_node_sdk3.getArch)().then(() => getCompileContractCmd(parsedArgs, sourceFile)).then(import_node_sdk3.execCmd).then(({ stderr }) => {
253
- if (stderr.length > 0)
254
- (0, import_node_sdk3.sendWarn)(stderr);
255
- return {
256
- contract: sourceFile,
257
- artifact: getOutputContractFilename(parsedArgs, sourceFile)
258
- };
259
- }).catch((err) => {
260
- emitExternalError(err, sourceFile);
261
- return {
262
- contract: sourceFile,
263
- artifact: COMPILE_ERR_MSG
264
- };
265
- });
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
+ };
266
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 }) => {
267
286
  if (stderr.length > 0)
268
287
  (0, import_node_sdk3.sendWarn)(stderr);
288
+ const artifactName = getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName);
269
289
  return {
270
290
  contract: sourceFile,
271
- artifact: getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName)
291
+ artifact: artifactName
272
292
  };
273
293
  }).catch((err) => {
274
294
  emitExternalError(err, sourceFile);
@@ -292,9 +312,14 @@ var compileExprs = (parsedArgs, sourceFile, exprKind) => getExprNames(parsedArgs
292
312
  emitExternalError(err, sourceFile);
293
313
  return [{
294
314
  contract: sourceFile,
295
- artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} values compiled`
315
+ artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} expressions compiled`
296
316
  }];
297
- }).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));
298
323
  var tryLegacyStorageNamingConvention = (parsedArgs, sourceFile) => {
299
324
  const storageListFile = `${removeExt(sourceFile)}.storages${extractExt(sourceFile)}`;
300
325
  const storageListFilename = getInputFilenameAbsPath(parsedArgs, storageListFile);
@@ -414,29 +439,106 @@ var import_node_sdk4 = require("@taqueria/node-sdk");
414
439
  var import_fast_glob = __toESM(require("fast-glob"));
415
440
  var import_promises3 = require("fs/promises");
416
441
  var import_path3 = require("path");
417
- 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
+ };
418
504
  var compileAll = async (parsedArgs) => {
419
505
  let p = [];
420
506
  const contractFilenames = await (0, import_fast_glob.default)(
421
507
  ["**/*.ligo", "**/*.religo", "**/*.mligo", "**/*.jsligo"],
422
- { 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
+ }
423
512
  );
424
- for (const filename of contractFilenames) {
513
+ const dependencyGraph = await buildDependencyGraph(parsedArgs, contractFilenames);
514
+ const { safeFiles, circularFiles } = detectCircularDependencies(dependencyGraph);
515
+ for (const filename of safeFiles) {
425
516
  if (await isMainContract(parsedArgs, filename)) {
426
517
  p.push(compileContractWithStorageAndParameter(parsedArgs, filename));
427
518
  }
428
519
  }
429
- 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));
430
529
  };
431
530
  var compile_all_default = compileAll;
432
531
 
433
532
  // ligo.ts
434
533
  var import_node_sdk5 = require("@taqueria/node-sdk");
435
- var getArbitraryLigoCmd = (parsedArgs, userArgs) => {
534
+ var import_node_sdk6 = require("@taqueria/node-sdk");
535
+ var import_path4 = require("path");
536
+ var getArbitraryLigoCmd = (parsedArgs, uid, gid, userArgs) => {
436
537
  const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
437
538
  if (!projectDir)
438
539
  throw `No project directory provided`;
439
- const owner = process.env.GID ? `${process.env.UID}:${process.env.GID}` : process.env.UID;
540
+ const userMap = uid && gid ? `${uid}:${gid}` : uid;
541
+ const userMapArgs = uid ? ["-u", userMap] : [];
440
542
  const binary = "docker";
441
543
  const baseArgs = [
442
544
  "run",
@@ -445,8 +547,7 @@ var getArbitraryLigoCmd = (parsedArgs, userArgs) => {
445
547
  `${projectDir}:/project`,
446
548
  "-w",
447
549
  "/project",
448
- "-u",
449
- owner,
550
+ ...userMapArgs,
450
551
  getLigoDockerImage()
451
552
  ];
452
553
  const processedUserArgs = userArgs.split(" ").map((arg) => arg.startsWith("\\-") ? arg.substring(1) : arg).filter(
@@ -459,7 +560,19 @@ var getArbitraryLigoCmd = (parsedArgs, userArgs) => {
459
560
  envVars
460
561
  ];
461
562
  };
462
- var runArbitraryLigoCmd = (parsedArgs, cmd) => (0, import_node_sdk5.getArch)().then(() => getArbitraryLigoCmd(parsedArgs, cmd)).then(([cmd2, envVars]) => (0, import_node_sdk5.spawnCmd)(cmd2, envVars)).then(
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 () => {
572
+ const uid = await (0, import_node_sdk5.execCmd)("id -u");
573
+ const gid = await (0, import_node_sdk5.execCmd)("id -g");
574
+ return [uid.stdout.trim(), gid.stdout.trim()];
575
+ }).then(([uid, gid]) => getArbitraryLigoCmd(parsedArgs, uid, gid, cmd)).then(([cmd2, envVars]) => (0, import_node_sdk5.spawnCmd)(cmd2, envVars)).then(
463
576
  (code) => code !== null && code === 0 ? `Command "${cmd}" ran successfully by LIGO` : `Command "${cmd}" failed. Please check your command`
464
577
  ).catch((err) => (0, import_node_sdk5.sendAsyncErr)(`An internal error has occurred: ${err.message}`));
465
578
  var ligo = (parsedArgs) => {
@@ -469,7 +582,7 @@ var ligo = (parsedArgs) => {
469
582
  var ligo_default = ligo;
470
583
 
471
584
  // test.ts
472
- var import_node_sdk6 = require("@taqueria/node-sdk");
585
+ var import_node_sdk7 = require("@taqueria/node-sdk");
473
586
  var getTestContractCmd = (parsedArgs, sourceFile) => {
474
587
  const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
475
588
  if (!projectDir)
@@ -479,9 +592,9 @@ var getTestContractCmd = (parsedArgs, sourceFile) => {
479
592
  const cmd = `${baseCmd} ${inputFile}`;
480
593
  return cmd;
481
594
  };
482
- 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 }) => {
483
596
  if (stderr.length > 0)
484
- (0, import_node_sdk6.sendWarn)(stderr);
597
+ (0, import_node_sdk7.sendWarn)(stderr);
485
598
  const result = "\u{1F389} All tests passed \u{1F389}";
486
599
  return {
487
600
  contract: sourceFile,
@@ -498,9 +611,9 @@ ${result}` : result
498
611
  var test = (parsedArgs) => {
499
612
  const sourceFile = parsedArgs.sourceFile;
500
613
  if (!sourceFile)
501
- return (0, import_node_sdk6.sendAsyncErr)(`No source file provided`);
502
- return testContract(parsedArgs, sourceFile).then((result) => [result]).then(import_node_sdk6.sendJsonRes).catch(
503
- (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)
504
617
  );
505
618
  };
506
619
  var test_default = test;
@@ -518,25 +631,25 @@ var main = (parsedArgs) => {
518
631
  case "test":
519
632
  return test_default(parsedArgs);
520
633
  case "get-image":
521
- return (0, import_node_sdk7.sendAsyncRes)(getLigoDockerImage());
634
+ return (0, import_node_sdk8.sendAsyncRes)(getLigoDockerImage());
522
635
  default:
523
- 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`);
524
637
  }
525
638
  };
526
639
  var main_default = main;
527
640
 
528
641
  // index.ts
529
- import_node_sdk8.Plugin.create((i18n) => ({
642
+ import_node_sdk9.Plugin.create((i18n) => ({
530
643
  schema: "1.0",
531
644
  version: "0.1",
532
645
  alias: "ligo",
533
646
  tasks: [
534
- import_node_sdk8.Task.create({
647
+ import_node_sdk9.Task.create({
535
648
  task: "ligo",
536
649
  command: "ligo",
537
650
  description: "This task allows you to run arbitrary LIGO native commands. Note that they might not benefit from the abstractions provided by Taqueria",
538
651
  options: [
539
- import_node_sdk8.Option.create({
652
+ import_node_sdk9.Option.create({
540
653
  shortFlag: "c",
541
654
  flag: "command",
542
655
  type: "string",
@@ -547,13 +660,13 @@ import_node_sdk8.Plugin.create((i18n) => ({
547
660
  handler: "proxy",
548
661
  encoding: "none"
549
662
  }),
550
- import_node_sdk8.Task.create({
663
+ import_node_sdk9.Task.create({
551
664
  task: "compile",
552
665
  command: "compile <sourceFile>",
553
666
  aliases: ["c", "compile-ligo"],
554
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",
555
668
  options: [
556
- import_node_sdk8.Option.create({
669
+ import_node_sdk9.Option.create({
557
670
  flag: "json",
558
671
  boolean: true,
559
672
  description: "Emit JSON-encoded Michelson"
@@ -562,12 +675,12 @@ import_node_sdk8.Plugin.create((i18n) => ({
562
675
  handler: "proxy",
563
676
  encoding: "json"
564
677
  }),
565
- import_node_sdk8.Task.create({
678
+ import_node_sdk9.Task.create({
566
679
  task: "compile-all",
567
680
  command: "compile-all",
568
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",
569
682
  options: [
570
- import_node_sdk8.Option.create({
683
+ import_node_sdk9.Option.create({
571
684
  flag: "json",
572
685
  boolean: true,
573
686
  description: "Emit JSON-encoded Michelson"
@@ -576,14 +689,14 @@ import_node_sdk8.Plugin.create((i18n) => ({
576
689
  handler: "proxy",
577
690
  encoding: "json"
578
691
  }),
579
- import_node_sdk8.Task.create({
692
+ import_node_sdk9.Task.create({
580
693
  task: "test",
581
694
  command: "test <sourceFile>",
582
695
  description: "Test a smart contract written in LIGO",
583
696
  handler: "proxy",
584
697
  encoding: "json"
585
698
  }),
586
- import_node_sdk8.Task.create({
699
+ import_node_sdk9.Task.create({
587
700
  task: "get-image",
588
701
  command: "get-image",
589
702
  description: "Gets the name of the image to be used",
@@ -592,19 +705,19 @@ import_node_sdk8.Plugin.create((i18n) => ({
592
705
  })
593
706
  ],
594
707
  templates: [
595
- import_node_sdk8.Template.create({
708
+ import_node_sdk9.Template.create({
596
709
  template: "contract",
597
710
  command: "contract <sourceFileName>",
598
711
  description: "Create a LIGO contract with boilerplate code",
599
712
  positionals: [
600
- import_node_sdk8.PositionalArg.create({
713
+ import_node_sdk9.PositionalArg.create({
601
714
  placeholder: "sourceFileName",
602
715
  type: "string",
603
716
  description: "The name of the LIGO contract to generate"
604
717
  })
605
718
  ],
606
719
  options: [
607
- import_node_sdk8.Option.create({
720
+ import_node_sdk9.Option.create({
608
721
  shortFlag: "s",
609
722
  flag: "syntax",
610
723
  type: "string",