ic-mops 0.32.2 → 0.33.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/.npmrc +1 -0
- package/cli.ts +10 -5
- package/commands/add.ts +15 -2
- package/commands/install-all.ts +15 -2
- package/commands/install.ts +3 -3
- package/commands/remove.ts +12 -1
- package/commands/sync.ts +34 -27
- package/commands/test/test.ts +7 -1
- package/commands/update.ts +10 -1
- package/declarations/main/main.did +40 -0
- package/declarations/main/main.did.d.ts +26 -0
- package/declarations/main/main.did.js +35 -0
- package/dist/cli.js +10 -5
- package/dist/commands/add.d.ts +7 -4
- package/dist/commands/add.js +7 -2
- package/dist/commands/install-all.d.ts +7 -4
- package/dist/commands/install-all.js +9 -2
- package/dist/commands/install.js +3 -3
- package/dist/commands/remove.d.ts +8 -5
- package/dist/commands/remove.js +3 -1
- package/dist/commands/sync.d.ts +5 -1
- package/dist/commands/sync.js +23 -21
- package/dist/commands/test/test.js +7 -1
- package/dist/commands/update.d.ts +7 -1
- package/dist/commands/update.js +3 -1
- package/dist/declarations/main/main.did +40 -0
- package/dist/declarations/main/main.did.d.ts +26 -0
- package/dist/declarations/main/main.did.js +35 -0
- package/dist/integrity.d.ts +5 -0
- package/dist/integrity.js +155 -0
- package/dist/package.json +2 -1
- package/dist/vessel.js +2 -2
- package/integrity.ts +188 -0
- package/package.json +2 -1
- package/vessel.ts +2 -2
|
@@ -4,7 +4,8 @@ import { checkConfigFile, readConfig } from '../mops.js';
|
|
|
4
4
|
import { install } from './install.js';
|
|
5
5
|
import { installFromGithub } from '../vessel.js';
|
|
6
6
|
import { notifyInstalls } from '../notify-installs.js';
|
|
7
|
-
|
|
7
|
+
import { checkIntegrity } from '../integrity.js';
|
|
8
|
+
export async function installAll({ verbose = false, silent = false, lockfile } = {}) {
|
|
8
9
|
if (!checkConfigFile()) {
|
|
9
10
|
return;
|
|
10
11
|
}
|
|
@@ -25,7 +26,13 @@ export async function installAll({ verbose = false, silent = false } = {}) {
|
|
|
25
26
|
installedPackages = { ...installedPackages, ...res };
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
|
-
|
|
29
|
+
if (!silent && lockfile !== 'ignore') {
|
|
30
|
+
logUpdate('Checking integrity...');
|
|
31
|
+
}
|
|
32
|
+
await Promise.all([
|
|
33
|
+
notifyInstalls(Object.keys(installedPackages)),
|
|
34
|
+
checkIntegrity(lockfile),
|
|
35
|
+
]);
|
|
29
36
|
if (!silent) {
|
|
30
37
|
logUpdate.clear();
|
|
31
38
|
console.log(chalk.green('All packages installed'));
|
package/dist/commands/install.js
CHANGED
|
@@ -118,8 +118,8 @@ export async function install(pkg, version = '', { verbose = false, silent = fal
|
|
|
118
118
|
if (!alreadyInstalled) {
|
|
119
119
|
installedDeps = { ...installedDeps, [pkg]: version };
|
|
120
120
|
}
|
|
121
|
-
if (ok) {
|
|
122
|
-
return
|
|
121
|
+
if (!ok) {
|
|
122
|
+
return false;
|
|
123
123
|
}
|
|
124
|
-
return
|
|
124
|
+
return installedDeps;
|
|
125
125
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
dryRun?: boolean
|
|
5
|
-
|
|
1
|
+
type RemoveOptions = {
|
|
2
|
+
verbose?: boolean;
|
|
3
|
+
dev?: boolean;
|
|
4
|
+
dryRun?: boolean;
|
|
5
|
+
lockfile?: 'save' | 'ignore';
|
|
6
|
+
};
|
|
7
|
+
export declare function remove(name: string, { dev, verbose, dryRun, lockfile }?: RemoveOptions): Promise<void>;
|
|
8
|
+
export {};
|
package/dist/commands/remove.js
CHANGED
|
@@ -2,7 +2,8 @@ import fs from 'node:fs';
|
|
|
2
2
|
import { deleteSync } from 'del';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { formatDir, formatGithubDir, checkConfigFile, readConfig, writeConfig } from '../mops.js';
|
|
5
|
-
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
6
|
+
export async function remove(name, { dev = false, verbose = false, dryRun = false, lockfile } = {}) {
|
|
6
7
|
if (!checkConfigFile()) {
|
|
7
8
|
return;
|
|
8
9
|
}
|
|
@@ -79,5 +80,6 @@ export async function remove(name, { dev = false, verbose = false, dryRun = fals
|
|
|
79
80
|
delete config['dev-dependencies'][name];
|
|
80
81
|
}
|
|
81
82
|
dryRun || writeConfig(config);
|
|
83
|
+
// await checkIntegrity(lockfile);
|
|
82
84
|
console.log(chalk.green('Package removed ') + `${name} = "${version}"`);
|
|
83
85
|
}
|
package/dist/commands/sync.d.ts
CHANGED
package/dist/commands/sync.js
CHANGED
|
@@ -5,6 +5,29 @@ import chalk from 'chalk';
|
|
|
5
5
|
import { checkConfigFile, getRootDir, readConfig } from '../mops.js';
|
|
6
6
|
import { add } from './add.js';
|
|
7
7
|
import { remove } from './remove.js';
|
|
8
|
+
import { checkIntegrity } from '../integrity.js';
|
|
9
|
+
export async function sync({ lockfile } = {}) {
|
|
10
|
+
if (!checkConfigFile()) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
let missing = await getMissingPackages();
|
|
14
|
+
let unused = await getUnusedPackages();
|
|
15
|
+
missing.length && console.log(`${chalk.yellow('Missing packages:')} ${missing.join(', ')}`);
|
|
16
|
+
unused.length && console.log(`${chalk.yellow('Unused packages:')} ${unused.join(', ')}`);
|
|
17
|
+
let config = readConfig();
|
|
18
|
+
let deps = new Set(Object.keys(config.dependencies || {}));
|
|
19
|
+
let devDeps = new Set(Object.keys(config['dev-dependencies'] || {}));
|
|
20
|
+
// add missing packages
|
|
21
|
+
for (let pkg of missing) {
|
|
22
|
+
await add(pkg, { lockfile: 'ignore' });
|
|
23
|
+
}
|
|
24
|
+
// remove unused packages
|
|
25
|
+
for (let pkg of unused) {
|
|
26
|
+
let dev = devDeps.has(pkg) && !deps.has(pkg);
|
|
27
|
+
await remove(pkg, { dev, lockfile: 'ignore' });
|
|
28
|
+
}
|
|
29
|
+
await checkIntegrity(lockfile);
|
|
30
|
+
}
|
|
8
31
|
let ignore = [
|
|
9
32
|
'**/node_modules/**',
|
|
10
33
|
'**/.vessel/**',
|
|
@@ -63,24 +86,3 @@ async function getUnusedPackages() {
|
|
|
63
86
|
}
|
|
64
87
|
return [...allDeps];
|
|
65
88
|
}
|
|
66
|
-
export async function sync() {
|
|
67
|
-
if (!checkConfigFile()) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
let missing = await getMissingPackages();
|
|
71
|
-
let unused = await getUnusedPackages();
|
|
72
|
-
missing.length && console.log(`${chalk.yellow('Missing packages:')} ${missing.join(', ')}`);
|
|
73
|
-
unused.length && console.log(`${chalk.yellow('Unused packages:')} ${unused.join(', ')}`);
|
|
74
|
-
let config = readConfig();
|
|
75
|
-
let deps = new Set(Object.keys(config.dependencies || {}));
|
|
76
|
-
let devDeps = new Set(Object.keys(config['dev-dependencies'] || {}));
|
|
77
|
-
// add missing packages
|
|
78
|
-
for (let pkg of missing) {
|
|
79
|
-
await add(pkg);
|
|
80
|
-
}
|
|
81
|
-
// remove unused packages
|
|
82
|
-
for (let pkg of unused) {
|
|
83
|
-
let dev = devDeps.has(pkg) && !deps.has(pkg);
|
|
84
|
-
await remove(pkg, { dev });
|
|
85
|
-
}
|
|
86
|
-
}
|
|
@@ -123,7 +123,13 @@ export async function testWithReporter(reporter, filter = '', mode = 'interprete
|
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
// run
|
|
126
|
-
let proc = spawn('wasmtime', [
|
|
126
|
+
let proc = spawn('wasmtime', [
|
|
127
|
+
'--max-wasm-stack=2000000',
|
|
128
|
+
'--enable-cranelift-nan-canonicalization',
|
|
129
|
+
'--wasm-features',
|
|
130
|
+
'multi-memory,bulk-memory',
|
|
131
|
+
wasmFile,
|
|
132
|
+
]);
|
|
127
133
|
await pipeMMF(proc, mmf);
|
|
128
134
|
}).finally(() => {
|
|
129
135
|
fs.rmSync(wasmFile, { force: true });
|
package/dist/commands/update.js
CHANGED
|
@@ -2,7 +2,8 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { checkConfigFile, getGithubCommit, parseGithubURL, readConfig } from '../mops.js';
|
|
3
3
|
import { add } from './add.js';
|
|
4
4
|
import { getAvailableUpdates } from './available-updates.js';
|
|
5
|
-
|
|
5
|
+
import { checkIntegrity } from '../integrity.js';
|
|
6
|
+
export async function update(pkg, { lockfile } = {}) {
|
|
6
7
|
if (!checkConfigFile()) {
|
|
7
8
|
return;
|
|
8
9
|
}
|
|
@@ -42,4 +43,5 @@ export async function update(pkg) {
|
|
|
42
43
|
await add(`${dep[0]}@${dep[2]}`, { dev });
|
|
43
44
|
}
|
|
44
45
|
}
|
|
46
|
+
await checkIntegrity(lockfile);
|
|
45
47
|
}
|
|
@@ -73,6 +73,14 @@ type Script =
|
|
|
73
73
|
name: text;
|
|
74
74
|
value: text;
|
|
75
75
|
};
|
|
76
|
+
type Result_8 =
|
|
77
|
+
variant {
|
|
78
|
+
err: Err;
|
|
79
|
+
ok: vec record {
|
|
80
|
+
FileId;
|
|
81
|
+
blob;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
76
84
|
type Result_7 =
|
|
77
85
|
variant {
|
|
78
86
|
err: Err;
|
|
@@ -145,6 +153,7 @@ type PackageSummary__1 =
|
|
|
145
153
|
owner: principal;
|
|
146
154
|
ownerInfo: User;
|
|
147
155
|
publication: PackagePublication;
|
|
156
|
+
quality: PackageQuality;
|
|
148
157
|
};
|
|
149
158
|
type PackageSummaryWithChanges__1 =
|
|
150
159
|
record {
|
|
@@ -156,6 +165,7 @@ type PackageSummaryWithChanges__1 =
|
|
|
156
165
|
owner: principal;
|
|
157
166
|
ownerInfo: User;
|
|
158
167
|
publication: PackagePublication;
|
|
168
|
+
quality: PackageQuality;
|
|
159
169
|
};
|
|
160
170
|
type PackageSummaryWithChanges =
|
|
161
171
|
record {
|
|
@@ -167,6 +177,7 @@ type PackageSummaryWithChanges =
|
|
|
167
177
|
owner: principal;
|
|
168
178
|
ownerInfo: User;
|
|
169
179
|
publication: PackagePublication;
|
|
180
|
+
quality: PackageQuality;
|
|
170
181
|
};
|
|
171
182
|
type PackageSummary =
|
|
172
183
|
record {
|
|
@@ -177,6 +188,18 @@ type PackageSummary =
|
|
|
177
188
|
owner: principal;
|
|
178
189
|
ownerInfo: User;
|
|
179
190
|
publication: PackagePublication;
|
|
191
|
+
quality: PackageQuality;
|
|
192
|
+
};
|
|
193
|
+
type PackageQuality =
|
|
194
|
+
record {
|
|
195
|
+
depsStatus: DepsStatus;
|
|
196
|
+
hasDescription: bool;
|
|
197
|
+
hasDocumentation: bool;
|
|
198
|
+
hasKeywords: bool;
|
|
199
|
+
hasLicense: bool;
|
|
200
|
+
hasReleaseNotes: bool;
|
|
201
|
+
hasRepository: bool;
|
|
202
|
+
hasTests: bool;
|
|
180
203
|
};
|
|
181
204
|
type PackagePublication =
|
|
182
205
|
record {
|
|
@@ -207,6 +230,7 @@ type PackageDetails =
|
|
|
207
230
|
owner: principal;
|
|
208
231
|
ownerInfo: User;
|
|
209
232
|
publication: PackagePublication;
|
|
233
|
+
quality: PackageQuality;
|
|
210
234
|
testStats: TestStats__1;
|
|
211
235
|
versionHistory: vec PackageSummaryWithChanges__1;
|
|
212
236
|
};
|
|
@@ -281,6 +305,12 @@ type DownloadsSnapshot =
|
|
|
281
305
|
endTime: Time;
|
|
282
306
|
startTime: Time;
|
|
283
307
|
};
|
|
308
|
+
type DepsStatus =
|
|
309
|
+
variant {
|
|
310
|
+
allLatest;
|
|
311
|
+
tooOld;
|
|
312
|
+
updatesAvailable;
|
|
313
|
+
};
|
|
284
314
|
type DependencyV2 =
|
|
285
315
|
record {
|
|
286
316
|
name: PackageName__1;
|
|
@@ -296,6 +326,7 @@ type DepChange =
|
|
|
296
326
|
service : {
|
|
297
327
|
backup: () -> ();
|
|
298
328
|
claimAirdrop: (principal) -> (text);
|
|
329
|
+
computeHashesForExistingFiles: () -> ();
|
|
299
330
|
diff: (text, text) -> (PackageChanges__1) query;
|
|
300
331
|
finishPublish: (PublishingId) -> (Result);
|
|
301
332
|
getAirdropAmount: () -> (nat) query;
|
|
@@ -311,6 +342,15 @@ service : {
|
|
|
311
342
|
(vec DownloadsSnapshot__1) query;
|
|
312
343
|
getDownloadTrendByPackageName: (PackageName) ->
|
|
313
344
|
(vec DownloadsSnapshot__1) query;
|
|
345
|
+
getFileHashes: (PackageName, PackageVersion) -> (Result_8);
|
|
346
|
+
getFileHashesByPackageIds: (vec PackageId) ->
|
|
347
|
+
(vec record {
|
|
348
|
+
PackageId;
|
|
349
|
+
vec record {
|
|
350
|
+
FileId;
|
|
351
|
+
blob;
|
|
352
|
+
};
|
|
353
|
+
});
|
|
314
354
|
getFileIds: (PackageName, PackageVersion) -> (Result_7) query;
|
|
315
355
|
getHighestSemverBatch:
|
|
316
356
|
(vec record {
|
|
@@ -11,6 +11,9 @@ export interface DependencyV2 {
|
|
|
11
11
|
'repo' : string,
|
|
12
12
|
'version' : string,
|
|
13
13
|
}
|
|
14
|
+
export type DepsStatus = { 'allLatest' : null } |
|
|
15
|
+
{ 'tooOld' : null } |
|
|
16
|
+
{ 'updatesAvailable' : null };
|
|
14
17
|
export interface DownloadsSnapshot {
|
|
15
18
|
'startTime' : Time,
|
|
16
19
|
'endTime' : Time,
|
|
@@ -76,6 +79,7 @@ export interface PackageDetails {
|
|
|
76
79
|
'ownerInfo' : User,
|
|
77
80
|
'owner' : Principal,
|
|
78
81
|
'deps' : Array<PackageSummary__1>,
|
|
82
|
+
'quality' : PackageQuality,
|
|
79
83
|
'testStats' : TestStats__1,
|
|
80
84
|
'downloadsTotal' : bigint,
|
|
81
85
|
'downloadsInLast30Days' : bigint,
|
|
@@ -101,9 +105,20 @@ export interface PackagePublication {
|
|
|
101
105
|
'time' : Time,
|
|
102
106
|
'user' : Principal,
|
|
103
107
|
}
|
|
108
|
+
export interface PackageQuality {
|
|
109
|
+
'depsStatus' : DepsStatus,
|
|
110
|
+
'hasDescription' : boolean,
|
|
111
|
+
'hasKeywords' : boolean,
|
|
112
|
+
'hasLicense' : boolean,
|
|
113
|
+
'hasDocumentation' : boolean,
|
|
114
|
+
'hasTests' : boolean,
|
|
115
|
+
'hasRepository' : boolean,
|
|
116
|
+
'hasReleaseNotes' : boolean,
|
|
117
|
+
}
|
|
104
118
|
export interface PackageSummary {
|
|
105
119
|
'ownerInfo' : User,
|
|
106
120
|
'owner' : Principal,
|
|
121
|
+
'quality' : PackageQuality,
|
|
107
122
|
'downloadsTotal' : bigint,
|
|
108
123
|
'downloadsInLast30Days' : bigint,
|
|
109
124
|
'downloadsInLast7Days' : bigint,
|
|
@@ -113,6 +128,7 @@ export interface PackageSummary {
|
|
|
113
128
|
export interface PackageSummaryWithChanges {
|
|
114
129
|
'ownerInfo' : User,
|
|
115
130
|
'owner' : Principal,
|
|
131
|
+
'quality' : PackageQuality,
|
|
116
132
|
'downloadsTotal' : bigint,
|
|
117
133
|
'downloadsInLast30Days' : bigint,
|
|
118
134
|
'downloadsInLast7Days' : bigint,
|
|
@@ -123,6 +139,7 @@ export interface PackageSummaryWithChanges {
|
|
|
123
139
|
export interface PackageSummaryWithChanges__1 {
|
|
124
140
|
'ownerInfo' : User,
|
|
125
141
|
'owner' : Principal,
|
|
142
|
+
'quality' : PackageQuality,
|
|
126
143
|
'downloadsTotal' : bigint,
|
|
127
144
|
'downloadsInLast30Days' : bigint,
|
|
128
145
|
'downloadsInLast7Days' : bigint,
|
|
@@ -133,6 +150,7 @@ export interface PackageSummaryWithChanges__1 {
|
|
|
133
150
|
export interface PackageSummary__1 {
|
|
134
151
|
'ownerInfo' : User,
|
|
135
152
|
'owner' : Principal,
|
|
153
|
+
'quality' : PackageQuality,
|
|
136
154
|
'downloadsTotal' : bigint,
|
|
137
155
|
'downloadsInLast30Days' : bigint,
|
|
138
156
|
'downloadsInLast7Days' : bigint,
|
|
@@ -173,6 +191,8 @@ export type Result_6 = { 'ok' : Array<[PackageName, PackageVersion]> } |
|
|
|
173
191
|
{ 'err' : Err };
|
|
174
192
|
export type Result_7 = { 'ok' : Array<FileId> } |
|
|
175
193
|
{ 'err' : Err };
|
|
194
|
+
export type Result_8 = { 'ok' : Array<[FileId, Uint8Array | number[]]> } |
|
|
195
|
+
{ 'err' : Err };
|
|
176
196
|
export interface Script { 'value' : string, 'name' : string }
|
|
177
197
|
export type SemverPart = { 'major' : null } |
|
|
178
198
|
{ 'minor' : null } |
|
|
@@ -233,6 +253,7 @@ export interface User__1 {
|
|
|
233
253
|
export interface _SERVICE {
|
|
234
254
|
'backup' : ActorMethod<[], undefined>,
|
|
235
255
|
'claimAirdrop' : ActorMethod<[Principal], string>,
|
|
256
|
+
'computeHashesForExistingFiles' : ActorMethod<[], undefined>,
|
|
236
257
|
'diff' : ActorMethod<[string, string], PackageChanges__1>,
|
|
237
258
|
'finishPublish' : ActorMethod<[PublishingId], Result>,
|
|
238
259
|
'getAirdropAmount' : ActorMethod<[], bigint>,
|
|
@@ -251,6 +272,11 @@ export interface _SERVICE {
|
|
|
251
272
|
[PackageName],
|
|
252
273
|
Array<DownloadsSnapshot__1>
|
|
253
274
|
>,
|
|
275
|
+
'getFileHashes' : ActorMethod<[PackageName, PackageVersion], Result_8>,
|
|
276
|
+
'getFileHashesByPackageIds' : ActorMethod<
|
|
277
|
+
[Array<PackageId>],
|
|
278
|
+
Array<[PackageId, Array<[FileId, Uint8Array | number[]]>]>
|
|
279
|
+
>,
|
|
254
280
|
'getFileIds' : ActorMethod<[PackageName, PackageVersion], Result_7>,
|
|
255
281
|
'getHighestSemverBatch' : ActorMethod<
|
|
256
282
|
[Array<[PackageName, PackageVersion, SemverPart]>],
|
|
@@ -28,6 +28,10 @@ export const idlFactory = ({ IDL }) => {
|
|
|
28
28
|
'downloads' : IDL.Nat,
|
|
29
29
|
});
|
|
30
30
|
const FileId = IDL.Text;
|
|
31
|
+
const Result_8 = IDL.Variant({
|
|
32
|
+
'ok' : IDL.Vec(IDL.Tuple(FileId, IDL.Vec(IDL.Nat8))),
|
|
33
|
+
'err' : Err,
|
|
34
|
+
});
|
|
31
35
|
const Result_7 = IDL.Variant({ 'ok' : IDL.Vec(FileId), 'err' : Err });
|
|
32
36
|
const SemverPart = IDL.Variant({
|
|
33
37
|
'major' : IDL.Null,
|
|
@@ -51,6 +55,21 @@ export const idlFactory = ({ IDL }) => {
|
|
|
51
55
|
'githubVerified' : IDL.Bool,
|
|
52
56
|
'github' : IDL.Text,
|
|
53
57
|
});
|
|
58
|
+
const DepsStatus = IDL.Variant({
|
|
59
|
+
'allLatest' : IDL.Null,
|
|
60
|
+
'tooOld' : IDL.Null,
|
|
61
|
+
'updatesAvailable' : IDL.Null,
|
|
62
|
+
});
|
|
63
|
+
const PackageQuality = IDL.Record({
|
|
64
|
+
'depsStatus' : DepsStatus,
|
|
65
|
+
'hasDescription' : IDL.Bool,
|
|
66
|
+
'hasKeywords' : IDL.Bool,
|
|
67
|
+
'hasLicense' : IDL.Bool,
|
|
68
|
+
'hasDocumentation' : IDL.Bool,
|
|
69
|
+
'hasTests' : IDL.Bool,
|
|
70
|
+
'hasRepository' : IDL.Bool,
|
|
71
|
+
'hasReleaseNotes' : IDL.Bool,
|
|
72
|
+
});
|
|
54
73
|
const Script = IDL.Record({ 'value' : IDL.Text, 'name' : IDL.Text });
|
|
55
74
|
const PackageName__1 = IDL.Text;
|
|
56
75
|
const DependencyV2 = IDL.Record({
|
|
@@ -84,6 +103,7 @@ export const idlFactory = ({ IDL }) => {
|
|
|
84
103
|
const PackageSummary = IDL.Record({
|
|
85
104
|
'ownerInfo' : User,
|
|
86
105
|
'owner' : IDL.Principal,
|
|
106
|
+
'quality' : PackageQuality,
|
|
87
107
|
'downloadsTotal' : IDL.Nat,
|
|
88
108
|
'downloadsInLast30Days' : IDL.Nat,
|
|
89
109
|
'downloadsInLast7Days' : IDL.Nat,
|
|
@@ -93,6 +113,7 @@ export const idlFactory = ({ IDL }) => {
|
|
|
93
113
|
const PackageSummary__1 = IDL.Record({
|
|
94
114
|
'ownerInfo' : User,
|
|
95
115
|
'owner' : IDL.Principal,
|
|
116
|
+
'quality' : PackageQuality,
|
|
96
117
|
'downloadsTotal' : IDL.Nat,
|
|
97
118
|
'downloadsInLast30Days' : IDL.Nat,
|
|
98
119
|
'downloadsInLast7Days' : IDL.Nat,
|
|
@@ -121,6 +142,7 @@ export const idlFactory = ({ IDL }) => {
|
|
|
121
142
|
const PackageSummaryWithChanges__1 = IDL.Record({
|
|
122
143
|
'ownerInfo' : User,
|
|
123
144
|
'owner' : IDL.Principal,
|
|
145
|
+
'quality' : PackageQuality,
|
|
124
146
|
'downloadsTotal' : IDL.Nat,
|
|
125
147
|
'downloadsInLast30Days' : IDL.Nat,
|
|
126
148
|
'downloadsInLast7Days' : IDL.Nat,
|
|
@@ -132,6 +154,7 @@ export const idlFactory = ({ IDL }) => {
|
|
|
132
154
|
'ownerInfo' : User,
|
|
133
155
|
'owner' : IDL.Principal,
|
|
134
156
|
'deps' : IDL.Vec(PackageSummary__1),
|
|
157
|
+
'quality' : PackageQuality,
|
|
135
158
|
'testStats' : TestStats__1,
|
|
136
159
|
'downloadsTotal' : IDL.Nat,
|
|
137
160
|
'downloadsInLast30Days' : IDL.Nat,
|
|
@@ -149,6 +172,7 @@ export const idlFactory = ({ IDL }) => {
|
|
|
149
172
|
const PackageSummaryWithChanges = IDL.Record({
|
|
150
173
|
'ownerInfo' : User,
|
|
151
174
|
'owner' : IDL.Principal,
|
|
175
|
+
'quality' : PackageQuality,
|
|
152
176
|
'downloadsTotal' : IDL.Nat,
|
|
153
177
|
'downloadsInLast30Days' : IDL.Nat,
|
|
154
178
|
'downloadsInLast7Days' : IDL.Nat,
|
|
@@ -235,6 +259,7 @@ export const idlFactory = ({ IDL }) => {
|
|
|
235
259
|
return IDL.Service({
|
|
236
260
|
'backup' : IDL.Func([], [], []),
|
|
237
261
|
'claimAirdrop' : IDL.Func([IDL.Principal], [IDL.Text], []),
|
|
262
|
+
'computeHashesForExistingFiles' : IDL.Func([], [], []),
|
|
238
263
|
'diff' : IDL.Func([IDL.Text, IDL.Text], [PackageChanges__1], ['query']),
|
|
239
264
|
'finishPublish' : IDL.Func([PublishingId], [Result], []),
|
|
240
265
|
'getAirdropAmount' : IDL.Func([], [IDL.Nat], ['query']),
|
|
@@ -256,6 +281,16 @@ export const idlFactory = ({ IDL }) => {
|
|
|
256
281
|
[IDL.Vec(DownloadsSnapshot__1)],
|
|
257
282
|
['query'],
|
|
258
283
|
),
|
|
284
|
+
'getFileHashes' : IDL.Func([PackageName, PackageVersion], [Result_8], []),
|
|
285
|
+
'getFileHashesByPackageIds' : IDL.Func(
|
|
286
|
+
[IDL.Vec(PackageId)],
|
|
287
|
+
[
|
|
288
|
+
IDL.Vec(
|
|
289
|
+
IDL.Tuple(PackageId, IDL.Vec(IDL.Tuple(FileId, IDL.Vec(IDL.Nat8))))
|
|
290
|
+
),
|
|
291
|
+
],
|
|
292
|
+
[],
|
|
293
|
+
),
|
|
259
294
|
'getFileIds' : IDL.Func(
|
|
260
295
|
[PackageName, PackageVersion],
|
|
261
296
|
[Result_7],
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function checkIntegrity(lock?: 'save' | 'check' | 'ignore'): Promise<void>;
|
|
2
|
+
export declare function getLocalFileHash(fileId: string): string;
|
|
3
|
+
export declare function checkRemote(): Promise<void>;
|
|
4
|
+
export declare function saveLockFile(): Promise<void>;
|
|
5
|
+
export declare function checkLockFile(force?: boolean): Promise<void>;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
4
|
+
import { bytesToHex } from '@noble/hashes/utils';
|
|
5
|
+
import { getDependencyType, getRootDir, mainActor } from './mops.js';
|
|
6
|
+
import { resolvePackages } from './resolve-packages.js';
|
|
7
|
+
export async function checkIntegrity(lock) {
|
|
8
|
+
let force = !!lock;
|
|
9
|
+
if (!lock) {
|
|
10
|
+
lock = process.env['CI'] ? 'check' : 'ignore';
|
|
11
|
+
}
|
|
12
|
+
if (lock === 'save') {
|
|
13
|
+
await saveLockFile();
|
|
14
|
+
await checkLockFile(force);
|
|
15
|
+
}
|
|
16
|
+
else if (lock === 'check') {
|
|
17
|
+
await checkLockFile(force);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function getFileHashesFromRegistry() {
|
|
21
|
+
let packageIds = await getResolvedMopsPackageIds();
|
|
22
|
+
let actor = await mainActor();
|
|
23
|
+
let fileHashesByPackageIds = await actor.getFileHashesByPackageIds(packageIds);
|
|
24
|
+
return fileHashesByPackageIds;
|
|
25
|
+
}
|
|
26
|
+
async function getResolvedMopsPackageIds() {
|
|
27
|
+
let resolvedPackages = await resolvePackages();
|
|
28
|
+
let packageIds = Object.entries(resolvedPackages)
|
|
29
|
+
.filter(([_, version]) => getDependencyType(version) === 'mops')
|
|
30
|
+
.map(([name, version]) => `${name}@${version}`);
|
|
31
|
+
return packageIds;
|
|
32
|
+
}
|
|
33
|
+
// get hash of local file from '.mops' dir by fileId
|
|
34
|
+
export function getLocalFileHash(fileId) {
|
|
35
|
+
let rootDir = getRootDir();
|
|
36
|
+
let file = path.join(rootDir, '.mops', fileId);
|
|
37
|
+
if (!fs.existsSync(file)) {
|
|
38
|
+
console.error(`Missing file ${fileId} in .mops dir`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
let fileData = fs.readFileSync(file);
|
|
42
|
+
return bytesToHex(sha256(fileData));
|
|
43
|
+
}
|
|
44
|
+
function getMopsTomlHash() {
|
|
45
|
+
return bytesToHex(sha256(fs.readFileSync(getRootDir() + '/mops.toml')));
|
|
46
|
+
}
|
|
47
|
+
// compare hashes of local files with hashes from the registry
|
|
48
|
+
export async function checkRemote() {
|
|
49
|
+
let fileHashesFromRegistry = await getFileHashesFromRegistry();
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
|
+
for (let [_packageId, fileHashes] of fileHashesFromRegistry) {
|
|
52
|
+
for (let [fileId, hash] of fileHashes) {
|
|
53
|
+
let remoteHash = new Uint8Array(hash);
|
|
54
|
+
let localHash = getLocalFileHash(fileId);
|
|
55
|
+
if (localHash !== bytesToHex(remoteHash)) {
|
|
56
|
+
console.error('Integrity check failed.');
|
|
57
|
+
console.error(`Mismatched hash for ${fileId}: ${localHash} vs ${bytesToHex(remoteHash)}`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export async function saveLockFile() {
|
|
64
|
+
let rootDir = getRootDir();
|
|
65
|
+
let lockFile = path.join(rootDir, 'mops.lock');
|
|
66
|
+
// if lock file exists and mops.toml hasn't changed, don't update it
|
|
67
|
+
if (fs.existsSync(lockFile)) {
|
|
68
|
+
let lockFileJson = JSON.parse(fs.readFileSync(lockFile).toString());
|
|
69
|
+
let mopsTomlHash = getMopsTomlHash();
|
|
70
|
+
if (mopsTomlHash === lockFileJson.mopsTomlHash) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
let fileHashes = await getFileHashesFromRegistry();
|
|
75
|
+
let lockFileJson = {
|
|
76
|
+
version: 1,
|
|
77
|
+
mopsTomlHash: getMopsTomlHash(),
|
|
78
|
+
hashes: fileHashes.reduce((acc, [packageId, fileHashes]) => {
|
|
79
|
+
acc[packageId] = fileHashes.reduce((acc, [fileId, hash]) => {
|
|
80
|
+
acc[fileId] = bytesToHex(new Uint8Array(hash));
|
|
81
|
+
return acc;
|
|
82
|
+
}, {});
|
|
83
|
+
return acc;
|
|
84
|
+
}, {}),
|
|
85
|
+
};
|
|
86
|
+
fs.writeFileSync(lockFile, JSON.stringify(lockFileJson, null, 2));
|
|
87
|
+
}
|
|
88
|
+
// compare hashes of local files with hashes from the lock file
|
|
89
|
+
export async function checkLockFile(force = false) {
|
|
90
|
+
let rootDir = getRootDir();
|
|
91
|
+
let lockFile = path.join(rootDir, 'mops.lock');
|
|
92
|
+
// check if lock file exists
|
|
93
|
+
if (!fs.existsSync(lockFile)) {
|
|
94
|
+
if (force) {
|
|
95
|
+
console.error('Missing lock file. Run `mops install` to generate it.');
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
let lockFileJson = JSON.parse(fs.readFileSync(lockFile).toString());
|
|
101
|
+
let packageIds = await getResolvedMopsPackageIds();
|
|
102
|
+
// check lock file version
|
|
103
|
+
if (lockFileJson.version !== 1) {
|
|
104
|
+
console.error('Integrity check failed');
|
|
105
|
+
console.error(`Invalid lock file version: ${lockFileJson.version}. Supported versions: 1`);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
// check mops.toml hash
|
|
109
|
+
if (lockFileJson.mopsTomlHash !== getMopsTomlHash()) {
|
|
110
|
+
console.error('Integrity check failed');
|
|
111
|
+
console.error('Mismatched mops.toml hash');
|
|
112
|
+
console.error(`Locked hash: ${lockFileJson.mopsTomlHash}`);
|
|
113
|
+
console.error(`Actual hash: ${getMopsTomlHash()}`);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
// check number of packages
|
|
117
|
+
if (Object.keys(lockFileJson.hashes).length !== packageIds.length) {
|
|
118
|
+
console.error('Integrity check failed');
|
|
119
|
+
console.error(`Mismatched number of resolved packages: ${JSON.stringify(Object.keys(lockFileJson.hashes).length)} vs ${JSON.stringify(packageIds.length)}`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
// check if resolved packages are in the lock file
|
|
123
|
+
for (let packageId of packageIds) {
|
|
124
|
+
if (!(packageId in lockFileJson.hashes)) {
|
|
125
|
+
console.error('Integrity check failed');
|
|
126
|
+
console.error(`Missing package ${packageId} in lock file`);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
for (let [packageId, hashes] of Object.entries(lockFileJson.hashes)) {
|
|
131
|
+
// check if package is in resolved packages
|
|
132
|
+
if (!packageIds.includes(packageId)) {
|
|
133
|
+
console.error('Integrity check failed');
|
|
134
|
+
console.error(`Package ${packageId} in lock file but not in resolved packages`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
for (let [fileId, lockedHash] of Object.entries(hashes)) {
|
|
138
|
+
// check if file belongs to package
|
|
139
|
+
if (!fileId.startsWith(packageId)) {
|
|
140
|
+
console.error('Integrity check failed');
|
|
141
|
+
console.error(`File ${fileId} in lock file does not belong to package ${packageId}`);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
// local file hash vs hash from lock file
|
|
145
|
+
let localHash = getLocalFileHash(fileId);
|
|
146
|
+
if (lockedHash !== localHash) {
|
|
147
|
+
console.error('Integrity check failed');
|
|
148
|
+
console.error(`Mismatched hash for ${fileId}`);
|
|
149
|
+
console.error(`Locked hash: ${lockedHash}`);
|
|
150
|
+
console.error(`Actual hash: ${localHash}`);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ic-mops",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mops": "dist/cli.js"
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"@dfinity/identity-secp256k1": "^0.18.1",
|
|
39
39
|
"@dfinity/principal": "^0.18.1",
|
|
40
40
|
"@iarna/toml": "^2.2.5",
|
|
41
|
+
"@noble/hashes": "1.3.2",
|
|
41
42
|
"as-table": "^1.0.55",
|
|
42
43
|
"cacheable-request": "10.2.12",
|
|
43
44
|
"camelcase": "^7.0.1",
|
package/dist/vessel.js
CHANGED
|
@@ -120,11 +120,11 @@ export const installFromGithub = async (name, repo, { verbose = false, dep = fal
|
|
|
120
120
|
let dir = formatGithubDir(name, repo);
|
|
121
121
|
let cacheName = `_github/${name}#${branch}` + (commitHash ? `@${commitHash}` : '');
|
|
122
122
|
if (existsSync(dir)) {
|
|
123
|
-
silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${repo} (local cache)
|
|
123
|
+
silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${repo} (local cache)`);
|
|
124
124
|
}
|
|
125
125
|
else if (isCached(cacheName)) {
|
|
126
126
|
await copyCache(cacheName, dir);
|
|
127
|
-
silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${repo} (global cache)
|
|
127
|
+
silent || logUpdate(`${dep ? 'Dependency' : 'Installing'} ${repo} (global cache)`);
|
|
128
128
|
}
|
|
129
129
|
else {
|
|
130
130
|
mkdirSync(dir, { recursive: true });
|