@taqueria/plugin-ligo 0.40.2 → 0.40.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 +24 -3
- package/compile.ts +110 -235
- package/index.js +92 -233
- package/index.js.map +1 -1
- package/index.mjs +92 -233
- package/index.mjs.map +1 -1
- package/package.json +2 -2
package/common.ts
CHANGED
|
@@ -38,8 +38,29 @@ export const getInputFilenameAbsPath = (parsedArgs: UnionOpts, sourceFile: strin
|
|
|
38
38
|
export const getInputFilenameRelPath = (parsedArgs: UnionOpts, sourceFile: string): string =>
|
|
39
39
|
join(parsedArgs.config.contractsDir ?? 'contracts', sourceFile);
|
|
40
40
|
|
|
41
|
-
export const
|
|
41
|
+
export const formatLigoError = (err: Error): Error => {
|
|
42
|
+
let result = err.message.replace(/Command failed.+?\n/, '');
|
|
43
|
+
if (
|
|
44
|
+
result.includes('An internal error ocurred. Please, contact the developers.')
|
|
45
|
+
&& result.includes('Module Contract not found with last Contract.')
|
|
46
|
+
) {
|
|
47
|
+
result =
|
|
48
|
+
`The contract must be imported with "Contract" as the namespace: #import "path/to/contract.ligo" "Contract"`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
err.message = result.replace(
|
|
52
|
+
'An internal error ocurred. Please, contact the developers.',
|
|
53
|
+
'The LIGO compiler experienced an internal error. Please contact the LIGO developers.',
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
return err;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const emitExternalError = (errs: unknown[] | unknown, sourceFile: string): void => {
|
|
42
60
|
sendErr(`\n=== Error messages for ${sourceFile} ===`);
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
const errors = Array.isArray(errs) ? errs : [errs];
|
|
62
|
+
errors.map(err => {
|
|
63
|
+
err instanceof Error ? sendErr(err.message) : sendErr(err as any);
|
|
64
|
+
});
|
|
65
|
+
sendErr(`===`);
|
|
45
66
|
};
|
package/compile.ts
CHANGED
|
@@ -15,21 +15,24 @@ import * as readline from 'readline';
|
|
|
15
15
|
import {
|
|
16
16
|
CompileOpts as Opts,
|
|
17
17
|
emitExternalError,
|
|
18
|
+
formatLigoError,
|
|
18
19
|
getInputFilenameAbsPath,
|
|
19
20
|
getInputFilenameRelPath,
|
|
20
21
|
getLigoDockerImage,
|
|
21
22
|
UnionOpts,
|
|
22
23
|
} from './common';
|
|
23
24
|
|
|
24
|
-
export type TableRow = { source: string; artifact: string };
|
|
25
|
+
export type TableRow = { source: string; artifact: string; err?: unknown };
|
|
25
26
|
|
|
26
27
|
export type ExprKind = 'storage' | 'default_storage' | 'parameter';
|
|
27
28
|
|
|
29
|
+
export type Syntax = 'mligo' | 'jsligo' | 'religo' | 'ligo';
|
|
30
|
+
|
|
28
31
|
export type ModuleInfo = {
|
|
29
32
|
moduleName: string;
|
|
30
33
|
sourceName: string;
|
|
31
34
|
sourceFile: string;
|
|
32
|
-
syntax:
|
|
35
|
+
syntax: Syntax;
|
|
33
36
|
type: 'file-main' | 'file-entry' | 'module-main' | 'module-entry';
|
|
34
37
|
};
|
|
35
38
|
|
|
@@ -217,10 +220,10 @@ const compileExpr =
|
|
|
217
220
|
};
|
|
218
221
|
})
|
|
219
222
|
.catch(err => {
|
|
220
|
-
emitExternalError(err, sourceFile);
|
|
221
223
|
return {
|
|
222
224
|
source: module.sourceName,
|
|
223
|
-
artifact: `${sourceFile} not compiled`,
|
|
225
|
+
artifact: `${exprName} in ${sourceFile} not compiled`,
|
|
226
|
+
err,
|
|
224
227
|
};
|
|
225
228
|
});
|
|
226
229
|
};
|
|
@@ -251,247 +254,118 @@ const getExprNames = (parsedArgs: Opts, sourceFile: string): Promise<string[]> =
|
|
|
251
254
|
});
|
|
252
255
|
};
|
|
253
256
|
|
|
254
|
-
const compileExprs = (
|
|
257
|
+
const compileExprs = async (
|
|
255
258
|
parsedArgs: Opts,
|
|
256
259
|
sourceFile: string,
|
|
257
260
|
module: ModuleInfo,
|
|
258
261
|
exprKind: ExprKind,
|
|
259
|
-
): Promise<TableRow[]> =>
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
.catch(err => {
|
|
272
|
-
emitExternalError(err, sourceFile);
|
|
273
|
-
return [{
|
|
274
|
-
source: module.sourceName,
|
|
275
|
-
artifact: `No ${isStorageKind(exprKind) ? 'storage' : 'parameter'} expressions compiled`,
|
|
276
|
-
}];
|
|
277
|
-
})
|
|
278
|
-
.then(results =>
|
|
279
|
-
results.length > 0 ? results : [{
|
|
280
|
-
source: module.sourceName,
|
|
281
|
-
artifact: `No ${isStorageKind(exprKind) ? 'storage' : 'parameter'} expressions found`,
|
|
282
|
-
}]
|
|
283
|
-
);
|
|
262
|
+
): Promise<TableRow[]> => {
|
|
263
|
+
// Get expressions from file
|
|
264
|
+
let exprs = [];
|
|
265
|
+
try {
|
|
266
|
+
exprs = await getExprNames(parsedArgs, sourceFile);
|
|
267
|
+
} catch (err) {
|
|
268
|
+
emitExternalError(err, sourceFile);
|
|
269
|
+
return [{
|
|
270
|
+
source: module.sourceName,
|
|
271
|
+
artifact: `No ${isStorageKind(exprKind) ? 'storage' : 'parameter'} expressions compiled`,
|
|
272
|
+
}];
|
|
273
|
+
}
|
|
284
274
|
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
'// For added type-safety, you can reference the type of your storage from the contract',
|
|
323
|
-
`// E.g. let storage : Contract.${module.moduleName}.storage = 10`,
|
|
324
|
-
];
|
|
325
|
-
break;
|
|
326
|
-
case 'mligo-module-entry':
|
|
327
|
-
return [
|
|
328
|
-
'// 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.',
|
|
329
|
-
'',
|
|
330
|
-
'// If your storage is a simple value, you can define it directly',
|
|
331
|
-
'// E.g. let storage = 10',
|
|
332
|
-
'',
|
|
333
|
-
'// For added type-safety, you can reference the type of your storage from the contract',
|
|
334
|
-
`// E.g. let storage : Contract.${module.moduleName}.storage = 10`,
|
|
335
|
-
];
|
|
336
|
-
break;
|
|
337
|
-
case 'jsligo-file-main':
|
|
338
|
-
return [
|
|
339
|
-
'// 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.',
|
|
340
|
-
`// NOTE: The "storage" type should be exported from the contract file (${module.sourceFile})`,
|
|
341
|
-
'',
|
|
342
|
-
'// If your storage is a simple value, you can define it directly',
|
|
343
|
-
'// E.g. const storage = 10',
|
|
344
|
-
'',
|
|
345
|
-
'// 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.',
|
|
346
|
-
'// E.g. const storage : Contract.storage = 10',
|
|
347
|
-
];
|
|
348
|
-
break;
|
|
349
|
-
case 'jsligo-file-entry':
|
|
350
|
-
return [
|
|
351
|
-
'// 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.',
|
|
352
|
-
'',
|
|
353
|
-
'// If your storage is a simple value, you can define it directly',
|
|
354
|
-
'// E.g. const storage = 10',
|
|
355
|
-
'',
|
|
356
|
-
'// 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.',
|
|
357
|
-
'// E.g. const storage : Contract.storage = 10',
|
|
358
|
-
];
|
|
359
|
-
break;
|
|
360
|
-
case 'jsligo-module-main':
|
|
361
|
-
return [
|
|
362
|
-
'// 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.',
|
|
363
|
-
`// NOTE: The "storage" type should be exported from the contract file (${module.sourceFile})`,
|
|
364
|
-
'',
|
|
365
|
-
'// If your storage is a simple value, you can define it directly',
|
|
366
|
-
'// E.g. const storage = 10',
|
|
367
|
-
'',
|
|
368
|
-
'// 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.',
|
|
369
|
-
`// E.g. const storage : Contract.${module.moduleName}.storage = 10`,
|
|
370
|
-
];
|
|
371
|
-
break;
|
|
372
|
-
case 'jsligo-module-entry':
|
|
373
|
-
return [
|
|
374
|
-
'// 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.',
|
|
375
|
-
'',
|
|
376
|
-
'// If your storage is a simple value, you can define it directly',
|
|
377
|
-
'// E.g. const storage = 10',
|
|
378
|
-
'',
|
|
379
|
-
'// 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.',
|
|
380
|
-
`// E.g. const storage : Contract.${module.moduleName}.storage = 10`,
|
|
381
|
-
];
|
|
382
|
-
break;
|
|
383
|
-
default:
|
|
384
|
-
return [];
|
|
385
|
-
}
|
|
386
|
-
})();
|
|
387
|
-
return linkToContract + instruction + syntax.join('\n');
|
|
275
|
+
const results = await Promise.all(exprs.map(async (exprName, index) => {
|
|
276
|
+
const compileResult = await compileExpr(
|
|
277
|
+
parsedArgs,
|
|
278
|
+
sourceFile,
|
|
279
|
+
module,
|
|
280
|
+
exprKind === 'storage' && index === 0 ? 'default_storage' : exprKind,
|
|
281
|
+
)(exprName);
|
|
282
|
+
return compileResult;
|
|
283
|
+
}));
|
|
284
|
+
|
|
285
|
+
// Collect errors
|
|
286
|
+
const errors = results.reduce(
|
|
287
|
+
(acc, result) => {
|
|
288
|
+
if (result.err) {
|
|
289
|
+
// If its not an Error object, then just add it to the list
|
|
290
|
+
if (!(result.err instanceof Error)) return [...acc, result.err];
|
|
291
|
+
|
|
292
|
+
// Otherwise, get all ligo errors and ensure that the list is unique
|
|
293
|
+
const ligoErrs = (acc
|
|
294
|
+
.filter(err => err instanceof Error) as Error[])
|
|
295
|
+
.map(err => err.message);
|
|
296
|
+
|
|
297
|
+
const formattedError = formatLigoError(result.err);
|
|
298
|
+
|
|
299
|
+
return (ligoErrs.includes(formattedError.message)) ? acc : [...acc, formattedError];
|
|
300
|
+
}
|
|
301
|
+
return acc;
|
|
302
|
+
},
|
|
303
|
+
[] as unknown[],
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
// Collect table rows
|
|
307
|
+
const retval = results.map(({ source, artifact }) => ({ source, artifact }));
|
|
308
|
+
|
|
309
|
+
if (errors.length) emitExternalError(errors, sourceFile);
|
|
310
|
+
|
|
311
|
+
return retval;
|
|
388
312
|
};
|
|
389
313
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
'',
|
|
423
|
-
'// If your parameter is a simple value, you can define it directly',
|
|
424
|
-
'// E.g. let default_parameter = 10',
|
|
425
|
-
'',
|
|
426
|
-
'// For added type-safety, you can reference the type of your parameter from the contract',
|
|
427
|
-
`// E.g. let default_parameter : Contract.${module.moduleName}.parameter = 10`,
|
|
428
|
-
];
|
|
429
|
-
break;
|
|
430
|
-
case 'mligo-module-entry':
|
|
431
|
-
return [
|
|
432
|
-
'// 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.',
|
|
433
|
-
'',
|
|
434
|
-
'// If your parameter is a simple value, you can define it directly',
|
|
435
|
-
'// E.g. let default_parameter = 10',
|
|
436
|
-
'',
|
|
437
|
-
'// For added type-safety, you can reference the type of your parameter from the contract',
|
|
438
|
-
`// E.g. let default_parameter : parameter_of Contract.${module.moduleName} = 10`,
|
|
439
|
-
];
|
|
440
|
-
break;
|
|
441
|
-
case 'jsligo-file-main':
|
|
442
|
-
return [
|
|
443
|
-
'// 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.',
|
|
444
|
-
`// NOTE: The "parameter" type should be exported from the contract file (${module.sourceFile})`,
|
|
445
|
-
'',
|
|
446
|
-
'// If your parameter is a simple value, you can define it directly',
|
|
447
|
-
'// E.g. const default_parameter = 10',
|
|
448
|
-
'',
|
|
449
|
-
'// For added type-safety, you can reference the type of your parameter from the contract',
|
|
450
|
-
'// E.g. const default_parameter : Contract.parameter = 10',
|
|
451
|
-
];
|
|
452
|
-
break;
|
|
453
|
-
case 'jsligo-file-entry':
|
|
454
|
-
return [
|
|
455
|
-
'// 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.',
|
|
456
|
-
'',
|
|
457
|
-
'// If your parameter is a simple value, you can define it directly',
|
|
458
|
-
'// E.g. const default_parameter = 10',
|
|
459
|
-
'',
|
|
460
|
-
'// For added type-safety, you can reference the type of your parameter from the contract',
|
|
461
|
-
'// E.g. const default_parameter : parameter_of Contract = 10',
|
|
462
|
-
];
|
|
463
|
-
break;
|
|
464
|
-
case 'jsligo-module-main':
|
|
465
|
-
return [
|
|
466
|
-
'// 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.',
|
|
467
|
-
`// NOTE: The "parameter" type should be exported from the contract file (${module.sourceFile})`,
|
|
468
|
-
'',
|
|
469
|
-
'// If your parameter is a simple value, you can define it directly',
|
|
470
|
-
'// E.g. const default_parameter = 10',
|
|
471
|
-
'',
|
|
472
|
-
'// For added type-safety, you can reference the type of your parameter from the contract',
|
|
473
|
-
`// E.g. const default_parameter : Contract.${module.moduleName}.parameter = 10`,
|
|
474
|
-
];
|
|
475
|
-
break;
|
|
476
|
-
case 'jsligo-module-entry':
|
|
477
|
-
return [
|
|
478
|
-
'// 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.',
|
|
479
|
-
'',
|
|
480
|
-
'// If your parameter is a simple value, you can define it directly',
|
|
481
|
-
'// E.g. const default_parameter = 10',
|
|
482
|
-
'',
|
|
483
|
-
'// For added type-safety, you can reference the type of your parameter from the contract',
|
|
484
|
-
`// E.g. const default_parameter : parameter_of Contract.${module.moduleName} = 10`,
|
|
485
|
-
];
|
|
486
|
-
break;
|
|
487
|
-
default:
|
|
488
|
-
return [];
|
|
489
|
-
}
|
|
490
|
-
})();
|
|
314
|
+
// Helper function to get the initial message based on the pair value
|
|
315
|
+
const getInitialMessage = (pair: string, module: ModuleInfo) => {
|
|
316
|
+
const messages = {
|
|
317
|
+
'mligo-file-main':
|
|
318
|
+
`// 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.`,
|
|
319
|
+
'mligo-file-entry':
|
|
320
|
+
`// 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.`,
|
|
321
|
+
'mligo-module-main':
|
|
322
|
+
`// 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.`,
|
|
323
|
+
'mligo-module-entry':
|
|
324
|
+
`// 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.`,
|
|
325
|
+
'jsligo-file-main':
|
|
326
|
+
`// 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.\n`
|
|
327
|
+
+ `// NOTE: The "storage" type should be exported from the contract file (${module.sourceFile})`,
|
|
328
|
+
'jsligo-file-entry':
|
|
329
|
+
`// 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.`,
|
|
330
|
+
'jsligo-module-main':
|
|
331
|
+
`// 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.\n`
|
|
332
|
+
+ `// NOTE: The "storage" type should be exported from the contract file (${module.sourceFile})`,
|
|
333
|
+
'jsligo-module-entry':
|
|
334
|
+
`// 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.`,
|
|
335
|
+
// ... any other combinations
|
|
336
|
+
} as Record<string, string>;
|
|
337
|
+
|
|
338
|
+
return messages[pair] || '// This file was created by Taqueria.';
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
// Helper function to get a common message
|
|
342
|
+
const getCommonMsg = (langType: Syntax, listType: ExprKind) => {
|
|
343
|
+
const varKeyword = langType === 'mligo' ? 'let' : 'const';
|
|
344
|
+
const commonMsgForStorage = `// IMPORTANT: We suggest always explicitly typing your storage values:\n`
|
|
345
|
+
+ `// E.g.: \`${varKeyword} storage: int = 10\` or \`${varKeyword} storage: Contract.storage = 10\``;
|
|
491
346
|
|
|
492
|
-
|
|
347
|
+
const commonMsgForParameter = `// IMPORTANT: We suggest always explicitly typing your parameter values:\n`
|
|
348
|
+
+ `// E.g.: \`${varKeyword} parameter: int = 10\` or \`${varKeyword} parameter: Contract.parameter = 10\``;
|
|
349
|
+
|
|
350
|
+
return listType === 'storage' ? commonMsgForStorage : commonMsgForParameter;
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
// Main function to get the content for storage or parameter
|
|
354
|
+
const getContent = (moduleInfo: ModuleInfo, listType: ExprKind) => {
|
|
355
|
+
const linkToContract = `#import "${moduleInfo.sourceFile}" "Contract"`;
|
|
356
|
+
const pair = `${moduleInfo.syntax}-${moduleInfo.type}`;
|
|
357
|
+
const initialMsg = getInitialMessage(pair, moduleInfo);
|
|
358
|
+
const commonMsg = getCommonMsg(moduleInfo.syntax, listType);
|
|
359
|
+
|
|
360
|
+
return `${linkToContract}\n\n${initialMsg}\n\n${commonMsg}`;
|
|
493
361
|
};
|
|
494
362
|
|
|
363
|
+
// Usage for storage list
|
|
364
|
+
const initContentForStorage = (moduleInfo: ModuleInfo) => getContent(moduleInfo, 'storage');
|
|
365
|
+
|
|
366
|
+
// Usage for parameter list
|
|
367
|
+
const initContentForParameter = (moduleInfo: ModuleInfo) => getContent(moduleInfo, 'parameter');
|
|
368
|
+
|
|
495
369
|
export const compileContractWithStorageAndParameter = async (
|
|
496
370
|
parsedArgs: Opts,
|
|
497
371
|
sourceFile: string,
|
|
@@ -499,6 +373,7 @@ export const compileContractWithStorageAndParameter = async (
|
|
|
499
373
|
): Promise<TableRow[]> => {
|
|
500
374
|
const contractCompileResult = await compileContract(parsedArgs, sourceFile, module);
|
|
501
375
|
if (contractCompileResult.artifact === COMPILE_ERR_MSG) return [contractCompileResult];
|
|
376
|
+
debugger;
|
|
502
377
|
|
|
503
378
|
const storageListFile = `${module.moduleName}.storageList${extractExt(sourceFile)}`;
|
|
504
379
|
const storageListFilename = getInputFilenameAbsPath(parsedArgs, storageListFile);
|