ic-mops 1.0.1 → 1.1.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 (93) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/bundle/cli.tgz +0 -0
  3. package/check-requirements.ts +1 -1
  4. package/cli.ts +29 -5
  5. package/commands/bench.ts +1 -1
  6. package/commands/install/install-all.ts +28 -6
  7. package/commands/install/install-dep.ts +5 -4
  8. package/commands/install/install-deps.ts +3 -2
  9. package/commands/install/install-local-dep.ts +11 -5
  10. package/commands/install/install-mops-dep.ts +8 -5
  11. package/commands/replica.ts +33 -3
  12. package/commands/sources.ts +1 -1
  13. package/commands/sync.ts +4 -19
  14. package/commands/test/mmf1.ts +4 -0
  15. package/commands/test/reporters/silent-reporter.ts +22 -4
  16. package/commands/test/test.ts +74 -10
  17. package/commands/watch/deployer.ts +155 -0
  18. package/commands/watch/error-checker.ts +87 -0
  19. package/commands/watch/generator.ts +99 -0
  20. package/commands/watch/globMoFiles.ts +16 -0
  21. package/commands/watch/parseDfxJson.ts +64 -0
  22. package/commands/watch/tester.ts +81 -0
  23. package/commands/watch/warning-checker.ts +133 -0
  24. package/commands/watch/watch.ts +90 -0
  25. package/declarations/main/main.did +16 -10
  26. package/declarations/main/main.did.d.ts +19 -10
  27. package/declarations/main/main.did.js +25 -11
  28. package/dist/check-requirements.js +1 -1
  29. package/dist/cli.js +26 -5
  30. package/dist/commands/bench.js +1 -1
  31. package/dist/commands/install/install-all.d.ts +2 -1
  32. package/dist/commands/install/install-all.js +24 -6
  33. package/dist/commands/install/install-dep.d.ts +2 -1
  34. package/dist/commands/install/install-dep.js +4 -4
  35. package/dist/commands/install/install-deps.d.ts +2 -1
  36. package/dist/commands/install/install-deps.js +2 -2
  37. package/dist/commands/install/install-local-dep.d.ts +2 -1
  38. package/dist/commands/install/install-local-dep.js +9 -4
  39. package/dist/commands/install/install-mops-dep.d.ts +2 -1
  40. package/dist/commands/install/install-mops-dep.js +7 -5
  41. package/dist/commands/replica.d.ts +2 -2
  42. package/dist/commands/replica.js +26 -3
  43. package/dist/commands/sources.d.ts +1 -1
  44. package/dist/commands/sources.js +1 -1
  45. package/dist/commands/sync.js +3 -18
  46. package/dist/commands/test/mmf1.d.ts +1 -0
  47. package/dist/commands/test/mmf1.js +3 -0
  48. package/dist/commands/test/reporters/silent-reporter.d.ts +6 -1
  49. package/dist/commands/test/reporters/silent-reporter.js +18 -5
  50. package/dist/commands/test/test.d.ts +1 -1
  51. package/dist/commands/test/test.js +62 -10
  52. package/dist/commands/watch/deployer.d.ts +24 -0
  53. package/dist/commands/watch/deployer.js +125 -0
  54. package/dist/commands/watch/error-checker.d.ts +13 -0
  55. package/dist/commands/watch/error-checker.js +76 -0
  56. package/dist/commands/watch/generator.d.ts +21 -0
  57. package/dist/commands/watch/generator.js +79 -0
  58. package/dist/commands/watch/globMoFiles.d.ts +1 -0
  59. package/dist/commands/watch/globMoFiles.js +14 -0
  60. package/dist/commands/watch/parseDfxJson.d.ts +2 -0
  61. package/dist/commands/watch/parseDfxJson.js +22 -0
  62. package/dist/commands/watch/tester.d.ts +19 -0
  63. package/dist/commands/watch/tester.js +63 -0
  64. package/dist/commands/watch/warning-checker.d.ts +20 -0
  65. package/dist/commands/watch/warning-checker.js +111 -0
  66. package/dist/commands/watch/watch.d.ts +7 -0
  67. package/dist/commands/watch/watch.js +79 -0
  68. package/dist/declarations/main/main.did +16 -10
  69. package/dist/declarations/main/main.did.d.ts +19 -10
  70. package/dist/declarations/main/main.did.js +25 -11
  71. package/dist/helpers/get-moc-path.d.ts +1 -1
  72. package/dist/helpers/get-moc-path.js +17 -3
  73. package/dist/helpers/get-moc-version.d.ts +1 -1
  74. package/dist/helpers/get-moc-version.js +17 -5
  75. package/dist/integrity.d.ts +20 -0
  76. package/dist/integrity.js +42 -10
  77. package/dist/mops.d.ts +2 -1
  78. package/dist/mops.js +13 -10
  79. package/dist/package.json +3 -2
  80. package/dist/parallel.d.ts +1 -1
  81. package/dist/resolve-packages.js +7 -0
  82. package/dist/templates/mops-test.yml +4 -2
  83. package/dist/vessel.d.ts +2 -1
  84. package/dist/vessel.js +4 -1
  85. package/helpers/get-moc-path.ts +19 -3
  86. package/helpers/get-moc-version.ts +17 -5
  87. package/integrity.ts +56 -13
  88. package/mops.ts +15 -11
  89. package/package.json +3 -2
  90. package/parallel.ts +2 -2
  91. package/resolve-packages.ts +9 -0
  92. package/templates/mops-test.yml +4 -2
  93. package/vessel.ts +5 -1
@@ -63,7 +63,7 @@ export interface Main {
63
63
  'getBackupCanisterId' : ActorMethod<[], Principal>,
64
64
  'getDefaultPackages' : ActorMethod<
65
65
  [string],
66
- Array<[PackageName, PackageVersion]>
66
+ Array<[PackageName, PackageVersion__1]>
67
67
  >,
68
68
  'getDownloadTrendByPackageId' : ActorMethod<
69
69
  [PackageId],
@@ -73,22 +73,25 @@ export interface Main {
73
73
  [PackageName],
74
74
  Array<DownloadsSnapshot__1>
75
75
  >,
76
- 'getFileHashes' : ActorMethod<[PackageName, PackageVersion], Result_8>,
76
+ 'getFileHashes' : ActorMethod<[PackageName, PackageVersion__1], Result_8>,
77
77
  'getFileHashesByPackageIds' : ActorMethod<
78
78
  [Array<PackageId>],
79
79
  Array<[PackageId, Array<[FileId, Uint8Array | number[]]>]>
80
80
  >,
81
- 'getFileHashesQuery' : ActorMethod<[PackageName, PackageVersion], Result_8>,
82
- 'getFileIds' : ActorMethod<[PackageName, PackageVersion], Result_7>,
81
+ 'getFileHashesQuery' : ActorMethod<
82
+ [PackageName, PackageVersion__1],
83
+ Result_8
84
+ >,
85
+ 'getFileIds' : ActorMethod<[PackageName, PackageVersion__1], Result_7>,
83
86
  'getHighestSemverBatch' : ActorMethod<
84
- [Array<[PackageName, PackageVersion, SemverPart]>],
87
+ [Array<[PackageName, PackageVersion__1, SemverPart]>],
85
88
  Result_6
86
89
  >,
87
90
  'getHighestVersion' : ActorMethod<[PackageName], Result_5>,
88
91
  'getMostDownloadedPackages' : ActorMethod<[], Array<PackageSummary>>,
89
92
  'getMostDownloadedPackagesIn7Days' : ActorMethod<[], Array<PackageSummary>>,
90
93
  'getNewPackages' : ActorMethod<[], Array<PackageSummary>>,
91
- 'getPackageDetails' : ActorMethod<[PackageName, PackageVersion], Result_4>,
94
+ 'getPackageDetails' : ActorMethod<[PackageName, PackageVersion__1], Result_4>,
92
95
  'getPackagesByCategory' : ActorMethod<
93
96
  [],
94
97
  Array<[string, Array<PackageSummary>]>
@@ -102,9 +105,9 @@ export interface Main {
102
105
  'getTotalPackages' : ActorMethod<[], bigint>,
103
106
  'getUser' : ActorMethod<[Principal], [] | [User__1]>,
104
107
  'http_request' : ActorMethod<[Request], Response>,
105
- 'notifyInstall' : ActorMethod<[PackageName, PackageVersion], undefined>,
108
+ 'notifyInstall' : ActorMethod<[PackageName, PackageVersion__1], undefined>,
106
109
  'notifyInstalls' : ActorMethod<
107
- [Array<[PackageName, PackageVersion]>],
110
+ [Array<[PackageName, PackageVersion__1]>],
108
111
  undefined
109
112
  >,
110
113
  'restore' : ActorMethod<[bigint], undefined>,
@@ -182,6 +185,7 @@ export interface PackageDetails {
182
185
  'deps' : Array<PackageSummary__1>,
183
186
  'quality' : PackageQuality,
184
187
  'testStats' : TestStats__1,
188
+ 'highestVersion' : PackageVersion,
185
189
  'downloadsTotal' : bigint,
186
190
  'downloadsInLast30Days' : bigint,
187
191
  'downloadTrend' : Array<DownloadsSnapshot>,
@@ -221,6 +225,7 @@ export interface PackageSummary {
221
225
  'owner' : Principal,
222
226
  'depAlias' : string,
223
227
  'quality' : PackageQuality,
228
+ 'highestVersion' : PackageVersion,
224
229
  'downloadsTotal' : bigint,
225
230
  'downloadsInLast30Days' : bigint,
226
231
  'downloadsInLast7Days' : bigint,
@@ -232,6 +237,7 @@ export interface PackageSummaryWithChanges {
232
237
  'owner' : Principal,
233
238
  'depAlias' : string,
234
239
  'quality' : PackageQuality,
240
+ 'highestVersion' : PackageVersion,
235
241
  'downloadsTotal' : bigint,
236
242
  'downloadsInLast30Days' : bigint,
237
243
  'downloadsInLast7Days' : bigint,
@@ -244,6 +250,7 @@ export interface PackageSummaryWithChanges__1 {
244
250
  'owner' : Principal,
245
251
  'depAlias' : string,
246
252
  'quality' : PackageQuality,
253
+ 'highestVersion' : PackageVersion,
247
254
  'downloadsTotal' : bigint,
248
255
  'downloadsInLast30Days' : bigint,
249
256
  'downloadsInLast7Days' : bigint,
@@ -256,6 +263,7 @@ export interface PackageSummary__1 {
256
263
  'owner' : Principal,
257
264
  'depAlias' : string,
258
265
  'quality' : PackageQuality,
266
+ 'highestVersion' : PackageVersion,
259
267
  'downloadsTotal' : bigint,
260
268
  'downloadsInLast30Days' : bigint,
261
269
  'downloadsInLast7Days' : bigint,
@@ -263,6 +271,7 @@ export interface PackageSummary__1 {
263
271
  'publication' : PackagePublication,
264
272
  }
265
273
  export type PackageVersion = string;
274
+ export type PackageVersion__1 = string;
266
275
  export type PageCount = bigint;
267
276
  export type PublishingId = string;
268
277
  export interface Request {
@@ -290,9 +299,9 @@ export type Result_3 = { 'ok' : FileId } |
290
299
  { 'err' : Err };
291
300
  export type Result_4 = { 'ok' : PackageDetails } |
292
301
  { 'err' : Err };
293
- export type Result_5 = { 'ok' : PackageVersion } |
302
+ export type Result_5 = { 'ok' : PackageVersion__1 } |
294
303
  { 'err' : Err };
295
- export type Result_6 = { 'ok' : Array<[PackageName, PackageVersion]> } |
304
+ export type Result_6 = { 'ok' : Array<[PackageName, PackageVersion__1]> } |
296
305
  { 'err' : Err };
297
306
  export type Result_7 = { 'ok' : Array<FileId> } |
298
307
  { 'err' : Err };
@@ -4,7 +4,7 @@ export const idlFactory = ({ IDL }) => {
4
4
  const Result = IDL.Variant({ 'ok' : IDL.Null, 'err' : Err });
5
5
  const Text = IDL.Text;
6
6
  const PackageName = IDL.Text;
7
- const PackageVersion = IDL.Text;
7
+ const PackageVersion__1 = IDL.Text;
8
8
  const PackageId = IDL.Text;
9
9
  const Time = IDL.Int;
10
10
  const DownloadsSnapshot__1 = IDL.Record({
@@ -24,10 +24,10 @@ export const idlFactory = ({ IDL }) => {
24
24
  'patch' : IDL.Null,
25
25
  });
26
26
  const Result_6 = IDL.Variant({
27
- 'ok' : IDL.Vec(IDL.Tuple(PackageName, PackageVersion)),
27
+ 'ok' : IDL.Vec(IDL.Tuple(PackageName, PackageVersion__1)),
28
28
  'err' : Err,
29
29
  });
30
- const Result_5 = IDL.Variant({ 'ok' : PackageVersion, 'err' : Err });
30
+ const Result_5 = IDL.Variant({ 'ok' : PackageVersion__1, 'err' : Err });
31
31
  const User = IDL.Record({
32
32
  'id' : IDL.Principal,
33
33
  'emailVerified' : IDL.Bool,
@@ -55,6 +55,7 @@ export const idlFactory = ({ IDL }) => {
55
55
  'hasRepository' : IDL.Bool,
56
56
  'hasReleaseNotes' : IDL.Bool,
57
57
  });
58
+ const PackageVersion = IDL.Text;
58
59
  const Script = IDL.Record({ 'value' : IDL.Text, 'name' : IDL.Text });
59
60
  const PackageName__1 = IDL.Text;
60
61
  const DependencyV2 = IDL.Record({
@@ -92,6 +93,7 @@ export const idlFactory = ({ IDL }) => {
92
93
  'owner' : IDL.Principal,
93
94
  'depAlias' : IDL.Text,
94
95
  'quality' : PackageQuality,
96
+ 'highestVersion' : PackageVersion,
95
97
  'downloadsTotal' : IDL.Nat,
96
98
  'downloadsInLast30Days' : IDL.Nat,
97
99
  'downloadsInLast7Days' : IDL.Nat,
@@ -119,6 +121,7 @@ export const idlFactory = ({ IDL }) => {
119
121
  'owner' : IDL.Principal,
120
122
  'depAlias' : IDL.Text,
121
123
  'quality' : PackageQuality,
124
+ 'highestVersion' : PackageVersion,
122
125
  'downloadsTotal' : IDL.Nat,
123
126
  'downloadsInLast30Days' : IDL.Nat,
124
127
  'downloadsInLast7Days' : IDL.Nat,
@@ -160,6 +163,7 @@ export const idlFactory = ({ IDL }) => {
160
163
  'owner' : IDL.Principal,
161
164
  'depAlias' : IDL.Text,
162
165
  'quality' : PackageQuality,
166
+ 'highestVersion' : PackageVersion,
163
167
  'downloadsTotal' : IDL.Nat,
164
168
  'downloadsInLast30Days' : IDL.Nat,
165
169
  'downloadsInLast7Days' : IDL.Nat,
@@ -175,6 +179,7 @@ export const idlFactory = ({ IDL }) => {
175
179
  'deps' : IDL.Vec(PackageSummary__1),
176
180
  'quality' : PackageQuality,
177
181
  'testStats' : TestStats__1,
182
+ 'highestVersion' : PackageVersion,
178
183
  'downloadsTotal' : IDL.Nat,
179
184
  'downloadsInLast30Days' : IDL.Nat,
180
185
  'downloadTrend' : IDL.Vec(DownloadsSnapshot),
@@ -193,6 +198,7 @@ export const idlFactory = ({ IDL }) => {
193
198
  'owner' : IDL.Principal,
194
199
  'depAlias' : IDL.Text,
195
200
  'quality' : PackageQuality,
201
+ 'highestVersion' : PackageVersion,
196
202
  'downloadsTotal' : IDL.Nat,
197
203
  'downloadsInLast30Days' : IDL.Nat,
198
204
  'downloadsInLast7Days' : IDL.Nat,
@@ -295,7 +301,7 @@ export const idlFactory = ({ IDL }) => {
295
301
  'getBackupCanisterId' : IDL.Func([], [IDL.Principal], ['query']),
296
302
  'getDefaultPackages' : IDL.Func(
297
303
  [IDL.Text],
298
- [IDL.Vec(IDL.Tuple(PackageName, PackageVersion))],
304
+ [IDL.Vec(IDL.Tuple(PackageName, PackageVersion__1))],
299
305
  ['query'],
300
306
  ),
301
307
  'getDownloadTrendByPackageId' : IDL.Func(
@@ -308,7 +314,11 @@ export const idlFactory = ({ IDL }) => {
308
314
  [IDL.Vec(DownloadsSnapshot__1)],
309
315
  ['query'],
310
316
  ),
311
- 'getFileHashes' : IDL.Func([PackageName, PackageVersion], [Result_8], []),
317
+ 'getFileHashes' : IDL.Func(
318
+ [PackageName, PackageVersion__1],
319
+ [Result_8],
320
+ [],
321
+ ),
312
322
  'getFileHashesByPackageIds' : IDL.Func(
313
323
  [IDL.Vec(PackageId)],
314
324
  [
@@ -319,17 +329,17 @@ export const idlFactory = ({ IDL }) => {
319
329
  [],
320
330
  ),
321
331
  'getFileHashesQuery' : IDL.Func(
322
- [PackageName, PackageVersion],
332
+ [PackageName, PackageVersion__1],
323
333
  [Result_8],
324
334
  ['query'],
325
335
  ),
326
336
  'getFileIds' : IDL.Func(
327
- [PackageName, PackageVersion],
337
+ [PackageName, PackageVersion__1],
328
338
  [Result_7],
329
339
  ['query'],
330
340
  ),
331
341
  'getHighestSemverBatch' : IDL.Func(
332
- [IDL.Vec(IDL.Tuple(PackageName, PackageVersion, SemverPart))],
342
+ [IDL.Vec(IDL.Tuple(PackageName, PackageVersion__1, SemverPart))],
333
343
  [Result_6],
334
344
  ['query'],
335
345
  ),
@@ -346,7 +356,7 @@ export const idlFactory = ({ IDL }) => {
346
356
  ),
347
357
  'getNewPackages' : IDL.Func([], [IDL.Vec(PackageSummary)], ['query']),
348
358
  'getPackageDetails' : IDL.Func(
349
- [PackageName, PackageVersion],
359
+ [PackageName, PackageVersion__1],
350
360
  [Result_4],
351
361
  ['query'],
352
362
  ),
@@ -369,9 +379,13 @@ export const idlFactory = ({ IDL }) => {
369
379
  'getTotalPackages' : IDL.Func([], [IDL.Nat], ['query']),
370
380
  'getUser' : IDL.Func([IDL.Principal], [IDL.Opt(User__1)], ['query']),
371
381
  'http_request' : IDL.Func([Request], [Response], ['query']),
372
- 'notifyInstall' : IDL.Func([PackageName, PackageVersion], [], ['oneway']),
382
+ 'notifyInstall' : IDL.Func(
383
+ [PackageName, PackageVersion__1],
384
+ [],
385
+ ['oneway'],
386
+ ),
373
387
  'notifyInstalls' : IDL.Func(
374
- [IDL.Vec(IDL.Tuple(PackageName, PackageVersion))],
388
+ [IDL.Vec(IDL.Tuple(PackageName, PackageVersion__1))],
375
389
  [],
376
390
  ['oneway'],
377
391
  ),
@@ -1 +1 @@
1
- export declare function getMocPath(): string;
1
+ export declare function getMocPath(throwIfNotFound?: boolean): string;
@@ -1,12 +1,26 @@
1
1
  import process from 'node:process';
2
- import { execSync } from 'node:child_process';
3
- export function getMocPath() {
2
+ import { execFileSync } from 'node:child_process';
3
+ export function getMocPath(throwIfNotFound = false) {
4
4
  let mocPath = process.env.DFX_MOC_PATH;
5
5
  if (!mocPath) {
6
- mocPath = execSync('dfx cache show').toString().trim() + '/moc';
6
+ try {
7
+ mocPath = execFileSync('dfx', ['cache', 'show']).toString().trim() + '/moc';
8
+ }
9
+ catch (e) {
10
+ mocPath = '';
11
+ }
7
12
  }
8
13
  if (!mocPath) {
9
14
  mocPath = 'moc';
10
15
  }
16
+ if (throwIfNotFound) {
17
+ try {
18
+ execFileSync(mocPath, ['--version']);
19
+ }
20
+ catch (e) {
21
+ console.error(e);
22
+ throw new Error('moc not found');
23
+ }
24
+ }
11
25
  return mocPath;
12
26
  }
@@ -1 +1 @@
1
- export declare function getMocVersion(): string;
1
+ export declare function getMocVersion(throwOnError?: boolean): string;
@@ -1,7 +1,19 @@
1
- import { execSync } from 'node:child_process';
1
+ import { execFileSync } from 'node:child_process';
2
2
  import { getMocPath } from './get-moc-path.js';
3
- export function getMocVersion() {
4
- let mocPath = getMocPath();
5
- let match = execSync(mocPath).toString().trim().match(/Motoko compiler ([^\s]+) .*/);
6
- return match?.[1] || '';
3
+ export function getMocVersion(throwOnError = false) {
4
+ let mocPath = getMocPath(false);
5
+ if (!mocPath) {
6
+ return '';
7
+ }
8
+ try {
9
+ let match = execFileSync(mocPath, ['--version']).toString().trim().match(/Motoko compiler ([^\s]+) .*/);
10
+ return match?.[1] || '';
11
+ }
12
+ catch (e) {
13
+ if (throwOnError) {
14
+ console.error(e);
15
+ throw new Error('moc not found');
16
+ }
17
+ return '';
18
+ }
7
19
  }
@@ -1,5 +1,25 @@
1
+ type LockFileV1 = {
2
+ version: 1;
3
+ mopsTomlHash: string;
4
+ hashes: Record<string, Record<string, string>>;
5
+ };
6
+ type LockFileV2 = {
7
+ version: 2;
8
+ mopsTomlDepsHash: string;
9
+ hashes: Record<string, Record<string, string>>;
10
+ };
11
+ type LockFileV3 = {
12
+ version: 3;
13
+ mopsTomlDepsHash: string;
14
+ hashes: Record<string, Record<string, string>>;
15
+ deps: Record<string, string>;
16
+ };
17
+ type LockFile = LockFileV1 | LockFileV2 | LockFileV3;
1
18
  export declare function checkIntegrity(lock?: 'check' | 'update' | 'ignore'): Promise<void>;
2
19
  export declare function getLocalFileHash(fileId: string): string;
3
20
  export declare function checkRemote(): Promise<void>;
21
+ export declare function readLockFile(): LockFile | null;
22
+ export declare function checkLockFileLight(): boolean;
4
23
  export declare function updateLockFile(): Promise<void>;
5
24
  export declare function checkLockFile(force?: boolean): Promise<void>;
25
+ export {};
package/dist/integrity.js CHANGED
@@ -78,21 +78,36 @@ export async function checkRemote() {
78
78
  }
79
79
  }
80
80
  }
81
- export async function updateLockFile() {
81
+ export function readLockFile() {
82
82
  let rootDir = getRootDir();
83
83
  let lockFile = path.join(rootDir, 'mops.lock');
84
- // if lock file exists and mops.toml hasn't changed, don't update it
85
84
  if (fs.existsSync(lockFile)) {
86
- let lockFileJson = JSON.parse(fs.readFileSync(lockFile).toString());
85
+ return JSON.parse(fs.readFileSync(lockFile).toString());
86
+ }
87
+ return null;
88
+ }
89
+ // check if lock file exists and integrity of mopsTomlDepsHash
90
+ export function checkLockFileLight() {
91
+ let existingLockFileJson = readLockFile();
92
+ if (existingLockFileJson) {
87
93
  let mopsTomlDepsHash = getMopsTomlDepsHash();
88
- if (mopsTomlDepsHash === lockFileJson.mopsTomlDepsHash) {
89
- return;
94
+ if (existingLockFileJson.version === 3 && mopsTomlDepsHash === existingLockFileJson.mopsTomlDepsHash) {
95
+ return true;
90
96
  }
91
97
  }
98
+ return false;
99
+ }
100
+ export async function updateLockFile() {
101
+ // if lock file exists and mops.toml hasn't changed, don't update it
102
+ if (checkLockFileLight()) {
103
+ return;
104
+ }
105
+ let resolvedDeps = await resolvePackages();
92
106
  let fileHashes = await getFileHashesFromRegistry();
93
107
  let lockFileJson = {
94
- version: 2,
108
+ version: 3,
95
109
  mopsTomlDepsHash: getMopsTomlDepsHash(),
110
+ deps: resolvedDeps,
96
111
  hashes: fileHashes.reduce((acc, [packageId, fileHashes]) => {
97
112
  acc[packageId] = fileHashes.reduce((acc, [fileId, hash]) => {
98
113
  acc[fileId] = bytesToHex(new Uint8Array(hash));
@@ -101,10 +116,13 @@ export async function updateLockFile() {
101
116
  return acc;
102
117
  }, {}),
103
118
  };
119
+ let rootDir = getRootDir();
120
+ let lockFile = path.join(rootDir, 'mops.lock');
104
121
  fs.writeFileSync(lockFile, JSON.stringify(lockFileJson, null, 2));
105
122
  }
106
123
  // compare hashes of local files with hashes from the lock file
107
124
  export async function checkLockFile(force = false) {
125
+ let supportedVersions = [1, 2, 3];
108
126
  let rootDir = getRootDir();
109
127
  let lockFile = path.join(rootDir, 'mops.lock');
110
128
  // check if lock file exists
@@ -118,9 +136,9 @@ export async function checkLockFile(force = false) {
118
136
  let lockFileJsonGeneric = JSON.parse(fs.readFileSync(lockFile).toString());
119
137
  let packageIds = await getResolvedMopsPackageIds();
120
138
  // check lock file version
121
- if (lockFileJsonGeneric.version !== 1 && lockFileJsonGeneric.version !== 2) {
139
+ if (!supportedVersions.includes(lockFileJsonGeneric.version)) {
122
140
  console.error('Integrity check failed');
123
- console.error(`Invalid lock file version: ${lockFileJsonGeneric.version}. Supported versions: 1`);
141
+ console.error(`Invalid lock file version: ${lockFileJsonGeneric.version}. Supported versions: ${supportedVersions.join(', ')}`);
124
142
  process.exit(1);
125
143
  }
126
144
  let lockFileJson = lockFileJsonGeneric;
@@ -134,8 +152,8 @@ export async function checkLockFile(force = false) {
134
152
  process.exit(1);
135
153
  }
136
154
  }
137
- // V2: check mops.toml deps hash
138
- if (lockFileJson.version === 2) {
155
+ // V2, V3: check mops.toml deps hash
156
+ if (lockFileJson.version === 2 || lockFileJson.version === 3) {
139
157
  if (lockFileJson.mopsTomlDepsHash !== getMopsTomlDepsHash()) {
140
158
  console.error('Integrity check failed');
141
159
  console.error('Mismatched mops.toml dependencies hash');
@@ -144,6 +162,20 @@ export async function checkLockFile(force = false) {
144
162
  process.exit(1);
145
163
  }
146
164
  }
165
+ // V3: check locked deps (including GitHub and local packages)
166
+ if (lockFileJson.version === 3) {
167
+ let lockedDeps = { ...lockFileJson.deps };
168
+ let resolvedDeps = await resolvePackages();
169
+ for (let name of Object.keys(resolvedDeps)) {
170
+ if (lockedDeps[name] !== resolvedDeps[name]) {
171
+ console.error('Integrity check failed');
172
+ console.error(`Mismatched package ${name}`);
173
+ console.error(`Locked: ${lockedDeps[name]}`);
174
+ console.error(`Actual: ${resolvedDeps[name]}`);
175
+ process.exit(1);
176
+ }
177
+ }
178
+ }
147
179
  // check number of packages
148
180
  if (Object.keys(lockFileJson.hashes).length !== packageIds.length) {
149
181
  console.error('Integrity check failed');
package/dist/mops.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Identity } from '@dfinity/agent';
2
- import { Config } from './types.js';
2
+ import { Config, Dependency } from './types.js';
3
3
  import { mainActor, storageActor } from './api/actors.js';
4
4
  import { getNetwork } from './api/network.js';
5
5
  import { getHighestVersion } from './api/getHighestVersion.js';
@@ -21,6 +21,7 @@ export declare function parseGithubURL(href: string): {
21
21
  };
22
22
  export declare function getGithubCommit(repo: string, ref: string): Promise<any>;
23
23
  export declare function getDependencyType(version: string): "local" | "mops" | "github";
24
+ export declare function parseDepValue(name: string, value: string): Dependency;
24
25
  export declare function readConfig(configFile?: string): Config;
25
26
  export declare function writeConfig(config: Config, configFile?: string): void;
26
27
  export declare function formatDir(name: string, version: string): string;
package/dist/mops.js CHANGED
@@ -135,6 +135,18 @@ export function getDependencyType(version) {
135
135
  return 'mops';
136
136
  }
137
137
  }
138
+ export function parseDepValue(name, value) {
139
+ let depType = getDependencyType(value);
140
+ if (depType === 'github') {
141
+ return { name, repo: value, version: '' };
142
+ }
143
+ else if (depType === 'local') {
144
+ return { name, repo: '', path: value, version: '' };
145
+ }
146
+ else {
147
+ return { name, repo: '', version: value };
148
+ }
149
+ }
138
150
  export function readConfig(configFile = getClosestConfigFile()) {
139
151
  let text = fs.readFileSync(configFile).toString();
140
152
  let toml = TOML.parse(text);
@@ -143,16 +155,7 @@ export function readConfig(configFile = getClosestConfigFile()) {
143
155
  if (!data || typeof data !== 'string') {
144
156
  throw Error(`Invalid dependency value ${name} = "${data}"`);
145
157
  }
146
- let depType = getDependencyType(data);
147
- if (depType === 'github') {
148
- deps[name] = { name, repo: data, version: '' };
149
- }
150
- else if (depType === 'local') {
151
- deps[name] = { name, repo: '', path: data, version: '' };
152
- }
153
- else {
154
- deps[name] = { name, repo: '', version: data };
155
- }
158
+ deps[name] = parseDepValue(name, data);
156
159
  });
157
160
  };
158
161
  processDeps(toml.dependencies || {});
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "bin/mops.js",
@@ -64,6 +64,7 @@
64
64
  "octokit": "3.1.2",
65
65
  "pem-file": "1.0.1",
66
66
  "pic-ic": "0.5.3",
67
+ "promisify-child-process": "4.1.2",
67
68
  "prompts": "2.4.2",
68
69
  "semver": "7.6.3",
69
70
  "stream-to-promise": "3.0.0",
@@ -77,7 +78,7 @@
77
78
  "@types/fs-extra": "11.0.4",
78
79
  "@types/glob": "8.1.0",
79
80
  "@types/ncp": "2.0.8",
80
- "@types/node": "22.5.4",
81
+ "@types/node": "22.7.4",
81
82
  "@types/prompts": "2.4.9",
82
83
  "@types/semver": "7.5.8",
83
84
  "@types/stream-to-promise": "2.2.4",
@@ -1 +1 @@
1
- export declare function parallel(threads: number, items: any[], fn: CallableFunction): Promise<void>;
1
+ export declare function parallel<T>(threads: number, items: T[], fn: (item: T) => Promise<void>): Promise<void>;
@@ -5,10 +5,17 @@ import { checkConfigFile, getRootDir, parseGithubURL, readConfig } from './mops.
5
5
  import { readVesselConfig } from './vessel.js';
6
6
  import { getDepCacheDir, getDepCacheName } from './cache.js';
7
7
  import { getPackageId } from './helpers/get-package-id.js';
8
+ import { checkLockFileLight, readLockFile } from './integrity.js';
8
9
  export async function resolvePackages({ conflicts = 'ignore' } = {}) {
9
10
  if (!checkConfigFile()) {
10
11
  return {};
11
12
  }
13
+ if (checkLockFileLight()) {
14
+ let lockFileJson = readLockFile();
15
+ if (lockFileJson && lockFileJson.version === 3) {
16
+ return lockFileJson.deps;
17
+ }
18
+ }
12
19
  let rootDir = getRootDir();
13
20
  let packages = {};
14
21
  let versions = {};
@@ -14,9 +14,11 @@ jobs:
14
14
  steps:
15
15
  - uses: actions/checkout@v4
16
16
  - uses: ZenVoich/setup-mops@v1
17
+ with:
18
+ mops-version: 1
17
19
 
18
- - name: make sure moc is installed
19
- run: mops toolchain bin moc || mops toolchain use moc latest
20
+ - name: install mops packages
21
+ run: mops install
20
22
 
21
23
  - name: run tests
22
24
  run: mops test
package/dist/vessel.d.ts CHANGED
@@ -13,8 +13,9 @@ export declare const readVesselConfig: (dir: string, { cache, silent }?: {
13
13
  silent?: boolean | undefined;
14
14
  }) => Promise<VesselConfig | null>;
15
15
  export declare const downloadFromGithub: (repo: string, dest: string, onProgress: any) => Promise<unknown>;
16
- export declare const installFromGithub: (name: string, repo: string, { verbose, dep, silent }?: {
16
+ export declare const installFromGithub: (name: string, repo: string, { verbose, dep, silent, ignoreTransitive }?: {
17
17
  verbose?: boolean | undefined;
18
18
  dep?: boolean | undefined;
19
19
  silent?: boolean | undefined;
20
+ ignoreTransitive?: boolean | undefined;
20
21
  }) => Promise<void>;
package/dist/vessel.js CHANGED
@@ -116,7 +116,7 @@ export const downloadFromGithub = async (repo, dest, onProgress) => {
116
116
  });
117
117
  return promise;
118
118
  };
119
- export const installFromGithub = async (name, repo, { verbose = false, dep = false, silent = false } = {}) => {
119
+ export const installFromGithub = async (name, repo, { verbose = false, dep = false, silent = false, ignoreTransitive = false } = {}) => {
120
120
  let cacheName = getGithubDepCacheName(name, repo);
121
121
  let cacheDir = getDepCacheDir(cacheName);
122
122
  let logUpdate = createLogUpdate(process.stdout, { showCursor: true });
@@ -143,6 +143,9 @@ export const installFromGithub = async (name, repo, { verbose = false, dep = fal
143
143
  else {
144
144
  logUpdate.clear();
145
145
  }
146
+ if (ignoreTransitive) {
147
+ return;
148
+ }
146
149
  const config = await readVesselConfig(cacheDir, { silent });
147
150
  if (config) {
148
151
  for (const { name, repo } of config.dependencies) {
@@ -1,13 +1,29 @@
1
1
  import process from 'node:process';
2
- import {execSync} from 'node:child_process';
2
+ import {execFileSync} from 'node:child_process';
3
3
 
4
- export function getMocPath() : string {
4
+ export function getMocPath(throwIfNotFound = false) : string {
5
5
  let mocPath = process.env.DFX_MOC_PATH;
6
6
  if (!mocPath) {
7
- mocPath = execSync('dfx cache show').toString().trim() + '/moc';
7
+ try {
8
+ mocPath = execFileSync('dfx', ['cache', 'show']).toString().trim() + '/moc';
9
+ }
10
+ catch (e) {
11
+ mocPath = '';
12
+ }
8
13
  }
9
14
  if (!mocPath) {
10
15
  mocPath = 'moc';
11
16
  }
17
+
18
+ if (throwIfNotFound) {
19
+ try {
20
+ execFileSync(mocPath, ['--version']);
21
+ }
22
+ catch (e) {
23
+ console.error(e);
24
+ throw new Error('moc not found');
25
+ }
26
+ }
27
+
12
28
  return mocPath;
13
29
  }
@@ -1,8 +1,20 @@
1
- import {execSync} from 'node:child_process';
1
+ import {execFileSync} from 'node:child_process';
2
2
  import {getMocPath} from './get-moc-path.js';
3
3
 
4
- export function getMocVersion() : string {
5
- let mocPath = getMocPath();
6
- let match = execSync(mocPath).toString().trim().match(/Motoko compiler ([^\s]+) .*/);
7
- return match?.[1] || '';
4
+ export function getMocVersion(throwOnError = false) : string {
5
+ let mocPath = getMocPath(false);
6
+ if (!mocPath) {
7
+ return '';
8
+ }
9
+ try {
10
+ let match = execFileSync(mocPath, ['--version']).toString().trim().match(/Motoko compiler ([^\s]+) .*/);
11
+ return match?.[1] || '';
12
+ }
13
+ catch (e) {
14
+ if (throwOnError) {
15
+ console.error(e);
16
+ throw new Error('moc not found');
17
+ }
18
+ return '';
19
+ }
8
20
  }