ic-mops 0.19.0 → 0.20.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 (96) hide show
  1. package/.gitignore +3 -0
  2. package/{cache.js → cache.ts} +8 -8
  3. package/{cli.js → cli.ts} +5 -5
  4. package/commands/{add.js → add.ts} +16 -8
  5. package/commands/{bump.js → bump.ts} +5 -5
  6. package/commands/{docs.js → docs.ts} +10 -10
  7. package/commands/{import-identity.js → import-identity.ts} +7 -7
  8. package/commands/{init.js → init.ts} +20 -17
  9. package/commands/{install-all.js → install-all.ts} +1 -1
  10. package/commands/{install.js → install.ts} +11 -11
  11. package/commands/{mmf1.js → mmf1.ts} +20 -18
  12. package/commands/{publish.js → publish.ts} +28 -15
  13. package/commands/{remove.js → remove.ts} +23 -16
  14. package/commands/{search.js → search.ts} +2 -2
  15. package/commands/self-update.ts +6 -0
  16. package/commands/{sources.js → sources.ts} +30 -24
  17. package/commands/{template.js → template.ts} +2 -2
  18. package/commands/{test.js → test.ts} +24 -19
  19. package/commands/{user.js → user.ts} +7 -2
  20. package/declarations/main/index.js +0 -2
  21. package/declarations/main/main.did +4 -1
  22. package/declarations/main/main.did.d.ts +4 -4
  23. package/declarations/main/main.did.js +20 -20
  24. package/declarations/storage/index.d.ts +50 -0
  25. package/declarations/storage/index.js +3 -11
  26. package/dist/cache.d.ts +5 -0
  27. package/dist/cache.js +46 -0
  28. package/dist/cli.d.ts +2 -0
  29. package/dist/cli.js +265 -0
  30. package/dist/commands/add.d.ts +4 -0
  31. package/dist/commands/add.js +82 -0
  32. package/dist/commands/bump.d.ts +1 -0
  33. package/dist/commands/bump.js +50 -0
  34. package/dist/commands/docs.d.ts +3 -0
  35. package/dist/commands/docs.js +78 -0
  36. package/dist/commands/import-identity.d.ts +1 -0
  37. package/dist/commands/import-identity.js +47 -0
  38. package/dist/commands/init.d.ts +1 -0
  39. package/dist/commands/init.js +82 -0
  40. package/dist/commands/install-all.d.ts +4 -0
  41. package/dist/commands/install-all.js +29 -0
  42. package/dist/commands/install.d.ts +5 -0
  43. package/dist/commands/install.js +110 -0
  44. package/dist/commands/mmf1.d.ts +21 -0
  45. package/dist/commands/mmf1.js +93 -0
  46. package/dist/commands/publish.d.ts +3 -0
  47. package/dist/commands/publish.js +254 -0
  48. package/dist/commands/remove.d.ts +5 -0
  49. package/dist/commands/remove.js +83 -0
  50. package/dist/commands/search.d.ts +1 -0
  51. package/dist/commands/search.js +36 -0
  52. package/dist/commands/self-update.d.ts +3 -0
  53. package/dist/commands/self-update.js +5 -0
  54. package/dist/commands/sources.d.ts +3 -0
  55. package/dist/commands/sources.js +124 -0
  56. package/dist/commands/template.d.ts +1 -0
  57. package/dist/commands/template.js +28 -0
  58. package/dist/commands/test.d.ts +4 -0
  59. package/dist/commands/test.js +201 -0
  60. package/dist/commands/user.d.ts +2 -0
  61. package/dist/commands/user.js +23 -0
  62. package/dist/commands/whoami.d.ts +1 -0
  63. package/dist/commands/whoami.js +11 -0
  64. package/dist/declarations/main/index.d.ts +50 -0
  65. package/dist/declarations/main/index.js +41 -0
  66. package/dist/declarations/main/main.did +222 -0
  67. package/dist/declarations/main/main.did.d.ts +198 -0
  68. package/dist/declarations/main/main.did.js +218 -0
  69. package/dist/declarations/storage/index.d.ts +50 -0
  70. package/dist/declarations/storage/index.js +30 -0
  71. package/dist/declarations/storage/storage.did +46 -0
  72. package/dist/declarations/storage/storage.did.d.ts +37 -0
  73. package/dist/declarations/storage/storage.did.js +38 -0
  74. package/dist/mops.d.ts +33 -0
  75. package/dist/mops.js +259 -0
  76. package/dist/package.json +79 -0
  77. package/dist/parallel.d.ts +1 -0
  78. package/dist/parallel.js +24 -0
  79. package/dist/pem.d.ts +5 -0
  80. package/dist/pem.js +49 -0
  81. package/dist/templates/mops-test.yml +30 -0
  82. package/dist/types.d.ts +27 -0
  83. package/dist/types.js +1 -0
  84. package/dist/vessel.d.ts +19 -0
  85. package/dist/vessel.js +154 -0
  86. package/global.d.ts +2 -0
  87. package/{mops.js → mops.ts} +58 -47
  88. package/package.json +44 -19
  89. package/{parallel.js → parallel.ts} +2 -2
  90. package/{pem.js → pem.ts} +12 -11
  91. package/templates/mops-test.yml +1 -1
  92. package/tsconfig.json +16 -0
  93. package/types.ts +29 -0
  94. package/{vessel.js → vessel.ts} +37 -25
  95. package/commands/self-update.js +0 -6
  96. /package/commands/{whoami.js → whoami.ts} +0 -0
@@ -0,0 +1,110 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import logUpdate from 'log-update';
4
+ import chalk from 'chalk';
5
+ import { checkConfigFile, formatDir, getHighestVersion, mainActor, progressBar, readConfig, storageActor } from '../mops.js';
6
+ import { parallel } from '../parallel.js';
7
+ import { installFromGithub } from '../vessel.js';
8
+ import { addCache, copyCache, isCached } from '../cache.js';
9
+ export async function install(pkg, version = '', { verbose = false, silent = false, dep = false } = {}) {
10
+ if (!checkConfigFile()) {
11
+ return false;
12
+ }
13
+ // progress
14
+ let total = Infinity;
15
+ let step = 0;
16
+ let progress = () => {
17
+ step++;
18
+ silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${pkg}@${version} ${progressBar(step, total)}`);
19
+ };
20
+ progress();
21
+ if (!version) {
22
+ let versionRes = await getHighestVersion(pkg);
23
+ if ('err' in versionRes) {
24
+ console.log(chalk.red('Error: ') + versionRes.err);
25
+ return false;
26
+ }
27
+ version = versionRes.ok;
28
+ }
29
+ let dir = formatDir(pkg, version);
30
+ let actor = await mainActor();
31
+ // already installed
32
+ if (fs.existsSync(dir)) {
33
+ silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${pkg}@${version} (already installed)`);
34
+ }
35
+ // copy from cache
36
+ else if (isCached(`${pkg}@${version}`)) {
37
+ actor.notifyInstall(pkg, version);
38
+ await copyCache(`${pkg}@${version}`, dir);
39
+ silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${pkg}@${version} (cache)`);
40
+ }
41
+ // download
42
+ else {
43
+ let [packageDetailsRes, filesIdsRes] = await Promise.all([
44
+ actor.getPackageDetails(pkg, version),
45
+ actor.getFileIds(pkg, version),
46
+ ]);
47
+ if ('err' in packageDetailsRes) {
48
+ console.log(chalk.red('Error: ') + packageDetailsRes.err);
49
+ return false;
50
+ }
51
+ let packageDetails = packageDetailsRes.ok;
52
+ if ('err' in filesIdsRes) {
53
+ console.log(chalk.red('Error: ') + filesIdsRes.err);
54
+ return false;
55
+ }
56
+ let filesIds = filesIdsRes.ok;
57
+ total = filesIds.length + 2;
58
+ let storage = await storageActor(packageDetails.publication.storage);
59
+ actor.notifyInstall(pkg, version);
60
+ // download files
61
+ let filesData = new Map;
62
+ await parallel(16, filesIds, async (fileId) => {
63
+ let fileMetaRes = await storage.getFileMeta(fileId);
64
+ if ('err' in fileMetaRes) {
65
+ console.log(chalk.red('ERR: ') + fileMetaRes.err);
66
+ return;
67
+ }
68
+ let fileMeta = fileMetaRes.ok;
69
+ let buffer = Buffer.from([]);
70
+ for (let i = 0n; i < fileMeta.chunkCount; i++) {
71
+ let chunkRes = await storage.downloadChunk(fileId, i);
72
+ if ('err' in chunkRes) {
73
+ console.log(chalk.red('ERR: ') + chunkRes.err);
74
+ return;
75
+ }
76
+ let chunk = chunkRes.ok;
77
+ buffer = Buffer.concat([buffer, Buffer.from(chunk)]);
78
+ }
79
+ filesData.set(fileMeta.path, buffer);
80
+ progress();
81
+ });
82
+ // write files to disk
83
+ for (let [filePath, buffer] of filesData.entries()) {
84
+ fs.mkdirSync(path.join(dir, path.dirname(filePath)), { recursive: true });
85
+ fs.writeFileSync(path.join(dir, filePath), buffer);
86
+ }
87
+ // add to cache
88
+ await addCache(`${pkg}@${version}`, dir);
89
+ progress();
90
+ }
91
+ if (verbose) {
92
+ silent || logUpdate.done();
93
+ }
94
+ // install dependencies
95
+ let ok = true;
96
+ let config = readConfig(path.join(dir, 'mops.toml'));
97
+ let deps = Object.values(config.dependencies || {});
98
+ for (const { name, repo, version } of deps) {
99
+ if (repo) {
100
+ await installFromGithub(name, repo, { silent, verbose });
101
+ }
102
+ else {
103
+ let res = await install(name, version, { silent, verbose });
104
+ if (!res) {
105
+ ok = false;
106
+ }
107
+ }
108
+ }
109
+ return ok;
110
+ }
@@ -0,0 +1,21 @@
1
+ type Strategy = 'store' | 'print';
2
+ export declare class MMF1 {
3
+ stack: string[];
4
+ currSuite: string;
5
+ failed: number;
6
+ passed: number;
7
+ skipped: number;
8
+ srategy: Strategy;
9
+ output: string[];
10
+ constructor(srategy: Strategy);
11
+ _log(...args: string[]): void;
12
+ flush(): void;
13
+ parseLine(line: string): void;
14
+ _testStart(name: string): void;
15
+ _testEnd(name: string): void;
16
+ _testSkip(name: string): void;
17
+ _status(name: string, status: string): void;
18
+ fail(stderr: string): void;
19
+ pass(): void;
20
+ }
21
+ export {};
@@ -0,0 +1,93 @@
1
+ // mops message format v1
2
+ // mops:1:start
3
+ // mops:1:end
4
+ // mops:1:skip
5
+ import chalk from 'chalk';
6
+ export class MMF1 {
7
+ constructor(srategy) {
8
+ this.stack = [];
9
+ this.currSuite = '';
10
+ this.failed = 0;
11
+ this.passed = 0;
12
+ this.skipped = 0;
13
+ this.output = [];
14
+ this.srategy = srategy;
15
+ }
16
+ _log(...args) {
17
+ if (this.srategy === 'store') {
18
+ this.output.push(args.join(' '));
19
+ }
20
+ else if (this.srategy === 'print') {
21
+ console.log(...args);
22
+ }
23
+ }
24
+ flush() {
25
+ for (let out of this.output) {
26
+ console.log(out);
27
+ }
28
+ this.output = [];
29
+ }
30
+ parseLine(line) {
31
+ if (line.startsWith('mops:1:start ')) {
32
+ this._testStart(line.split('mops:1:start ')[1] || '');
33
+ }
34
+ else if (line.startsWith('mops:1:end ')) {
35
+ this._testEnd(line.split('mops:1:end ')[1] || '');
36
+ }
37
+ else if (line.startsWith('mops:1:skip ')) {
38
+ this._testSkip(line.split('mops:1:skip ')[1] || '');
39
+ }
40
+ else {
41
+ this._log(' '.repeat(this.stack.length * 2), chalk.gray('stdout'), line);
42
+ }
43
+ }
44
+ _testStart(name) {
45
+ let suite = this.stack[this.stack.length - 1];
46
+ if (suite) {
47
+ if (this.currSuite !== suite) {
48
+ this.currSuite = suite;
49
+ this._log(' '.repeat((this.stack.length - 1) * 2), (chalk.gray('•')) + '', suite);
50
+ }
51
+ }
52
+ this.stack.push(name);
53
+ }
54
+ _testEnd(name) {
55
+ if (name !== this.stack.pop()) {
56
+ throw 'mmf1._testEnd: start and end test mismatch';
57
+ }
58
+ this._status(name, 'pass');
59
+ }
60
+ _testSkip(name) {
61
+ this._status(name, 'skip');
62
+ }
63
+ _status(name, status) {
64
+ if (status === 'pass') {
65
+ // do not print suite at the end
66
+ if (name === this.currSuite) {
67
+ return;
68
+ }
69
+ this.passed++;
70
+ this._log(' '.repeat(this.stack.length * 2), chalk.green('✓'), name);
71
+ }
72
+ else if (status === 'fail') {
73
+ this.failed++;
74
+ this._log(' '.repeat(this.stack.length * 2), chalk.red('✖'), name);
75
+ }
76
+ else if (status === 'skip') {
77
+ this.skipped++;
78
+ this._log(' '.repeat(this.stack.length * 2), chalk.yellow('−'), name);
79
+ }
80
+ }
81
+ fail(stderr) {
82
+ let name = this.stack.pop() || '';
83
+ this._status(name, 'fail');
84
+ this._log(' '.repeat(this.stack.length * 2), chalk.red('FAIL'), stderr);
85
+ }
86
+ pass() {
87
+ let name = this.stack.pop();
88
+ if (name) {
89
+ this._status(name, 'pass');
90
+ }
91
+ this._log(' '.repeat(this.stack.length * 2), chalk.green('PASS'));
92
+ }
93
+ }
@@ -0,0 +1,3 @@
1
+ export declare function publish({ noDocs }?: {
2
+ noDocs?: boolean | undefined;
3
+ }): Promise<void>;
@@ -0,0 +1,254 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import chalk from 'chalk';
4
+ import logUpdate from 'log-update';
5
+ import { globbySync } from 'globby';
6
+ import { minimatch } from 'minimatch';
7
+ import prompts from 'prompts';
8
+ import { checkConfigFile, getRootDir, mainActor, progressBar, readConfig } from '../mops.js';
9
+ import { parallel } from '../parallel.js';
10
+ import { docs } from './docs.js';
11
+ export async function publish({ noDocs = false } = {}) {
12
+ if (!checkConfigFile()) {
13
+ return;
14
+ }
15
+ let rootDir = getRootDir();
16
+ let config = readConfig();
17
+ // validate
18
+ for (let key of Object.keys(config)) {
19
+ if (!['package', 'dependencies', 'dev-dependencies', 'scripts'].includes(key)) {
20
+ console.log(chalk.red('Error: ') + `Unknown config section [${key}]`);
21
+ return;
22
+ }
23
+ }
24
+ // required fields
25
+ if (!config.package) {
26
+ console.log(chalk.red('Error: ') + 'Please specify [package] section in your mops.toml');
27
+ return;
28
+ }
29
+ for (let key of ['name', 'version']) {
30
+ // @ts-ignore
31
+ if (!config.package[key]) {
32
+ console.log(chalk.red('Error: ') + `Please specify "${key}" in [config] section in your mops.toml`);
33
+ return;
34
+ }
35
+ }
36
+ // desired fields
37
+ for (let key of ['description', 'repository']) {
38
+ // @ts-ignore
39
+ if (!config.package[key]) {
40
+ let res = await prompts({
41
+ type: 'confirm',
42
+ name: 'ok',
43
+ message: `Missing recommended config key "${key}", publish anyway?`,
44
+ });
45
+ if (!res.ok) {
46
+ return;
47
+ }
48
+ }
49
+ }
50
+ let packageKeys = [
51
+ 'name',
52
+ 'version',
53
+ 'keywords',
54
+ 'description',
55
+ 'repository',
56
+ 'documentation',
57
+ 'homepage',
58
+ 'baseDir',
59
+ 'readme',
60
+ 'license',
61
+ 'files',
62
+ 'dfx',
63
+ 'moc',
64
+ 'donation',
65
+ ];
66
+ for (let key of Object.keys(config.package)) {
67
+ if (!packageKeys.includes(key)) {
68
+ console.log(chalk.red('Error: ') + `Unknown config key 'package.${key}'`);
69
+ return;
70
+ }
71
+ }
72
+ // check lengths
73
+ let keysMax = {
74
+ name: 50,
75
+ version: 20,
76
+ keywords: 5,
77
+ description: 200,
78
+ repository: 300,
79
+ documentation: 300,
80
+ homepage: 300,
81
+ readme: 100,
82
+ license: 30,
83
+ files: 20,
84
+ dfx: 10,
85
+ moc: 10,
86
+ donation: 64,
87
+ root: 50,
88
+ };
89
+ for (let [key, max] of Object.entries(keysMax)) {
90
+ // @ts-ignore
91
+ if (config.package[key] && config.package[key].length > max) {
92
+ console.log(chalk.red('Error: ') + `package.${key} value max length is ${max}`);
93
+ return;
94
+ }
95
+ }
96
+ if (config.dependencies) {
97
+ if (Object.keys(config.dependencies).length > 100) {
98
+ console.log(chalk.red('Error: ') + 'max dependencies is 100');
99
+ return;
100
+ }
101
+ for (let dep of Object.values(config.dependencies)) {
102
+ if (dep.path) {
103
+ console.log(chalk.red('Error: ') + 'you can\'t publish packages with local dependencies');
104
+ return;
105
+ }
106
+ delete dep.path;
107
+ }
108
+ }
109
+ if (config['dev-dependencies']) {
110
+ if (Object.keys(config['dev-dependencies']).length > 100) {
111
+ console.log(chalk.red('Error: ') + 'max dev-dependencies is 100');
112
+ return;
113
+ }
114
+ for (let dep of Object.values(config['dev-dependencies'])) {
115
+ if (dep.path) {
116
+ console.log(chalk.red('Error: ') + 'you can\'t publish packages with local dev-dependencies');
117
+ return;
118
+ }
119
+ delete dep.path;
120
+ }
121
+ }
122
+ if (config.package.keywords) {
123
+ for (let keyword of config.package.keywords) {
124
+ if (keyword.length > 20) {
125
+ console.log(chalk.red('Error: ') + 'max keyword length is 20');
126
+ return;
127
+ }
128
+ }
129
+ }
130
+ if (config.package.files) {
131
+ for (let file of config.package.files) {
132
+ if (file.startsWith('/') || file.startsWith('../')) {
133
+ console.log(chalk.red('Error: ') + 'file path cannot start with \'/\' or \'../\'');
134
+ return;
135
+ }
136
+ }
137
+ }
138
+ let toBackendDep = (dep) => {
139
+ return {
140
+ ...dep,
141
+ version: dep.version || '',
142
+ repo: dep.repo || ''
143
+ };
144
+ };
145
+ // map fields
146
+ let backendPkgConfig = {
147
+ name: config.package.name,
148
+ version: config.package.version,
149
+ keywords: config.package.keywords || [],
150
+ description: config.package.description || '',
151
+ repository: config.package.repository || '',
152
+ homepage: config.package.homepage || '',
153
+ documentation: config.package.documentation || '',
154
+ baseDir: 'src',
155
+ readme: 'README.md',
156
+ license: config.package.license || '',
157
+ dfx: config.package.dfx || '',
158
+ moc: config.package.moc || '',
159
+ donation: config.package.donation || '',
160
+ dependencies: Object.values(config.dependencies || {}).map(toBackendDep),
161
+ devDependencies: Object.values(config['dev-dependencies'] || {}).map(toBackendDep),
162
+ scripts: [],
163
+ };
164
+ let defaultFiles = [
165
+ 'mops.toml',
166
+ 'README.md',
167
+ 'LICENSE',
168
+ 'NOTICE',
169
+ '!.mops/**',
170
+ '!test/**',
171
+ '!tests/**',
172
+ '!**/*.test.mo',
173
+ '!**/*.Test.mo',
174
+ ];
175
+ let files = config.package.files || ['**/*.mo'];
176
+ files = [...files, ...defaultFiles];
177
+ files = globbySync([...files, ...defaultFiles]);
178
+ // generate docs
179
+ let docsFile = path.join(rootDir, '.mops/.docs/docs.tgz');
180
+ if (!noDocs) {
181
+ await docs({ silent: true });
182
+ if (fs.existsSync(docsFile)) {
183
+ files.unshift(docsFile);
184
+ }
185
+ }
186
+ // check required files
187
+ if (!files.includes('mops.toml')) {
188
+ console.log(chalk.red('Error: ') + ' please add mops.toml file');
189
+ return;
190
+ }
191
+ if (!files.includes('README.md')) {
192
+ console.log(chalk.red('Error: ') + ' please add README.md file');
193
+ return;
194
+ }
195
+ // check allowed exts
196
+ for (let file of files) {
197
+ if (!minimatch(file, '**/*.{mo,did,md,toml}') && !file.toLowerCase().endsWith('license') && file !== docsFile) {
198
+ console.log(chalk.red('Error: ') + `file ${file} has unsupported extension. Allowed: .mo, .did, .md, .toml`);
199
+ return;
200
+ }
201
+ }
202
+ // progress
203
+ let total = files.length + 2;
204
+ let step = 0;
205
+ function progress() {
206
+ step++;
207
+ logUpdate(`Publishing ${config.package?.name}@${config.package?.version} ${progressBar(step, total)}`);
208
+ }
209
+ // upload config
210
+ let actor = await mainActor(true);
211
+ progress();
212
+ let publishing = await actor.startPublish(backendPkgConfig);
213
+ if ('err' in publishing) {
214
+ console.log(chalk.red('Error: ') + publishing.err);
215
+ return;
216
+ }
217
+ let puiblishingId = publishing.ok;
218
+ // upload files
219
+ await parallel(8, files, async (file) => {
220
+ progress();
221
+ let chunkSize = 1024 * 1024 + 512 * 1024; // 1.5mb
222
+ let content = fs.readFileSync(file);
223
+ let chunkCount = Math.ceil(content.length / chunkSize);
224
+ let firstChunk = Array.from(content.slice(0, chunkSize));
225
+ // remove path from docs file
226
+ if (file === docsFile) {
227
+ file = path.basename(file);
228
+ }
229
+ let res = await actor.startFileUpload(puiblishingId, file, BigInt(chunkCount), firstChunk);
230
+ if ('err' in res) {
231
+ console.log(chalk.red('Error: ') + res.err);
232
+ return;
233
+ }
234
+ let fileId = res.ok;
235
+ for (let i = 1; i < chunkCount; i++) {
236
+ let start = i * chunkSize;
237
+ let chunk = Array.from(content.slice(start, start + chunkSize));
238
+ let res = await actor.uploadFileChunk(puiblishingId, fileId, BigInt(i), chunk);
239
+ if ('err' in res) {
240
+ console.log(chalk.red('Error: ') + res.err);
241
+ return;
242
+ }
243
+ }
244
+ });
245
+ fs.rmSync(path.join(rootDir, '.mops/.docs'), { force: true, recursive: true });
246
+ // finish
247
+ progress();
248
+ let res = await actor.finishPublish(puiblishingId);
249
+ if ('err' in res) {
250
+ console.log(chalk.red('Error: ') + res.err);
251
+ return;
252
+ }
253
+ console.log(chalk.green('Published ') + `${config.package.name}@${config.package.version}`);
254
+ }
@@ -0,0 +1,5 @@
1
+ export declare function remove(name: string, { dev, verbose, dryRun }?: {
2
+ dev?: boolean | undefined;
3
+ verbose?: boolean | undefined;
4
+ dryRun?: boolean | undefined;
5
+ }): Promise<void>;
@@ -0,0 +1,83 @@
1
+ import fs from 'node:fs';
2
+ import { deleteSync } from 'del';
3
+ import chalk from 'chalk';
4
+ import { formatDir, formatGithubDir, checkConfigFile, readConfig, writeConfig } from '../mops.js';
5
+ export async function remove(name, { dev = false, verbose = false, dryRun = false } = {}) {
6
+ if (!checkConfigFile()) {
7
+ return;
8
+ }
9
+ function getTransitiveDependencies(config, exceptPkgId) {
10
+ let deps = Object.values(config.dependencies || {});
11
+ let devDeps = Object.values(config['dev-dependencies'] || {});
12
+ return [...deps, ...devDeps]
13
+ .filter((dep) => {
14
+ let depId = dep.name + '@' + dep.version;
15
+ return depId !== exceptPkgId;
16
+ }).map((dep) => {
17
+ return [dep, ...getTransitiveDependenciesOf(dep.name, dep.version, dep.repo)];
18
+ }).flat();
19
+ }
20
+ function getTransitiveDependenciesOf(name, version, repo) {
21
+ let pkgDir = '';
22
+ if (repo) {
23
+ pkgDir = formatGithubDir(name, repo);
24
+ }
25
+ else if (version) {
26
+ pkgDir = formatDir(name, version);
27
+ }
28
+ let configFile = pkgDir + '/mops.toml';
29
+ if (!fs.existsSync(configFile)) {
30
+ verbose && console.log('no config', configFile);
31
+ return [];
32
+ }
33
+ let config = readConfig(configFile);
34
+ let deps = Object.values(config.dependencies || {}).map((dep) => {
35
+ return [dep, ...getTransitiveDependenciesOf(dep.name, dep.version)];
36
+ }).flat();
37
+ return deps;
38
+ }
39
+ let config = readConfig();
40
+ let deps = dev ? config['dev-dependencies'] : config.dependencies;
41
+ deps = deps || {};
42
+ let pkgDetails = deps[name];
43
+ if (!pkgDetails) {
44
+ return console.log(chalk.red('Error: ') + `No ${dev ? 'dev ' : ''}dependency to remove "${name}"`);
45
+ }
46
+ let version = pkgDetails.version;
47
+ let packageId = `${name}@${version}`;
48
+ // transitive deps ignoring deps of this package
49
+ let transitiveDeps = getTransitiveDependencies(config, packageId);
50
+ let transitiveDepIds = new Set(transitiveDeps.map((dep) => {
51
+ return dep.name + '@' + dep.version;
52
+ }));
53
+ // transitive deps of this package (including itself)
54
+ let transitiveDepsOfPackage = [pkgDetails, ...getTransitiveDependenciesOf(name, version)];
55
+ // remove local cache
56
+ for (let dep of transitiveDepsOfPackage) {
57
+ let depId = dep.name + '@' + dep.version;
58
+ if (transitiveDepIds.has(depId)) {
59
+ verbose && console.log(`Ignored transitive dependency ${depId} (other deps depend on it)`);
60
+ continue;
61
+ }
62
+ let pkgDir;
63
+ if (dep.repo) {
64
+ pkgDir = formatGithubDir(dep.name, dep.repo);
65
+ }
66
+ else if (dep.version) {
67
+ pkgDir = formatDir(dep.name, dep.version);
68
+ }
69
+ if (pkgDir && fs.existsSync(pkgDir)) {
70
+ dryRun || deleteSync([`${pkgDir}`]);
71
+ verbose && console.log(`Removed local cache ${pkgDir}`);
72
+ }
73
+ }
74
+ // remove from config
75
+ if (!dev && config.dependencies) {
76
+ delete config.dependencies[name];
77
+ }
78
+ if (dev && config['dev-dependencies']) {
79
+ delete config['dev-dependencies'][name];
80
+ }
81
+ dryRun || writeConfig(config);
82
+ console.log(chalk.green('Package removed ') + `${name} = "${version}"`);
83
+ }
@@ -0,0 +1 @@
1
+ export declare function search(text: string): Promise<void>;
@@ -0,0 +1,36 @@
1
+ import asTable from 'as-table';
2
+ import chalk from 'chalk';
3
+ import { mainActor } from '../mops.js';
4
+ export async function search(text) {
5
+ let actor = await mainActor();
6
+ let res = await actor.search(text, [], []);
7
+ let packages = res[0];
8
+ if (!packages.length) {
9
+ console.log('Packages not found');
10
+ return;
11
+ }
12
+ let ellipsis = (text, max) => {
13
+ if (text.length <= max) {
14
+ return text;
15
+ }
16
+ else {
17
+ return text.slice(0, max) + '…';
18
+ }
19
+ };
20
+ let maxNameLength = Math.max(...packages.map(a => a.config.name.length));
21
+ let table = packages.map((item) => {
22
+ return {
23
+ NAME: chalk.bold(item.config.name),
24
+ DESCRIPTION: ellipsis(item.config.description, process.stdout.columns - 40 - maxNameLength),
25
+ VERSION: item.config.version,
26
+ UPDATED: new Date(Number(item.publication.time / 1000000n)).toISOString().split('T')[0],
27
+ };
28
+ });
29
+ console.log('');
30
+ console.log(asTable.configure({
31
+ delimiter: chalk.gray(' | '),
32
+ dash: chalk.gray('─'),
33
+ title: t => chalk.gray.bold(t),
34
+ })(table));
35
+ console.log('');
36
+ }
@@ -0,0 +1,3 @@
1
+ export declare function selfUpdate({ detached }?: {
2
+ detached?: boolean | undefined;
3
+ }): void;
@@ -0,0 +1,5 @@
1
+ import child_process from 'node:child_process';
2
+ export function selfUpdate({ detached = false } = {}) {
3
+ console.log('Updating mops CLI...');
4
+ child_process.spawn('npm i ic-mops -g', { stdio: 'inherit', detached });
5
+ }
@@ -0,0 +1,3 @@
1
+ export declare function sources({ verbose }?: {
2
+ verbose?: boolean | undefined;
3
+ }): Promise<(string | undefined)[]>;