@taqueria/plugin-ligo 0.37.21 → 0.37.34

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/index.mjs CHANGED
@@ -8,109 +8,33 @@ import { writeFile } from "fs/promises";
8
8
  // ligo_templates.ts
9
9
  var mligo_template = `
10
10
  type storage = int
11
-
12
- type parameter =
13
- Increment of int
14
- | Decrement of int
15
- | Reset
16
-
17
11
  type return = operation list * storage
18
12
 
19
- // Two entrypoints
20
-
21
- let add (store, delta : storage * int) : storage = store + delta
22
- let sub (store, delta : storage * int) : storage = store - delta
23
-
24
- (* Main access point that dispatches to the entrypoints according to
25
- the smart contract parameter. *)
26
-
27
- let main (action, store : parameter * storage) : return =
28
- ([] : operation list), // No operations
29
- (match action with
30
- Increment (n) -> add (store, n)
31
- | Decrement (n) -> sub (store, n)
32
- | Reset -> 0)
33
- `;
34
- var pascaligo_template = `
35
- type storage is int
36
-
37
- type parameter is
38
- Increment of int
39
- | Decrement of int
40
- | Reset
41
-
42
- type return is list (operation) * storage
43
-
44
- // Two entrypoints
45
-
46
- function add (const store : storage; const delta : int) : storage is
47
- store + delta
48
-
49
- function sub (const store : storage; const delta : int) : storage is
50
- store - delta
51
-
52
- (* Main access point that dispatches to the entrypoints according to
53
- the smart contract parameter. *)
54
-
55
- function main (const action : parameter; const store : storage) : return is
56
- ((nil : list (operation)), // No operations
57
- case action of [
58
- Increment (n) -> add (store, n)
59
- | Decrement (n) -> sub (store, n)
60
- | Reset -> 0
61
- ])
62
- `;
63
- var religo_template = `
64
- type storage = int;
65
-
66
- type parameter =
67
- Increment (int)
68
- | Decrement (int)
69
- | Reset;
70
-
71
- type return = (list (operation), storage);
72
-
73
- // Two entrypoints
74
-
75
- let add = ((store, delta) : (storage, int)) : storage => store + delta;
76
- let sub = ((store, delta) : (storage, int)) : storage => store - delta;
77
-
78
- /* Main access point that dispatches to the entrypoints according to
79
- the smart contract parameter. */
80
-
81
- let main = ((action, store) : (parameter, storage)) : return => {
82
- (([] : list (operation)), // No operations
83
- (switch (action) {
84
- | Increment (n) => add ((store, n))
85
- | Decrement (n) => sub ((store, n))
86
- | Reset => 0}))
87
- };
13
+ (* Three entrypoints *)
14
+ [@entry] let increment (delta : int) (store : storage) : return =
15
+ [], store + delta
16
+ [@entry] let decrement (delta : int) (store : storage) : return =
17
+ [], store - delta
18
+ [@entry] let reset (() : unit) (_ : storage) : return =
19
+ [], 0
88
20
  `;
89
21
  var jsligo_template = `
90
22
  type storage = int;
91
-
92
- type parameter =
93
- ["Increment", int]
94
- | ["Decrement", int]
95
- | ["Reset"];
96
-
97
23
  type ret = [list<operation>, storage];
98
24
 
99
- // Two entrypoints
25
+ // Three entrypoints
100
26
 
101
- const add = ([store, delta] : [storage, int]) : storage => store + delta;
102
- const sub = ([store, delta] : [storage, int]) : storage => store - delta;
27
+ // @entry
28
+ const increment = (delta : int, store : storage) : ret =>
29
+ [list([]), store + delta];
103
30
 
104
- /* Main access point that dispatches to the entrypoints according to
105
- the smart contract parameter. */
31
+ // @entry
32
+ const decrement = (delta : int, store : storage) : ret =>
33
+ [list([]), store - delta];
106
34
 
107
- const main = ([action, store] : [parameter, storage]) : ret => {
108
- return [list([]) as list<operation>, // No operations
109
- match (action, {
110
- Increment:(n: int) => add ([store, n]),
111
- Decrement:(n: int) => sub ([store, n]),
112
- Reset :() => 0})]
113
- };
35
+ // @entry
36
+ const reset = (_ : unit, _ : storage) : ret =>
37
+ [list([]), 0];
114
38
  `;
115
39
 
116
40
  // createContract.ts
@@ -119,19 +43,11 @@ var getLigoTemplate = async (contractName, syntax) => {
119
43
  const ext = matchResult ? matchResult[0].substring(1) : null;
120
44
  if (syntax === "mligo")
121
45
  return mligo_template;
122
- if (syntax === "ligo")
123
- return pascaligo_template;
124
- if (syntax === "religo")
125
- return religo_template;
126
46
  if (syntax === "jsligo")
127
47
  return jsligo_template;
128
48
  if (syntax === void 0) {
129
49
  if (ext === "mligo")
130
50
  return mligo_template;
131
- if (ext === "ligo")
132
- return pascaligo_template;
133
- if (ext === "religo")
134
- return religo_template;
135
51
  if (ext === "jsligo")
136
52
  return jsligo_template;
137
53
  return sendAsyncErr(
@@ -156,7 +72,7 @@ import { sendAsyncErr as sendAsyncErr5, sendAsyncRes } from "@taqueria/node-sdk"
156
72
  // common.ts
157
73
  import { getDockerImage, sendErr } from "@taqueria/node-sdk";
158
74
  import { join } from "path";
159
- var LIGO_DEFAULT_IMAGE = "ligolang/ligo:0.69.0";
75
+ var LIGO_DEFAULT_IMAGE = "ligolang/ligo:0.71.0";
160
76
  var LIGO_IMAGE_ENV_VAR = "TAQ_LIGO_IMAGE";
161
77
  var getLigoDockerImage = () => getDockerImage(LIGO_DEFAULT_IMAGE, LIGO_IMAGE_ENV_VAR);
162
78
  var getInputFilenameAbsPath = (parsedArgs, sourceFile) => join(parsedArgs.config.projectDir, parsedArgs.config.contractsDir ?? "contracts", sourceFile);
@@ -170,22 +86,75 @@ var emitExternalError = (err, sourceFile) => {
170
86
  };
171
87
 
172
88
  // compile.ts
173
- import { execCmd, getArch, getArtifactsDir, sendAsyncErr as sendAsyncErr2, sendErr as sendErr2, sendJsonRes, sendWarn } from "@taqueria/node-sdk";
89
+ import {
90
+ execCmd,
91
+ getArch,
92
+ getArtifactsDir,
93
+ sendErr as sendErr2,
94
+ sendJsonRes,
95
+ sendWarn
96
+ } from "@taqueria/node-sdk";
174
97
  import { access, readFile, writeFile as writeFile2 } from "fs/promises";
175
- import { basename, extname, join as join2 } from "path";
98
+ import { basename, join as join2 } from "path";
176
99
  var COMPILE_ERR_MSG = "Not compiled";
177
100
  var isStorageKind = (exprKind) => exprKind === "storage" || exprKind === "default_storage";
178
- var isLIGOFile = (sourceFile) => /.+\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
101
+ var isSupportedLigoSyntax = (sourceFile) => /\.(mligo|jsligo)$/.test(sourceFile);
102
+ var isUnsupportedLigoSyntax = (sourceFile) => /\.(ligo|religo)$/.test(sourceFile);
103
+ var isLIGOFile = (sourceFile) => isSupportedLigoSyntax(sourceFile) || isUnsupportedLigoSyntax(sourceFile);
179
104
  var isStorageListFile = (sourceFile) => /.+\.(storageList|storages)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
180
105
  var isParameterListFile = (sourceFile) => /.+\.(parameterList|parameters)\.(ligo|religo|mligo|jsligo)$/.test(sourceFile);
181
- var isContractFile = (sourceFile) => isLIGOFile(sourceFile) && !isStorageListFile(sourceFile) && !isParameterListFile(sourceFile);
182
- var getModuleName = async (parsedArgs, sourceFile) => {
183
- const fileContent = await readFile(getInputFilenameAbsPath(parsedArgs, sourceFile), "utf8");
184
- if (fileContent.includes("@entry") && fileContent.includes("module")) {
185
- const match = fileContent.match(/module ([^\s]+)/);
186
- return match ? match[1] : void 0;
106
+ var listContractModules = async (parsedArgs, sourceFile) => {
107
+ try {
108
+ await getArch();
109
+ const cmd = await getListDeclarationsCmd(parsedArgs, sourceFile);
110
+ const { stderr, stdout } = await execCmd(cmd);
111
+ if (stderr.length > 0)
112
+ return Promise.reject(stderr);
113
+ return JSON.parse(stdout).declarations.reduce(
114
+ (acc, decl) => {
115
+ const srcFile = removeExt(basename(sourceFile));
116
+ const syntax = extractExt(sourceFile).replace(".", "");
117
+ if (decl === "main") {
118
+ return [...acc, { moduleName: srcFile, sourceName: sourceFile, sourceFile, type: "file-main", syntax }];
119
+ } else if (decl === "$main") {
120
+ return [...acc, { moduleName: srcFile, sourceName: sourceFile, sourceFile, type: "file-entry", syntax }];
121
+ } else if (decl.endsWith(".main")) {
122
+ const moduleName = decl.replace(/\.main$/, "");
123
+ return [...acc, {
124
+ moduleName,
125
+ sourceName: `${sourceFile}/${moduleName}`,
126
+ sourceFile,
127
+ type: "module-main",
128
+ syntax
129
+ }];
130
+ } else if (decl.endsWith(".$main")) {
131
+ const moduleName = decl.replace(/\.\$main$/, "");
132
+ return [...acc, {
133
+ moduleName,
134
+ sourceName: `${sourceFile}/${moduleName}`,
135
+ sourceFile,
136
+ type: "module-entry",
137
+ syntax
138
+ }];
139
+ }
140
+ return acc;
141
+ },
142
+ []
143
+ );
144
+ } catch (err) {
145
+ emitExternalError(err, sourceFile);
146
+ return [];
187
147
  }
188
- return void 0;
148
+ };
149
+ var getListDeclarationsCmd = async (parsedArgs, sourceFile) => {
150
+ const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
151
+ if (!projectDir)
152
+ throw new Error(`No project directory provided`);
153
+ const baseCmd = `DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run --rm -v "${projectDir}":/project -w /project -u $(id -u):$(id -g) ${getLigoDockerImage()} info list-declarations`;
154
+ const inputFile = getInputFilenameRelPath(parsedArgs, sourceFile);
155
+ const flags = "--display-format json";
156
+ const cmd = `${baseCmd} ${inputFile} ${flags}`;
157
+ return cmd;
189
158
  };
190
159
  var extractExt = (path) => {
191
160
  const matchResult = path.match(/\.(ligo|religo|mligo|jsligo)$/);
@@ -196,291 +165,396 @@ var removeExt = (path) => {
196
165
  return path.replace(extRegex, "");
197
166
  };
198
167
  var isOutputFormatJSON = (parsedArgs) => parsedArgs.json;
199
- var getOutputContractFilename = (parsedArgs, sourceFile) => {
200
- const outputFile = basename(sourceFile, extname(sourceFile));
168
+ var getOutputContractFilename = (parsedArgs, module) => {
201
169
  const ext = isOutputFormatJSON(parsedArgs) ? ".json" : ".tz";
202
- return join2(getArtifactsDir(parsedArgs), `${outputFile}${ext}`);
170
+ return join2(getArtifactsDir(parsedArgs), `${module.moduleName}${ext}`);
203
171
  };
204
- var getContractNameForExpr = (sourceFile, exprKind) => {
205
- try {
206
- return isStorageKind(exprKind) ? sourceFile.match(/.+(?=\.(?:storageList|storages)\.(ligo|religo|mligo|jsligo))/).join(".") : sourceFile.match(/.+(?=\.(?:parameterList|parameters)\.(ligo|religo|mligo|jsligo))/).join(".");
207
- } catch (err) {
208
- throw new Error(`Something went wrong internally when dealing with filename format: ${err}`);
209
- }
210
- };
211
- var getOutputExprFilename = (parsedArgs, sourceFile, exprKind, exprName) => {
212
- const contractName = basename(getContractNameForExpr(sourceFile, exprKind), extname(sourceFile));
172
+ var getOutputExprFilename = (parsedArgs, module, exprKind, exprName) => {
173
+ const contractName = module.moduleName;
213
174
  const ext = isOutputFormatJSON(parsedArgs) ? ".json" : ".tz";
214
175
  const outputFile = exprKind === "default_storage" ? `${contractName}.default_storage${ext}` : `${contractName}.${exprKind}.${exprName}${ext}`;
215
176
  return join2(getArtifactsDir(parsedArgs), `${outputFile}`);
216
177
  };
217
- var getCompileContractCmd = async (parsedArgs, sourceFile) => {
178
+ var getCompileContractCmd = async (parsedArgs, sourceFile, module) => {
218
179
  const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
219
180
  if (!projectDir)
220
- throw `No project directory provided`;
181
+ throw new Error(`No project directory provided`);
221
182
  const baseCmd = `DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run --rm -v "${projectDir}":/project -w /project -u $(id -u):$(id -g) ${getLigoDockerImage()} compile contract`;
222
183
  const inputFile = getInputFilenameRelPath(parsedArgs, sourceFile);
223
- const outputFile = `-o ${getOutputContractFilename(parsedArgs, sourceFile)}`;
184
+ const outputFile = `-o ${getOutputContractFilename(parsedArgs, module)}`;
224
185
  const flags = isOutputFormatJSON(parsedArgs) ? " --michelson-format json " : "";
225
- const moduleName = await getModuleName(parsedArgs, sourceFile);
226
- const entryFlag = moduleName ? `-m ${moduleName}` : "";
227
- const cmd = `${baseCmd} ${inputFile} ${outputFile} ${flags}${entryFlag}`;
186
+ const moduleFlag = module.type.startsWith("file-") ? "" : `-m ${module.moduleName}`;
187
+ const cmd = `${baseCmd} ${inputFile} ${outputFile} ${flags}${moduleFlag}`;
228
188
  return cmd;
229
189
  };
230
- var getCompileExprCmd = (parsedArgs, sourceFile, exprKind, exprName) => {
190
+ var getCompileExprCmd = (parsedArgs, sourceFile, module, exprKind, exprName) => {
231
191
  const projectDir = process.env.PROJECT_DIR ?? parsedArgs.projectDir;
232
192
  if (!projectDir)
233
- throw `No project directory provided`;
193
+ throw new Error(`No project directory provided`);
234
194
  const compilerType = isStorageKind(exprKind) ? "storage" : "parameter";
235
195
  const baseCmd = `DOCKER_DEFAULT_PLATFORM=linux/amd64 docker run --rm -v "${projectDir}":/project -w /project -u $(id -u):$(id -g) ${getLigoDockerImage()} compile ${compilerType}`;
236
196
  const inputFile = getInputFilenameRelPath(parsedArgs, sourceFile);
237
- const outputFile = `-o ${getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName)}`;
197
+ const outputFile = `-o ${getOutputExprFilename(parsedArgs, module, exprKind, exprName)}`;
238
198
  const flags = isOutputFormatJSON(parsedArgs) ? " --michelson-format json " : "";
239
- const cmd = `${baseCmd} ${inputFile} ${exprName} ${outputFile} ${flags}`;
199
+ const moduleFlag = (() => {
200
+ switch (module.type) {
201
+ case "file-main":
202
+ case "file-entry":
203
+ return "-m Contract";
204
+ default:
205
+ return `-m Contract.${module.moduleName}`;
206
+ }
207
+ })();
208
+ const cmd = `${baseCmd} ${inputFile} ${exprName} ${outputFile} ${flags} ${moduleFlag}`;
240
209
  return cmd;
241
210
  };
242
- var compileContract = async (parsedArgs, sourceFile) => {
211
+ var compileContract = async (parsedArgs, sourceFile, module) => {
243
212
  try {
244
213
  await getArch();
245
- const cmd = await getCompileContractCmd(parsedArgs, sourceFile);
214
+ const cmd = await getCompileContractCmd(parsedArgs, sourceFile, module);
246
215
  const { stderr } = await execCmd(cmd);
247
216
  if (stderr.length > 0)
248
217
  sendWarn(stderr);
249
218
  return {
250
- contract: sourceFile,
251
- artifact: getOutputContractFilename(parsedArgs, sourceFile)
219
+ source: module.sourceName,
220
+ artifact: getOutputContractFilename(parsedArgs, module)
252
221
  };
253
222
  } catch (err) {
254
223
  emitExternalError(err, sourceFile);
255
224
  return {
256
- contract: sourceFile,
225
+ source: module.sourceName,
257
226
  artifact: COMPILE_ERR_MSG
258
227
  };
259
228
  }
260
229
  };
261
- var compileExpr = (parsedArgs, sourceFile, exprKind) => (exprName) => getArch().then(() => getCompileExprCmd(parsedArgs, sourceFile, exprKind, exprName)).then(execCmd).then(({ stderr }) => {
262
- if (stderr.length > 0)
263
- sendWarn(stderr);
264
- const artifactName = getOutputExprFilename(parsedArgs, sourceFile, exprKind, exprName);
265
- return {
266
- contract: sourceFile,
267
- artifact: artifactName
268
- };
269
- }).catch((err) => {
270
- emitExternalError(err, sourceFile);
271
- return {
272
- contract: sourceFile,
273
- artifact: COMPILE_ERR_MSG
274
- };
275
- });
230
+ var compileExpr = (parsedArgs, sourceFile, module, exprKind) => (exprName) => {
231
+ return getArch().then(() => getCompileExprCmd(parsedArgs, sourceFile, module, exprKind, exprName)).then(execCmd).then(({ stderr }) => {
232
+ if (stderr.length > 0)
233
+ sendWarn(stderr);
234
+ const artifactName = getOutputExprFilename(parsedArgs, module, exprKind, exprName);
235
+ return {
236
+ source: module.sourceName,
237
+ artifact: artifactName
238
+ };
239
+ }).catch((err) => {
240
+ emitExternalError(err, sourceFile);
241
+ return {
242
+ source: module.sourceName,
243
+ artifact: `${sourceFile} not compiled`
244
+ };
245
+ });
246
+ };
276
247
  var getExprNames = (parsedArgs, sourceFile) => readFile(getInputFilenameAbsPath(parsedArgs, sourceFile), "utf8").then((data) => data.match(/(?<=\n\s*(let|const)\s+)[a-zA-Z0-9_]+/g) ?? []);
277
- var compileExprs = (parsedArgs, sourceFile, exprKind) => getExprNames(parsedArgs, sourceFile).then((exprNames) => {
248
+ var compileExprs = (parsedArgs, sourceFile, module, exprKind) => getExprNames(parsedArgs, sourceFile).then((exprNames) => {
278
249
  if (exprNames.length === 0)
279
250
  return [];
280
251
  const firstExprName = exprNames.slice(0, 1)[0];
281
252
  const restExprNames = exprNames.slice(1, exprNames.length);
282
253
  const firstExprKind = isStorageKind(exprKind) ? "default_storage" : "parameter";
283
254
  const restExprKind = isStorageKind(exprKind) ? "storage" : "parameter";
284
- const firstExprResult = compileExpr(parsedArgs, sourceFile, firstExprKind)(firstExprName);
285
- const restExprResults = restExprNames.map(compileExpr(parsedArgs, sourceFile, restExprKind));
255
+ const firstExprResult = compileExpr(parsedArgs, sourceFile, module, firstExprKind)(firstExprName);
256
+ const restExprResults = restExprNames.map(compileExpr(parsedArgs, sourceFile, module, restExprKind));
286
257
  return Promise.all([firstExprResult].concat(restExprResults));
287
258
  }).catch((err) => {
288
259
  emitExternalError(err, sourceFile);
289
260
  return [{
290
- contract: sourceFile,
261
+ source: module.sourceName,
291
262
  artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} expressions compiled`
292
263
  }];
293
264
  }).then(
294
265
  (results) => results.length > 0 ? results : [{
295
- contract: sourceFile,
266
+ source: module.sourceName,
296
267
  artifact: `No ${isStorageKind(exprKind) ? "storage" : "parameter"} expressions found`
297
268
  }]
298
- ).then(mergeArtifactsOutput(sourceFile));
299
- var tryLegacyStorageNamingConvention = (parsedArgs, sourceFile) => {
300
- const storageListFile = `${removeExt(sourceFile)}.storages${extractExt(sourceFile)}`;
301
- const storageListFilename = getInputFilenameAbsPath(parsedArgs, storageListFile);
302
- return access(storageListFilename).then(() => {
303
- sendWarn(
304
- `Warning: The naming convention of "<CONTRACT>.storages.<EXTENSION>" is deprecated and renamed to "<CONTRACT>.storageList.<EXTENSION>". Please adjust your storage file names accordingly
305
- `
306
- );
307
- return compileExprs(parsedArgs, storageListFile, "storage");
308
- });
309
- };
310
- var tryLegacyParameterNamingConvention = (parsedArgs, sourceFile) => {
311
- const parameterListFile = `${removeExt(sourceFile)}.parameters${extractExt(sourceFile)}`;
312
- const parameterListFilename = getInputFilenameAbsPath(parsedArgs, parameterListFile);
313
- return access(parameterListFilename).then(() => {
314
- sendWarn(
315
- `Warning: The naming convention of "<CONTRACT>.parameters.<EXTENSION>" is deprecated and renamed to "<CONTRACT>.parameterList.<EXTENSION>". Please adjust your parameter file names accordingly
316
- `
317
- );
318
- return compileExprs(parsedArgs, parameterListFile, "parameter");
319
- });
320
- };
321
- var initContentForStorage = (sourceFile) => {
322
- const linkToContract = `#include "${sourceFile}"
269
+ );
270
+ var initContentForStorage = (module) => {
271
+ const linkToContract = `#import "${module.sourceFile}" "Contract"
323
272
 
324
273
  `;
325
- const instruction = "// Define your initial storage values as a list of LIGO variable definitions,\n// the first of which will be considered the default value to be used for origination later on\n";
326
- const ext = extractExt(sourceFile);
327
- let syntax = "";
328
- if (ext === ".ligo")
329
- syntax = "// E.g. const aStorageValue : aStorageType = 10;\n\n";
330
- else if (ext === ".religo")
331
- syntax = "// E.g. let aStorageValue : aStorageType = 10;\n\n";
332
- else if (ext === ".mligo")
333
- syntax = "// E.g. let aStorageValue : aStorageType = 10\n\n";
334
- else if (ext === ".jsligo")
335
- syntax = "// E.g. const aStorageValue : aStorageType = 10;\n\n";
336
- return linkToContract + instruction + syntax;
274
+ const instruction = "// Define your initial storage values as a list of LIGO variable definitions, the first of which will be considered the default value to be used for origination later on\n";
275
+ const syntax = (() => {
276
+ const pair = [module.syntax, module.type].join("-");
277
+ switch (pair) {
278
+ case "mligo-file-main":
279
+ return [
280
+ "// When this file was created, the smart contract was defined with a main function that was not within a named module. As such, the examples below are written with that assumption in mind.",
281
+ "",
282
+ "// If your storage is a simple value, you can define it directly",
283
+ "// E.g. let storage = 10",
284
+ "",
285
+ "// For added type-safety, you can reference the type of your storage from the contract",
286
+ "// E.g. let storage : Contract.storage = 10"
287
+ ];
288
+ break;
289
+ case "mligo-file-entry":
290
+ return [
291
+ "// When this file was created, the smart contract was defined with an entrypoint using `@entry` that was not within a named module. As such, the examples below are written with that assumption in mind.",
292
+ "",
293
+ "// If your storage is a simple value, you can define it directly",
294
+ "// E.g. let storage = 10",
295
+ "",
296
+ "// For added type-safety, you can reference the type of your storage from the contract",
297
+ "// E.g. let storage : Contract.storage = 10"
298
+ ];
299
+ break;
300
+ case "mligo-module-main":
301
+ return [
302
+ "// When this file was created, the smart contract was defined with a main function that was within a named module. As such, the examples below are written with that assumption in mind.",
303
+ "",
304
+ "// If your storage is a simple value, you can define it directly",
305
+ "// E.g. let storage = 10",
306
+ "",
307
+ "// For added type-safety, you can reference the type of your storage from the contract",
308
+ `// E.g. let storage : Contract.${module.moduleName}.storage = 10`
309
+ ];
310
+ break;
311
+ case "mligo-module-entry":
312
+ return [
313
+ "// When this file was created, the smart contract was defined with an entrypoint using `@entry` that was within a named module. As such, the examples below are written with that assumption in mind.",
314
+ "",
315
+ "// If your storage is a simple value, you can define it directly",
316
+ "// E.g. let storage = 10",
317
+ "",
318
+ "// For added type-safety, you can reference the type of your storage from the contract",
319
+ `// E.g. let storage : Contract.${module.moduleName}.storage = 10`
320
+ ];
321
+ break;
322
+ case "jsligo-file-main":
323
+ return [
324
+ "// When this file was created, the smart contract was defined with a main function that was not within a namespace. As such, the examples below are written with that assumption in mind.",
325
+ `// NOTE: The "storage" type should be exported from the contract file (${module.sourceFile})`,
326
+ "",
327
+ "// If your storage is a simple value, you can define it directly",
328
+ "// E.g. const storage = 10",
329
+ "",
330
+ "// For added type-safety, you can reference the type of your storage from the contract. This assumes that you have exported your `storage` type from the contract file.",
331
+ "// E.g. const storage : Contract.storage = 10"
332
+ ];
333
+ break;
334
+ case "jsligo-file-entry":
335
+ return [
336
+ "// When this file was created, the smart contract was defined with an entrypoint using `@entry` that was not within a namespace. As such, the examples below are written with that assumption in mind.",
337
+ "",
338
+ "// If your storage is a simple value, you can define it directly",
339
+ "// E.g. const storage = 10",
340
+ "",
341
+ "// For added type-safety, you can reference the type of your storage from the contract. This assumes that you have exported your `storage` type from the contract file.",
342
+ "// E.g. const storage : Contract.storage = 10"
343
+ ];
344
+ break;
345
+ case "jsligo-module-main":
346
+ return [
347
+ "// When this file was created, the smart contract was defined with a main function that was within a namespace. As such, the examples below are written with that assumption in mind.",
348
+ `// NOTE: The "storage" type should be exported from the contract file (${module.sourceFile})`,
349
+ "",
350
+ "// If your storage is a simple value, you can define it directly",
351
+ "// E.g. const storage = 10",
352
+ "",
353
+ "// For added type-safety, you can reference the type of your storage from the contract. This assumes that you have exported your `storage` type from the contract file.",
354
+ `// E.g. const storage : Contract.${module.moduleName}.storage = 10`
355
+ ];
356
+ break;
357
+ case "jsligo-module-entry":
358
+ return [
359
+ "// When this file was created, the smart contract was defined with an entrypoint using `@entry` that was within a namespace. As such, the examples below are written with that assumption in mind.",
360
+ "",
361
+ "// If your storage is a simple value, you can define it directly",
362
+ "// E.g. const storage = 10",
363
+ "",
364
+ "// For added type-safety, you can reference the type of your storage from the contract. This assumes that you have exported your `storage` type from the contract file.",
365
+ `// E.g. const storage : Contract.${module.moduleName}.storage = 10`
366
+ ];
367
+ break;
368
+ default:
369
+ return [];
370
+ }
371
+ })();
372
+ return linkToContract + instruction + syntax.join("\n");
337
373
  };
338
- var initContentForParameter = (sourceFile) => {
339
- const linkToContract = `#include "${sourceFile}"
374
+ var initContentForParameter = (module) => {
375
+ const linkToContract = `#import "${module.sourceFile}" "Contract"
340
376
 
341
377
  `;
342
378
  const instruction = "// Define your parameter values as a list of LIGO variable definitions\n";
343
- const ext = extractExt(sourceFile);
344
- let syntax = "";
345
- if (ext === ".ligo")
346
- syntax = "// E.g. const aParameterValue : aParameterType = Increment(1);\n\n";
347
- else if (ext === ".religo")
348
- syntax = "// E.g. let aParameterValue : aParameterType = (Increment (1));\n\n";
349
- else if (ext === ".mligo")
350
- syntax = "// E.g. let aParameterValue : aParameterType = Increment 1\n\n";
351
- else if (ext === ".jsligo")
352
- syntax = "// E.g. const aParameterValue : aParameterType = (Increment (1));\n\n";
353
- return linkToContract + instruction + syntax;
379
+ const syntax = (() => {
380
+ const pair = [module.syntax, module.type].join("-");
381
+ switch (pair) {
382
+ case "mligo-file-main":
383
+ return [
384
+ "// When this file was created, the smart contract was defined with a main function that was not within a named module. As such, the examples below are written with that assumption in mind.",
385
+ "",
386
+ "// If your parameter is a simple value, you can define it directly",
387
+ "// E.g. let default_parameter = 10",
388
+ "",
389
+ "// For added type-safety, you can reference the type of your parameter from the contract",
390
+ "// E.g. let default_parameter : Contract.parameter = 10"
391
+ ];
392
+ break;
393
+ case "mligo-file-entry":
394
+ return [
395
+ "// When this file was created, the smart contract was defined with an entrypoint using `@entry` that was not within a named module. As such, the examples below are written with that assumption in mind.",
396
+ "",
397
+ "// If your parameter is a simple value, you can define it directly",
398
+ "// E.g. let default_parameter = 10",
399
+ "",
400
+ "// For added type-safety, you can reference the type of your parameter from the contract",
401
+ "// E.g. let default_parameter : parameter_of Contract = 10"
402
+ ];
403
+ break;
404
+ case "mligo-module-main":
405
+ return [
406
+ "// When this file was created, the smart contract was defined with a main function that was within a named module. As such, the examples below are written with that assumption in mind.",
407
+ "",
408
+ "// If your parameter is a simple value, you can define it directly",
409
+ "// E.g. let default_parameter = 10",
410
+ "",
411
+ "// For added type-safety, you can reference the type of your parameter from the contract",
412
+ `// E.g. let default_parameter : Contract.${module.moduleName}.parameter = 10`
413
+ ];
414
+ break;
415
+ case "mligo-module-entry":
416
+ return [
417
+ "// When this file was created, the smart contract was defined with an entrypoint using `@entry` that was within a named module. As such, the examples below are written with that assumption in mind.",
418
+ "",
419
+ "// If your parameter is a simple value, you can define it directly",
420
+ "// E.g. let default_parameter = 10",
421
+ "",
422
+ "// For added type-safety, you can reference the type of your parameter from the contract",
423
+ `// E.g. let default_parameter : parameter_of Contract.${module.moduleName} = 10`
424
+ ];
425
+ break;
426
+ case "jsligo-file-main":
427
+ return [
428
+ "// When this file was created, the smart contract was defined with a main function that was not within a namespace. As such, the examples below are written with that assumption in mind.",
429
+ `// NOTE: The "parameter" type should be exported from the contract file (${module.sourceFile})`,
430
+ "",
431
+ "// If your parameter is a simple value, you can define it directly",
432
+ "// E.g. const default_parameter = 10",
433
+ "",
434
+ "// For added type-safety, you can reference the type of your parameter from the contract",
435
+ "// E.g. const default_parameter : Contract.parameter = 10"
436
+ ];
437
+ break;
438
+ case "jsligo-file-entry":
439
+ return [
440
+ "// When this file was created, the smart contract was defined with an entrypoint using `@entry` that was not within a namespace. As such, the examples below are written with that assumption in mind.",
441
+ "",
442
+ "// If your parameter is a simple value, you can define it directly",
443
+ "// E.g. const default_parameter = 10",
444
+ "",
445
+ "// For added type-safety, you can reference the type of your parameter from the contract",
446
+ "// E.g. const default_parameter : parameter_of Contract = 10"
447
+ ];
448
+ break;
449
+ case "jsligo-module-main":
450
+ return [
451
+ "// When this file was created, the smart contract was defined with a main function that was within a namespace. As such, the examples below are written with that assumption in mind.",
452
+ `// NOTE: The "parameter" type should be exported from the contract file (${module.sourceFile})`,
453
+ "",
454
+ "// If your parameter is a simple value, you can define it directly",
455
+ "// E.g. const default_parameter = 10",
456
+ "",
457
+ "// For added type-safety, you can reference the type of your parameter from the contract",
458
+ `// E.g. const default_parameter : Contract.${module.moduleName}.parameter = 10`
459
+ ];
460
+ break;
461
+ case "jsligo-module-entry":
462
+ return [
463
+ "// When this file was created, the smart contract was defined with an entrypoint using `@entry` that was within a namespace. As such, the examples below are written with that assumption in mind.",
464
+ "",
465
+ "// If your parameter is a simple value, you can define it directly",
466
+ "// E.g. const default_parameter = 10",
467
+ "",
468
+ "// For added type-safety, you can reference the type of your parameter from the contract",
469
+ `// E.g. const default_parameter : parameter_of Contract.${module.moduleName} = 10`
470
+ ];
471
+ break;
472
+ default:
473
+ return [];
474
+ }
475
+ })();
476
+ return linkToContract + instruction + syntax.join("\n");
354
477
  };
355
- var compileContractWithStorageAndParameter = async (parsedArgs, sourceFile) => {
356
- const contractCompileResult = await compileContract(parsedArgs, sourceFile);
478
+ var compileContractWithStorageAndParameter = async (parsedArgs, sourceFile, module) => {
479
+ const contractCompileResult = await compileContract(parsedArgs, sourceFile, module);
357
480
  if (contractCompileResult.artifact === COMPILE_ERR_MSG)
358
481
  return [contractCompileResult];
359
- const storageListFile = `${removeExt(sourceFile)}.storageList${extractExt(sourceFile)}`;
482
+ const storageListFile = `${module.moduleName}.storageList${extractExt(sourceFile)}`;
360
483
  const storageListFilename = getInputFilenameAbsPath(parsedArgs, storageListFile);
361
- const storageCompileResult = await access(storageListFilename).then(() => compileExprs(parsedArgs, storageListFile, "storage")).catch(() => tryLegacyStorageNamingConvention(parsedArgs, sourceFile)).catch(() => {
484
+ const storageCompileResult = await access(storageListFilename).then(() => compileExprs(parsedArgs, storageListFile, module, "storage")).catch(() => {
362
485
  sendWarn(
363
- `Note: storage file associated with "${sourceFile}" can't be found, so "${storageListFile}" has been created for you. Use this file to define all initial storage values for this contract
486
+ `Note: storage file associated with "${module.moduleName}" can't be found, so "${storageListFile}" has been created for you. Use this file to define all initial storage values for this contract
364
487
  `
365
488
  );
366
- writeFile2(storageListFilename, initContentForStorage(sourceFile), "utf8");
489
+ return writeFile2(storageListFilename, initContentForStorage(module), "utf8");
367
490
  });
368
- const parameterListFile = `${removeExt(sourceFile)}.parameterList${extractExt(sourceFile)}`;
491
+ const parameterListFile = `${module.moduleName}.parameterList${extractExt(sourceFile)}`;
369
492
  const parameterListFilename = getInputFilenameAbsPath(parsedArgs, parameterListFile);
370
- const parameterCompileResult = await access(parameterListFilename).then(() => compileExprs(parsedArgs, parameterListFile, "parameter")).catch(() => tryLegacyParameterNamingConvention(parsedArgs, sourceFile)).catch(() => {
493
+ const parameterCompileResult = await access(parameterListFilename).then(() => compileExprs(parsedArgs, parameterListFile, module, "parameter")).catch(() => {
371
494
  sendWarn(
372
- `Note: parameter file associated with "${sourceFile}" can't be found, so "${parameterListFile}" has been created for you. Use this file to define all parameter values for this contract
495
+ `Note: parameter file associated with "${module.moduleName}" can't be found, so "${parameterListFile}" has been created for you. Use this file to define all parameter values for this contract
373
496
  `
374
497
  );
375
- writeFile2(parameterListFilename, initContentForParameter(sourceFile), "utf8");
498
+ return writeFile2(parameterListFilename, initContentForParameter(module), "utf8");
376
499
  });
377
- let compileResults = [contractCompileResult];
378
- if (storageCompileResult)
379
- compileResults = compileResults.concat(storageCompileResult);
380
- if (parameterCompileResult)
381
- compileResults = compileResults.concat(parameterCompileResult);
382
- return compileResults;
383
- };
384
- var mergeArtifactsOutput = (sourceFile) => (tableRows) => {
385
- const artifactsOutput = tableRows.reduce(
386
- (acc, row) => row.artifact === COMPILE_ERR_MSG ? acc : `${acc}${row.artifact}
387
- `,
388
- ""
389
- );
390
- return [{
391
- contract: sourceFile,
392
- artifact: artifactsOutput
393
- }];
500
+ const storageArtifacts = storageCompileResult ? storageCompileResult.map((res) => res.artifact).join("\n") : "";
501
+ const parameterArtifacts = parameterCompileResult ? parameterCompileResult.map((res) => res.artifact).join("\n") : "";
502
+ const combinedArtifact = [
503
+ contractCompileResult.artifact,
504
+ storageArtifacts,
505
+ parameterArtifacts
506
+ ].filter(Boolean).join("\n");
507
+ const combinedRow = {
508
+ source: module.sourceName,
509
+ artifact: combinedArtifact
510
+ };
511
+ return [combinedRow];
394
512
  };
395
- var compile = (parsedArgs) => {
513
+ var compile = async (parsedArgs) => {
396
514
  const sourceFile = parsedArgs.sourceFile;
397
- let p;
398
- if (isStorageListFile(sourceFile))
399
- p = compileExprs(parsedArgs, sourceFile, "storage");
400
- else if (isParameterListFile(sourceFile))
401
- p = compileExprs(parsedArgs, sourceFile, "parameter");
402
- else if (isContractFile(sourceFile))
403
- p = compileContractWithStorageAndParameter(parsedArgs, sourceFile);
404
- else {
405
- return sendAsyncErr2(
406
- `${sourceFile} doesn't have a valid LIGO extension ('.ligo', '.religo', '.mligo' or '.jsligo')`
407
- );
515
+ if (!isLIGOFile(sourceFile)) {
516
+ sendErr2(`${sourceFile} is not a LIGO file`);
517
+ return;
518
+ }
519
+ if (isStorageListFile(sourceFile) || isParameterListFile(sourceFile)) {
520
+ sendErr2(`Storage and parameter list files are not meant to be compiled directly`);
521
+ return;
522
+ }
523
+ if (isUnsupportedLigoSyntax(sourceFile)) {
524
+ sendErr2(`Unsupported LIGO syntax detected in ${sourceFile}. Note, we only support .jsligo and .mligo files.`);
525
+ return;
526
+ }
527
+ try {
528
+ const modules = await listContractModules(parsedArgs, sourceFile);
529
+ if (modules.length === 0) {
530
+ return sendJsonRes([
531
+ {
532
+ source: sourceFile,
533
+ artifact: `No contract modules found in "${sourceFile}"`
534
+ }
535
+ ]);
536
+ }
537
+ let allCompileResults = [];
538
+ for (const module of modules) {
539
+ if (parsedArgs.module && parsedArgs.module !== module.moduleName)
540
+ continue;
541
+ const compileResults = await compileContractWithStorageAndParameter(parsedArgs, sourceFile, module);
542
+ allCompileResults = allCompileResults.concat(compileResults);
543
+ }
544
+ sendJsonRes(allCompileResults, { footer: `
545
+ Compiled ${allCompileResults.length} contract(s) in "${sourceFile}"` });
546
+ } catch (err) {
547
+ sendErr2(`Error processing "${sourceFile}": ${err}`);
408
548
  }
409
- return p.then(sendJsonRes).catch((err) => sendErr2(err, false));
410
549
  };
411
550
  var compile_default = compile;
412
551
 
413
552
  // compile-all.ts
414
553
  import { sendErr as sendErr3, sendJsonRes as sendJsonRes2 } from "@taqueria/node-sdk";
415
554
  import glob from "fast-glob";
416
- import { readFile as readFile2 } from "fs/promises";
417
555
  import { join as join3 } from "path";
418
- var isMainContract = async (parsedArgs, contractFilename) => {
419
- if (/storageList\.\w{0,2}ligo$/.test(contractFilename))
420
- return false;
421
- const fileContent = await readFile2(getInputFilenameAbsPath(parsedArgs, contractFilename), "utf8");
422
- const entryOrMainFunctionRegex = /@entry|((const|let|function)\s+main)/g;
423
- return entryOrMainFunctionRegex.test(fileContent);
424
- };
425
- var parseIncludes = async (parsedArgs, contractFilename) => {
426
- const fileContent = await readFile2(getInputFilenameAbsPath(parsedArgs, contractFilename), "utf8");
427
- const includeRegex = /#include\s+"([^"]+\.m?ligo)"/g;
428
- let match;
429
- const includes = [];
430
- while ((match = includeRegex.exec(fileContent)) !== null) {
431
- includes.push(match[1]);
432
- }
433
- return includes;
434
- };
435
- var buildDependencyGraph = async (parsedArgs, contractFilenames) => {
436
- const graph = /* @__PURE__ */ new Map();
437
- for (const filename of contractFilenames) {
438
- const includes = await parseIncludes(parsedArgs, filename);
439
- graph.set(filename, new Set(includes));
440
- }
441
- return graph;
442
- };
443
- var visit = (node, graph, visited, stack) => {
444
- if (stack.has(node))
445
- return [true, visited];
446
- if (!visited.has(node)) {
447
- const newVisited = new Set(visited).add(node);
448
- const newStack = new Set(stack).add(node);
449
- const [circular, updatedVisited] = Array.from(graph.get(node) || []).reduce(
450
- ([circularFound, vSet], dependency) => {
451
- const [result, v] = visit(dependency, graph, vSet, newStack);
452
- return [circularFound || result, v];
453
- },
454
- [false, newVisited]
455
- );
456
- if (!circular)
457
- return [false, updatedVisited];
458
- }
459
- return [false, visited];
460
- };
461
- var detectCircularDependencies = (graph) => {
462
- const { safeFiles, circularFiles, visited } = Array.from(graph.keys()).reduce(
463
- (acc, filename) => {
464
- const [isCircular, updatedVisited] = visit(
465
- filename,
466
- graph,
467
- acc.visited,
468
- /* @__PURE__ */ new Set()
469
- );
470
- if (isCircular) {
471
- acc.circularFiles.push(filename);
472
- } else {
473
- acc.safeFiles.push(filename);
474
- }
475
- acc.visited = updatedVisited;
476
- return acc;
477
- },
478
- { safeFiles: [], circularFiles: [], visited: /* @__PURE__ */ new Set() }
479
- );
480
- return { safeFiles, circularFiles };
481
- };
482
556
  var compileAll = async (parsedArgs) => {
483
- let p = [];
557
+ let compilePromises = [];
484
558
  const contractFilenames = await glob(
485
559
  ["**/*.ligo", "**/*.religo", "**/*.mligo", "**/*.jsligo"],
486
560
  {
@@ -488,27 +562,20 @@ var compileAll = async (parsedArgs) => {
488
562
  absolute: false
489
563
  }
490
564
  );
491
- const dependencyGraph = await buildDependencyGraph(parsedArgs, contractFilenames);
492
- const { safeFiles, circularFiles } = detectCircularDependencies(dependencyGraph);
493
- for (const filename of safeFiles) {
494
- if (await isMainContract(parsedArgs, filename)) {
495
- p.push(compileContractWithStorageAndParameter(parsedArgs, filename));
565
+ for (const filename of contractFilenames) {
566
+ if (isStorageListFile(filename) || isParameterListFile(filename))
567
+ continue;
568
+ const moduleNames = await listContractModules(parsedArgs, filename);
569
+ for (const moduleName of moduleNames) {
570
+ compilePromises.push(compileContractWithStorageAndParameter(parsedArgs, filename, moduleName));
496
571
  }
497
572
  }
498
- return Promise.all(p).then((tables) => tables.flat()).then((table) => {
499
- if (circularFiles.length > 0) {
500
- console.warn(
501
- "Warning: Circular dependencies detected in the following files. They have been skipped:"
502
- );
503
- console.warn(circularFiles.join(", "));
504
- }
505
- return table;
506
- }).then(sendJsonRes2).catch((err) => sendErr3(err, false));
573
+ return Promise.all(compilePromises).then((tables) => tables.flat()).then(sendJsonRes2).catch((err) => sendErr3(err, false));
507
574
  };
508
575
  var compile_all_default = compileAll;
509
576
 
510
577
  // ligo.ts
511
- import { execCmd as execCmd2, getArch as getArch2, sendAsyncErr as sendAsyncErr3, sendRes, spawnCmd } from "@taqueria/node-sdk";
578
+ import { execCmd as execCmd2, getArch as getArch2, sendAsyncErr as sendAsyncErr3, sendRes as sendRes2, spawnCmd } from "@taqueria/node-sdk";
512
579
  import { readJsonFile, writeJsonFile } from "@taqueria/node-sdk";
513
580
  import { join as join4 } from "path";
514
581
  var getArbitraryLigoCmd = (parsedArgs, uid, gid, userArgs) => {
@@ -531,7 +598,7 @@ var getArbitraryLigoCmd = (parsedArgs, uid, gid, userArgs) => {
531
598
  const processedUserArgs = userArgs.split(" ").map((arg) => arg.startsWith("\\-") ? arg.substring(1) : arg).filter(
532
599
  (arg) => arg
533
600
  );
534
- const args = baseArgs.concat(processedUserArgs);
601
+ const args = [...baseArgs, ...processedUserArgs, "--skip-analytics"];
535
602
  const envVars = { "DOCKER_DEFAULT_PLATFORM": "linux/amd64" };
536
603
  return [
537
604
  [binary, ...args].join(" "),
@@ -555,7 +622,7 @@ var runArbitraryLigoCmd = (parsedArgs, cmd) => ensureEsyExists(parsedArgs).then(
555
622
  ).catch((err) => sendAsyncErr3(`An internal error has occurred: ${err.message}`));
556
623
  var ligo = (parsedArgs) => {
557
624
  const args = parsedArgs.command;
558
- return runArbitraryLigoCmd(parsedArgs, args).then(sendRes).catch((err) => sendAsyncErr3(err, false));
625
+ return runArbitraryLigoCmd(parsedArgs, args).then(sendRes2).catch((err) => sendAsyncErr3(err, false));
559
626
  };
560
627
  var ligo_default = ligo;
561
628
 
@@ -648,6 +715,12 @@ Plugin.create((i18n) => ({
648
715
  flag: "json",
649
716
  boolean: true,
650
717
  description: "Emit JSON-encoded Michelson"
718
+ }),
719
+ Option.create({
720
+ flag: "module",
721
+ shortFlag: "m",
722
+ type: "string",
723
+ description: "The LIGO module to be compiled"
651
724
  })
652
725
  ],
653
726
  handler: "proxy",
@@ -705,6 +778,7 @@ Plugin.create((i18n) => ({
705
778
  handler: createContract_default
706
779
  })
707
780
  ],
708
- proxy: main_default
781
+ proxy: main_default,
782
+ postInstall: `node ${__dirname}/postinstall.js`
709
783
  }), process.argv);
710
784
  //# sourceMappingURL=index.mjs.map