ic-mops 2.10.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 (48) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/bundle/cli.tgz +0 -0
  3. package/cli.ts +24 -0
  4. package/commands/build.ts +10 -1
  5. package/commands/check-stable.ts +52 -21
  6. package/commands/check.ts +65 -52
  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 +18 -0
  12. package/dist/commands/build.js +5 -1
  13. package/dist/commands/check-stable.d.ts +1 -0
  14. package/dist/commands/check-stable.js +39 -21
  15. package/dist/commands/check.js +51 -42
  16. package/dist/commands/migrate.d.ts +2 -0
  17. package/dist/commands/migrate.js +104 -0
  18. package/dist/declarations/main/main.did +38 -0
  19. package/dist/declarations/main/main.did.d.ts +36 -0
  20. package/dist/declarations/main/main.did.js +36 -0
  21. package/dist/helpers/migrations.d.ts +10 -0
  22. package/dist/helpers/migrations.js +109 -0
  23. package/dist/helpers/resolve-canisters.d.ts +1 -1
  24. package/dist/helpers/resolve-canisters.js +15 -1
  25. package/dist/package.json +1 -1
  26. package/dist/tests/migrate.test.d.ts +1 -0
  27. package/dist/tests/migrate.test.js +160 -0
  28. package/dist/types.d.ts +7 -0
  29. package/helpers/migrations.ts +166 -0
  30. package/helpers/resolve-canisters.ts +17 -0
  31. package/package.json +1 -1
  32. package/tests/__snapshots__/migrate.test.ts.snap +119 -0
  33. package/tests/migrate/basic/deployed.most +12 -0
  34. package/tests/migrate/basic/migrations/20250101_000000_Init.mo +5 -0
  35. package/tests/migrate/basic/migrations/20250201_000000_AddName.mo +5 -0
  36. package/tests/migrate/basic/migrations/20250301_000000_AddEmail.mo +9 -0
  37. package/tests/migrate/basic/mops.toml +15 -0
  38. package/tests/migrate/basic/next-migration/.gitkeep +0 -0
  39. package/tests/migrate/basic/src/main.mo +11 -0
  40. package/tests/migrate/with-next/deployed.most +12 -0
  41. package/tests/migrate/with-next/migrations/20250101_000000_Init.mo +5 -0
  42. package/tests/migrate/with-next/migrations/20250201_000000_AddName.mo +5 -0
  43. package/tests/migrate/with-next/migrations/20250301_000000_AddEmail.mo +9 -0
  44. package/tests/migrate/with-next/mops.toml +15 -0
  45. package/tests/migrate/with-next/next-migration/20250401_000000_RenameId.mo +9 -0
  46. package/tests/migrate/with-next/src/main.mo +11 -0
  47. package/tests/migrate.test.ts +228 -0
  48. package/types.ts +8 -0
package/dist/cli.js CHANGED
@@ -33,6 +33,7 @@ import { test } from "./commands/test/test.js";
33
33
  import { toolchain } from "./commands/toolchain/index.js";
34
34
  import { update } from "./commands/update.js";
35
35
  import { getPrincipal, getUserProp, importPem, setUserProp, } from "./commands/user.js";
36
+ import { migrateNew, migrateFreeze } from "./commands/migrate.js";
36
37
  import { watch } from "./commands/watch/watch.js";
37
38
  import { apiVersion, checkApiCompatibility, checkConfigFile, getGlobalMocArgs, getNetworkFile, readConfig, setNetwork, version, } from "./mops.js";
38
39
  import { resolvePackages } from "./resolve-packages.js";
@@ -550,6 +551,23 @@ toolchainCommand
550
551
  console.log(bin);
551
552
  });
552
553
  program.addCommand(toolchainCommand);
554
+ // migrate
555
+ const migrateCommand = new Command("migrate").description("Manage enhanced migration chains");
556
+ migrateCommand
557
+ .command("new <name> [canister]")
558
+ .description("Create a new migration file in the next-migration directory")
559
+ .action(async (name, canister) => {
560
+ checkConfigFile(true);
561
+ await migrateNew(name, canister);
562
+ });
563
+ migrateCommand
564
+ .command("freeze [canister]")
565
+ .description("Move the next migration into the frozen chain")
566
+ .action(async (canister) => {
567
+ checkConfigFile(true);
568
+ await migrateFreeze(canister);
569
+ });
570
+ program.addCommand(migrateCommand);
553
571
  // self
554
572
  const selfCommand = new Command("self").description("Mops CLI management");
555
573
  selfCommand
@@ -7,6 +7,7 @@ import { lock, unlockSync } from "proper-lockfile";
7
7
  import { cliError } from "../error.js";
8
8
  import { isCandidCompatible } from "../helpers/is-candid-compatible.js";
9
9
  import { filterCanisters, resolveCanisterConfigs, validateCanisterArgs, } from "../helpers/resolve-canisters.js";
10
+ import { prepareMigrationArgs } from "../helpers/migrations.js";
10
11
  import { getWasmBindings } from "../wasm.js";
11
12
  import { getGlobalMocArgs, readConfig, resolveConfigPath } from "../mops.js";
12
13
  import { sourcesArgs } from "./sources.js";
@@ -62,6 +63,7 @@ export async function build(canisterNames, options) {
62
63
  catch { }
63
64
  };
64
65
  process.on("exit", exitCleanup);
66
+ const migration = await prepareMigrationArgs(canister.migrations, canisterName, "build", options.verbose);
65
67
  try {
66
68
  let args = [
67
69
  "-c",
@@ -72,6 +74,7 @@ export async function build(canisterNames, options) {
72
74
  motokoPath,
73
75
  ...(await sourcesArgs()).flat(),
74
76
  ...getGlobalMocArgs(config),
77
+ ...migration.migrationArgs,
75
78
  ];
76
79
  args.push(...collectExtraArgs(config, canister, canisterName, options.extraArgs));
77
80
  const isPublicCandid = true; // always true for now to reduce corner cases
@@ -148,6 +151,7 @@ export async function build(canisterNames, options) {
148
151
  }
149
152
  }
150
153
  finally {
154
+ await migration.cleanup();
151
155
  process.removeListener("exit", exitCleanup);
152
156
  try {
153
157
  await release?.();
@@ -173,7 +177,7 @@ function collectExtraArgs(config, canister, canisterName, extraArgs) {
173
177
  args.push(...config.build.args);
174
178
  }
175
179
  if (canister.args) {
176
- validateCanisterArgs(canister, canisterName);
180
+ validateCanisterArgs(canister, canisterName, config);
177
181
  args.push(...canister.args);
178
182
  }
179
183
  if (extraArgs) {
@@ -16,5 +16,6 @@ export interface RunStableCheckParams {
16
16
  canisterArgs: string[];
17
17
  sources?: string[];
18
18
  options?: Partial<CheckStableOptions>;
19
+ hasMigrations?: boolean;
19
20
  }
20
21
  export declare function runStableCheck(params: RunStableCheckParams): Promise<void>;
@@ -4,6 +4,7 @@ import { rm } from "node:fs/promises";
4
4
  import chalk from "chalk";
5
5
  import { execa } from "execa";
6
6
  import { cliError } from "../error.js";
7
+ import { prepareMigrationArgs } from "../helpers/migrations.js";
7
8
  import { getGlobalMocArgs, readConfig, resolveConfigPath } from "../mops.js";
8
9
  import { filterCanisters, looksLikeFile, resolveCanisterConfigs, resolveSingleCanister, validateCanisterArgs, } from "../helpers/resolve-canisters.js";
9
10
  import { sourcesArgs } from "./sources.js";
@@ -41,16 +42,23 @@ export async function checkStable(args, options = {}) {
41
42
  if (!canister.main) {
42
43
  cliError(`No main file specified for canister '${name}' in mops.toml`);
43
44
  }
44
- validateCanisterArgs(canister, name);
45
- await runStableCheck({
46
- oldFile,
47
- canisterMain: resolveConfigPath(canister.main),
48
- canisterName: name,
49
- mocPath,
50
- globalMocArgs,
51
- canisterArgs: canister.args ?? [],
52
- options,
53
- });
45
+ validateCanisterArgs(canister, name, config);
46
+ const migration = await prepareMigrationArgs(canister.migrations, name, "check", options.verbose);
47
+ try {
48
+ await runStableCheck({
49
+ oldFile,
50
+ canisterMain: resolveConfigPath(canister.main),
51
+ canisterName: name,
52
+ mocPath,
53
+ globalMocArgs,
54
+ canisterArgs: [...migration.migrationArgs, ...(canister.args ?? [])],
55
+ options,
56
+ hasMigrations: !!canister.migrations,
57
+ });
58
+ }
59
+ finally {
60
+ await migration.cleanup();
61
+ }
54
62
  return;
55
63
  }
56
64
  const canisters = resolveCanisterConfigs(config);
@@ -62,23 +70,30 @@ export async function checkStable(args, options = {}) {
62
70
  if (!canister.main) {
63
71
  cliError(`No main file specified for canister '${name}' in mops.toml`);
64
72
  }
65
- validateCanisterArgs(canister, name);
73
+ validateCanisterArgs(canister, name, config);
66
74
  const stablePath = resolveStablePath(canister, name, {
67
75
  required: !!canisterNames,
68
76
  });
69
77
  if (!stablePath) {
70
78
  continue;
71
79
  }
72
- await runStableCheck({
73
- oldFile: stablePath,
74
- canisterMain: resolveConfigPath(canister.main),
75
- canisterName: name,
76
- mocPath,
77
- globalMocArgs,
78
- canisterArgs: canister.args ?? [],
79
- sources,
80
- options,
81
- });
80
+ const migration = await prepareMigrationArgs(canister.migrations, name, "check", options.verbose);
81
+ try {
82
+ await runStableCheck({
83
+ oldFile: stablePath,
84
+ canisterMain: resolveConfigPath(canister.main),
85
+ canisterName: name,
86
+ mocPath,
87
+ globalMocArgs,
88
+ canisterArgs: [...migration.migrationArgs, ...(canister.args ?? [])],
89
+ sources,
90
+ options,
91
+ hasMigrations: !!canister.migrations,
92
+ });
93
+ }
94
+ finally {
95
+ await migration.cleanup();
96
+ }
82
97
  checked++;
83
98
  }
84
99
  if (checked === 0 && !canisterNames) {
@@ -118,6 +133,9 @@ export async function runStableCheck(params) {
118
133
  if (result.stderr) {
119
134
  console.error(result.stderr);
120
135
  }
136
+ if (params.hasMigrations) {
137
+ console.error(chalk.yellow("Hint: You may need a migration. Run `mops migrate new <Name>` to create one."));
138
+ }
121
139
  cliError(`✗ Stable compatibility check failed for canister '${canisterName}'`);
122
140
  }
123
141
  console.log(chalk.green(`✓ Stable compatibility check passed for canister '${canisterName}'`));
@@ -6,6 +6,7 @@ import { getGlobalMocArgs, getRootDir, readConfig, resolveConfigPath, } from "..
6
6
  import { autofixMotoko } from "../helpers/autofix-motoko.js";
7
7
  import { getMocSemVer } from "../helpers/get-moc-version.js";
8
8
  import { filterCanisters, looksLikeFile, resolveCanisterConfigs, validateCanisterArgs, } from "../helpers/resolve-canisters.js";
9
+ import { prepareMigrationArgs } from "../helpers/migrations.js";
9
10
  import { resolveStablePath, runStableCheck } from "./check-stable.js";
10
11
  import { sourcesArgs } from "./sources.js";
11
12
  import { toolchain } from "./toolchain/index.js";
@@ -87,53 +88,61 @@ async function checkCanisters(config, canisters, options) {
87
88
  if (!canister.main) {
88
89
  cliError(`No main file specified for canister '${canisterName}' in mops.toml`);
89
90
  }
90
- validateCanisterArgs(canister, canisterName);
91
+ validateCanisterArgs(canister, canisterName, config);
91
92
  const motokoPath = resolveConfigPath(canister.main);
92
- const mocArgs = [
93
- "--check",
94
- ...(allLibs ? ["--all-libs"] : []),
95
- ...sources,
96
- ...globalMocArgs,
97
- ...(canister.args ?? []),
98
- ...(options.extraArgs ?? []),
99
- ];
100
- if (options.fix) {
101
- if (options.verbose) {
102
- console.log(chalk.blue("check"), chalk.gray(`Attempting to fix ${canisterName}`));
103
- }
104
- const fixResult = await autofixMotoko(mocPath, [motokoPath], mocArgs);
105
- logAutofixResult(fixResult, options.verbose);
106
- }
93
+ const migration = await prepareMigrationArgs(canister.migrations, canisterName, "check", options.verbose);
107
94
  try {
108
- const args = [motokoPath, ...mocArgs];
109
- if (options.verbose) {
110
- console.log(chalk.blue("check"), chalk.gray(`Checking canister ${canisterName}:`));
111
- console.log(chalk.gray(mocPath, JSON.stringify(args)));
95
+ const mocArgs = [
96
+ "--check",
97
+ ...(allLibs ? ["--all-libs"] : []),
98
+ ...sources,
99
+ ...globalMocArgs,
100
+ ...migration.migrationArgs,
101
+ ...(canister.args ?? []),
102
+ ...(options.extraArgs ?? []),
103
+ ];
104
+ if (options.fix) {
105
+ if (options.verbose) {
106
+ console.log(chalk.blue("check"), chalk.gray(`Attempting to fix ${canisterName}`));
107
+ }
108
+ const fixResult = await autofixMotoko(mocPath, [motokoPath], mocArgs);
109
+ logAutofixResult(fixResult, options.verbose);
112
110
  }
113
- const result = await execa(mocPath, args, {
114
- stdio: "inherit",
115
- reject: false,
116
- });
117
- if (result.exitCode !== 0) {
118
- cliError(`✗ Check failed for canister ${canisterName} (exit code: ${result.exitCode})`);
111
+ try {
112
+ const args = [motokoPath, ...mocArgs];
113
+ if (options.verbose) {
114
+ console.log(chalk.blue("check"), chalk.gray(`Checking canister ${canisterName}:`));
115
+ console.log(chalk.gray(mocPath, JSON.stringify(args)));
116
+ }
117
+ const result = await execa(mocPath, args, {
118
+ stdio: "inherit",
119
+ reject: false,
120
+ });
121
+ if (result.exitCode !== 0) {
122
+ cliError(`✗ Check failed for canister ${canisterName} (exit code: ${result.exitCode})`);
123
+ }
124
+ console.log(chalk.green(`✓ ${canisterName}`));
125
+ }
126
+ catch (err) {
127
+ cliError(`Error while checking canister ${canisterName}${err?.message ? `\n${err.message}` : ""}`);
128
+ }
129
+ const stablePath = resolveStablePath(canister, canisterName);
130
+ if (stablePath) {
131
+ await runStableCheck({
132
+ oldFile: stablePath,
133
+ canisterMain: motokoPath,
134
+ canisterName,
135
+ mocPath,
136
+ globalMocArgs,
137
+ canisterArgs: [...migration.migrationArgs, ...(canister.args ?? [])],
138
+ sources,
139
+ options: { verbose: options.verbose, extraArgs: options.extraArgs },
140
+ hasMigrations: !!canister.migrations,
141
+ });
119
142
  }
120
- console.log(chalk.green(`✓ ${canisterName}`));
121
- }
122
- catch (err) {
123
- cliError(`Error while checking canister ${canisterName}${err?.message ? `\n${err.message}` : ""}`);
124
143
  }
125
- const stablePath = resolveStablePath(canister, canisterName);
126
- if (stablePath) {
127
- await runStableCheck({
128
- oldFile: stablePath,
129
- canisterMain: motokoPath,
130
- canisterName,
131
- mocPath,
132
- globalMocArgs,
133
- canisterArgs: canister.args ?? [],
134
- sources,
135
- options: { verbose: options.verbose, extraArgs: options.extraArgs },
136
- });
144
+ finally {
145
+ await migration.cleanup();
137
146
  }
138
147
  }
139
148
  }
@@ -0,0 +1,2 @@
1
+ export declare function migrateNew(name: string, canisterName?: string): Promise<void>;
2
+ export declare function migrateFreeze(canisterName?: string): Promise<void>;
@@ -0,0 +1,104 @@
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 { getNextMigrationFile, validateMigrationsConfig, validateNextMigrationOrder, } from "../helpers/migrations.js";
7
+ import { resolveCanisterConfigs } from "../helpers/resolve-canisters.js";
8
+ import { readConfig, resolveConfigPath } from "../mops.js";
9
+ function resolveMigrationCanister(canisterName) {
10
+ const config = readConfig();
11
+ const canisters = resolveCanisterConfigs(config);
12
+ const withMigrations = Object.entries(canisters).filter(([, c]) => c.migrations);
13
+ if (withMigrations.length === 0) {
14
+ cliError("No canisters with [migrations] config found in mops.toml.\n" +
15
+ "Add a [canisters.<name>.migrations] section first:\n\n" +
16
+ " [canisters.backend.migrations]\n" +
17
+ ' chain = "migrations"\n' +
18
+ ' next = "next-migration" # required for migrate new/freeze');
19
+ }
20
+ if (canisterName) {
21
+ const canister = canisters[canisterName];
22
+ if (!canister) {
23
+ cliError(`Canister '${canisterName}' not found in mops.toml. Available: ${Object.keys(canisters).join(", ")}`);
24
+ }
25
+ if (!canister.migrations) {
26
+ cliError(`Canister '${canisterName}' has no [canisters.${canisterName}.migrations] config in mops.toml`);
27
+ }
28
+ return { name: canisterName, canister };
29
+ }
30
+ if (withMigrations.length > 1) {
31
+ cliError(`Multiple canisters with [migrations] config. Please specify one: ${withMigrations.map(([n]) => n).join(", ")}`);
32
+ }
33
+ return { name: withMigrations[0][0], canister: withMigrations[0][1] };
34
+ }
35
+ const VALID_NAME_RE = /^[A-Za-z][A-Za-z0-9_]*$/;
36
+ function generateTimestamp() {
37
+ const now = new Date();
38
+ const pad = (n) => String(n).padStart(2, "0");
39
+ return (`${now.getUTCFullYear()}${pad(now.getUTCMonth() + 1)}${pad(now.getUTCDate())}` +
40
+ `_${pad(now.getUTCHours())}${pad(now.getUTCMinutes())}${pad(now.getUTCSeconds())}`);
41
+ }
42
+ const MIGRATION_TEMPLATE = `module {
43
+ public func migration(old : {}) : {} {
44
+ {}
45
+ }
46
+ }
47
+ `;
48
+ export async function migrateNew(name, canisterName) {
49
+ if (!VALID_NAME_RE.test(name)) {
50
+ cliError(`Invalid migration name: "${name}"\n` +
51
+ "Name must start with a letter and contain only letters, digits, and underscores.");
52
+ }
53
+ const { name: resolvedName, canister } = resolveMigrationCanister(canisterName);
54
+ const migrations = canister.migrations;
55
+ validateMigrationsConfig(migrations, resolvedName);
56
+ if (!migrations.next) {
57
+ cliError(`[canisters.${resolvedName}.migrations] is missing the "next" field.\n` +
58
+ 'Add next = "next-migration" to use `mops migrate new/freeze`.');
59
+ }
60
+ const chainDir = resolveConfigPath(migrations.chain);
61
+ const nextDir = resolveConfigPath(migrations.next);
62
+ const existingNext = existsSync(nextDir)
63
+ ? getNextMigrationFile(nextDir)
64
+ : null;
65
+ if (existingNext) {
66
+ cliError(`A next migration already exists: ${existingNext}\n` +
67
+ "Freeze it first with `mops migrate freeze`.");
68
+ }
69
+ const timestamp = generateTimestamp();
70
+ const fileName = `${timestamp}_${name}.mo`;
71
+ validateNextMigrationOrder(chainDir, fileName);
72
+ if (!existsSync(chainDir)) {
73
+ mkdirSync(chainDir, { recursive: true });
74
+ }
75
+ if (!existsSync(nextDir)) {
76
+ mkdirSync(nextDir, { recursive: true });
77
+ }
78
+ const filePath = join(nextDir, fileName);
79
+ await writeFile(filePath, MIGRATION_TEMPLATE);
80
+ console.log(chalk.green(`✓ Created migration: ${filePath}`));
81
+ }
82
+ export async function migrateFreeze(canisterName) {
83
+ const { name: resolvedName, canister } = resolveMigrationCanister(canisterName);
84
+ const migrations = canister.migrations;
85
+ validateMigrationsConfig(migrations, resolvedName);
86
+ if (!migrations.next) {
87
+ cliError(`[canisters.${resolvedName}.migrations] is missing the "next" field.\n` +
88
+ 'Add next = "next-migration" to use `mops migrate new/freeze`.');
89
+ }
90
+ const chainDir = resolveConfigPath(migrations.chain);
91
+ const nextDir = resolveConfigPath(migrations.next);
92
+ const nextFile = existsSync(nextDir) ? getNextMigrationFile(nextDir) : null;
93
+ if (!nextFile) {
94
+ cliError("No next migration to freeze. Create one with `mops migrate new <Name>`.");
95
+ }
96
+ validateNextMigrationOrder(chainDir, nextFile);
97
+ if (!existsSync(chainDir)) {
98
+ mkdirSync(chainDir, { recursive: true });
99
+ }
100
+ const src = join(nextDir, nextFile);
101
+ const dest = join(chainDir, nextFile);
102
+ renameSync(src, dest);
103
+ console.log(chalk.green(`✓ Frozen migration: ${nextFile} → ${chainDir}/`));
104
+ }
@@ -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)],
@@ -0,0 +1,10 @@
1
+ import { MigrationsConfig } from "../types.js";
2
+ export interface MigrationArgsResult {
3
+ migrationArgs: string[];
4
+ cleanup: () => Promise<void>;
5
+ }
6
+ export declare function getMigrationFiles(dir: string): string[];
7
+ export declare function getNextMigrationFile(nextDir: string): string | null;
8
+ export declare function validateNextMigrationOrder(chainDirOrFiles: string | string[], nextFile: string): void;
9
+ export declare function validateMigrationsConfig(migrations: MigrationsConfig, canisterName: string): void;
10
+ export declare function prepareMigrationArgs(migrations: MigrationsConfig | undefined, canisterName: string, mode: "check" | "build", verbose?: boolean): Promise<MigrationArgsResult>;