@mimicprotocol/cli 0.0.1-rc.9
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/README.md +96 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +6 -0
- package/dist/commands/codegen.js +100 -0
- package/dist/commands/compile.js +91 -0
- package/dist/commands/deploy.js +122 -0
- package/dist/commands/init.js +102 -0
- package/dist/commands/test.js +63 -0
- package/dist/errors.js +32 -0
- package/dist/helpers.js +17 -0
- package/dist/index.js +2 -0
- package/dist/lib/AbisInterfaceGenerator/AbiTypeConverter.js +137 -0
- package/dist/lib/AbisInterfaceGenerator/ArrayHandler.js +67 -0
- package/dist/lib/AbisInterfaceGenerator/ContractClassGenerator.js +57 -0
- package/dist/lib/AbisInterfaceGenerator/FunctionHandler.js +173 -0
- package/dist/lib/AbisInterfaceGenerator/ImportManager.js +17 -0
- package/dist/lib/AbisInterfaceGenerator/NameManager.js +98 -0
- package/dist/lib/AbisInterfaceGenerator/TupleHandler.js +250 -0
- package/dist/lib/AbisInterfaceGenerator/index.js +11 -0
- package/dist/lib/AbisInterfaceGenerator/types.js +4 -0
- package/dist/lib/InputsInterfaceGenerator.js +88 -0
- package/dist/lib/ManifestHandler.js +134 -0
- package/dist/lib/index.js +12 -0
- package/dist/log.js +13 -0
- package/dist/templates/manifest.yaml +9 -0
- package/dist/templates/package.json +27 -0
- package/dist/templates/src/task.ts +7 -0
- package/dist/templates/tests/Task.spec.ts +39 -0
- package/dist/templates/tsconfig.json +4 -0
- package/dist/types.js +25 -0
- package/dist/validators.js +18 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<a href="https://mimic.fi"><img src="https://www.mimic.fi/logo.png" alt="Mimic Protocol" width="200"></a>
|
|
3
|
+
</h1>
|
|
4
|
+
|
|
5
|
+
<h4 align="center">Blockchain automation protocol</h4>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://github.com/mimic-protocol/tooling/actions/workflows/ci.yml">
|
|
9
|
+
<img src="https://github.com/mimic-protocol/tooling/actions/workflows/ci.yml/badge.svg" alt="Build">
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://discord.mimic.fi">
|
|
12
|
+
<img alt="Discord" src="https://img.shields.io/discord/989984112397922325">
|
|
13
|
+
</a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="#content">Content</a> •
|
|
18
|
+
<a href="#setup">Setup</a> •
|
|
19
|
+
<a href="#usage">Usage</a> •
|
|
20
|
+
<a href="#security">Security</a> •
|
|
21
|
+
<a href="#license">License</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Content
|
|
27
|
+
|
|
28
|
+
The `mimic` CLI is a command-line interface to:
|
|
29
|
+
- Initialize a Mimic-compatible task project
|
|
30
|
+
- Generate types from your task manifest and ABIs
|
|
31
|
+
- Compile your AssemblyScript tasks to WebAssembly
|
|
32
|
+
- Test your tasks
|
|
33
|
+
- Deploy compiled tasks to IPFS and the Mimic Registry
|
|
34
|
+
- Link tasks to a project in the Mimic explorer
|
|
35
|
+
|
|
36
|
+
## Setup
|
|
37
|
+
|
|
38
|
+
To set up this project you'll need [git](https://git-scm.com) and [yarn](https://classic.yarnpkg.com) installed.
|
|
39
|
+
|
|
40
|
+
Install the CLI from the root of the monorepo:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Clone this repository
|
|
44
|
+
$ git clone https://github.com/mimic-protocol/tooling
|
|
45
|
+
|
|
46
|
+
# Go into the repository
|
|
47
|
+
$ cd tooling
|
|
48
|
+
|
|
49
|
+
# Install dependencies
|
|
50
|
+
$ yarn
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
Here's a quick overview of common commands:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
USAGE
|
|
59
|
+
$ mimic [COMMAND]
|
|
60
|
+
|
|
61
|
+
COMMANDS
|
|
62
|
+
codegen Generates typed interfaces for declared inputs and ABIs from your manifest.yaml file
|
|
63
|
+
compile Compiles task
|
|
64
|
+
test Tests your tasks
|
|
65
|
+
deploy Uploads your compiled task artifacts to IPFS and registers it into the Mimic Registry
|
|
66
|
+
init Initializes a new Mimic-compatible project structure in the specified directory
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
For full CLI documentation and examples please visit [docs.mimic.fi](https://docs.mimic.fi/)
|
|
70
|
+
|
|
71
|
+
## Security
|
|
72
|
+
|
|
73
|
+
To read more about our auditing and related security processes please refer to the [security section](https://docs.mimic.fi/miscellaneous/security) of our docs site.
|
|
74
|
+
|
|
75
|
+
However, if you found any potential issue in any of our smart contracts or in any piece of code you consider critical
|
|
76
|
+
for the safety of the protocol, please contact us through <a href="mailto:security@mimic.fi">security@mimic.fi</a>.
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
This project is licensed under the GNU General Public License v3.0.
|
|
81
|
+
See the [LICENSE](../../LICENSE) file for details.
|
|
82
|
+
|
|
83
|
+
### Third-Party Code
|
|
84
|
+
|
|
85
|
+
This project includes code from [The Graph Tooling](https://github.com/graphprotocol/graph-tooling), licensed under the MIT License.
|
|
86
|
+
See the [LICENSE-MIT](https://github.com/graphprotocol/graph-tooling/blob/27659e56adfa3ef395ceaf39053dc4a31e6d86b7/LICENSE-MIT) file for details.
|
|
87
|
+
Their original license and attribution are preserved.
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
> Website [mimic.fi](https://mimic.fi) ·
|
|
93
|
+
> Docs [docs.mimic.fi](https://docs.mimic.fi) ·
|
|
94
|
+
> GitHub [@mimic-fi](https://github.com/mimic-fi) ·
|
|
95
|
+
> Twitter [@mimicfi](https://twitter.com/mimicfi) ·
|
|
96
|
+
> Discord [mimic](https://discord.mimic.fi)
|
package/bin/run.cmd
ADDED
package/bin/run.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const prompts_1 = require("@inquirer/prompts");
|
|
40
|
+
const core_1 = require("@oclif/core");
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path_1 = require("path");
|
|
43
|
+
const lib_1 = require("../lib");
|
|
44
|
+
const log_1 = __importDefault(require("../log"));
|
|
45
|
+
class Codegen extends core_1.Command {
|
|
46
|
+
async run() {
|
|
47
|
+
const { flags } = await this.parse(Codegen);
|
|
48
|
+
const { manifest: manifestDir, output: outputDir, clean } = flags;
|
|
49
|
+
const manifest = lib_1.ManifestHandler.load(this, manifestDir);
|
|
50
|
+
if (clean) {
|
|
51
|
+
const shouldDelete = await (0, prompts_1.confirm)({
|
|
52
|
+
message: `Are you sure you want to ${log_1.default.warnText('delete')} all the contents in ${log_1.default.highlightText(outputDir)}. This action is ${log_1.default.warnText('irreversible')}`,
|
|
53
|
+
default: false,
|
|
54
|
+
});
|
|
55
|
+
if (!shouldDelete) {
|
|
56
|
+
console.log('You can remove the --clean flag from your command');
|
|
57
|
+
console.log('Stopping initialization...');
|
|
58
|
+
this.exit(0);
|
|
59
|
+
}
|
|
60
|
+
log_1.default.startAction(`Deleting contents of ${outputDir}`);
|
|
61
|
+
if (fs.existsSync(outputDir))
|
|
62
|
+
fs.rmSync(outputDir, { recursive: true, force: true });
|
|
63
|
+
}
|
|
64
|
+
log_1.default.startAction('Generating code');
|
|
65
|
+
if (Object.keys(manifest.inputs).length == 0 && Object.keys(manifest.abis).length == 0) {
|
|
66
|
+
log_1.default.stopAction();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (!fs.existsSync(outputDir))
|
|
70
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
71
|
+
generateAbisCode(manifest, outputDir, manifestDir);
|
|
72
|
+
generateInputsCode(manifest, outputDir);
|
|
73
|
+
log_1.default.stopAction();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
Codegen.description = 'Generates typed interfaces for declared inputs and ABIs from your manifest.yaml file';
|
|
77
|
+
Codegen.examples = ['<%= config.bin %> <%= command.id %> --manifest ./manifest.yaml --output ./types'];
|
|
78
|
+
Codegen.flags = {
|
|
79
|
+
manifest: core_1.Flags.string({ char: 'm', description: 'Specify a custom manifest file path', default: 'manifest.yaml' }),
|
|
80
|
+
output: core_1.Flags.string({ char: 'o', description: 'Ouput directory for generated types', default: './src/types' }),
|
|
81
|
+
clean: core_1.Flags.boolean({
|
|
82
|
+
char: 'c',
|
|
83
|
+
description: 'Remove existing generated types before generating new files',
|
|
84
|
+
default: false,
|
|
85
|
+
}),
|
|
86
|
+
};
|
|
87
|
+
exports.default = Codegen;
|
|
88
|
+
function generateAbisCode(manifest, outputDir, manifestDir) {
|
|
89
|
+
for (const [contractName, path] of Object.entries(manifest.abis)) {
|
|
90
|
+
const abi = JSON.parse(fs.readFileSync((0, path_1.join)(manifestDir, '../', path), 'utf-8'));
|
|
91
|
+
const abiInterface = lib_1.AbisInterfaceGenerator.generate(abi, contractName);
|
|
92
|
+
if (abiInterface.length > 0)
|
|
93
|
+
fs.writeFileSync(`${outputDir}/${contractName}.ts`, abiInterface);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function generateInputsCode(manifest, outputDir) {
|
|
97
|
+
const inputsInterface = lib_1.InputsInterfaceGenerator.generate(manifest.inputs);
|
|
98
|
+
if (inputsInterface.length > 0)
|
|
99
|
+
fs.writeFileSync(`${outputDir}/index.ts`, inputsInterface);
|
|
100
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const core_1 = require("@oclif/core");
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const ManifestHandler_1 = __importDefault(require("../lib/ManifestHandler"));
|
|
44
|
+
const log_1 = __importDefault(require("../log"));
|
|
45
|
+
class Compile extends core_1.Command {
|
|
46
|
+
async run() {
|
|
47
|
+
const { flags } = await this.parse(Compile);
|
|
48
|
+
const { task: taskFile, output: outputDir, manifest: manifestDir } = flags;
|
|
49
|
+
console.log(`Compiling AssemblyScript from ${taskFile}`);
|
|
50
|
+
if (!fs.existsSync(outputDir))
|
|
51
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
52
|
+
log_1.default.startAction('Verifying Manifest');
|
|
53
|
+
const manifest = ManifestHandler_1.default.load(this, manifestDir);
|
|
54
|
+
log_1.default.startAction('Compiling');
|
|
55
|
+
const wasmPath = path.join(outputDir, 'task.wasm');
|
|
56
|
+
const watPath = path.join(outputDir, 'task.wat');
|
|
57
|
+
const ascArgs = [
|
|
58
|
+
'asc',
|
|
59
|
+
taskFile,
|
|
60
|
+
'--target',
|
|
61
|
+
'release',
|
|
62
|
+
'--outFile',
|
|
63
|
+
wasmPath,
|
|
64
|
+
'--textFile',
|
|
65
|
+
watPath,
|
|
66
|
+
'--optimize',
|
|
67
|
+
'--exportRuntime',
|
|
68
|
+
'--transform',
|
|
69
|
+
'json-as/transform',
|
|
70
|
+
];
|
|
71
|
+
const result = (0, child_process_1.spawnSync)('yarn', ascArgs, { stdio: 'inherit' });
|
|
72
|
+
if (result.status !== 0) {
|
|
73
|
+
this.error('AssemblyScript compilation failed', {
|
|
74
|
+
code: 'BuildError',
|
|
75
|
+
suggestions: ['Check the AssemblyScript file'],
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
log_1.default.startAction('Saving files');
|
|
79
|
+
fs.writeFileSync(path.join(outputDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
|
|
80
|
+
log_1.default.stopAction();
|
|
81
|
+
console.log(`Build complete! Artifacts in ${outputDir}/`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
Compile.description = 'Compiles task';
|
|
85
|
+
Compile.examples = ['<%= config.bin %> <%= command.id %> --task src/task.ts --output ./output'];
|
|
86
|
+
Compile.flags = {
|
|
87
|
+
task: core_1.Flags.string({ char: 't', description: 'task to compile', default: 'src/task.ts' }),
|
|
88
|
+
manifest: core_1.Flags.string({ char: 'm', description: 'manifest to validate', default: 'manifest.yaml' }),
|
|
89
|
+
output: core_1.Flags.string({ char: 'o', description: 'output directory', default: './build' }),
|
|
90
|
+
};
|
|
91
|
+
exports.default = Compile;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const core_1 = require("@oclif/core");
|
|
40
|
+
const axios_1 = __importStar(require("axios"));
|
|
41
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path_1 = require("path");
|
|
44
|
+
const errors_1 = require("../errors");
|
|
45
|
+
const log_1 = __importDefault(require("../log"));
|
|
46
|
+
const MIMIC_REGISTRY = 'https://api-protocol.mimic.fi';
|
|
47
|
+
class Deploy extends core_1.Command {
|
|
48
|
+
async run() {
|
|
49
|
+
const { flags } = await this.parse(Deploy);
|
|
50
|
+
const { key, input: inputDir, output: outputDir } = flags;
|
|
51
|
+
log_1.default.startAction('Validating');
|
|
52
|
+
const fullInputDir = (0, path_1.resolve)(inputDir);
|
|
53
|
+
const fullOutputDir = (0, path_1.resolve)(outputDir);
|
|
54
|
+
if (!fs.existsSync(fullInputDir))
|
|
55
|
+
this.error(`Directory ${log_1.default.highlightText(fullInputDir)} does not exist`, {
|
|
56
|
+
code: 'Directory Not Found',
|
|
57
|
+
suggestions: ['Use the --input flag to specify the correct path'],
|
|
58
|
+
});
|
|
59
|
+
const neededFiles = ['manifest.json', 'task.wasm'].map((file) => (0, path_1.join)(fullInputDir, file));
|
|
60
|
+
for (const file of neededFiles) {
|
|
61
|
+
if (!fs.existsSync(file))
|
|
62
|
+
this.error(`Could not find ${file}`, {
|
|
63
|
+
code: 'File Not Found',
|
|
64
|
+
suggestions: [`Use ${log_1.default.highlightText('mimic compile')} to generate the needed files`],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
log_1.default.startAction('Uploading to Mimic Registry');
|
|
68
|
+
const CID = await this.uploadToRegistry(neededFiles, key);
|
|
69
|
+
console.log(`IPFS CID: ${log_1.default.highlightText(CID)}`);
|
|
70
|
+
log_1.default.stopAction();
|
|
71
|
+
if (!fs.existsSync(fullOutputDir))
|
|
72
|
+
fs.mkdirSync(fullOutputDir, { recursive: true });
|
|
73
|
+
fs.writeFileSync((0, path_1.join)(fullOutputDir, 'CID.json'), JSON.stringify({ CID }, null, 2));
|
|
74
|
+
console.log(`CID saved at ${log_1.default.highlightText(fullOutputDir)}`);
|
|
75
|
+
console.log(`Task deployed!`);
|
|
76
|
+
}
|
|
77
|
+
async uploadToRegistry(files, key) {
|
|
78
|
+
try {
|
|
79
|
+
const form = filesToForm(files);
|
|
80
|
+
const { data } = await axios_1.default.post(`${MIMIC_REGISTRY}/tasks`, form, {
|
|
81
|
+
headers: {
|
|
82
|
+
'x-api-key': key,
|
|
83
|
+
'Content-Type': `multipart/form-data; boundary=${form.getBoundary()}`,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
return data.CID;
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
this.handleError(err, 'Failed to upload to registry');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
handleError(err, message) {
|
|
93
|
+
if (!(err instanceof axios_1.AxiosError))
|
|
94
|
+
this.error(err);
|
|
95
|
+
const statusCode = err.response?.status;
|
|
96
|
+
if (statusCode === 400) {
|
|
97
|
+
const errMessage = err.response?.data?.content?.message || message;
|
|
98
|
+
this.error(errMessage, { code: 'Bad Request', suggestions: ['Review the uploaded files'] });
|
|
99
|
+
}
|
|
100
|
+
if (statusCode === 401)
|
|
101
|
+
this.error(message, { code: 'Unauthorized', suggestions: ['Review your key'] });
|
|
102
|
+
if (statusCode === 403)
|
|
103
|
+
this.error(message, { code: 'Invalid api key', suggestions: ['Review your key'] });
|
|
104
|
+
this.error(`${message} - ${err.message}`, { code: `${statusCode} Error`, suggestions: errors_1.GENERIC_SUGGESTION });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
Deploy.description = 'Uploads your compiled task artifacts to IPFS and registers it into the Mimic Registry';
|
|
108
|
+
Deploy.examples = ['<%= config.bin %> <%= command.id %> --input ./dist --key MY_KEY --output ./dist'];
|
|
109
|
+
Deploy.flags = {
|
|
110
|
+
key: core_1.Flags.string({ char: 'k', description: 'Your account deployment key', required: true }),
|
|
111
|
+
input: core_1.Flags.string({ char: 'i', description: 'Directory containing the compiled artifacts', default: './build' }),
|
|
112
|
+
output: core_1.Flags.string({ char: 'o', description: 'Output directory for deployment CID', default: './build' }),
|
|
113
|
+
};
|
|
114
|
+
exports.default = Deploy;
|
|
115
|
+
const filesToForm = (files) => {
|
|
116
|
+
return files.reduce((form, file) => {
|
|
117
|
+
const fileStream = fs.createReadStream(file);
|
|
118
|
+
const filename = file.split('/').pop();
|
|
119
|
+
form.append('file', fileStream, { filename });
|
|
120
|
+
return form;
|
|
121
|
+
}, new form_data_1.default());
|
|
122
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const prompts_1 = require("@inquirer/prompts");
|
|
40
|
+
const core_1 = require("@oclif/core");
|
|
41
|
+
const child_process_1 = require("child_process");
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const log_1 = __importDefault(require("../log"));
|
|
45
|
+
class Init extends core_1.Command {
|
|
46
|
+
async run() {
|
|
47
|
+
const { flags } = await this.parse(Init);
|
|
48
|
+
const { directory, force } = flags;
|
|
49
|
+
const fullDirectory = path.resolve(directory);
|
|
50
|
+
const templateDirectory = path.join(__dirname, '../templates');
|
|
51
|
+
if (force) {
|
|
52
|
+
const shouldDelete = await (0, prompts_1.confirm)({
|
|
53
|
+
message: `Are you sure you want to ${log_1.default.warnText('delete')} all the contents in ${log_1.default.highlightText(fullDirectory)}. This action is ${log_1.default.warnText('irreversible')}`,
|
|
54
|
+
default: false,
|
|
55
|
+
});
|
|
56
|
+
if (!shouldDelete) {
|
|
57
|
+
console.log('You can remove the --force flag from your command');
|
|
58
|
+
console.log('Stopping initialization...');
|
|
59
|
+
this.exit(0);
|
|
60
|
+
}
|
|
61
|
+
log_1.default.startAction(`Deleting contents of ${fullDirectory}`);
|
|
62
|
+
if (fs.existsSync(fullDirectory))
|
|
63
|
+
fs.rmSync(fullDirectory, { recursive: true });
|
|
64
|
+
}
|
|
65
|
+
log_1.default.startAction('Creating files');
|
|
66
|
+
if (fs.existsSync(fullDirectory) && fs.readdirSync(fullDirectory).length > 0) {
|
|
67
|
+
this.error(`Directory ${log_1.default.highlightText(fullDirectory)} is not empty`, {
|
|
68
|
+
code: 'DirectoryNotEmpty',
|
|
69
|
+
suggestions: [
|
|
70
|
+
'You can specify the directory with --directory',
|
|
71
|
+
`You can ${log_1.default.warnText('overwrite')} an existing directory with --force`,
|
|
72
|
+
],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
fs.cpSync(templateDirectory, fullDirectory, { recursive: true });
|
|
76
|
+
this.installDependencies(fullDirectory);
|
|
77
|
+
this.runCodegen(fullDirectory);
|
|
78
|
+
log_1.default.stopAction();
|
|
79
|
+
console.log('New project initialized!');
|
|
80
|
+
}
|
|
81
|
+
installDependencies(fullDirectory) {
|
|
82
|
+
if (process.env.NODE_ENV === 'test')
|
|
83
|
+
return;
|
|
84
|
+
(0, child_process_1.spawnSync)('yarn', ['install'], {
|
|
85
|
+
cwd: fullDirectory,
|
|
86
|
+
stdio: 'inherit',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
runCodegen(fullDirectory) {
|
|
90
|
+
(0, child_process_1.spawnSync)('yarn', ['codegen'], {
|
|
91
|
+
cwd: fullDirectory,
|
|
92
|
+
stdio: 'inherit',
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
Init.description = 'Initializes a new Mimic-compatible project structure in the specified directory';
|
|
97
|
+
Init.examples = ['<%= config.bin %> <%= command.id %> --directory ./new-project --force'];
|
|
98
|
+
Init.flags = {
|
|
99
|
+
directory: core_1.Flags.string({ char: 'd', description: 'Directory to initialize project', default: './' }),
|
|
100
|
+
force: core_1.Flags.boolean({ char: 'f', description: 'Overwrite existing files if they already exist', default: false }),
|
|
101
|
+
};
|
|
102
|
+
exports.default = Init;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const core_1 = require("@oclif/core");
|
|
37
|
+
const child_process_1 = require("child_process");
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
class Test extends core_1.Command {
|
|
40
|
+
async run() {
|
|
41
|
+
const { flags } = await this.parse(Test);
|
|
42
|
+
const baseDir = path.resolve(flags.directory);
|
|
43
|
+
const testPath = path.join(baseDir, 'tests');
|
|
44
|
+
if (!flags.skipCompile) {
|
|
45
|
+
const codegen = (0, child_process_1.spawnSync)('yarn', ['mimic', 'codegen'], { cwd: baseDir, stdio: 'inherit' });
|
|
46
|
+
if (codegen.status !== 0)
|
|
47
|
+
return;
|
|
48
|
+
const compile = (0, child_process_1.spawnSync)('yarn', ['mimic', 'compile'], { cwd: baseDir, stdio: 'inherit' });
|
|
49
|
+
if (compile.status !== 0)
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
(0, child_process_1.spawnSync)('yarn', ['tsx', './node_modules/mocha/bin/mocha.js', `${testPath}/**/*.spec.ts`], {
|
|
53
|
+
stdio: 'inherit',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
Test.description = 'Runs task tests';
|
|
58
|
+
Test.examples = ['<%= config.bin %> <%= command.id %> --directory ./'];
|
|
59
|
+
Test.flags = {
|
|
60
|
+
directory: core_1.Flags.string({ char: 'd', description: 'task directory', default: './' }),
|
|
61
|
+
skipCompile: core_1.Flags.boolean({ description: 'skip codegen and compile steps' }),
|
|
62
|
+
};
|
|
63
|
+
exports.default = Test;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GENERIC_SUGGESTION = exports.EmptyManifestError = exports.DuplicateEntryError = exports.MoreThanOneEntryError = void 0;
|
|
4
|
+
class MoreThanOneEntryError extends Error {
|
|
5
|
+
constructor(location) {
|
|
6
|
+
super('More than one entry');
|
|
7
|
+
this.name = this.constructor.name;
|
|
8
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
9
|
+
this.location = location;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.MoreThanOneEntryError = MoreThanOneEntryError;
|
|
13
|
+
class DuplicateEntryError extends Error {
|
|
14
|
+
constructor(duplicateKey) {
|
|
15
|
+
super('Duplicate Entry');
|
|
16
|
+
this.name = this.constructor.name;
|
|
17
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
18
|
+
this.duplicateKey = duplicateKey;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.DuplicateEntryError = DuplicateEntryError;
|
|
22
|
+
class EmptyManifestError extends Error {
|
|
23
|
+
constructor() {
|
|
24
|
+
super('Empty Manifest');
|
|
25
|
+
this.name = this.constructor.name;
|
|
26
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.EmptyManifestError = EmptyManifestError;
|
|
30
|
+
exports.GENERIC_SUGGESTION = [
|
|
31
|
+
'Contact the Mimic team for further assistance at our website https://www.mimic.fi or discord https://discord.mimic.fi',
|
|
32
|
+
];
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getFunctionSelector = getFunctionSelector;
|
|
7
|
+
exports.pascalCase = pascalCase;
|
|
8
|
+
const ethers_1 = require("ethers");
|
|
9
|
+
const camelCase_1 = __importDefault(require("lodash/camelCase"));
|
|
10
|
+
const startCase_1 = __importDefault(require("lodash/startCase"));
|
|
11
|
+
function getFunctionSelector(fn) {
|
|
12
|
+
const iface = new ethers_1.Interface([fn]);
|
|
13
|
+
return iface.getFunction(fn.name).selector;
|
|
14
|
+
}
|
|
15
|
+
function pascalCase(str) {
|
|
16
|
+
return (0, startCase_1.default)((0, camelCase_1.default)(str)).replace(/\s/g, '');
|
|
17
|
+
}
|
package/dist/index.js
ADDED