ic-mops 0.36.1 → 0.37.0

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.
Files changed (106) hide show
  1. package/bin/moc-wrapper.sh +3 -0
  2. package/bin/mops.ts +3 -0
  3. package/cache.ts +2 -2
  4. package/cli.ts +61 -4
  5. package/commands/add.ts +3 -1
  6. package/commands/bench-replica.ts +5 -3
  7. package/commands/docs.ts +9 -6
  8. package/commands/install-all.ts +7 -2
  9. package/commands/install.ts +5 -1
  10. package/commands/publish.ts +2 -0
  11. package/commands/test/test.ts +42 -19
  12. package/commands/toolchain/index.ts +325 -0
  13. package/commands/toolchain/moc.ts +58 -0
  14. package/commands/toolchain/pocket-ic.ts +74 -0
  15. package/commands/toolchain/toolchain-utils.ts +83 -0
  16. package/commands/toolchain/wasmtime.ts +45 -0
  17. package/dist/bin/mops.d.ts +1 -1
  18. package/dist/cache.js +2 -2
  19. package/dist/cli.d.ts +0 -1
  20. package/dist/cli.js +52 -3
  21. package/dist/commands/add.js +2 -1
  22. package/dist/commands/bench-replica.d.ts +1 -1
  23. package/dist/commands/bench-replica.js +5 -3
  24. package/dist/commands/docs.js +9 -6
  25. package/dist/commands/install-all.js +5 -2
  26. package/dist/commands/install.js +5 -1
  27. package/dist/commands/publish.js +1 -0
  28. package/dist/commands/test/test.js +41 -19
  29. package/dist/commands/toolchain/index.d.ts +26 -0
  30. package/dist/commands/toolchain/index.js +274 -0
  31. package/dist/commands/toolchain/moc.d.ts +5 -1
  32. package/dist/commands/toolchain/moc.js +18 -6
  33. package/dist/commands/toolchain/mocv.js +0 -1
  34. package/dist/commands/toolchain/pocket-ic.d.ts +12 -0
  35. package/dist/commands/toolchain/pocket-ic.js +62 -0
  36. package/dist/commands/toolchain/toolchain-utils.d.ts +2 -2
  37. package/dist/commands/toolchain/toolchain-utils.js +22 -6
  38. package/dist/commands/toolchain/wasmtime.d.ts +5 -1
  39. package/dist/commands/toolchain/wasmtime.js +16 -4
  40. package/dist/integrity.js +40 -15
  41. package/dist/mops.js +2 -2
  42. package/dist/package.json +9 -4
  43. package/dist/pic-js/examples/clock/tests/clock/index.d.ts +1 -0
  44. package/dist/pic-js/examples/clock/tests/clock/index.js +5 -0
  45. package/dist/pic-js/examples/clock/tests/jest.config.d.ts +3 -0
  46. package/dist/pic-js/examples/clock/tests/jest.config.js +8 -0
  47. package/dist/pic-js/examples/clock/tests/src/clock.spec.d.ts +1 -0
  48. package/dist/pic-js/examples/clock/tests/src/clock.spec.js +48 -0
  49. package/dist/pic-js/examples/counter/tests/counter/index.d.ts +1 -0
  50. package/dist/pic-js/examples/counter/tests/counter/index.js +5 -0
  51. package/dist/pic-js/examples/counter/tests/jest.config.d.ts +3 -0
  52. package/dist/pic-js/examples/counter/tests/jest.config.js +8 -0
  53. package/dist/pic-js/examples/counter/tests/src/counter.spec.d.ts +1 -0
  54. package/dist/pic-js/examples/counter/tests/src/counter.spec.js +80 -0
  55. package/dist/pic-js/examples/todo/tests/jest.config.d.ts +3 -0
  56. package/dist/pic-js/examples/todo/tests/jest.config.js +8 -0
  57. package/dist/pic-js/examples/todo/tests/src/todo.spec.d.ts +1 -0
  58. package/dist/pic-js/examples/todo/tests/src/todo.spec.js +211 -0
  59. package/dist/pic-js/examples/todo/tests/todo/index.d.ts +1 -0
  60. package/dist/pic-js/examples/todo/tests/todo/index.js +5 -0
  61. package/dist/pic-js/packages/pic/src/error.d.ts +12 -0
  62. package/dist/pic-js/packages/pic/src/error.js +36 -0
  63. package/dist/pic-js/packages/pic/src/http-client.d.ts +15 -0
  64. package/dist/pic-js/packages/pic/src/http-client.js +37 -0
  65. package/dist/pic-js/packages/pic/src/identity.d.ts +66 -0
  66. package/dist/pic-js/packages/pic/src/identity.js +86 -0
  67. package/dist/pic-js/packages/pic/src/index.d.ts +4 -0
  68. package/dist/pic-js/packages/pic/src/index.js +8 -0
  69. package/dist/pic-js/packages/pic/src/management-canister.d.ts +30 -0
  70. package/dist/pic-js/packages/pic/src/management-canister.js +43 -0
  71. package/dist/pic-js/packages/pic/src/pocket-ic-actor.d.ts +83 -0
  72. package/dist/pic-js/packages/pic/src/pocket-ic-actor.js +58 -0
  73. package/dist/pic-js/packages/pic/src/pocket-ic-client-types.d.ts +61 -0
  74. package/dist/pic-js/packages/pic/src/pocket-ic-client-types.js +2 -0
  75. package/dist/pic-js/packages/pic/src/pocket-ic-client.d.ts +24 -0
  76. package/dist/pic-js/packages/pic/src/pocket-ic-client.js +123 -0
  77. package/dist/pic-js/packages/pic/src/pocket-ic-server.d.ts +10 -0
  78. package/dist/pic-js/packages/pic/src/pocket-ic-server.js +55 -0
  79. package/dist/pic-js/packages/pic/src/pocket-ic-types.d.ts +40 -0
  80. package/dist/pic-js/packages/pic/src/pocket-ic-types.js +2 -0
  81. package/dist/pic-js/packages/pic/src/pocket-ic.d.ts +447 -0
  82. package/dist/pic-js/packages/pic/src/pocket-ic.js +551 -0
  83. package/dist/pic-js/packages/pic/src/util/candid.d.ts +1 -0
  84. package/dist/pic-js/packages/pic/src/util/candid.js +7 -0
  85. package/dist/pic-js/packages/pic/src/util/encoding.d.ts +5 -0
  86. package/dist/pic-js/packages/pic/src/util/encoding.js +19 -0
  87. package/dist/pic-js/packages/pic/src/util/fs.d.ts +4 -0
  88. package/dist/pic-js/packages/pic/src/util/fs.js +29 -0
  89. package/dist/pic-js/packages/pic/src/util/index.d.ts +5 -0
  90. package/dist/pic-js/packages/pic/src/util/index.js +21 -0
  91. package/dist/pic-js/packages/pic/src/util/os.d.ts +4 -0
  92. package/dist/pic-js/packages/pic/src/util/os.js +19 -0
  93. package/dist/pic-js/packages/pic/src/util/poll.d.ts +5 -0
  94. package/dist/pic-js/packages/pic/src/util/poll.js +28 -0
  95. package/dist/templates/mops-test.yml +4 -4
  96. package/dist/types.d.ts +7 -0
  97. package/dist/vessel.js +5 -1
  98. package/global.d.ts +2 -1
  99. package/integrity.ts +57 -17
  100. package/mops.ts +3 -3
  101. package/package.json +9 -4
  102. package/templates/mops-test.yml +4 -4
  103. package/types.ts +10 -1
  104. package/vessel.ts +6 -1
  105. package/bun.lockb +0 -0
  106. package/cli-local.ts +0 -3
@@ -0,0 +1,325 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import {execSync} from 'node:child_process';
5
+ import chalk from 'chalk';
6
+ import prompts from 'prompts';
7
+ import {createLogUpdate} from 'log-update';
8
+ import {checkConfigFile, getClosestConfigFile, getRootDir, globalCacheDir, readConfig, writeConfig} from '../../mops.js';
9
+ import {Tool} from '../../types.js';
10
+ import * as moc from './moc.js';
11
+ import * as pocketIc from './pocket-ic.js';
12
+ import * as wasmtime from './wasmtime.js';
13
+
14
+ function getToolUtils(tool: Tool) {
15
+ if (tool === 'moc') {
16
+ return moc;
17
+ }
18
+ else if (tool === 'pocket-ic') {
19
+ return pocketIc;
20
+ }
21
+ else if (tool === 'wasmtime') {
22
+ return wasmtime;
23
+ }
24
+ else {
25
+ console.error(`Unknown tool '${tool}'`);
26
+ process.exit(1);
27
+ }
28
+ }
29
+
30
+ async function ensureToolchainInited({strict = true} = {}) {
31
+ // auto init in CI
32
+ if (process.env.CI) {
33
+ await init({silent: true});
34
+ return true;
35
+ }
36
+
37
+ // for non-stict perform check only if dfx.json exists and moc is listed in [toolchain] section
38
+ let rootDir = getRootDir();
39
+ let config = readConfig();
40
+ if (!strict && (!config.toolchain?.moc || rootDir && !fs.existsSync(path.join(rootDir, 'dfx.json')))) {
41
+ return true;
42
+ }
43
+
44
+ try {
45
+ let res = execSync('which moc-wrapper').toString().trim();
46
+ if (res && process.env.DFX_MOC_PATH === 'moc-wrapper') {
47
+ return true;
48
+ }
49
+ }
50
+ catch {}
51
+ console.error('Toolchain management is not initialized. Run "mops toolchain init"');
52
+ process.exit(1);
53
+ }
54
+
55
+ // update shell config files to set DFX_MOC_PATH to moc-wrapper
56
+ async function init({reset = false, silent = false} = {}) {
57
+ if (process.platform == 'win32') {
58
+ console.error('Windows is not supported. Please use WSL');
59
+ process.exit(1);
60
+ }
61
+
62
+ try {
63
+ let res = execSync('which mocv').toString().trim();
64
+ if (res) {
65
+ console.error('Mops is not compatible with mocv. Please uninstall mocv and try again.');
66
+ console.log('Steps to uninstall mocv:');
67
+ console.log('1. Run "mocv reset"');
68
+ console.log('2. Run "npm uninstall -g mocv"');
69
+ process.exit(1);
70
+ }
71
+ }
72
+ catch {}
73
+
74
+ let zshrc = path.join(os.homedir(), '.zshrc');
75
+ let bashrc = path.join(os.homedir(), '.bashrc');
76
+
77
+ let shellConfigFiles = [bashrc, zshrc, process.env.GITHUB_ENV || ''].map(x => x).filter((file) => {
78
+ return fs.existsSync(file);
79
+ });
80
+
81
+ if (shellConfigFiles.length === 0) {
82
+ console.error('Shell config files not found: ".bashrc" or ".zshrc"');
83
+ process.exit(1);
84
+ }
85
+
86
+ // update all existing shell config files
87
+ for (let shellConfigFile of shellConfigFiles) {
88
+ let text = fs.readFileSync(shellConfigFile).toString();
89
+ let setDfxMocPathLine = '\nexport DFX_MOC_PATH=moc-wrapper';
90
+
91
+ let newLines = [
92
+ setDfxMocPathLine,
93
+ ];
94
+
95
+ let oldLines = [
96
+ // legacy mocv lines
97
+ `\nexport DFX_MOC_PATH=${path.join(path.join(os.homedir(), '.cache/mocv'), 'versions/current')}/moc`,
98
+ '\nexport DFX_MOC_PATH="$HOME/.cache/mocv/versions/current/moc"',
99
+ // new
100
+ setDfxMocPathLine,
101
+ ];
102
+
103
+ // remove old lines
104
+ for (let oldLine of oldLines) {
105
+ text = text.replace(oldLine, '');
106
+ }
107
+
108
+ if (text.endsWith('\n\n')) {
109
+ text = text.trimEnd() + '\n';
110
+ }
111
+
112
+ // insert new lines
113
+ if (!reset) {
114
+ if (!text.endsWith('\n')) {
115
+ text += '\n';
116
+ }
117
+ for (let newLine of newLines) {
118
+ if (shellConfigFile === process.env.GITHUB_ENV) {
119
+ newLine = newLine.replace('export ', '');
120
+ }
121
+ text += newLine;
122
+ }
123
+ text += '\n';
124
+ }
125
+
126
+ fs.writeFileSync(shellConfigFile, text);
127
+ }
128
+
129
+ if (!silent) {
130
+ console.log(chalk.green('Success!'));
131
+ console.log('Restart terminal to apply changes');
132
+ }
133
+ }
134
+
135
+ async function download(tool: Tool, version: string, {silent = false, verbose = false} = {}) {
136
+ let toolUtils = getToolUtils(tool);
137
+ await toolUtils.download(version, {silent, verbose});
138
+ }
139
+
140
+ async function installAll({silent = false, verbose = false} = {}) {
141
+ let config = readConfig();
142
+
143
+ if (!config.toolchain) {
144
+ return;
145
+ }
146
+
147
+ let logUpdate = createLogUpdate(process.stdout, {showCursor: true});
148
+
149
+ let log = (...args: string[]) => {
150
+ if (silent) {
151
+ return;
152
+ }
153
+ if (verbose) {
154
+ console.log(...args);
155
+ }
156
+ else {
157
+ logUpdate(...args);
158
+ }
159
+ };
160
+
161
+ log('Installing toolchain...');
162
+
163
+ if (config.toolchain?.moc) {
164
+ log('Installing moc', config.toolchain.moc);
165
+ await download('moc', config.toolchain.moc, {verbose});
166
+ }
167
+ if (config.toolchain?.wasmtime) {
168
+ log('Installing wasmtime', config.toolchain.wasmtime);
169
+ await download('wasmtime', config.toolchain.wasmtime, {verbose});
170
+ }
171
+ if (config.toolchain?.['pocket-ic']) {
172
+ log('Installing pocket-ic', config.toolchain['pocket-ic']);
173
+ await download('pocket-ic', config.toolchain['pocket-ic'], {verbose});
174
+ }
175
+
176
+ if (!silent) {
177
+ logUpdate.clear();
178
+ console.log(chalk.green('Toolchain installed'));
179
+ }
180
+ }
181
+
182
+ async function promptVersion(tool: Tool): Promise<string> {
183
+ let config = readConfig();
184
+ config.toolchain = config.toolchain || {};
185
+ let current = config.toolchain[tool];
186
+
187
+ let toolUtils = getToolUtils(tool);
188
+ let releases = await toolUtils.getReleases();
189
+ let versions = releases.map((item: {tag_name: any;}) => item.tag_name);
190
+ let currentIndex = versions.indexOf(current);
191
+
192
+ let res = await prompts({
193
+ type: 'select',
194
+ name: 'version',
195
+ message: `Select ${tool} version`,
196
+ choices: releases.map((release: {published_at: string | number | Date; tag_name: string;}, i: any) => {
197
+ let date = new Date(release.published_at).toLocaleDateString(undefined, {year: 'numeric', month: 'short', day: 'numeric'});
198
+ return {
199
+ title: release.tag_name + chalk.gray(` ${date}${currentIndex === i ? chalk.italic(' (current)') : ''}`),
200
+ value: release.tag_name,
201
+ };
202
+ }),
203
+ initial: currentIndex == -1 ? 0 : currentIndex,
204
+ });
205
+
206
+ return res.version;
207
+ }
208
+
209
+ // download binary and set version in mops.toml
210
+ async function use(tool: Tool, version?: string) {
211
+ if (tool === 'moc') {
212
+ await ensureToolchainInited();
213
+ }
214
+ if (!version) {
215
+ version = await promptVersion(tool);
216
+ }
217
+ if (!version) {
218
+ return;
219
+ }
220
+ if (version === 'latest') {
221
+ version = await getToolUtils(tool).getLatestReleaseTag();
222
+ }
223
+
224
+ await download(tool, version);
225
+
226
+ let config = readConfig();
227
+ config.toolchain = config.toolchain || {};
228
+
229
+ let oldVersion = config.toolchain[tool];
230
+
231
+ config.toolchain[tool] = version;
232
+ writeConfig(config);
233
+
234
+ if (oldVersion === version) {
235
+ console.log((`${tool} ${version} is already installed`));
236
+ }
237
+ else {
238
+ console.log(chalk.green(`Installed ${tool} ${version}`));
239
+ }
240
+ }
241
+
242
+ // download latest binary and set version in mops.toml
243
+ async function update(tool?: Tool) {
244
+ if (tool === 'moc') {
245
+ await ensureToolchainInited();
246
+ }
247
+
248
+ let config = readConfig();
249
+ config.toolchain = config.toolchain || {};
250
+
251
+ let tools = tool ? [tool] : Object.keys(config.toolchain) as Tool[];
252
+
253
+ for (let tool of tools) {
254
+ if (!config.toolchain[tool]) {
255
+ console.error(`Tool '${tool}' is not defined in [toolchain] section in mops.toml`);
256
+ process.exit(1);
257
+ }
258
+
259
+ let toolUtils = getToolUtils(tool);
260
+ let version = await toolUtils.getLatestReleaseTag();
261
+
262
+ await download(tool, version);
263
+
264
+ let oldVersion = config.toolchain[tool];
265
+ config.toolchain[tool] = version;
266
+ writeConfig(config);
267
+
268
+ if (oldVersion === version) {
269
+ console.log((`Latest ${tool} ${version} is already installed`));
270
+ }
271
+ else {
272
+ console.log(chalk.green(`Installed ${tool} ${version}`));
273
+ }
274
+ }
275
+ }
276
+
277
+ // return current version from mops.toml
278
+ async function bin(tool: Tool, {fallback = false} = {}): Promise<string> {
279
+ let hasConfig = getClosestConfigFile();
280
+
281
+ // fallback to dfx moc
282
+ if (!hasConfig) {
283
+ if (tool === 'moc' && fallback) {
284
+ return execSync('dfx cache show').toString().trim() + '/moc';
285
+ }
286
+ checkConfigFile();
287
+ process.exit(1);
288
+ }
289
+
290
+ let config = readConfig();
291
+ let version = config.toolchain?.[tool];
292
+
293
+ if (version) {
294
+ if (tool === 'moc') {
295
+ await ensureToolchainInited();
296
+ }
297
+
298
+ await download(tool, version, {silent: true});
299
+
300
+ if (tool === 'moc') {
301
+ return path.join(globalCacheDir, 'moc', version, tool);
302
+ }
303
+ else {
304
+ return path.join(globalCacheDir, tool, version, tool);
305
+ }
306
+ }
307
+ else {
308
+ // fallback to dfx moc
309
+ if (tool === 'moc' && fallback) {
310
+ return execSync('dfx cache show').toString().trim() + '/moc';
311
+ }
312
+ console.error(`Tool '${tool}' is not defined in [toolchain] section in mops.toml`);
313
+ console.log(`Run ${chalk.green(`mops toolchain use ${tool}`)} to install it`);
314
+ process.exit(1);
315
+ }
316
+ }
317
+
318
+ export let toolchain = {
319
+ init,
320
+ use,
321
+ update,
322
+ bin,
323
+ installAll,
324
+ ensureToolchainInited,
325
+ };
@@ -0,0 +1,58 @@
1
+ import path from 'node:path';
2
+ import fs from 'fs-extra';
3
+
4
+ import {globalCacheDir} from '../../mops.js';
5
+ import * as toolchainUtils from './toolchain-utils.js';
6
+
7
+ let cacheDir = path.join(globalCacheDir, 'moc');
8
+
9
+ export let repo = 'dfinity/motoko';
10
+
11
+ export let getLatestReleaseTag = async () => {
12
+ return toolchainUtils.getLatestReleaseTag(repo);
13
+ };
14
+
15
+ export let getReleases = async () => {
16
+ return toolchainUtils.getReleases(repo);
17
+ };
18
+
19
+ export let isCached = (version: string) => {
20
+ let dir = path.join(cacheDir, version);
21
+ return fs.existsSync(dir) && fs.existsSync(path.join(dir, 'moc'));
22
+ };
23
+
24
+ export let download = async (version: string, {silent = false, verbose = false} = {}) => {
25
+ if (process.platform == 'win32') {
26
+ console.error('Windows is not supported. Please use WSL');
27
+ process.exit(1);
28
+ }
29
+ if (!version) {
30
+ console.error('version is not defined');
31
+ process.exit(1);
32
+ }
33
+ if (isCached(version)) {
34
+ if (verbose) {
35
+ console.log(`moc ${version} is already installed`);
36
+ }
37
+ return;
38
+ }
39
+
40
+ let url;
41
+ if (parseInt(version.replaceAll('.', '')) >= parseInt('0.9.5'.replaceAll('.', ''))) {
42
+ let platfrom = process.platform == 'darwin' ? 'Darwin' : 'Linux';
43
+ let arch = process.arch.startsWith('arm') ? 'arm64' : 'x86_64';
44
+ // currently only x64 binaries are available
45
+ arch = 'x86_64';
46
+ url = `https://github.com/dfinity/motoko/releases/download/${version}/motoko-${platfrom}-${arch}-${version}.tar.gz`;
47
+ }
48
+ else {
49
+ let platfrom = process.platform == 'darwin' ? 'macos' : 'linux64';
50
+ url = `https://github.com/dfinity/motoko/releases/download/${version}/motoko-${platfrom}-${version}.tar.gz`;
51
+ }
52
+
53
+ if (verbose && !silent) {
54
+ console.log(`Downloading ${url}`);
55
+ }
56
+
57
+ await toolchainUtils.downloadAndExtract(url, path.join(cacheDir, version));
58
+ };
@@ -0,0 +1,74 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+
4
+ import {globalCacheDir} from '../../mops.js';
5
+ import * as toolchainUtils from './toolchain-utils.js';
6
+
7
+ let cacheDir = path.join(globalCacheDir, 'pocket-ic');
8
+
9
+ export let repo = 'dfinity/pocketic';
10
+
11
+ export let getLatestReleaseTag = async () => {
12
+ return '1.0.0';
13
+ // return toolchainUtils.getLatestReleaseTag(repo);
14
+ };
15
+
16
+ export let getReleases = async () => {
17
+ // return toolchainUtils.getReleases(repo);
18
+ return [
19
+ // {
20
+ // tag_name: '2.0.1',
21
+ // published_at: new Date('2023-11-23'),
22
+ // draft: false,
23
+ // },
24
+ // {
25
+ // tag_name: '2.0.0',
26
+ // published_at: new Date('2023-11-21'),
27
+ // draft: false,
28
+ // },
29
+ {
30
+ tag_name: '1.0.0',
31
+ published_at: new Date('2023-10-12'),
32
+ draft: false,
33
+ },
34
+ ];
35
+ };
36
+
37
+ export let isCached = (version: string) => {
38
+ let dir = path.join(cacheDir, version);
39
+ return fs.existsSync(dir) && fs.existsSync(path.join(dir, 'pocket-ic'));
40
+ };
41
+
42
+ export let download = async (version: string, {silent = false, verbose = false} = {}) => {
43
+ if (!version) {
44
+ console.error('version is not defined');
45
+ process.exit(1);
46
+ }
47
+ if (version !== '1.0.0') {
48
+ console.error('Currently only pocket-ic 1.0.0 is supported');
49
+ process.exit(1);
50
+ }
51
+ if (isCached(version)) {
52
+ if (verbose) {
53
+ console.log(`pocket-ic ${version} is already installed`);
54
+ }
55
+ return;
56
+ }
57
+
58
+ let platfrom = process.platform == 'darwin' ? 'darwin' : 'linux';
59
+ let arch = 'x86_64';
60
+
61
+ let hashes: Record<string, string> = {
62
+ // '2.0.1': '69e1408347723dbaa7a6cd2faa9b65c42abbe861',
63
+ // '2.0.0': '29ec86dc9f9ca4691d4d4386c8b2aa41e14d9d16',
64
+ '1.0.0': '307d5847c1d2fe1f5e19181c7d0fcec23f4658b3',
65
+ };
66
+
67
+ let url = `https://download.dfinity.systems/ic/${hashes[version]}/openssl-static-binaries/${arch}-${platfrom}/pocket-ic.gz`;
68
+
69
+ if (verbose && !silent) {
70
+ console.log(`Downloading ${url}`);
71
+ }
72
+
73
+ await toolchainUtils.downloadAndExtract(url, path.join(cacheDir, version));
74
+ };
@@ -0,0 +1,83 @@
1
+ import path from 'node:path';
2
+ import {unzipSync} from 'node:zlib';
3
+ import {chmodSync} from 'node:fs';
4
+ import fs from 'fs-extra';
5
+ import decompress from 'decompress';
6
+ import decompressTarxz from 'decomp-tarxz';
7
+ import {deleteSync} from 'del';
8
+ import {Octokit} from 'octokit';
9
+ import tar from 'tar';
10
+
11
+ import {getRootDir} from '../../mops.js';
12
+
13
+ export let downloadAndExtract = async (url: string, dest: string) => {
14
+ let res = await fetch(url);
15
+
16
+ if (res.status !== 200) {
17
+ console.error(`ERROR ${res.status} ${url}`);
18
+ process.exit(1);
19
+ }
20
+
21
+ let arrayBuffer = await res.arrayBuffer();
22
+ let buffer = Buffer.from(arrayBuffer);
23
+
24
+ let tmpDir = path.join(getRootDir(), '.mops', '_tmp');
25
+ let archive = path.join(tmpDir, path.basename(url));
26
+
27
+ fs.mkdirSync(tmpDir, {recursive: true});
28
+ fs.writeFileSync(archive, buffer);
29
+
30
+ fs.mkdirSync(dest, {recursive: true});
31
+
32
+ if (archive.endsWith('.xz')) {
33
+ await decompress(archive, tmpDir, {
34
+ plugins: [decompressTarxz()],
35
+ }).catch(() => {
36
+ deleteSync([tmpDir]);
37
+ });
38
+ fs.cpSync(path.join(tmpDir, path.parse(archive).name.replace('.tar', '')), dest, {recursive: true});
39
+ }
40
+ else if (archive.endsWith('tar.gz')) {
41
+ await tar.extract({
42
+ file: archive,
43
+ cwd: dest,
44
+ });
45
+ }
46
+ else if (archive.endsWith('.gz')) {
47
+ let destFile = path.join(dest, path.parse(archive).name);
48
+ fs.writeFileSync(destFile, unzipSync(buffer));
49
+ chmodSync(destFile, 0o700);
50
+ }
51
+
52
+ deleteSync([tmpDir], {force: true});
53
+ };
54
+
55
+ export let getLatestReleaseTag = async (repo: string): Promise<string> => {
56
+ let releases = await getReleases(repo);
57
+ let release = releases.find((release: any) => !release.prerelease && !release.draft);
58
+ if (!release?.tag_name) {
59
+ console.error(`Failed to fetch latest release tag for ${repo}`);
60
+ process.exit(1);
61
+ }
62
+ return release.tag_name.replace(/^v/, '');
63
+ };
64
+
65
+ export let getReleases = async (repo: string) => {
66
+ let octokit = new Octokit;
67
+ let res = await octokit.request(`GET /repos/${repo}/releases`, {
68
+ per_page: 10,
69
+ headers: {
70
+ 'X-GitHub-Api-Version': '2022-11-28'
71
+ }
72
+ });
73
+ if (res.status !== 200) {
74
+ console.log('Releases fetch error');
75
+ process.exit(1);
76
+ }
77
+ return res.data.map((release: any) => {
78
+ return {
79
+ ...release,
80
+ tag_name: release.tag_name.replace(/^v/, ''),
81
+ };
82
+ });
83
+ };
@@ -0,0 +1,45 @@
1
+ import path from 'node:path';
2
+ import fs from 'fs-extra';
3
+
4
+ import {globalCacheDir} from '../../mops.js';
5
+ import * as toolchainUtils from './toolchain-utils.js';
6
+
7
+ let cacheDir = path.join(globalCacheDir, 'wasmtime');
8
+
9
+ export let repo = 'bytecodealliance/wasmtime';
10
+
11
+ export let getLatestReleaseTag = async () => {
12
+ return toolchainUtils.getLatestReleaseTag(repo);
13
+ };
14
+
15
+ export let getReleases = async () => {
16
+ return toolchainUtils.getReleases(repo);
17
+ };
18
+
19
+ export let isCached = (version: string) => {
20
+ let dir = path.join(cacheDir, version);
21
+ return fs.existsSync(dir) && fs.existsSync(path.join(dir, 'wasmtime'));
22
+ };
23
+
24
+ export let download = async (version: string, {silent = false, verbose = false} = {}) => {
25
+ if (!version) {
26
+ console.error('version is not defined');
27
+ process.exit(1);
28
+ }
29
+ if (isCached(version)) {
30
+ if (verbose) {
31
+ console.log(`wasmtime ${version} is already installed`);
32
+ }
33
+ return;
34
+ }
35
+
36
+ let platfrom = process.platform == 'darwin' ? 'macos' : 'linux';
37
+ let arch = process.arch.startsWith('arm') ? 'aarch64' : 'x86_64';
38
+ let url = `https://github.com/bytecodealliance/wasmtime/releases/download/v${version}/wasmtime-v${version}-${arch}-${platfrom}.tar.xz`;
39
+
40
+ if (verbose && !silent) {
41
+ console.log(`Downloading ${url}`);
42
+ }
43
+
44
+ await toolchainUtils.downloadAndExtract(url, path.join(cacheDir, version));
45
+ };
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ import '../cli.js';
package/dist/cache.js CHANGED
@@ -32,7 +32,7 @@ export let copyCache = (pkgId, dest) => {
32
32
  });
33
33
  };
34
34
  export let cacheSize = async () => {
35
- let dir = path.join(globalCacheDir, 'packages');
35
+ let dir = path.join(globalCacheDir);
36
36
  fs.mkdirSync(dir, { recursive: true });
37
37
  let size = await getFolderSize.strict(dir);
38
38
  if (size < 1024 * 1024) {
@@ -41,6 +41,6 @@ export let cacheSize = async () => {
41
41
  return (size / 1024 / 1024).toFixed(2) + ' MB';
42
42
  };
43
43
  export let cleanCache = async () => {
44
- let dir = path.join(globalCacheDir, 'packages');
44
+ let dir = path.join(globalCacheDir);
45
45
  fs.rmSync(dir, { recursive: true, force: true });
46
46
  };
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env node
2
1
  declare global {
3
2
  var MOPS_NETWORK: string;
4
3
  }