ic-mops 1.4.0-pre.0 → 1.5.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.
package/CHANGELOG.md CHANGED
@@ -1,9 +1,27 @@
1
1
  # Mops CLI Changelog
2
2
 
3
+ ## 1.5.0
4
+ - Compile benchmarks with `--release` flag by default
5
+ - Respect `profile` field in `dfx.json` for benchmarks
6
+
7
+ ## 1.4.0
8
+ - Update `mops bench` command output:
9
+ - Print only final results if benchmarks run in a CI environment or there is no vertical space to progressively print the results
10
+ - Hide "Stable Memory" table if it has no data
11
+ - Hide verbose output when running in a CI environment ("Starting replica...", "Running simple.bench.mo...", etc.)
12
+ - Add LaTeX colors to the diffs when running in a CI environment with `--compare` flag
13
+ - CLI now fails if excess arguments are passed to it
14
+
15
+ ## 1.3.0
16
+ - Show error on `mops install <pkg>` command. Use `mops add <pkg>` instead.
17
+ - Added support for pocket-ic replica that comes with dfx in `mops bench` command. To activate it, remove `pocket-ic` from `mops.toml` and run `mops bench --replica pocket-ic`. Requires dfx 0.24.1 or higher.
18
+ - `mops init` now pre-fills package name with current directory name in kebab-case
19
+ - Updated non-major npm dependencies
20
+
3
21
  ## 1.2.0
4
22
  - Removed `mops transfer-ownership` command
5
23
  - Added `mops owner` command to manage package owners ([docs](https://docs.mops.one/cli/mops-owner))
6
- - Added `mops maintainers` command to manage package maintainers ([docs](https://docs.mops.one/cli/mops-maintainers))
24
+ - Added `mops maintainer` command to manage package maintainers ([docs](https://docs.mops.one/cli/mops-maintainer))
7
25
  - Added experimental support for pocket-ic replica that comes with dfx in `mops test` command ([docs](https://docs.mops.one/cli/mops-test#--replica))
8
26
  - Added flag `--verbose` to `mops test` command to show replica logs
9
27
  - Fixed bug where `mops watch` would fail if dfx.json did not exist
package/README.md CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  Mops is a package manager for the Motoko programming language.
4
4
 
5
- See https://mops.one
5
+ - [Motoko Package Registry](https://mops.one)
6
+ - [Documentation](https://docs.mops.one)
7
+ - [Blog](https://blog.mops.one)
8
+ - [CLI](https://cli.mops.one)
6
9
 
7
10
  ## Setup
8
11
 
@@ -12,6 +15,10 @@ See https://mops.one
12
15
 
13
16
  ### 2. Install CLI tool
14
17
  ```
18
+ curl -fsSL cli.mops.one/install.sh | sh
19
+ ```
20
+ or
21
+ ```
15
22
  npm i -g ic-mops
16
23
  ```
17
24
 
@@ -33,8 +40,6 @@ Add `mops` as a packtool to your `dfx.json`
33
40
  ### 2. Initialize
34
41
  Run this command in the root directory of your project (where is `dfx.json` placed)
35
42
 
36
- If there are Vessel config files, mops will migrate packages from `vessel.dhall` to `mops.toml`
37
-
38
43
  ```
39
44
  mops init
40
45
  ```
@@ -110,4 +115,7 @@ Publish package to the mops registry!
110
115
 
111
116
  ```
112
117
  mops publish
113
- ```
118
+ ```
119
+
120
+ ------------
121
+ *Built for the [Supernova Hackathon](https://dfinity.org/supernova/)*
package/bundle/cli.tgz CHANGED
Binary file
package/cli.ts CHANGED
@@ -2,6 +2,7 @@ import process from 'node:process';
2
2
  import fs from 'node:fs';
3
3
  import events from 'node:events';
4
4
  import {Command, Argument, Option} from 'commander';
5
+ import chalk from 'chalk';
5
6
 
6
7
  import {init} from './commands/init.js';
7
8
  import {publish} from './commands/publish.js';
@@ -98,6 +99,11 @@ program
98
99
  .option('--verbose')
99
100
  .addOption(new Option('--lock <action>', 'Lockfile action').choices(['check', 'update', 'ignore']))
100
101
  .action(async (options) => {
102
+ if (process.argv.at(-1) !== 'install') {
103
+ console.log(`${chalk.red('Error:')} ${chalk.yellow('mops install')} command installs all dependencies.\nUse ${chalk.green(`mops add ${process.argv.at(-1)}`)} instead.`);
104
+ process.exit(1);
105
+ }
106
+
101
107
  if (!checkConfigFile()) {
102
108
  process.exit(1);
103
109
  }
@@ -7,33 +7,36 @@ import {PocketIc, PocketIcServer} from 'pic-ic';
7
7
  import {getRootDir, readConfig} from '../mops.js';
8
8
  import {createActor, idlFactory} from '../declarations/bench/index.js';
9
9
  import {toolchain} from './toolchain/index.js';
10
+ import {getDfxVersion} from '../helpers/get-dfx-version.js';
10
11
 
11
12
  export class BenchReplica {
12
- type : 'dfx' | 'pocket-ic';
13
+ type : 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
13
14
  verbose = false;
14
15
  canisters : Record<string, {cwd : string; canisterId : string; actor : any;}> = {};
15
16
  pocketIcServer ?: PocketIcServer;
16
17
  pocketIc ?: PocketIc;
17
18
 
18
- constructor(type : 'dfx' | 'pocket-ic', verbose = false) {
19
+ constructor(type : 'dfx' | 'pocket-ic' | 'dfx-pocket-ic', verbose = false) {
19
20
  this.type = type;
20
21
  this.verbose = verbose;
21
22
  }
22
23
 
23
24
  async start({silent = false} = {}) {
24
- silent || console.log(`Starting ${this.type} replica...`);
25
+ if (!process.env.CI && !silent) {
26
+ console.log(`Starting ${this.type} replica...`);
27
+ }
25
28
 
26
- if (this.type == 'dfx') {
29
+ if (this.type == 'dfx' || this.type === 'dfx-pocket-ic') {
27
30
  await this.stop();
28
31
  let dir = path.join(getRootDir(), '.mops/.bench');
29
32
  fs.writeFileSync(path.join(dir, 'dfx.json'), JSON.stringify(this.dfxJson(''), null, 2));
30
- execSync('dfx start --background --clean --artificial-delay 0' + (this.verbose ? '' : ' -qqqq'), {cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit']});
33
+ execSync('dfx start --background --clean --artificial-delay 0' + (this.type === 'dfx-pocket-ic' ? ' --pocketic' : '') + (this.verbose ? '' : ' -qqqq'), {cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit']});
31
34
  }
32
35
  else {
33
36
  let pocketIcBin = await toolchain.bin('pocket-ic');
34
37
  let config = readConfig();
35
- if (config.toolchain?.['pocket-ic'] !== '6.0.0') {
36
- console.error('Current Mops CLI only supports pocket-ic 6.0.0');
38
+ if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
39
+ console.error('Current Mops CLI only supports pocket-ic 4.0.0');
37
40
  process.exit(1);
38
41
  }
39
42
  this.pocketIcServer = await PocketIcServer.start({
@@ -44,7 +47,7 @@ export class BenchReplica {
44
47
  }
45
48
 
46
49
  async stop() {
47
- if (this.type == 'dfx') {
50
+ if (this.type == 'dfx' || this.type === 'dfx-pocket-ic') {
48
51
  let dir = path.join(getRootDir(), '.mops/.bench');
49
52
  execSync('dfx stop' + (this.verbose ? '' : ' -qqqq'), {cwd: dir, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe']});
50
53
  }
@@ -55,7 +58,7 @@ export class BenchReplica {
55
58
  }
56
59
 
57
60
  async deploy(name : string, wasm : string, cwd : string = process.cwd()) {
58
- if (this.type === 'dfx') {
61
+ if (this.type === 'dfx' || this.type === 'dfx-pocket-ic') {
59
62
  await execaCommand(`dfx deploy ${name} --mode reinstall --yes --identity anonymous`, {cwd, stdio: this.verbose ? 'pipe' : ['pipe', 'ignore', 'pipe']});
60
63
  let canisterId = execSync(`dfx canister id ${name}`, {cwd}).toString().trim();
61
64
  let actor = await createActor(canisterId, {
@@ -96,6 +99,7 @@ export class BenchReplica {
96
99
  return {
97
100
  version: 1,
98
101
  canisters,
102
+ dfx: getDfxVersion(),
99
103
  defaults: {
100
104
  build: {
101
105
  packtool: 'mops sources',
@@ -109,4 +113,4 @@ export class BenchReplica {
109
113
  },
110
114
  };
111
115
  }
112
- }
116
+ }
package/commands/bench.ts CHANGED
@@ -5,11 +5,14 @@ import os from 'node:os';
5
5
  import chalk from 'chalk';
6
6
  import {globSync} from 'glob';
7
7
  import {markdownTable} from 'markdown-table';
8
- import logUpdate from 'log-update';
8
+ import {createLogUpdate} from 'log-update';
9
9
  import {execaCommand} from 'execa';
10
10
  import stringWidth from 'string-width';
11
+ import {filesize} from 'filesize';
12
+ import terminalSize from 'terminal-size';
13
+ import {SemVer} from 'semver';
11
14
 
12
- import {getRootDir, readConfig} from '../mops.js';
15
+ import {getRootDir, readConfig, readDfxJson} from '../mops.js';
13
16
  import {parallel} from '../parallel.js';
14
17
  import {absToRel} from './test/utils.js';
15
18
  import {getMocVersion} from '../helpers/get-moc-version.js';
@@ -20,7 +23,8 @@ import {sources} from './sources.js';
20
23
  import {Benchmark, Benchmarks} from '../declarations/main/main.did.js';
21
24
  import {BenchResult, _SERVICE} from '../declarations/bench/bench.did.js';
22
25
  import {BenchReplica} from './bench-replica.js';
23
- import {filesize} from 'filesize';
26
+
27
+ type ReplicaName = 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
24
28
 
25
29
  let ignore = [
26
30
  '**/node_modules/**',
@@ -35,7 +39,7 @@ let globConfig = {
35
39
  };
36
40
 
37
41
  type BenchOptions = {
38
- replica : 'dfx' | 'pocket-ic',
42
+ replica : ReplicaName,
39
43
  replicaVersion : string,
40
44
  compiler : 'moc',
41
45
  compilerVersion : string,
@@ -45,11 +49,12 @@ type BenchOptions = {
45
49
  compare : boolean,
46
50
  verbose : boolean,
47
51
  silent : boolean,
48
-
52
+ profile : 'Debug' | 'Release',
49
53
  };
50
54
 
51
55
  export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}) : Promise<Benchmarks> {
52
56
  let config = readConfig();
57
+ let dfxJson = readDfxJson();
53
58
 
54
59
  let defaultOptions : BenchOptions = {
55
60
  replica: config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx',
@@ -62,20 +67,39 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
62
67
  compare: false,
63
68
  verbose: false,
64
69
  silent: false,
70
+ profile: dfxJson.profile || 'Release',
65
71
  };
66
72
 
67
73
  let options : BenchOptions = {...defaultOptions, ...optionsArg};
68
74
 
69
- if (options.replica == 'dfx') {
75
+ let replicaType = options.replica ?? (config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx' as ReplicaName);
76
+ if (replicaType === 'pocket-ic' && !config.toolchain?.['pocket-ic']) {
77
+ let dfxVersion = getDfxVersion();
78
+ if (!dfxVersion || new SemVer(dfxVersion).compare('0.24.1') < 0) {
79
+ console.log(chalk.red('Please update dfx to the version >=0.24.1 or specify pocket-ic version in mops.toml'));
80
+ process.exit(1);
81
+ }
82
+ else {
83
+ replicaType = 'dfx-pocket-ic';
84
+ }
85
+ }
86
+
87
+ options.replica = replicaType;
88
+
89
+ if (process.env.CI) {
90
+ console.log('# Benchmark Results\n\n');
91
+ }
92
+
93
+ if (replicaType == 'dfx') {
70
94
  options.replicaVersion = getDfxVersion();
71
95
  }
72
- else if (options.replica == 'pocket-ic') {
96
+ else if (replicaType == 'pocket-ic') {
73
97
  options.replicaVersion = config.toolchain?.['pocket-ic'] || '';
74
98
  }
75
99
 
76
100
  options.verbose && console.log(options);
77
101
 
78
- let replica = new BenchReplica(options.replica, options.verbose);
102
+ let replica = new BenchReplica(replicaType, options.verbose);
79
103
 
80
104
  let rootDir = getRootDir();
81
105
  let globStr = '**/bench?(mark)/**/*.bench.mo';
@@ -106,14 +130,19 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
106
130
  for (let file of files) {
107
131
  console.log(chalk.gray(`• ${absToRel(file)}`));
108
132
  }
109
- console.log('');
110
- console.log('='.repeat(50));
111
- console.log('');
133
+ if (!process.env.CI) {
134
+ console.log('');
135
+ console.log('='.repeat(50));
136
+ console.log('');
137
+ }
112
138
  }
113
139
 
114
140
  await replica.start({silent: options.silent});
115
141
 
116
- options.silent || console.log('Deploying canisters...');
142
+ if (!process.env.CI && !options.silent) {
143
+ console.log('Deploying canisters...');
144
+ }
145
+
117
146
  await parallel(os.cpus().length, files, async (file : string) => {
118
147
  try {
119
148
  await deployBenchFile(file, options, replica);
@@ -128,8 +157,8 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
128
157
  let benchResults : Benchmarks = [];
129
158
 
130
159
  await parallel(1, files, async (file : string) => {
131
- if (!options.silent) {
132
- console.log('\n' + ''.repeat(50));
160
+ if (!options.silent && !process.env.CI) {
161
+ console.log('\n' + '-'.repeat(50));
133
162
  console.log(`\nRunning ${chalk.gray(absToRel(file))}...`);
134
163
  console.log('');
135
164
  }
@@ -144,7 +173,9 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
144
173
  }
145
174
  });
146
175
 
147
- options.silent || console.log('Stopping replica...');
176
+ if (!process.env.CI && !options.silent) {
177
+ console.log('Stopping replica...');
178
+ }
148
179
  await replica.stop();
149
180
 
150
181
  fs.rmSync(benchDir, {recursive: true, force: true});
@@ -154,12 +185,22 @@ export async function bench(filter = '', optionsArg : Partial<BenchOptions> = {}
154
185
 
155
186
  function getMocArgs(options : BenchOptions) : string {
156
187
  let args = '';
188
+
157
189
  if (options.forceGc) {
158
190
  args += ' --force-gc';
159
191
  }
192
+
160
193
  if (options.gc) {
161
194
  args += ` --${options.gc}-gc`;
162
195
  }
196
+
197
+ if (options.profile === 'Debug') {
198
+ args += ' --debug';
199
+ }
200
+ else if (options.profile === 'Release') {
201
+ args += ' --release';
202
+ }
203
+
163
204
  return args;
164
205
  }
165
206
 
@@ -234,6 +275,7 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
234
275
 
235
276
  let getTable = (prop : keyof BenchResult) : string => {
236
277
  let resArr = [['', ...schema.cols]];
278
+ let allZero = true;
237
279
 
238
280
  for (let [_rowIndex, row] of schema.rows.entries()) {
239
281
  let curRow = [row];
@@ -241,6 +283,9 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
241
283
  for (let [_colIndex, col] of schema.cols.entries()) {
242
284
  let res = results.get(`${row}:${col}`);
243
285
  if (res) {
286
+ if (res[prop] != 0n) {
287
+ allZero = false;
288
+ }
244
289
 
245
290
  // compare with previous results
246
291
  let diff = '';
@@ -248,10 +293,18 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
248
293
  let prevRes = prevResults.get(`${row}:${col}`);
249
294
  if (prevRes) {
250
295
  let percent = (Number(res[prop]) - Number(prevRes[prop])) / Number(prevRes[prop]) * 100;
296
+ if (Object.is(percent, NaN)) {
297
+ percent = 0;
298
+ }
251
299
  let sign = percent > 0 ? '+' : '';
252
300
  let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
253
301
  let color : keyof typeof chalk = percent == 0 ? 'gray' : (percent > 0 ? 'red' : 'green');
254
- diff = ` (${chalk[color](percentText)})`;
302
+ if (process.env.CI) {
303
+ diff = ` $({\\color{${color}}${percentText.replace('%', '\\\\%')}})$`;
304
+ }
305
+ else {
306
+ diff = ` (${chalk[color](percentText)})`;
307
+ }
255
308
  }
256
309
  else {
257
310
  diff = chalk.yellow(' (no previous results)');
@@ -278,25 +331,47 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
278
331
  resArr.push(curRow);
279
332
  }
280
333
 
334
+ // don't show Stable Memory table if all values are 0
335
+ if (allZero && prop == 'rts_logical_stable_memory_size') {
336
+ return '';
337
+ }
338
+
281
339
  return markdownTable(resArr, {
282
340
  align: ['l', ...'r'.repeat(schema.cols.length)],
283
341
  stringLength: stringWidth,
284
342
  });
285
343
  };
286
344
 
287
- let printResults = () => {
288
- logUpdate(`
289
- \n${chalk.bold(schema.name)}
290
- ${schema.description ? '\n' + chalk.gray(schema.description) : ''}
345
+ let logUpdate = createLogUpdate(process.stdout, {showCursor: true});
346
+
347
+ let getOutput = () => {
348
+ return `
349
+ \n${process.env.CI ? `## ${schema.name}` : chalk.bold(schema.name)}
350
+ ${schema.description ? '\n' + (process.env.CI ? `_${schema.description}_` : chalk.gray(schema.description)) : ''}
291
351
  \n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
292
352
  \n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
293
- \n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}
294
353
  \n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
295
- `);
354
+ ${getTable('rts_logical_stable_memory_size') ? `\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}` : ''}
355
+ `;
296
356
  };
297
357
 
298
- if (!process.env.CI && !options.silent) {
299
- printResults();
358
+ let canUpdateLog = !process.env.CI && !options.silent && terminalSize().rows > getOutput().split('\n').length;
359
+
360
+ let log = () => {
361
+ if (options.silent) {
362
+ return;
363
+ }
364
+ let output = getOutput();
365
+ if (process.env.CI || terminalSize().rows <= output.split('\n').length) {
366
+ console.log(output);
367
+ }
368
+ else {
369
+ logUpdate(output);
370
+ }
371
+ };
372
+
373
+ if (canUpdateLog) {
374
+ log();
300
375
  }
301
376
 
302
377
  // run all cells
@@ -314,16 +389,18 @@ async function runBenchFile(file : string, options : BenchOptions, replica : Ben
314
389
  // @ts-ignore
315
390
  reclaimedCells[rowIndex][colIndex] = res.rts_reclaimed;
316
391
 
317
- if (!process.env.CI && !options.silent) {
318
- printResults();
392
+ if (canUpdateLog) {
393
+ log();
319
394
  }
320
395
  }
321
396
  }
322
397
 
323
- if (process.env.CI) {
324
- printResults();
398
+ if (canUpdateLog) {
399
+ logUpdate.done();
400
+ }
401
+ else {
402
+ log();
325
403
  }
326
- logUpdate.done();
327
404
 
328
405
  // save results
329
406
  if (options.save) {
package/commands/init.ts CHANGED
@@ -11,6 +11,7 @@ import {installAll} from './install/install-all.js';
11
11
  import {VesselConfig, readVesselConfig} from '../vessel.js';
12
12
  import {Config, Dependencies} from '../types.js';
13
13
  import {template} from './template.js';
14
+ import {kebabCase} from 'change-case';
14
15
 
15
16
  export async function init({yes = false} = {}) {
16
17
  let configFile = path.join(process.cwd(), 'mops.toml');
@@ -88,7 +89,7 @@ export async function init({yes = false} = {}) {
88
89
  type: 'text',
89
90
  name: 'name',
90
91
  message: 'Enter package name:',
91
- initial: '',
92
+ initial: kebabCase(path.basename(process.cwd())),
92
93
  },
93
94
  {
94
95
  type: 'text',
@@ -133,7 +134,7 @@ export async function init({yes = false} = {}) {
133
134
  ], promptsConfig);
134
135
 
135
136
  config.package = {
136
- name: (res.name || '').trim(),
137
+ name: kebabCase((res.name || '').trim()),
137
138
  version: '1.0.0',
138
139
  description: (res.description || '').trim(),
139
140
  repository: (res.repository || '').trim(),
@@ -87,8 +87,8 @@ export class Replica {
87
87
 
88
88
  // eslint-disable-next-line
89
89
  let config = readConfig();
90
- if (config.toolchain?.['pocket-ic'] !== '6.0.0') {
91
- console.error('Current Mops CLI only supports pocket-ic 6.0.0');
90
+ if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
91
+ console.error('Current Mops CLI only supports pocket-ic 4.0.0');
92
92
  process.exit(1);
93
93
  }
94
94
 
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import chalk from 'chalk';
4
4
  import prompts from 'prompts';
5
- import camelCase from 'camelcase';
5
+ import {kebabCase, pascalCase} from 'change-case';
6
6
  import {getRootDir, readConfig} from '../mops.js';
7
7
  import {copyTemplateFileSync} from '../templates.js';
8
8
 
@@ -99,8 +99,8 @@ export async function template(templateName ?: string, options : any = {}) {
99
99
  let data = fs.readFileSync(dest).toString();
100
100
  data = data.replace(/<year>/g, new Date().getFullYear().toString());
101
101
  if (config.package?.name) {
102
- data = data.replace(/<name>/g, config.package.name);
103
- data = data.replace(/<import-name>/g, camelCase(config.package.name, {pascalCase: true}));
102
+ data = data.replace(/<name>/g, kebabCase(config.package.name));
103
+ data = data.replace(/<import-name>/g, pascalCase(config.package.name));
104
104
  }
105
105
  fs.writeFileSync(dest, data);
106
106
 
@@ -5,6 +5,7 @@ import {getRootDir} from '../../mops.js';
5
5
  type DfxConfig = {
6
6
  $schema : string;
7
7
  version : number;
8
+ profile : 'Debug' | 'Release';
8
9
  canisters : {
9
10
  [key : string] : {
10
11
  type : 'motoko' | 'assets';
@@ -41,7 +42,7 @@ type DfxConfig = {
41
42
  };
42
43
  };
43
44
 
44
- function readDfxJson() : DfxConfig | Record<string, never> {
45
+ export function readDfxJson() : DfxConfig | Record<string, never> {
45
46
  let dfxJsonPath = path.resolve(getRootDir(), 'dfx.json');
46
47
  if (!existsSync(dfxJsonPath)) {
47
48
  return {};
package/dist/cli.js CHANGED
@@ -2,6 +2,7 @@ import process from 'node:process';
2
2
  import fs from 'node:fs';
3
3
  import events from 'node:events';
4
4
  import { Command, Argument, Option } from 'commander';
5
+ import chalk from 'chalk';
5
6
  import { init } from './commands/init.js';
6
7
  import { publish } from './commands/publish.js';
7
8
  import { sources } from './commands/sources.js';
@@ -80,6 +81,10 @@ program
80
81
  .option('--verbose')
81
82
  .addOption(new Option('--lock <action>', 'Lockfile action').choices(['check', 'update', 'ignore']))
82
83
  .action(async (options) => {
84
+ if (process.argv.at(-1) !== 'install') {
85
+ console.log(`${chalk.red('Error:')} ${chalk.yellow('mops install')} command installs all dependencies.\nUse ${chalk.green(`mops add ${process.argv.at(-1)}`)} instead.`);
86
+ process.exit(1);
87
+ }
83
88
  if (!checkConfigFile()) {
84
89
  process.exit(1);
85
90
  }
@@ -1,6 +1,6 @@
1
1
  import { PocketIc, PocketIcServer } from 'pic-ic';
2
2
  export declare class BenchReplica {
3
- type: 'dfx' | 'pocket-ic';
3
+ type: 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
4
4
  verbose: boolean;
5
5
  canisters: Record<string, {
6
6
  cwd: string;
@@ -9,7 +9,7 @@ export declare class BenchReplica {
9
9
  }>;
10
10
  pocketIcServer?: PocketIcServer;
11
11
  pocketIc?: PocketIc;
12
- constructor(type: 'dfx' | 'pocket-ic', verbose?: boolean);
12
+ constructor(type: 'dfx' | 'pocket-ic' | 'dfx-pocket-ic', verbose?: boolean);
13
13
  start({ silent }?: {
14
14
  silent?: boolean | undefined;
15
15
  }): Promise<void>;
@@ -20,6 +20,7 @@ export declare class BenchReplica {
20
20
  dfxJson(canisterName: string): {
21
21
  version: number;
22
22
  canisters: Record<string, any>;
23
+ dfx: string;
23
24
  defaults: {
24
25
  build: {
25
26
  packtool: string;
@@ -7,6 +7,7 @@ import { PocketIc, PocketIcServer } from 'pic-ic';
7
7
  import { getRootDir, readConfig } from '../mops.js';
8
8
  import { createActor, idlFactory } from '../declarations/bench/index.js';
9
9
  import { toolchain } from './toolchain/index.js';
10
+ import { getDfxVersion } from '../helpers/get-dfx-version.js';
10
11
  export class BenchReplica {
11
12
  constructor(type, verbose = false) {
12
13
  this.verbose = false;
@@ -15,18 +16,20 @@ export class BenchReplica {
15
16
  this.verbose = verbose;
16
17
  }
17
18
  async start({ silent = false } = {}) {
18
- silent || console.log(`Starting ${this.type} replica...`);
19
- if (this.type == 'dfx') {
19
+ if (!process.env.CI && !silent) {
20
+ console.log(`Starting ${this.type} replica...`);
21
+ }
22
+ if (this.type == 'dfx' || this.type === 'dfx-pocket-ic') {
20
23
  await this.stop();
21
24
  let dir = path.join(getRootDir(), '.mops/.bench');
22
25
  fs.writeFileSync(path.join(dir, 'dfx.json'), JSON.stringify(this.dfxJson(''), null, 2));
23
- execSync('dfx start --background --clean --artificial-delay 0' + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit'] });
26
+ execSync('dfx start --background --clean --artificial-delay 0' + (this.type === 'dfx-pocket-ic' ? ' --pocketic' : '') + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['inherit', this.verbose ? 'inherit' : 'ignore', 'inherit'] });
24
27
  }
25
28
  else {
26
29
  let pocketIcBin = await toolchain.bin('pocket-ic');
27
30
  let config = readConfig();
28
- if (config.toolchain?.['pocket-ic'] !== '6.0.0') {
29
- console.error('Current Mops CLI only supports pocket-ic 6.0.0');
31
+ if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
32
+ console.error('Current Mops CLI only supports pocket-ic 4.0.0');
30
33
  process.exit(1);
31
34
  }
32
35
  this.pocketIcServer = await PocketIcServer.start({
@@ -36,7 +39,7 @@ export class BenchReplica {
36
39
  }
37
40
  }
38
41
  async stop() {
39
- if (this.type == 'dfx') {
42
+ if (this.type == 'dfx' || this.type === 'dfx-pocket-ic') {
40
43
  let dir = path.join(getRootDir(), '.mops/.bench');
41
44
  execSync('dfx stop' + (this.verbose ? '' : ' -qqqq'), { cwd: dir, stdio: ['pipe', this.verbose ? 'inherit' : 'ignore', 'pipe'] });
42
45
  }
@@ -46,7 +49,7 @@ export class BenchReplica {
46
49
  }
47
50
  }
48
51
  async deploy(name, wasm, cwd = process.cwd()) {
49
- if (this.type === 'dfx') {
52
+ if (this.type === 'dfx' || this.type === 'dfx-pocket-ic') {
50
53
  await execaCommand(`dfx deploy ${name} --mode reinstall --yes --identity anonymous`, { cwd, stdio: this.verbose ? 'pipe' : ['pipe', 'ignore', 'pipe'] });
51
54
  let canisterId = execSync(`dfx canister id ${name}`, { cwd }).toString().trim();
52
55
  let actor = await createActor(canisterId, {
@@ -83,6 +86,7 @@ export class BenchReplica {
83
86
  return {
84
87
  version: 1,
85
88
  canisters,
89
+ dfx: getDfxVersion(),
86
90
  defaults: {
87
91
  build: {
88
92
  packtool: 'mops sources',
@@ -1,6 +1,7 @@
1
1
  import { Benchmarks } from '../declarations/main/main.did.js';
2
+ type ReplicaName = 'dfx' | 'pocket-ic' | 'dfx-pocket-ic';
2
3
  type BenchOptions = {
3
- replica: 'dfx' | 'pocket-ic';
4
+ replica: ReplicaName;
4
5
  replicaVersion: string;
5
6
  compiler: 'moc';
6
7
  compilerVersion: string;
@@ -10,6 +11,7 @@ type BenchOptions = {
10
11
  compare: boolean;
11
12
  verbose: boolean;
12
13
  silent: boolean;
14
+ profile: 'Debug' | 'Release';
13
15
  };
14
16
  export declare function bench(filter?: string, optionsArg?: Partial<BenchOptions>): Promise<Benchmarks>;
15
17
  export {};
@@ -5,10 +5,13 @@ import os from 'node:os';
5
5
  import chalk from 'chalk';
6
6
  import { globSync } from 'glob';
7
7
  import { markdownTable } from 'markdown-table';
8
- import logUpdate from 'log-update';
8
+ import { createLogUpdate } from 'log-update';
9
9
  import { execaCommand } from 'execa';
10
10
  import stringWidth from 'string-width';
11
- import { getRootDir, readConfig } from '../mops.js';
11
+ import { filesize } from 'filesize';
12
+ import terminalSize from 'terminal-size';
13
+ import { SemVer } from 'semver';
14
+ import { getRootDir, readConfig, readDfxJson } from '../mops.js';
12
15
  import { parallel } from '../parallel.js';
13
16
  import { absToRel } from './test/utils.js';
14
17
  import { getMocVersion } from '../helpers/get-moc-version.js';
@@ -16,7 +19,6 @@ import { getDfxVersion } from '../helpers/get-dfx-version.js';
16
19
  import { getMocPath } from '../helpers/get-moc-path.js';
17
20
  import { sources } from './sources.js';
18
21
  import { BenchReplica } from './bench-replica.js';
19
- import { filesize } from 'filesize';
20
22
  let ignore = [
21
23
  '**/node_modules/**',
22
24
  '**/.mops/**',
@@ -29,6 +31,7 @@ let globConfig = {
29
31
  };
30
32
  export async function bench(filter = '', optionsArg = {}) {
31
33
  let config = readConfig();
34
+ let dfxJson = readDfxJson();
32
35
  let defaultOptions = {
33
36
  replica: config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx',
34
37
  replicaVersion: '',
@@ -40,16 +43,32 @@ export async function bench(filter = '', optionsArg = {}) {
40
43
  compare: false,
41
44
  verbose: false,
42
45
  silent: false,
46
+ profile: dfxJson.profile || 'Release',
43
47
  };
44
48
  let options = { ...defaultOptions, ...optionsArg };
45
- if (options.replica == 'dfx') {
49
+ let replicaType = options.replica ?? (config.toolchain?.['pocket-ic'] ? 'pocket-ic' : 'dfx');
50
+ if (replicaType === 'pocket-ic' && !config.toolchain?.['pocket-ic']) {
51
+ let dfxVersion = getDfxVersion();
52
+ if (!dfxVersion || new SemVer(dfxVersion).compare('0.24.1') < 0) {
53
+ console.log(chalk.red('Please update dfx to the version >=0.24.1 or specify pocket-ic version in mops.toml'));
54
+ process.exit(1);
55
+ }
56
+ else {
57
+ replicaType = 'dfx-pocket-ic';
58
+ }
59
+ }
60
+ options.replica = replicaType;
61
+ if (process.env.CI) {
62
+ console.log('# Benchmark Results\n\n');
63
+ }
64
+ if (replicaType == 'dfx') {
46
65
  options.replicaVersion = getDfxVersion();
47
66
  }
48
- else if (options.replica == 'pocket-ic') {
67
+ else if (replicaType == 'pocket-ic') {
49
68
  options.replicaVersion = config.toolchain?.['pocket-ic'] || '';
50
69
  }
51
70
  options.verbose && console.log(options);
52
- let replica = new BenchReplica(options.replica, options.verbose);
71
+ let replica = new BenchReplica(replicaType, options.verbose);
53
72
  let rootDir = getRootDir();
54
73
  let globStr = '**/bench?(mark)/**/*.bench.mo';
55
74
  if (filter) {
@@ -76,12 +95,16 @@ export async function bench(filter = '', optionsArg = {}) {
76
95
  for (let file of files) {
77
96
  console.log(chalk.gray(`• ${absToRel(file)}`));
78
97
  }
79
- console.log('');
80
- console.log('='.repeat(50));
81
- console.log('');
98
+ if (!process.env.CI) {
99
+ console.log('');
100
+ console.log('='.repeat(50));
101
+ console.log('');
102
+ }
82
103
  }
83
104
  await replica.start({ silent: options.silent });
84
- options.silent || console.log('Deploying canisters...');
105
+ if (!process.env.CI && !options.silent) {
106
+ console.log('Deploying canisters...');
107
+ }
85
108
  await parallel(os.cpus().length, files, async (file) => {
86
109
  try {
87
110
  await deployBenchFile(file, options, replica);
@@ -94,8 +117,8 @@ export async function bench(filter = '', optionsArg = {}) {
94
117
  });
95
118
  let benchResults = [];
96
119
  await parallel(1, files, async (file) => {
97
- if (!options.silent) {
98
- console.log('\n' + ''.repeat(50));
120
+ if (!options.silent && !process.env.CI) {
121
+ console.log('\n' + '-'.repeat(50));
99
122
  console.log(`\nRunning ${chalk.gray(absToRel(file))}...`);
100
123
  console.log('');
101
124
  }
@@ -109,7 +132,9 @@ export async function bench(filter = '', optionsArg = {}) {
109
132
  throw err;
110
133
  }
111
134
  });
112
- options.silent || console.log('Stopping replica...');
135
+ if (!process.env.CI && !options.silent) {
136
+ console.log('Stopping replica...');
137
+ }
113
138
  await replica.stop();
114
139
  fs.rmSync(benchDir, { recursive: true, force: true });
115
140
  return benchResults;
@@ -122,6 +147,12 @@ function getMocArgs(options) {
122
147
  if (options.gc) {
123
148
  args += ` --${options.gc}-gc`;
124
149
  }
150
+ if (options.profile === 'Debug') {
151
+ args += ' --debug';
152
+ }
153
+ else if (options.profile === 'Release') {
154
+ args += ' --release';
155
+ }
125
156
  return args;
126
157
  }
127
158
  async function deployBenchFile(file, options, replica) {
@@ -182,21 +213,33 @@ async function runBenchFile(file, options, replica) {
182
213
  };
183
214
  let getTable = (prop) => {
184
215
  let resArr = [['', ...schema.cols]];
216
+ let allZero = true;
185
217
  for (let [_rowIndex, row] of schema.rows.entries()) {
186
218
  let curRow = [row];
187
219
  for (let [_colIndex, col] of schema.cols.entries()) {
188
220
  let res = results.get(`${row}:${col}`);
189
221
  if (res) {
222
+ if (res[prop] != 0n) {
223
+ allZero = false;
224
+ }
190
225
  // compare with previous results
191
226
  let diff = '';
192
227
  if (options.compare && prevResults) {
193
228
  let prevRes = prevResults.get(`${row}:${col}`);
194
229
  if (prevRes) {
195
230
  let percent = (Number(res[prop]) - Number(prevRes[prop])) / Number(prevRes[prop]) * 100;
231
+ if (Object.is(percent, NaN)) {
232
+ percent = 0;
233
+ }
196
234
  let sign = percent > 0 ? '+' : '';
197
235
  let percentText = percent == 0 ? '0%' : sign + percent.toFixed(2) + '%';
198
236
  let color = percent == 0 ? 'gray' : (percent > 0 ? 'red' : 'green');
199
- diff = ` (${chalk[color](percentText)})`;
237
+ if (process.env.CI) {
238
+ diff = ` $({\\color{${color}}${percentText.replace('%', '\\\\%')}})$`;
239
+ }
240
+ else {
241
+ diff = ` (${chalk[color](percentText)})`;
242
+ }
200
243
  }
201
244
  else {
202
245
  diff = chalk.yellow(' (no previous results)');
@@ -221,23 +264,41 @@ async function runBenchFile(file, options, replica) {
221
264
  }
222
265
  resArr.push(curRow);
223
266
  }
267
+ // don't show Stable Memory table if all values are 0
268
+ if (allZero && prop == 'rts_logical_stable_memory_size') {
269
+ return '';
270
+ }
224
271
  return markdownTable(resArr, {
225
272
  align: ['l', ...'r'.repeat(schema.cols.length)],
226
273
  stringLength: stringWidth,
227
274
  });
228
275
  };
229
- let printResults = () => {
230
- logUpdate(`
231
- \n${chalk.bold(schema.name)}
232
- ${schema.description ? '\n' + chalk.gray(schema.description) : ''}
276
+ let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
277
+ let getOutput = () => {
278
+ return `
279
+ \n${process.env.CI ? `## ${schema.name}` : chalk.bold(schema.name)}
280
+ ${schema.description ? '\n' + (process.env.CI ? `_${schema.description}_` : chalk.gray(schema.description)) : ''}
233
281
  \n\n${chalk.blue('Instructions')}\n\n${getTable('instructions')}
234
282
  \n\n${chalk.blue('Heap')}\n\n${getTable('rts_heap_size')}
235
- \n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}
236
283
  \n\n${chalk.blue('Garbage Collection')}\n\n${getTable('rts_reclaimed')}
237
- `);
284
+ ${getTable('rts_logical_stable_memory_size') ? `\n\n${chalk.blue('Stable Memory')}\n\n${getTable('rts_logical_stable_memory_size')}` : ''}
285
+ `;
238
286
  };
239
- if (!process.env.CI && !options.silent) {
240
- printResults();
287
+ let canUpdateLog = !process.env.CI && !options.silent && terminalSize().rows > getOutput().split('\n').length;
288
+ let log = () => {
289
+ if (options.silent) {
290
+ return;
291
+ }
292
+ let output = getOutput();
293
+ if (process.env.CI || terminalSize().rows <= output.split('\n').length) {
294
+ console.log(output);
295
+ }
296
+ else {
297
+ logUpdate(output);
298
+ }
299
+ };
300
+ if (canUpdateLog) {
301
+ log();
241
302
  }
242
303
  // run all cells
243
304
  for (let [rowIndex, row] of schema.rows.entries()) {
@@ -252,15 +313,17 @@ async function runBenchFile(file, options, replica) {
252
313
  logicalStableMemoryCells[rowIndex][colIndex] = res.rts_logical_stable_memory_size;
253
314
  // @ts-ignore
254
315
  reclaimedCells[rowIndex][colIndex] = res.rts_reclaimed;
255
- if (!process.env.CI && !options.silent) {
256
- printResults();
316
+ if (canUpdateLog) {
317
+ log();
257
318
  }
258
319
  }
259
320
  }
260
- if (process.env.CI) {
261
- printResults();
321
+ if (canUpdateLog) {
322
+ logUpdate.done();
323
+ }
324
+ else {
325
+ log();
262
326
  }
263
- logUpdate.done();
264
327
  // save results
265
328
  if (options.save) {
266
329
  console.log(`Saving results to ${chalk.gray(absToRel(resultsJsonFile))}`);
@@ -9,6 +9,7 @@ import { mainActor } from '../api/actors.js';
9
9
  import { installAll } from './install/install-all.js';
10
10
  import { readVesselConfig } from '../vessel.js';
11
11
  import { template } from './template.js';
12
+ import { kebabCase } from 'change-case';
12
13
  export async function init({ yes = false } = {}) {
13
14
  let configFile = path.join(process.cwd(), 'mops.toml');
14
15
  let exists = existsSync(configFile);
@@ -73,7 +74,7 @@ export async function init({ yes = false } = {}) {
73
74
  type: 'text',
74
75
  name: 'name',
75
76
  message: 'Enter package name:',
76
- initial: '',
77
+ initial: kebabCase(path.basename(process.cwd())),
77
78
  },
78
79
  {
79
80
  type: 'text',
@@ -117,7 +118,7 @@ export async function init({ yes = false } = {}) {
117
118
  },
118
119
  ], promptsConfig);
119
120
  config.package = {
120
- name: (res.name || '').trim(),
121
+ name: kebabCase((res.name || '').trim()),
121
122
  version: '1.0.0',
122
123
  description: (res.description || '').trim(),
123
124
  repository: (res.repository || '').trim(),
@@ -65,8 +65,8 @@ export class Replica {
65
65
  let pocketIcBin = await toolchain.bin('pocket-ic');
66
66
  // eslint-disable-next-line
67
67
  let config = readConfig();
68
- if (config.toolchain?.['pocket-ic'] !== '6.0.0') {
69
- console.error('Current Mops CLI only supports pocket-ic 6.0.0');
68
+ if (config.toolchain?.['pocket-ic'] !== '4.0.0') {
69
+ console.error('Current Mops CLI only supports pocket-ic 4.0.0');
70
70
  process.exit(1);
71
71
  }
72
72
  this.pocketIcServer = await PocketIcServer.start({
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import chalk from 'chalk';
4
4
  import prompts from 'prompts';
5
- import camelCase from 'camelcase';
5
+ import { kebabCase, pascalCase } from 'change-case';
6
6
  import { getRootDir, readConfig } from '../mops.js';
7
7
  import { copyTemplateFileSync } from '../templates.js';
8
8
  export async function template(templateName, options = {}) {
@@ -93,8 +93,8 @@ export async function template(templateName, options = {}) {
93
93
  let data = fs.readFileSync(dest).toString();
94
94
  data = data.replace(/<year>/g, new Date().getFullYear().toString());
95
95
  if (config.package?.name) {
96
- data = data.replace(/<name>/g, config.package.name);
97
- data = data.replace(/<import-name>/g, camelCase(config.package.name, { pascalCase: true }));
96
+ data = data.replace(/<name>/g, kebabCase(config.package.name));
97
+ data = data.replace(/<import-name>/g, pascalCase(config.package.name));
98
98
  }
99
99
  fs.writeFileSync(dest, data);
100
100
  console.log(chalk.green('Created'), path.relative(getRootDir(), 'README.md'));
@@ -1,2 +1,43 @@
1
+ type DfxConfig = {
2
+ $schema: string;
3
+ version: number;
4
+ profile: 'Debug' | 'Release';
5
+ canisters: {
6
+ [key: string]: {
7
+ type: 'motoko' | 'assets';
8
+ main?: string;
9
+ specified_id?: string;
10
+ declarations?: {
11
+ output: string;
12
+ node_compatibility: boolean;
13
+ };
14
+ build?: string[];
15
+ frontend?: {
16
+ entrypoint: string;
17
+ };
18
+ source?: string[];
19
+ remote?: {
20
+ id: {
21
+ ic: string;
22
+ staging: string;
23
+ };
24
+ };
25
+ };
26
+ };
27
+ defaults: {
28
+ build: {
29
+ packtool: string;
30
+ };
31
+ };
32
+ dfx: string;
33
+ networks: {
34
+ [key: string]: {
35
+ type: string;
36
+ providers: string[];
37
+ };
38
+ };
39
+ };
40
+ export declare function readDfxJson(): DfxConfig | Record<string, never>;
1
41
  export declare function getMotokoCanisters(): Record<string, string>;
2
42
  export declare function getMotokoCanistersWithDeclarations(): Record<string, string>;
43
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { getRootDir } from '../../mops.js';
4
- function readDfxJson() {
4
+ export function readDfxJson() {
5
5
  let dfxJsonPath = path.resolve(getRootDir(), 'dfx.json');
6
6
  if (!existsSync(dfxJsonPath)) {
7
7
  return {};
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "1.4.0-pre.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "bin/mops.js",
@@ -28,20 +28,20 @@
28
28
  "node": ">=18.0.0"
29
29
  },
30
30
  "dependencies": {
31
- "@dfinity/agent": "2.2.0",
32
- "@dfinity/candid": "2.2.0",
33
- "@dfinity/identity": "2.2.0",
34
- "@dfinity/identity-secp256k1": "2.2.0",
35
- "@dfinity/principal": "2.2.0",
31
+ "@dfinity/agent": "2.3.0",
32
+ "@dfinity/candid": "2.3.0",
33
+ "@dfinity/identity": "2.3.0",
34
+ "@dfinity/identity-secp256k1": "2.3.0",
35
+ "@dfinity/principal": "2.3.0",
36
36
  "@iarna/toml": "2.2.5",
37
- "@noble/hashes": "1.5.0",
37
+ "@noble/hashes": "1.7.1",
38
38
  "as-table": "1.0.55",
39
39
  "buffer": "6.0.3",
40
40
  "cacheable-request": "12.0.1",
41
- "camelcase": "8.0.0",
42
- "chalk": "5.3.0",
41
+ "chalk": "5.4.1",
42
+ "change-case": "5.4.4",
43
43
  "chokidar": "3.6.0",
44
- "commander": "12.1.0",
44
+ "commander": "13.1.0",
45
45
  "debounce": "2.1.1",
46
46
  "decomp-tarxz": "0.1.1",
47
47
  "decompress": "4.2.1",
@@ -51,25 +51,26 @@
51
51
  "filesize": "10.1.6",
52
52
  "fs-extra": "11.2.0",
53
53
  "get-folder-size": "5.0.0",
54
- "glob": "11.0.0",
54
+ "glob": "11.0.1",
55
55
  "globby": "14.0.2",
56
- "got": "14.4.2",
56
+ "got": "14.4.6",
57
57
  "log-update": "6.1.0",
58
- "markdown-table": "3.0.3",
59
- "mdast-util-from-markdown": "2.0.1",
60
- "mdast-util-to-markdown": "2.1.0",
58
+ "markdown-table": "3.0.4",
59
+ "mdast-util-from-markdown": "2.0.2",
60
+ "mdast-util-to-markdown": "2.1.2",
61
61
  "minimatch": "10.0.1",
62
62
  "ncp": "2.0.0",
63
63
  "node-fetch": "3.3.2",
64
64
  "octokit": "3.1.2",
65
65
  "pem-file": "1.0.1",
66
- "pic-ic": "0.7.0",
66
+ "pic-ic": "0.5.3",
67
67
  "promisify-child-process": "4.1.2",
68
68
  "prompts": "2.4.2",
69
- "semver": "7.6.3",
69
+ "semver": "7.7.1",
70
70
  "stream-to-promise": "3.0.0",
71
71
  "string-width": "7.2.0",
72
- "tar": "7.4.3"
72
+ "tar": "7.4.3",
73
+ "terminal-size": "4.0.0"
73
74
  },
74
75
  "devDependencies": {
75
76
  "@tsconfig/strictest": "2.0.5",
@@ -78,7 +79,7 @@
78
79
  "@types/fs-extra": "11.0.4",
79
80
  "@types/glob": "8.1.0",
80
81
  "@types/ncp": "2.0.8",
81
- "@types/node": "22.7.4",
82
+ "@types/node": "22.13.4",
82
83
  "@types/prompts": "2.4.9",
83
84
  "@types/semver": "7.5.8",
84
85
  "@types/stream-to-promise": "2.2.4",
@@ -86,7 +87,7 @@
86
87
  "bun": "1.1.27",
87
88
  "esbuild": "0.23.1",
88
89
  "eslint": "8.57.0",
89
- "tsx": "4.19.1",
90
- "typescript": "5.6.2"
90
+ "tsx": "4.19.2",
91
+ "typescript": "5.7.3"
91
92
  }
92
93
  }
package/dist/pem.d.ts CHANGED
@@ -2,4 +2,4 @@ import { Buffer } from 'node:buffer';
2
2
  import { Ed25519KeyIdentity } from '@dfinity/identity';
3
3
  import { Secp256k1KeyIdentity } from '@dfinity/identity-secp256k1';
4
4
  export declare function decodeFile(file: string, password?: string): Secp256k1KeyIdentity | Ed25519KeyIdentity;
5
- export declare function encrypt(buffer: Buffer, password: string): Buffer;
5
+ export declare function encrypt(buffer: Buffer, password: string): Buffer<ArrayBuffer>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "1.4.0-pre.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "dist/bin/mops.js",
@@ -44,20 +44,20 @@
44
44
  "esbuild": "esbuild"
45
45
  },
46
46
  "dependencies": {
47
- "@dfinity/agent": "2.2.0",
48
- "@dfinity/candid": "2.2.0",
49
- "@dfinity/identity": "2.2.0",
50
- "@dfinity/identity-secp256k1": "2.2.0",
51
- "@dfinity/principal": "2.2.0",
47
+ "@dfinity/agent": "2.3.0",
48
+ "@dfinity/candid": "2.3.0",
49
+ "@dfinity/identity": "2.3.0",
50
+ "@dfinity/identity-secp256k1": "2.3.0",
51
+ "@dfinity/principal": "2.3.0",
52
52
  "@iarna/toml": "2.2.5",
53
- "@noble/hashes": "1.5.0",
53
+ "@noble/hashes": "1.7.1",
54
54
  "as-table": "1.0.55",
55
55
  "buffer": "6.0.3",
56
56
  "cacheable-request": "12.0.1",
57
- "camelcase": "8.0.0",
58
- "chalk": "5.3.0",
57
+ "chalk": "5.4.1",
58
+ "change-case": "5.4.4",
59
59
  "chokidar": "3.6.0",
60
- "commander": "12.1.0",
60
+ "commander": "13.1.0",
61
61
  "debounce": "2.1.1",
62
62
  "decomp-tarxz": "0.1.1",
63
63
  "decompress": "4.2.1",
@@ -67,25 +67,26 @@
67
67
  "filesize": "10.1.6",
68
68
  "fs-extra": "11.2.0",
69
69
  "get-folder-size": "5.0.0",
70
- "glob": "11.0.0",
70
+ "glob": "11.0.1",
71
71
  "globby": "14.0.2",
72
- "got": "14.4.2",
72
+ "got": "14.4.6",
73
73
  "log-update": "6.1.0",
74
- "markdown-table": "3.0.3",
75
- "mdast-util-from-markdown": "2.0.1",
76
- "mdast-util-to-markdown": "2.1.0",
74
+ "markdown-table": "3.0.4",
75
+ "mdast-util-from-markdown": "2.0.2",
76
+ "mdast-util-to-markdown": "2.1.2",
77
77
  "minimatch": "10.0.1",
78
78
  "ncp": "2.0.0",
79
79
  "node-fetch": "3.3.2",
80
80
  "octokit": "3.1.2",
81
81
  "pem-file": "1.0.1",
82
- "pic-ic": "0.7.0",
82
+ "pic-ic": "0.5.3",
83
83
  "promisify-child-process": "4.1.2",
84
84
  "prompts": "2.4.2",
85
- "semver": "7.6.3",
85
+ "semver": "7.7.1",
86
86
  "stream-to-promise": "3.0.0",
87
87
  "string-width": "7.2.0",
88
- "tar": "7.4.3"
88
+ "tar": "7.4.3",
89
+ "terminal-size": "4.0.0"
89
90
  },
90
91
  "devDependencies": {
91
92
  "@tsconfig/strictest": "2.0.5",
@@ -94,7 +95,7 @@
94
95
  "@types/fs-extra": "11.0.4",
95
96
  "@types/glob": "8.1.0",
96
97
  "@types/ncp": "2.0.8",
97
- "@types/node": "22.7.4",
98
+ "@types/node": "22.13.4",
98
99
  "@types/prompts": "2.4.9",
99
100
  "@types/semver": "7.5.8",
100
101
  "@types/stream-to-promise": "2.2.4",
@@ -102,7 +103,7 @@
102
103
  "bun": "1.1.27",
103
104
  "esbuild": "0.23.1",
104
105
  "eslint": "8.57.0",
105
- "tsx": "4.19.1",
106
- "typescript": "5.6.2"
106
+ "tsx": "4.19.2",
107
+ "typescript": "5.7.3"
107
108
  }
108
109
  }