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.
- package/.gitignore +3 -0
- package/{cache.js → cache.ts} +8 -8
- package/{cli.js → cli.ts} +5 -5
- package/commands/{add.js → add.ts} +16 -8
- package/commands/{bump.js → bump.ts} +5 -5
- package/commands/{docs.js → docs.ts} +10 -10
- package/commands/{import-identity.js → import-identity.ts} +7 -7
- package/commands/{init.js → init.ts} +20 -17
- package/commands/{install-all.js → install-all.ts} +1 -1
- package/commands/{install.js → install.ts} +11 -11
- package/commands/{mmf1.js → mmf1.ts} +20 -18
- package/commands/{publish.js → publish.ts} +28 -15
- package/commands/{remove.js → remove.ts} +23 -16
- package/commands/{search.js → search.ts} +2 -2
- package/commands/self-update.ts +6 -0
- package/commands/{sources.js → sources.ts} +30 -24
- package/commands/{template.js → template.ts} +2 -2
- package/commands/{test.js → test.ts} +24 -19
- package/commands/{user.js → user.ts} +7 -2
- package/declarations/main/index.js +0 -2
- package/declarations/main/main.did +4 -1
- package/declarations/main/main.did.d.ts +4 -4
- package/declarations/main/main.did.js +20 -20
- package/declarations/storage/index.d.ts +50 -0
- package/declarations/storage/index.js +3 -11
- package/dist/cache.d.ts +5 -0
- package/dist/cache.js +46 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +265 -0
- package/dist/commands/add.d.ts +4 -0
- package/dist/commands/add.js +82 -0
- package/dist/commands/bump.d.ts +1 -0
- package/dist/commands/bump.js +50 -0
- package/dist/commands/docs.d.ts +3 -0
- package/dist/commands/docs.js +78 -0
- package/dist/commands/import-identity.d.ts +1 -0
- package/dist/commands/import-identity.js +47 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +82 -0
- package/dist/commands/install-all.d.ts +4 -0
- package/dist/commands/install-all.js +29 -0
- package/dist/commands/install.d.ts +5 -0
- package/dist/commands/install.js +110 -0
- package/dist/commands/mmf1.d.ts +21 -0
- package/dist/commands/mmf1.js +93 -0
- package/dist/commands/publish.d.ts +3 -0
- package/dist/commands/publish.js +254 -0
- package/dist/commands/remove.d.ts +5 -0
- package/dist/commands/remove.js +83 -0
- package/dist/commands/search.d.ts +1 -0
- package/dist/commands/search.js +36 -0
- package/dist/commands/self-update.d.ts +3 -0
- package/dist/commands/self-update.js +5 -0
- package/dist/commands/sources.d.ts +3 -0
- package/dist/commands/sources.js +124 -0
- package/dist/commands/template.d.ts +1 -0
- package/dist/commands/template.js +28 -0
- package/dist/commands/test.d.ts +4 -0
- package/dist/commands/test.js +201 -0
- package/dist/commands/user.d.ts +2 -0
- package/dist/commands/user.js +23 -0
- package/dist/commands/whoami.d.ts +1 -0
- package/dist/commands/whoami.js +11 -0
- package/dist/declarations/main/index.d.ts +50 -0
- package/dist/declarations/main/index.js +41 -0
- package/dist/declarations/main/main.did +222 -0
- package/dist/declarations/main/main.did.d.ts +198 -0
- package/dist/declarations/main/main.did.js +218 -0
- package/dist/declarations/storage/index.d.ts +50 -0
- package/dist/declarations/storage/index.js +30 -0
- package/dist/declarations/storage/storage.did +46 -0
- package/dist/declarations/storage/storage.did.d.ts +37 -0
- package/dist/declarations/storage/storage.did.js +38 -0
- package/dist/mops.d.ts +33 -0
- package/dist/mops.js +259 -0
- package/dist/package.json +79 -0
- package/dist/parallel.d.ts +1 -0
- package/dist/parallel.js +24 -0
- package/dist/pem.d.ts +5 -0
- package/dist/pem.js +49 -0
- package/dist/templates/mops-test.yml +30 -0
- package/dist/types.d.ts +27 -0
- package/dist/types.js +1 -0
- package/dist/vessel.d.ts +19 -0
- package/dist/vessel.js +154 -0
- package/global.d.ts +2 -0
- package/{mops.js → mops.ts} +58 -47
- package/package.json +44 -19
- package/{parallel.js → parallel.ts} +2 -2
- package/{pem.js → pem.ts} +12 -11
- package/templates/mops-test.yml +1 -1
- package/tsconfig.json +16 -0
- package/types.ts +29 -0
- package/{vessel.js → vessel.ts} +37 -25
- package/commands/self-update.js +0 -6
- /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,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,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
|
+
}
|