ic-mops 2.9.0 → 2.11.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 (61) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/bundle/cli.tgz +0 -0
  3. package/cli.ts +34 -10
  4. package/commands/build.ts +16 -22
  5. package/commands/check-stable.ts +141 -17
  6. package/commands/check.ts +195 -101
  7. package/commands/migrate.ts +165 -0
  8. package/declarations/main/main.did +38 -0
  9. package/declarations/main/main.did.d.ts +36 -0
  10. package/declarations/main/main.did.js +36 -0
  11. package/dist/cli.js +28 -10
  12. package/dist/commands/build.js +7 -13
  13. package/dist/commands/check-stable.d.ts +8 -1
  14. package/dist/commands/check-stable.js +101 -19
  15. package/dist/commands/check.d.ts +1 -1
  16. package/dist/commands/check.js +136 -78
  17. package/dist/commands/migrate.d.ts +2 -0
  18. package/dist/commands/migrate.js +104 -0
  19. package/dist/declarations/main/main.did +38 -0
  20. package/dist/declarations/main/main.did.d.ts +36 -0
  21. package/dist/declarations/main/main.did.js +36 -0
  22. package/dist/helpers/migrations.d.ts +10 -0
  23. package/dist/helpers/migrations.js +109 -0
  24. package/dist/helpers/resolve-canisters.d.ts +3 -1
  25. package/dist/helpers/resolve-canisters.js +34 -5
  26. package/dist/package.json +1 -1
  27. package/dist/tests/check-stable.test.js +18 -0
  28. package/dist/tests/check.test.js +23 -5
  29. package/dist/tests/migrate.test.d.ts +1 -0
  30. package/dist/tests/migrate.test.js +160 -0
  31. package/dist/types.d.ts +7 -0
  32. package/helpers/migrations.ts +166 -0
  33. package/helpers/resolve-canisters.ts +53 -5
  34. package/package.json +1 -1
  35. package/tests/__snapshots__/check.test.ts.snap +2 -2
  36. package/tests/__snapshots__/migrate.test.ts.snap +119 -0
  37. package/tests/check/canisters-canister-args/Warning.mo +5 -0
  38. package/tests/check/canisters-canister-args/mops.toml +9 -0
  39. package/tests/check-stable/canister-args/migrations/20250101_000000_Init.mo +8 -0
  40. package/tests/check-stable/canister-args/migrations/20250201_000000_AddField.mo +9 -0
  41. package/tests/check-stable/canister-args/mops.toml +9 -0
  42. package/tests/check-stable/canister-args/old.most +8 -0
  43. package/tests/check-stable/canister-args/src/main.mo +11 -0
  44. package/tests/check-stable.test.ts +21 -0
  45. package/tests/check.test.ts +26 -5
  46. package/tests/migrate/basic/deployed.most +12 -0
  47. package/tests/migrate/basic/migrations/20250101_000000_Init.mo +5 -0
  48. package/tests/migrate/basic/migrations/20250201_000000_AddName.mo +5 -0
  49. package/tests/migrate/basic/migrations/20250301_000000_AddEmail.mo +9 -0
  50. package/tests/migrate/basic/mops.toml +15 -0
  51. package/tests/migrate/basic/next-migration/.gitkeep +0 -0
  52. package/tests/migrate/basic/src/main.mo +11 -0
  53. package/tests/migrate/with-next/deployed.most +12 -0
  54. package/tests/migrate/with-next/migrations/20250101_000000_Init.mo +5 -0
  55. package/tests/migrate/with-next/migrations/20250201_000000_AddName.mo +5 -0
  56. package/tests/migrate/with-next/migrations/20250301_000000_AddEmail.mo +9 -0
  57. package/tests/migrate/with-next/mops.toml +15 -0
  58. package/tests/migrate/with-next/next-migration/20250401_000000_RenameId.mo +9 -0
  59. package/tests/migrate/with-next/src/main.mo +11 -0
  60. package/tests/migrate.test.ts +228 -0
  61. package/types.ts +8 -0
package/commands/check.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import path from "node:path";
2
- import { existsSync } from "node:fs";
3
2
  import chalk from "chalk";
4
3
  import { execa } from "execa";
5
4
  import { cliError } from "../error.js";
@@ -9,13 +8,17 @@ import {
9
8
  readConfig,
10
9
  resolveConfigPath,
11
10
  } from "../mops.js";
12
- import { autofixMotoko } from "../helpers/autofix-motoko.js";
11
+ import { AutofixResult, autofixMotoko } from "../helpers/autofix-motoko.js";
13
12
  import { getMocSemVer } from "../helpers/get-moc-version.js";
14
13
  import {
14
+ filterCanisters,
15
+ looksLikeFile,
15
16
  resolveCanisterConfigs,
16
- resolveCanisterEntrypoints,
17
+ validateCanisterArgs,
17
18
  } from "../helpers/resolve-canisters.js";
18
- import { runStableCheck } from "./check-stable.js";
19
+ import { prepareMigrationArgs } from "../helpers/migrations.js";
20
+ import { CanisterConfig, Config } from "../types.js";
21
+ import { resolveStablePath, runStableCheck } from "./check-stable.js";
19
22
  import { sourcesArgs } from "./sources.js";
20
23
  import { toolchain } from "./toolchain/index.js";
21
24
  import { collectLintRules, lint } from "./lint.js";
@@ -33,52 +36,209 @@ export interface CheckOptions {
33
36
  extraArgs: string[];
34
37
  }
35
38
 
39
+ function checkAllLibsSupport(verbose?: boolean): boolean {
40
+ const allLibs = supportsAllLibsFlag();
41
+ if (!allLibs) {
42
+ console.log(
43
+ chalk.yellow(
44
+ `moc < ${MOC_ALL_LIBS_MIN_VERSION}: some diagnostic hints may be missing`,
45
+ ),
46
+ );
47
+ } else if (verbose) {
48
+ console.log(
49
+ chalk.blue("check"),
50
+ chalk.gray("Using --all-libs for richer diagnostics"),
51
+ );
52
+ }
53
+ return allLibs;
54
+ }
55
+
56
+ function logAutofixResult(
57
+ fixResult: AutofixResult | null,
58
+ verbose?: boolean,
59
+ ): void {
60
+ if (fixResult) {
61
+ for (const [file, codes] of fixResult.fixedFiles) {
62
+ const unique = [...new Set(codes)].sort();
63
+ const n = codes.length;
64
+ const rel = path.relative(process.cwd(), file);
65
+ console.log(
66
+ chalk.green(
67
+ `Fixed ${rel} (${n} ${n === 1 ? "fix" : "fixes"}: ${unique.join(", ")})`,
68
+ ),
69
+ );
70
+ }
71
+ const fileCount = fixResult.fixedFiles.size;
72
+ console.log(
73
+ chalk.green(
74
+ `\n✓ ${fixResult.totalFixCount} ${fixResult.totalFixCount === 1 ? "fix" : "fixes"} applied to ${fileCount} ${fileCount === 1 ? "file" : "files"}`,
75
+ ),
76
+ );
77
+ } else if (verbose) {
78
+ console.log(chalk.yellow("No fixes were needed"));
79
+ }
80
+ }
81
+
36
82
  export async function check(
37
- files: string | string[],
83
+ args: string[],
38
84
  options: Partial<CheckOptions> = {},
39
85
  ): Promise<void> {
40
- const explicitFiles = Array.isArray(files) ? files : files ? [files] : [];
41
- let fileList = [...explicitFiles];
42
-
43
86
  const config = readConfig();
87
+ const canisters = resolveCanisterConfigs(config);
88
+ const hasCanisters = Object.keys(canisters).length > 0;
89
+ const fileArgs = args.filter(looksLikeFile);
90
+ const nonFileArgs = args.filter((a) => !looksLikeFile(a));
91
+ const isFileMode = fileArgs.length > 0;
44
92
 
45
- if (fileList.length === 0) {
46
- fileList = resolveCanisterEntrypoints(config).map(resolveConfigPath);
47
- }
48
-
49
- if (fileList.length === 0) {
93
+ if (isFileMode && nonFileArgs.length > 0) {
50
94
  cliError(
51
- "No Motoko files specified and no canisters defined in mops.toml.\n" +
52
- "Either pass files: mops check <files...>\n" +
53
- "Or define canisters in mops.toml:\n\n" +
54
- " [canisters.backend]\n" +
55
- ' main = "src/main.mo"',
95
+ `Cannot mix file paths and canister names: ${args.join(", ")}\n` +
96
+ "Pass either file paths (e.g. mops check src/main.mo) or canister names (e.g. mops check backend)",
56
97
  );
57
98
  }
99
+
100
+ if (isFileMode) {
101
+ await checkFiles(config, fileArgs, options);
102
+ } else {
103
+ if (!hasCanisters) {
104
+ cliError(
105
+ "No canisters defined in mops.toml.\n" +
106
+ "Either pass files: mops check <files...>\n" +
107
+ "Or define canisters in mops.toml:\n\n" +
108
+ " [canisters.backend]\n" +
109
+ ' main = "src/main.mo"',
110
+ );
111
+ }
112
+
113
+ const canisterNames = args.length > 0 ? args : undefined;
114
+ const filtered = filterCanisters(canisters, canisterNames);
115
+ await checkCanisters(config, filtered, options);
116
+ }
117
+
118
+ if (config.toolchain?.lintoko) {
119
+ const rootDir = getRootDir();
120
+ const lintRules = await collectLintRules(config, rootDir);
121
+ const lintFiles = isFileMode ? fileArgs : undefined;
122
+ await lint(undefined, {
123
+ verbose: options.verbose,
124
+ fix: options.fix,
125
+ rules: lintRules,
126
+ files: lintFiles,
127
+ });
128
+ }
129
+ }
130
+
131
+ async function checkCanisters(
132
+ config: Config,
133
+ canisters: Record<string, CanisterConfig>,
134
+ options: Partial<CheckOptions>,
135
+ ): Promise<void> {
58
136
  const mocPath = await toolchain.bin("moc", { fallback: true });
59
- const sources = await sourcesArgs();
137
+ const sources = (await sourcesArgs()).flat();
60
138
  const globalMocArgs = getGlobalMocArgs(config);
139
+ const allLibs = checkAllLibsSupport(options.verbose);
61
140
 
62
- // --all-libs enables richer diagnostics with edit suggestions from moc (requires moc >= 1.3.0)
63
- const allLibs = supportsAllLibsFlag();
141
+ for (const [canisterName, canister] of Object.entries(canisters)) {
142
+ if (!canister.main) {
143
+ cliError(
144
+ `No main file specified for canister '${canisterName}' in mops.toml`,
145
+ );
146
+ }
64
147
 
65
- if (!allLibs) {
66
- console.log(
67
- chalk.yellow(
68
- `moc < ${MOC_ALL_LIBS_MIN_VERSION}: some diagnostic hints may be missing`,
69
- ),
70
- );
71
- } else if (options.verbose) {
72
- console.log(
73
- chalk.blue("check"),
74
- chalk.gray("Using --all-libs for richer diagnostics"),
148
+ validateCanisterArgs(canister, canisterName, config);
149
+ const motokoPath = resolveConfigPath(canister.main);
150
+
151
+ const migration = await prepareMigrationArgs(
152
+ canister.migrations,
153
+ canisterName,
154
+ "check",
155
+ options.verbose,
75
156
  );
157
+ try {
158
+ const mocArgs = [
159
+ "--check",
160
+ ...(allLibs ? ["--all-libs"] : []),
161
+ ...sources,
162
+ ...globalMocArgs,
163
+ ...migration.migrationArgs,
164
+ ...(canister.args ?? []),
165
+ ...(options.extraArgs ?? []),
166
+ ];
167
+
168
+ if (options.fix) {
169
+ if (options.verbose) {
170
+ console.log(
171
+ chalk.blue("check"),
172
+ chalk.gray(`Attempting to fix ${canisterName}`),
173
+ );
174
+ }
175
+
176
+ const fixResult = await autofixMotoko(mocPath, [motokoPath], mocArgs);
177
+ logAutofixResult(fixResult, options.verbose);
178
+ }
179
+
180
+ try {
181
+ const args = [motokoPath, ...mocArgs];
182
+ if (options.verbose) {
183
+ console.log(
184
+ chalk.blue("check"),
185
+ chalk.gray(`Checking canister ${canisterName}:`),
186
+ );
187
+ console.log(chalk.gray(mocPath, JSON.stringify(args)));
188
+ }
189
+
190
+ const result = await execa(mocPath, args, {
191
+ stdio: "inherit",
192
+ reject: false,
193
+ });
194
+
195
+ if (result.exitCode !== 0) {
196
+ cliError(
197
+ `✗ Check failed for canister ${canisterName} (exit code: ${result.exitCode})`,
198
+ );
199
+ }
200
+
201
+ console.log(chalk.green(`✓ ${canisterName}`));
202
+ } catch (err: any) {
203
+ cliError(
204
+ `Error while checking canister ${canisterName}${err?.message ? `\n${err.message}` : ""}`,
205
+ );
206
+ }
207
+
208
+ const stablePath = resolveStablePath(canister, canisterName);
209
+ if (stablePath) {
210
+ await runStableCheck({
211
+ oldFile: stablePath,
212
+ canisterMain: motokoPath,
213
+ canisterName,
214
+ mocPath,
215
+ globalMocArgs,
216
+ canisterArgs: [...migration.migrationArgs, ...(canister.args ?? [])],
217
+ sources,
218
+ options: { verbose: options.verbose, extraArgs: options.extraArgs },
219
+ hasMigrations: !!canister.migrations,
220
+ });
221
+ }
222
+ } finally {
223
+ await migration.cleanup();
224
+ }
76
225
  }
226
+ }
227
+
228
+ async function checkFiles(
229
+ config: Config,
230
+ files: string[],
231
+ options: Partial<CheckOptions>,
232
+ ): Promise<void> {
233
+ const mocPath = await toolchain.bin("moc", { fallback: true });
234
+ const sources = (await sourcesArgs()).flat();
235
+ const globalMocArgs = getGlobalMocArgs(config);
236
+ const allLibs = checkAllLibsSupport(options.verbose);
77
237
 
78
238
  const mocArgs = [
79
239
  "--check",
80
240
  ...(allLibs ? ["--all-libs"] : []),
81
- ...sources.flat(),
241
+ ...sources,
82
242
  ...globalMocArgs,
83
243
  ...(options.extraArgs ?? []),
84
244
  ];
@@ -88,32 +248,11 @@ export async function check(
88
248
  console.log(chalk.blue("check"), chalk.gray("Attempting to fix files"));
89
249
  }
90
250
 
91
- const fixResult = await autofixMotoko(mocPath, fileList, mocArgs);
92
- if (fixResult) {
93
- for (const [file, codes] of fixResult.fixedFiles) {
94
- const unique = [...new Set(codes)].sort();
95
- const n = codes.length;
96
- const rel = path.relative(process.cwd(), file);
97
- console.log(
98
- chalk.green(
99
- `Fixed ${rel} (${n} ${n === 1 ? "fix" : "fixes"}: ${unique.join(", ")})`,
100
- ),
101
- );
102
- }
103
- const fileCount = fixResult.fixedFiles.size;
104
- console.log(
105
- chalk.green(
106
- `\n✓ ${fixResult.totalFixCount} ${fixResult.totalFixCount === 1 ? "fix" : "fixes"} applied to ${fileCount} ${fileCount === 1 ? "file" : "files"}`,
107
- ),
108
- );
109
- } else {
110
- if (options.verbose) {
111
- console.log(chalk.yellow("No fixes were needed"));
112
- }
113
- }
251
+ const fixResult = await autofixMotoko(mocPath, files, mocArgs);
252
+ logAutofixResult(fixResult, options.verbose);
114
253
  }
115
254
 
116
- for (const file of fileList) {
255
+ for (const file of files) {
117
256
  try {
118
257
  const args = [file, ...mocArgs];
119
258
  if (options.verbose) {
@@ -139,49 +278,4 @@ export async function check(
139
278
  );
140
279
  }
141
280
  }
142
-
143
- const canisters = resolveCanisterConfigs(config);
144
- for (const [name, canister] of Object.entries(canisters)) {
145
- const stableConfig = canister["check-stable"];
146
- if (!stableConfig) {
147
- continue;
148
- }
149
-
150
- if (!canister.main) {
151
- cliError(`No main file specified for canister '${name}' in mops.toml`);
152
- }
153
-
154
- const stablePath = resolveConfigPath(stableConfig.path);
155
- if (!existsSync(stablePath)) {
156
- if (stableConfig.skipIfMissing) {
157
- continue;
158
- }
159
- cliError(
160
- `Deployed file not found: ${stablePath} (canister '${name}')\n` +
161
- "Set skipIfMissing = true in [canisters." +
162
- name +
163
- ".check-stable] to skip this check when the file is missing.",
164
- );
165
- }
166
-
167
- await runStableCheck({
168
- oldFile: stablePath,
169
- canisterMain: resolveConfigPath(canister.main),
170
- canisterName: name,
171
- mocPath,
172
- globalMocArgs,
173
- options: { verbose: options.verbose, extraArgs: options.extraArgs },
174
- });
175
- }
176
-
177
- if (config.toolchain?.lintoko) {
178
- const rootDir = getRootDir();
179
- const lintRules = await collectLintRules(config, rootDir);
180
- await lint(undefined, {
181
- verbose: options.verbose,
182
- fix: options.fix,
183
- rules: lintRules,
184
- files: explicitFiles.length > 0 ? explicitFiles : undefined,
185
- });
186
- }
187
281
  }
@@ -0,0 +1,165 @@
1
+ import { existsSync, mkdirSync, renameSync } from "node:fs";
2
+ import { writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import chalk from "chalk";
5
+ import { cliError } from "../error.js";
6
+ import {
7
+ getNextMigrationFile,
8
+ validateMigrationsConfig,
9
+ validateNextMigrationOrder,
10
+ } from "../helpers/migrations.js";
11
+ import { resolveCanisterConfigs } from "../helpers/resolve-canisters.js";
12
+ import { readConfig, resolveConfigPath } from "../mops.js";
13
+ import { CanisterConfig } from "../types.js";
14
+
15
+ function resolveMigrationCanister(canisterName?: string): {
16
+ name: string;
17
+ canister: CanisterConfig;
18
+ } {
19
+ const config = readConfig();
20
+ const canisters = resolveCanisterConfigs(config);
21
+ const withMigrations = Object.entries(canisters).filter(
22
+ ([, c]) => c.migrations,
23
+ );
24
+
25
+ if (withMigrations.length === 0) {
26
+ cliError(
27
+ "No canisters with [migrations] config found in mops.toml.\n" +
28
+ "Add a [canisters.<name>.migrations] section first:\n\n" +
29
+ " [canisters.backend.migrations]\n" +
30
+ ' chain = "migrations"\n' +
31
+ ' next = "next-migration" # required for migrate new/freeze',
32
+ );
33
+ }
34
+
35
+ if (canisterName) {
36
+ const canister = canisters[canisterName];
37
+ if (!canister) {
38
+ cliError(
39
+ `Canister '${canisterName}' not found in mops.toml. Available: ${Object.keys(canisters).join(", ")}`,
40
+ );
41
+ }
42
+ if (!canister.migrations) {
43
+ cliError(
44
+ `Canister '${canisterName}' has no [canisters.${canisterName}.migrations] config in mops.toml`,
45
+ );
46
+ }
47
+ return { name: canisterName, canister };
48
+ }
49
+
50
+ if (withMigrations.length > 1) {
51
+ cliError(
52
+ `Multiple canisters with [migrations] config. Please specify one: ${withMigrations.map(([n]) => n).join(", ")}`,
53
+ );
54
+ }
55
+
56
+ return { name: withMigrations[0]![0], canister: withMigrations[0]![1] };
57
+ }
58
+
59
+ const VALID_NAME_RE = /^[A-Za-z][A-Za-z0-9_]*$/;
60
+
61
+ function generateTimestamp(): string {
62
+ const now = new Date();
63
+ const pad = (n: number) => String(n).padStart(2, "0");
64
+ return (
65
+ `${now.getUTCFullYear()}${pad(now.getUTCMonth() + 1)}${pad(now.getUTCDate())}` +
66
+ `_${pad(now.getUTCHours())}${pad(now.getUTCMinutes())}${pad(now.getUTCSeconds())}`
67
+ );
68
+ }
69
+
70
+ const MIGRATION_TEMPLATE = `module {
71
+ public func migration(old : {}) : {} {
72
+ {}
73
+ }
74
+ }
75
+ `;
76
+
77
+ export async function migrateNew(
78
+ name: string,
79
+ canisterName?: string,
80
+ ): Promise<void> {
81
+ if (!VALID_NAME_RE.test(name)) {
82
+ cliError(
83
+ `Invalid migration name: "${name}"\n` +
84
+ "Name must start with a letter and contain only letters, digits, and underscores.",
85
+ );
86
+ }
87
+
88
+ const { name: resolvedName, canister } =
89
+ resolveMigrationCanister(canisterName);
90
+ const migrations = canister.migrations!;
91
+ validateMigrationsConfig(migrations, resolvedName);
92
+
93
+ if (!migrations.next) {
94
+ cliError(
95
+ `[canisters.${resolvedName}.migrations] is missing the "next" field.\n` +
96
+ 'Add next = "next-migration" to use `mops migrate new/freeze`.',
97
+ );
98
+ }
99
+
100
+ const chainDir = resolveConfigPath(migrations.chain);
101
+ const nextDir = resolveConfigPath(migrations.next);
102
+
103
+ const existingNext = existsSync(nextDir)
104
+ ? getNextMigrationFile(nextDir)
105
+ : null;
106
+ if (existingNext) {
107
+ cliError(
108
+ `A next migration already exists: ${existingNext}\n` +
109
+ "Freeze it first with `mops migrate freeze`.",
110
+ );
111
+ }
112
+
113
+ const timestamp = generateTimestamp();
114
+ const fileName = `${timestamp}_${name}.mo`;
115
+
116
+ validateNextMigrationOrder(chainDir, fileName);
117
+
118
+ if (!existsSync(chainDir)) {
119
+ mkdirSync(chainDir, { recursive: true });
120
+ }
121
+ if (!existsSync(nextDir)) {
122
+ mkdirSync(nextDir, { recursive: true });
123
+ }
124
+
125
+ const filePath = join(nextDir, fileName);
126
+ await writeFile(filePath, MIGRATION_TEMPLATE);
127
+
128
+ console.log(chalk.green(`✓ Created migration: ${filePath}`));
129
+ }
130
+
131
+ export async function migrateFreeze(canisterName?: string): Promise<void> {
132
+ const { name: resolvedName, canister } =
133
+ resolveMigrationCanister(canisterName);
134
+ const migrations = canister.migrations!;
135
+ validateMigrationsConfig(migrations, resolvedName);
136
+
137
+ if (!migrations.next) {
138
+ cliError(
139
+ `[canisters.${resolvedName}.migrations] is missing the "next" field.\n` +
140
+ 'Add next = "next-migration" to use `mops migrate new/freeze`.',
141
+ );
142
+ }
143
+
144
+ const chainDir = resolveConfigPath(migrations.chain);
145
+ const nextDir = resolveConfigPath(migrations.next);
146
+
147
+ const nextFile = existsSync(nextDir) ? getNextMigrationFile(nextDir) : null;
148
+ if (!nextFile) {
149
+ cliError(
150
+ "No next migration to freeze. Create one with `mops migrate new <Name>`.",
151
+ );
152
+ }
153
+
154
+ validateNextMigrationOrder(chainDir, nextFile);
155
+
156
+ if (!existsSync(chainDir)) {
157
+ mkdirSync(chainDir, { recursive: true });
158
+ }
159
+
160
+ const src = join(nextDir, nextFile);
161
+ const dest = join(chainDir, nextFile);
162
+ renameSync(src, dest);
163
+
164
+ console.log(chalk.green(`✓ Frozen migration: ${nextFile} → ${chainDir}/`));
165
+ }
@@ -42,6 +42,11 @@ type StreamingCallbackResponse =
42
42
  };
43
43
  type StreamingCallback = func (StreamingToken) ->
44
44
  (opt StreamingCallbackResponse) query;
45
+ type StructureStats =
46
+ record {
47
+ bytes: nat;
48
+ count: nat;
49
+ };
45
50
  type StorageStats =
46
51
  record {
47
52
  cyclesBalance: nat;
@@ -272,6 +277,38 @@ type PackageChanges =
272
277
  prevDocsCoverage: float64;
273
278
  tests: TestsChanges;
274
279
  };
280
+ type MemoryStats =
281
+ record {
282
+ dailySnapshots: StructureStats;
283
+ dailySnapshotsByPackageId: StructureStats;
284
+ dailySnapshotsByPackageName: StructureStats;
285
+ dailyTempRecords: StructureStats;
286
+ downloadsByPackageId: StructureStats;
287
+ downloadsByPackageName: StructureStats;
288
+ fileIdsByPackage: StructureStats;
289
+ hashByFileId: StructureStats;
290
+ highestConfigs: StructureStats;
291
+ maintainersByPackage: StructureStats;
292
+ ownersByPackage: StructureStats;
293
+ packageBenchmarks: StructureStats;
294
+ packageConfigs: StructureStats;
295
+ packageDocsCoverage: StructureStats;
296
+ packageFileStats: StructureStats;
297
+ packageNotes: StructureStats;
298
+ packagePublications: StructureStats;
299
+ packageTestStats: StructureStats;
300
+ packageVersions: StructureStats;
301
+ rtsHeapSize: nat;
302
+ rtsMemorySize: nat;
303
+ names: StructureStats;
304
+ storageByFileId: StructureStats;
305
+ storages: StructureStats;
306
+ users: StructureStats;
307
+ weeklySnapshots: StructureStats;
308
+ weeklySnapshotsByPackageId: StructureStats;
309
+ weeklySnapshotsByPackageName: StructureStats;
310
+ weeklyTempRecords: StructureStats;
311
+ };
275
312
  type Main =
276
313
  service {
277
314
  addMaintainer: (packageName: PackageName, newMaintainer: principal) ->
@@ -311,6 +348,7 @@ type Main =
311
348
  SemverPart;
312
349
  }) -> (Result_6) query;
313
350
  getHighestVersion: (name: PackageName) -> (Result_5) query;
351
+ getMemoryStats: () -> (MemoryStats) query;
314
352
  getMostDownloadedPackages: () -> (vec PackageSummary) query;
315
353
  getMostDownloadedPackagesIn7Days: () -> (vec PackageSummary) query;
316
354
  getNewPackages: () -> (vec PackageSummary) query;
@@ -45,6 +45,41 @@ export interface HttpRequestResult {
45
45
  'body' : Uint8Array | number[],
46
46
  'headers' : Array<HttpHeader>,
47
47
  }
48
+ export interface StructureStats {
49
+ 'count' : bigint,
50
+ 'bytes' : bigint,
51
+ }
52
+ export interface MemoryStats {
53
+ 'rtsHeapSize' : bigint,
54
+ 'rtsMemorySize' : bigint,
55
+ 'packageVersions' : StructureStats,
56
+ 'packageConfigs' : StructureStats,
57
+ 'highestConfigs' : StructureStats,
58
+ 'packagePublications' : StructureStats,
59
+ 'ownersByPackage' : StructureStats,
60
+ 'maintainersByPackage' : StructureStats,
61
+ 'fileIdsByPackage' : StructureStats,
62
+ 'hashByFileId' : StructureStats,
63
+ 'packageFileStats' : StructureStats,
64
+ 'packageTestStats' : StructureStats,
65
+ 'packageBenchmarks' : StructureStats,
66
+ 'packageNotes' : StructureStats,
67
+ 'packageDocsCoverage' : StructureStats,
68
+ 'downloadsByPackageName' : StructureStats,
69
+ 'downloadsByPackageId' : StructureStats,
70
+ 'dailySnapshots' : StructureStats,
71
+ 'weeklySnapshots' : StructureStats,
72
+ 'dailySnapshotsByPackageName' : StructureStats,
73
+ 'dailySnapshotsByPackageId' : StructureStats,
74
+ 'weeklySnapshotsByPackageName' : StructureStats,
75
+ 'weeklySnapshotsByPackageId' : StructureStats,
76
+ 'dailyTempRecords' : StructureStats,
77
+ 'weeklyTempRecords' : StructureStats,
78
+ 'storages' : StructureStats,
79
+ 'storageByFileId' : StructureStats,
80
+ 'users' : StructureStats,
81
+ 'names' : StructureStats,
82
+ }
48
83
  export interface Main {
49
84
  'addMaintainer' : ActorMethod<[PackageName, Principal], Result_3>,
50
85
  'addOwner' : ActorMethod<[PackageName, Principal], Result_3>,
@@ -77,6 +112,7 @@ export interface Main {
77
112
  Result_6
78
113
  >,
79
114
  'getHighestVersion' : ActorMethod<[PackageName], Result_5>,
115
+ 'getMemoryStats' : ActorMethod<[], MemoryStats, 'query'>,
80
116
  'getMostDownloadedPackages' : ActorMethod<[], Array<PackageSummary>>,
81
117
  'getMostDownloadedPackagesIn7Days' : ActorMethod<[], Array<PackageSummary>>,
82
118
  'getNewPackages' : ActorMethod<[], Array<PackageSummary>>,
@@ -196,6 +196,41 @@ export const idlFactory = ({ IDL }) => {
196
196
  'cyclesBalance' : IDL.Nat,
197
197
  'memorySize' : IDL.Nat,
198
198
  });
199
+ const StructureStats = IDL.Record({
200
+ 'count' : IDL.Nat,
201
+ 'bytes' : IDL.Nat,
202
+ });
203
+ const MemoryStats = IDL.Record({
204
+ 'rtsHeapSize' : IDL.Nat,
205
+ 'rtsMemorySize' : IDL.Nat,
206
+ 'packageVersions' : StructureStats,
207
+ 'packageConfigs' : StructureStats,
208
+ 'highestConfigs' : StructureStats,
209
+ 'packagePublications' : StructureStats,
210
+ 'ownersByPackage' : StructureStats,
211
+ 'maintainersByPackage' : StructureStats,
212
+ 'fileIdsByPackage' : StructureStats,
213
+ 'hashByFileId' : StructureStats,
214
+ 'packageFileStats' : StructureStats,
215
+ 'packageTestStats' : StructureStats,
216
+ 'packageBenchmarks' : StructureStats,
217
+ 'packageNotes' : StructureStats,
218
+ 'packageDocsCoverage' : StructureStats,
219
+ 'downloadsByPackageName' : StructureStats,
220
+ 'downloadsByPackageId' : StructureStats,
221
+ 'dailySnapshots' : StructureStats,
222
+ 'weeklySnapshots' : StructureStats,
223
+ 'dailySnapshotsByPackageName' : StructureStats,
224
+ 'dailySnapshotsByPackageId' : StructureStats,
225
+ 'weeklySnapshotsByPackageName' : StructureStats,
226
+ 'weeklySnapshotsByPackageId' : StructureStats,
227
+ 'dailyTempRecords' : StructureStats,
228
+ 'weeklyTempRecords' : StructureStats,
229
+ 'storages' : StructureStats,
230
+ 'storageByFileId' : StructureStats,
231
+ 'users' : StructureStats,
232
+ 'names' : StructureStats,
233
+ });
199
234
  const Header = IDL.Tuple(IDL.Text, IDL.Text);
200
235
  const Request = IDL.Record({
201
236
  'url' : IDL.Text,
@@ -308,6 +343,7 @@ export const idlFactory = ({ IDL }) => {
308
343
  ['query'],
309
344
  ),
310
345
  'getHighestVersion' : IDL.Func([PackageName], [Result_5], ['query']),
346
+ 'getMemoryStats' : IDL.Func([], [MemoryStats], ['query']),
311
347
  'getMostDownloadedPackages' : IDL.Func(
312
348
  [],
313
349
  [IDL.Vec(PackageSummary)],