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
package/integrity.ts CHANGED
@@ -24,7 +24,14 @@ type LockFileV2 = {
24
24
  hashes : Record<string, Record<string, string>>;
25
25
  };
26
26
 
27
- type LockFile = LockFileV1 | LockFileV2;
27
+ type LockFileV3 = {
28
+ version : 3;
29
+ mopsTomlDepsHash : string;
30
+ hashes : Record<string, Record<string, string>>;
31
+ deps : Record<string, string>;
32
+ };
33
+
34
+ type LockFile = LockFileV1 | LockFileV2 | LockFileV3;
28
35
 
29
36
  export async function checkIntegrity(lock ?: 'check' | 'update' | 'ignore') {
30
37
  let force = !!lock;
@@ -109,24 +116,41 @@ export async function checkRemote() {
109
116
  }
110
117
  }
111
118
 
112
- export async function updateLockFile() {
119
+ export function readLockFile() : LockFile | null {
113
120
  let rootDir = getRootDir();
114
121
  let lockFile = path.join(rootDir, 'mops.lock');
115
-
116
- // if lock file exists and mops.toml hasn't changed, don't update it
117
122
  if (fs.existsSync(lockFile)) {
118
- let lockFileJson : LockFileV2 = JSON.parse(fs.readFileSync(lockFile).toString());
123
+ return JSON.parse(fs.readFileSync(lockFile).toString()) as LockFile;
124
+ }
125
+ return null;
126
+ }
127
+
128
+ // check if lock file exists and integrity of mopsTomlDepsHash
129
+ export function checkLockFileLight() : boolean {
130
+ let existingLockFileJson = readLockFile();
131
+ if (existingLockFileJson) {
119
132
  let mopsTomlDepsHash = getMopsTomlDepsHash();
120
- if (mopsTomlDepsHash === lockFileJson.mopsTomlDepsHash) {
121
- return;
133
+ if (existingLockFileJson.version === 3 && mopsTomlDepsHash === existingLockFileJson.mopsTomlDepsHash) {
134
+ return true;
122
135
  }
123
136
  }
137
+ return false;
138
+ }
139
+
140
+ export async function updateLockFile() {
141
+ // if lock file exists and mops.toml hasn't changed, don't update it
142
+ if (checkLockFileLight()) {
143
+ return;
144
+ }
145
+
146
+ let resolvedDeps = await resolvePackages();
124
147
 
125
148
  let fileHashes = await getFileHashesFromRegistry();
126
149
 
127
- let lockFileJson : LockFileV2 = {
128
- version: 2,
150
+ let lockFileJson : LockFileV3 = {
151
+ version: 3,
129
152
  mopsTomlDepsHash: getMopsTomlDepsHash(),
153
+ deps: resolvedDeps,
130
154
  hashes: fileHashes.reduce((acc, [packageId, fileHashes]) => {
131
155
  acc[packageId] = fileHashes.reduce((acc, [fileId, hash]) => {
132
156
  acc[fileId] = bytesToHex(new Uint8Array(hash));
@@ -136,11 +160,14 @@ export async function updateLockFile() {
136
160
  }, {} as Record<string, Record<string, string>>),
137
161
  };
138
162
 
163
+ let rootDir = getRootDir();
164
+ let lockFile = path.join(rootDir, 'mops.lock');
139
165
  fs.writeFileSync(lockFile, JSON.stringify(lockFileJson, null, 2));
140
166
  }
141
167
 
142
168
  // compare hashes of local files with hashes from the lock file
143
169
  export async function checkLockFile(force = false) {
170
+ let supportedVersions = [1, 2, 3];
144
171
  let rootDir = getRootDir();
145
172
  let lockFile = path.join(rootDir, 'mops.lock');
146
173
 
@@ -157,9 +184,9 @@ export async function checkLockFile(force = false) {
157
184
  let packageIds = await getResolvedMopsPackageIds();
158
185
 
159
186
  // check lock file version
160
- if (lockFileJsonGeneric.version !== 1 && lockFileJsonGeneric.version !== 2) {
187
+ if (!supportedVersions.includes(lockFileJsonGeneric.version)) {
161
188
  console.error('Integrity check failed');
162
- console.error(`Invalid lock file version: ${lockFileJsonGeneric.version}. Supported versions: 1`);
189
+ console.error(`Invalid lock file version: ${lockFileJsonGeneric.version}. Supported versions: ${supportedVersions.join(', ')}`);
163
190
  process.exit(1);
164
191
  }
165
192
 
@@ -176,8 +203,8 @@ export async function checkLockFile(force = false) {
176
203
  }
177
204
  }
178
205
 
179
- // V2: check mops.toml deps hash
180
- if (lockFileJson.version === 2) {
206
+ // V2, V3: check mops.toml deps hash
207
+ if (lockFileJson.version === 2 || lockFileJson.version === 3) {
181
208
  if (lockFileJson.mopsTomlDepsHash !== getMopsTomlDepsHash()) {
182
209
  console.error('Integrity check failed');
183
210
  console.error('Mismatched mops.toml dependencies hash');
@@ -187,6 +214,22 @@ export async function checkLockFile(force = false) {
187
214
  }
188
215
  }
189
216
 
217
+ // V3: check locked deps (including GitHub and local packages)
218
+ if (lockFileJson.version === 3) {
219
+ let lockedDeps = {...lockFileJson.deps};
220
+ let resolvedDeps = await resolvePackages();
221
+
222
+ for (let name of Object.keys(resolvedDeps)) {
223
+ if (lockedDeps[name] !== resolvedDeps[name]) {
224
+ console.error('Integrity check failed');
225
+ console.error(`Mismatched package ${name}`);
226
+ console.error(`Locked: ${lockedDeps[name]}`);
227
+ console.error(`Actual: ${resolvedDeps[name]}`);
228
+ process.exit(1);
229
+ }
230
+ }
231
+ }
232
+
190
233
  // check number of packages
191
234
  if (Object.keys(lockFileJson.hashes).length !== packageIds.length) {
192
235
  console.error('Integrity check failed');
package/mops.ts CHANGED
@@ -8,7 +8,7 @@ import prompts from 'prompts';
8
8
  import fetch from 'node-fetch';
9
9
 
10
10
  import {decodeFile} from './pem.js';
11
- import {Config} from './types.js';
11
+ import {Config, Dependency} from './types.js';
12
12
  import {mainActor, storageActor} from './api/actors.js';
13
13
  import {getNetwork} from './api/network.js';
14
14
  import {getHighestVersion} from './api/getHighestVersion.js';
@@ -156,6 +156,19 @@ export function getDependencyType(version : string) {
156
156
  }
157
157
  }
158
158
 
159
+ export function parseDepValue(name : string, value : string) : Dependency {
160
+ let depType = getDependencyType(value);
161
+ if (depType === 'github') {
162
+ return {name, repo: value, version: ''};
163
+ }
164
+ else if (depType === 'local') {
165
+ return {name, repo: '', path: value, version: ''};
166
+ }
167
+ else {
168
+ return {name, repo: '', version: value};
169
+ }
170
+ }
171
+
159
172
  export function readConfig(configFile = getClosestConfigFile()) : Config {
160
173
  let text = fs.readFileSync(configFile).toString();
161
174
  let toml = TOML.parse(text);
@@ -165,16 +178,7 @@ export function readConfig(configFile = getClosestConfigFile()) : Config {
165
178
  if (!data || typeof data !== 'string') {
166
179
  throw Error(`Invalid dependency value ${name} = "${data}"`);
167
180
  }
168
- let depType = getDependencyType(data);
169
- if (depType === 'github') {
170
- deps[name] = {name, repo: data, version: ''};
171
- }
172
- else if (depType === 'local') {
173
- deps[name] = {name, repo: '', path: data, version: ''};
174
- }
175
- else {
176
- deps[name] = {name, repo: '', version: data};
177
- }
181
+ deps[name] = parseDepValue(name, data);
178
182
  });
179
183
  };
180
184
 
package/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": "dist/bin/mops.js",
@@ -80,6 +80,7 @@
80
80
  "octokit": "3.1.2",
81
81
  "pem-file": "1.0.1",
82
82
  "pic-ic": "0.5.3",
83
+ "promisify-child-process": "4.1.2",
83
84
  "prompts": "2.4.2",
84
85
  "semver": "7.6.3",
85
86
  "stream-to-promise": "3.0.0",
@@ -93,7 +94,7 @@
93
94
  "@types/fs-extra": "11.0.4",
94
95
  "@types/glob": "8.1.0",
95
96
  "@types/ncp": "2.0.8",
96
- "@types/node": "22.5.4",
97
+ "@types/node": "22.7.4",
97
98
  "@types/prompts": "2.4.9",
98
99
  "@types/semver": "7.5.8",
99
100
  "@types/stream-to-promise": "2.2.4",
package/parallel.ts CHANGED
@@ -1,4 +1,4 @@
1
- export async function parallel(threads : number, items : any[], fn : CallableFunction) {
1
+ export async function parallel<T>(threads : number, items : T[], fn : (item : T) => Promise<void>) {
2
2
  return new Promise<void>((resolve) => {
3
3
  let busyThreads = 0;
4
4
  items = items.slice();
@@ -14,7 +14,7 @@ export async function parallel(threads : number, items : any[], fn : CallableFun
14
14
  return;
15
15
  }
16
16
  busyThreads++;
17
- fn(items.shift()).then(() => {
17
+ fn(items.shift() as T).then(() => {
18
18
  busyThreads--;
19
19
  loop();
20
20
  });
@@ -6,12 +6,21 @@ import {VesselConfig, readVesselConfig} from './vessel.js';
6
6
  import {Config, Dependency} from './types.js';
7
7
  import {getDepCacheDir, getDepCacheName} from './cache.js';
8
8
  import {getPackageId} from './helpers/get-package-id.js';
9
+ import {checkLockFileLight, readLockFile} from './integrity.js';
9
10
 
10
11
  export async function resolvePackages({conflicts = 'ignore' as 'warning' | 'error' | 'ignore'} = {}) : Promise<Record<string, string>> {
11
12
  if (!checkConfigFile()) {
12
13
  return {};
13
14
  }
14
15
 
16
+ if (checkLockFileLight()) {
17
+ let lockFileJson = readLockFile();
18
+
19
+ if (lockFileJson && lockFileJson.version === 3) {
20
+ return lockFileJson.deps;
21
+ }
22
+ }
23
+
15
24
  let rootDir = getRootDir();
16
25
  let packages : Record<string, Dependency & {isRoot : boolean;}> = {};
17
26
  let versions : Record<string, Array<{
@@ -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/vessel.ts CHANGED
@@ -149,7 +149,7 @@ export const downloadFromGithub = async (repo : string, dest : string, onProgres
149
149
  return promise;
150
150
  };
151
151
 
152
- export const installFromGithub = async (name : string, repo : string, {verbose = false, dep = false, silent = false} = {}) => {
152
+ export const installFromGithub = async (name : string, repo : string, {verbose = false, dep = false, silent = false, ignoreTransitive = false} = {}) => {
153
153
  let cacheName = getGithubDepCacheName(name, repo);
154
154
  let cacheDir = getDepCacheDir(cacheName);
155
155
 
@@ -183,6 +183,10 @@ export const installFromGithub = async (name : string, repo : string, {verbose =
183
183
  logUpdate.clear();
184
184
  }
185
185
 
186
+ if (ignoreTransitive) {
187
+ return;
188
+ }
189
+
186
190
  const config = await readVesselConfig(cacheDir, {silent});
187
191
 
188
192
  if (config) {