ic-mops 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitignore +3 -0
- package/{cache.js → cache.ts} +8 -8
- package/{cli.js → cli.ts} +5 -5
- package/commands/{add.js → add.ts} +16 -8
- package/commands/{bump.js → bump.ts} +5 -5
- package/commands/{docs.js → docs.ts} +10 -10
- package/commands/{import-identity.js → import-identity.ts} +7 -7
- package/commands/{init.js → init.ts} +20 -17
- package/commands/{install-all.js → install-all.ts} +1 -1
- package/commands/{install.js → install.ts} +11 -11
- package/commands/{mmf1.js → mmf1.ts} +20 -18
- package/commands/{publish.js → publish.ts} +28 -15
- package/commands/{remove.js → remove.ts} +23 -16
- package/commands/{search.js → search.ts} +2 -2
- package/commands/self-update.ts +6 -0
- package/commands/{sources.js → sources.ts} +30 -24
- package/commands/{template.js → template.ts} +2 -2
- package/commands/{test.js → test.ts} +24 -19
- package/commands/{user.js → user.ts} +7 -2
- package/declarations/main/index.js +0 -2
- package/declarations/main/main.did +4 -1
- package/declarations/main/main.did.d.ts +4 -4
- package/declarations/main/main.did.js +20 -20
- package/declarations/storage/index.d.ts +50 -0
- package/declarations/storage/index.js +3 -11
- package/dist/cache.d.ts +5 -0
- package/dist/cache.js +46 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +265 -0
- package/dist/commands/add.d.ts +4 -0
- package/dist/commands/add.js +82 -0
- package/dist/commands/bump.d.ts +1 -0
- package/dist/commands/bump.js +50 -0
- package/dist/commands/docs.d.ts +3 -0
- package/dist/commands/docs.js +78 -0
- package/dist/commands/import-identity.d.ts +1 -0
- package/dist/commands/import-identity.js +47 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +82 -0
- package/dist/commands/install-all.d.ts +4 -0
- package/dist/commands/install-all.js +29 -0
- package/dist/commands/install.d.ts +5 -0
- package/dist/commands/install.js +110 -0
- package/dist/commands/mmf1.d.ts +21 -0
- package/dist/commands/mmf1.js +93 -0
- package/dist/commands/publish.d.ts +3 -0
- package/dist/commands/publish.js +254 -0
- package/dist/commands/remove.d.ts +5 -0
- package/dist/commands/remove.js +83 -0
- package/dist/commands/search.d.ts +1 -0
- package/dist/commands/search.js +36 -0
- package/dist/commands/self-update.d.ts +3 -0
- package/dist/commands/self-update.js +5 -0
- package/dist/commands/sources.d.ts +3 -0
- package/dist/commands/sources.js +124 -0
- package/dist/commands/template.d.ts +1 -0
- package/dist/commands/template.js +28 -0
- package/dist/commands/test.d.ts +4 -0
- package/dist/commands/test.js +201 -0
- package/dist/commands/user.d.ts +2 -0
- package/dist/commands/user.js +23 -0
- package/dist/commands/whoami.d.ts +1 -0
- package/dist/commands/whoami.js +11 -0
- package/dist/declarations/main/index.d.ts +50 -0
- package/dist/declarations/main/index.js +41 -0
- package/dist/declarations/main/main.did +222 -0
- package/dist/declarations/main/main.did.d.ts +198 -0
- package/dist/declarations/main/main.did.js +218 -0
- package/dist/declarations/storage/index.d.ts +50 -0
- package/dist/declarations/storage/index.js +30 -0
- package/dist/declarations/storage/storage.did +46 -0
- package/dist/declarations/storage/storage.did.d.ts +37 -0
- package/dist/declarations/storage/storage.did.js +38 -0
- package/dist/mops.d.ts +33 -0
- package/dist/mops.js +259 -0
- package/dist/package.json +79 -0
- package/dist/parallel.d.ts +1 -0
- package/dist/parallel.js +24 -0
- package/dist/pem.d.ts +5 -0
- package/dist/pem.js +49 -0
- package/dist/templates/mops-test.yml +30 -0
- package/dist/types.d.ts +27 -0
- package/dist/types.js +1 -0
- package/dist/vessel.d.ts +19 -0
- package/dist/vessel.js +154 -0
- package/global.d.ts +2 -0
- package/{mops.js → mops.ts} +58 -47
- package/package.json +44 -19
- package/{parallel.js → parallel.ts} +2 -2
- package/{pem.js → pem.ts} +12 -11
- package/templates/mops-test.yml +1 -1
- package/tsconfig.json +16 -0
- package/types.ts +29 -0
- package/{vessel.js → vessel.ts} +37 -25
- package/commands/self-update.js +0 -6
- /package/commands/{whoami.js → whoami.ts} +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Actor, HttpAgent } from "@dfinity/agent";
|
|
2
|
+
|
|
3
|
+
// Imports and re-exports candid interface
|
|
4
|
+
import { idlFactory } from './storage.did.js';
|
|
5
|
+
export { idlFactory } from './storage.did.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {string | import("@dfinity/principal").Principal} canisterId Canister ID of Agent
|
|
10
|
+
* @param {{agentOptions?: import("@dfinity/agent").HttpAgentOptions; actorOptions?: import("@dfinity/agent").ActorConfig}} [options]
|
|
11
|
+
* @return {import("@dfinity/agent").ActorSubclass<import("./storage.did.js")._SERVICE>}
|
|
12
|
+
*/
|
|
13
|
+
export const createActor = (canisterId, options) => {
|
|
14
|
+
const agent = new HttpAgent({ ...options?.agentOptions });
|
|
15
|
+
|
|
16
|
+
// Fetch root key for certificate validation during development
|
|
17
|
+
if(process.env.NODE_ENV !== "production") {
|
|
18
|
+
agent.fetchRootKey().catch(err=>{
|
|
19
|
+
console.warn("Unable to fetch root key. Check to ensure that your local replica is running");
|
|
20
|
+
console.error(err);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Creates an actor with using the candid interface and the HttpAgent
|
|
25
|
+
return Actor.createActor(idlFactory, {
|
|
26
|
+
agent,
|
|
27
|
+
canisterId,
|
|
28
|
+
...options?.actorOptions,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
type StorageStats =
|
|
2
|
+
record {
|
|
3
|
+
cyclesBalance: nat;
|
|
4
|
+
fileCount: nat;
|
|
5
|
+
memorySize: nat;
|
|
6
|
+
};
|
|
7
|
+
type Storage =
|
|
8
|
+
service {
|
|
9
|
+
acceptCycles: () -> ();
|
|
10
|
+
deleteFile: (FileId) -> ();
|
|
11
|
+
downloadChunk: (FileId, nat) -> (Result_2) query;
|
|
12
|
+
finishUpload: (FileId) -> ();
|
|
13
|
+
getFileIdsRange: (nat, nat) -> (vec FileId) query;
|
|
14
|
+
getFileMeta: (FileId) -> (Result_1) query;
|
|
15
|
+
getStats: () -> (StorageStats) query;
|
|
16
|
+
startUpload: (FileMeta) -> (Result);
|
|
17
|
+
updateFileOwners: (FileId, vec principal) -> ();
|
|
18
|
+
uploadChunk: (FileId, nat, Chunk) -> ();
|
|
19
|
+
};
|
|
20
|
+
type Result_2 =
|
|
21
|
+
variant {
|
|
22
|
+
err: Err;
|
|
23
|
+
ok: Chunk;
|
|
24
|
+
};
|
|
25
|
+
type Result_1 =
|
|
26
|
+
variant {
|
|
27
|
+
err: Err;
|
|
28
|
+
ok: FileMeta;
|
|
29
|
+
};
|
|
30
|
+
type Result =
|
|
31
|
+
variant {
|
|
32
|
+
err: Err;
|
|
33
|
+
ok;
|
|
34
|
+
};
|
|
35
|
+
type FileMeta =
|
|
36
|
+
record {
|
|
37
|
+
chunkCount: nat;
|
|
38
|
+
id: FileId__1;
|
|
39
|
+
owners: vec principal;
|
|
40
|
+
path: text;
|
|
41
|
+
};
|
|
42
|
+
type FileId__1 = text;
|
|
43
|
+
type FileId = text;
|
|
44
|
+
type Err = text;
|
|
45
|
+
type Chunk = blob;
|
|
46
|
+
service : () -> Storage
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Principal } from '@dfinity/principal';
|
|
2
|
+
import type { ActorMethod } from '@dfinity/agent';
|
|
3
|
+
|
|
4
|
+
export type Chunk = Array<number>;
|
|
5
|
+
export type Err = string;
|
|
6
|
+
export type FileId = string;
|
|
7
|
+
export type FileId__1 = string;
|
|
8
|
+
export interface FileMeta {
|
|
9
|
+
'id' : FileId__1,
|
|
10
|
+
'owners' : Array<Principal>,
|
|
11
|
+
'path' : string,
|
|
12
|
+
'chunkCount' : bigint,
|
|
13
|
+
}
|
|
14
|
+
export type Result = { 'ok' : null } |
|
|
15
|
+
{ 'err' : Err };
|
|
16
|
+
export type Result_1 = { 'ok' : FileMeta } |
|
|
17
|
+
{ 'err' : Err };
|
|
18
|
+
export type Result_2 = { 'ok' : Chunk } |
|
|
19
|
+
{ 'err' : Err };
|
|
20
|
+
export interface Storage {
|
|
21
|
+
'acceptCycles' : ActorMethod<[], undefined>,
|
|
22
|
+
'deleteFile' : ActorMethod<[FileId], undefined>,
|
|
23
|
+
'downloadChunk' : ActorMethod<[FileId, bigint], Result_2>,
|
|
24
|
+
'finishUpload' : ActorMethod<[FileId], undefined>,
|
|
25
|
+
'getFileIdsRange' : ActorMethod<[bigint, bigint], Array<FileId>>,
|
|
26
|
+
'getFileMeta' : ActorMethod<[FileId], Result_1>,
|
|
27
|
+
'getStats' : ActorMethod<[], StorageStats>,
|
|
28
|
+
'startUpload' : ActorMethod<[FileMeta], Result>,
|
|
29
|
+
'updateFileOwners' : ActorMethod<[FileId, Array<Principal>], undefined>,
|
|
30
|
+
'uploadChunk' : ActorMethod<[FileId, bigint, Chunk], undefined>,
|
|
31
|
+
}
|
|
32
|
+
export interface StorageStats {
|
|
33
|
+
'fileCount' : bigint,
|
|
34
|
+
'cyclesBalance' : bigint,
|
|
35
|
+
'memorySize' : bigint,
|
|
36
|
+
}
|
|
37
|
+
export interface _SERVICE extends Storage {}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const idlFactory = ({ IDL }) => {
|
|
2
|
+
const FileId = IDL.Text;
|
|
3
|
+
const Chunk = IDL.Vec(IDL.Nat8);
|
|
4
|
+
const Err = IDL.Text;
|
|
5
|
+
const Result_2 = IDL.Variant({ 'ok' : Chunk, 'err' : Err });
|
|
6
|
+
const FileId__1 = IDL.Text;
|
|
7
|
+
const FileMeta = IDL.Record({
|
|
8
|
+
'id' : FileId__1,
|
|
9
|
+
'owners' : IDL.Vec(IDL.Principal),
|
|
10
|
+
'path' : IDL.Text,
|
|
11
|
+
'chunkCount' : IDL.Nat,
|
|
12
|
+
});
|
|
13
|
+
const Result_1 = IDL.Variant({ 'ok' : FileMeta, 'err' : Err });
|
|
14
|
+
const StorageStats = IDL.Record({
|
|
15
|
+
'fileCount' : IDL.Nat,
|
|
16
|
+
'cyclesBalance' : IDL.Nat,
|
|
17
|
+
'memorySize' : IDL.Nat,
|
|
18
|
+
});
|
|
19
|
+
const Result = IDL.Variant({ 'ok' : IDL.Null, 'err' : Err });
|
|
20
|
+
const Storage = IDL.Service({
|
|
21
|
+
'acceptCycles' : IDL.Func([], [], []),
|
|
22
|
+
'deleteFile' : IDL.Func([FileId], [], []),
|
|
23
|
+
'downloadChunk' : IDL.Func([FileId, IDL.Nat], [Result_2], ['query']),
|
|
24
|
+
'finishUpload' : IDL.Func([FileId], [], []),
|
|
25
|
+
'getFileIdsRange' : IDL.Func(
|
|
26
|
+
[IDL.Nat, IDL.Nat],
|
|
27
|
+
[IDL.Vec(FileId)],
|
|
28
|
+
['query'],
|
|
29
|
+
),
|
|
30
|
+
'getFileMeta' : IDL.Func([FileId], [Result_1], ['query']),
|
|
31
|
+
'getStats' : IDL.Func([], [StorageStats], ['query']),
|
|
32
|
+
'startUpload' : IDL.Func([FileMeta], [Result], []),
|
|
33
|
+
'updateFileOwners' : IDL.Func([FileId, IDL.Vec(IDL.Principal)], [], []),
|
|
34
|
+
'uploadChunk' : IDL.Func([FileId, IDL.Nat, Chunk], [], []),
|
|
35
|
+
});
|
|
36
|
+
return Storage;
|
|
37
|
+
};
|
|
38
|
+
export const init = ({ IDL }) => { return []; };
|
package/dist/mops.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Identity } from '@dfinity/agent';
|
|
2
|
+
import { _SERVICE } from './declarations/main/main.did.js';
|
|
3
|
+
import { _SERVICE as _STORAGE_SERVICE } from './declarations/storage/storage.did.js';
|
|
4
|
+
import { Config } from './types.js';
|
|
5
|
+
import { Principal } from '@dfinity/principal';
|
|
6
|
+
export declare let apiVersion: string;
|
|
7
|
+
export declare let globalConfigDir: string;
|
|
8
|
+
export declare let globalCacheDir: string;
|
|
9
|
+
export declare function setNetwork(network: string): void;
|
|
10
|
+
export declare function getNetwork(): {
|
|
11
|
+
network: string;
|
|
12
|
+
host: string;
|
|
13
|
+
canisterId: string;
|
|
14
|
+
};
|
|
15
|
+
export declare let getIdentity: () => Promise<Identity | undefined>;
|
|
16
|
+
export declare let mainActor: (useIdentity?: boolean) => Promise<_SERVICE>;
|
|
17
|
+
export declare let storageActor: (storageId: Principal, useIdentity?: boolean) => Promise<_STORAGE_SERVICE>;
|
|
18
|
+
export declare function getClosestConfigFile(dir?: string): string;
|
|
19
|
+
export declare function getRootDir(): string;
|
|
20
|
+
export declare function checkConfigFile(): boolean;
|
|
21
|
+
export declare function progressBar(step: number, total: number): string;
|
|
22
|
+
export declare function getHighestVersion(pkgName: string): Promise<import("./declarations/main/main.did.js").Result_5>;
|
|
23
|
+
export declare function parseGithubURL(href: string): {
|
|
24
|
+
org: string | undefined;
|
|
25
|
+
gitName: string | undefined;
|
|
26
|
+
branch: string;
|
|
27
|
+
};
|
|
28
|
+
export declare function readConfig(configFile?: string): Config;
|
|
29
|
+
export declare function writeConfig(config: Config, configFile?: string): void;
|
|
30
|
+
export declare function formatDir(name: string, version: string): string;
|
|
31
|
+
export declare function formatGithubDir(name: string, repo: string): string;
|
|
32
|
+
export declare function readDfxJson(): any;
|
|
33
|
+
export declare function checkApiCompatibility(): Promise<boolean>;
|
package/dist/mops.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { Actor, HttpAgent } from '@dfinity/agent';
|
|
4
|
+
import TOML from '@iarna/toml';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
import ncp from 'ncp';
|
|
8
|
+
import fetch from 'node-fetch';
|
|
9
|
+
import { idlFactory } from './declarations/main/index.js';
|
|
10
|
+
import { idlFactory as storageIdlFactory } from './declarations/storage/index.js';
|
|
11
|
+
import { decodeFile } from './pem.js';
|
|
12
|
+
if (!global.fetch) {
|
|
13
|
+
global.fetch = fetch;
|
|
14
|
+
}
|
|
15
|
+
// (!) make changes in pair with backend
|
|
16
|
+
export let apiVersion = '1.2';
|
|
17
|
+
let networkFile = new URL('./network.txt', import.meta.url);
|
|
18
|
+
export let globalConfigDir = '';
|
|
19
|
+
export let globalCacheDir = '';
|
|
20
|
+
// OS specific dirs
|
|
21
|
+
if (process.platform == 'win32') {
|
|
22
|
+
globalConfigDir = path.join(process.env.LOCALAPPDATA || '', 'mops/config');
|
|
23
|
+
globalCacheDir = path.join(process.env.LOCALAPPDATA || '', 'mops/cache');
|
|
24
|
+
}
|
|
25
|
+
else if (process.platform == 'darwin') {
|
|
26
|
+
globalConfigDir = path.join(process.env.HOME || '', 'Library/Application Support/mops');
|
|
27
|
+
globalCacheDir = path.join(process.env.HOME || '', 'Library/Caches/mops');
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
globalConfigDir = path.join(process.env.HOME || '', '.config/mops');
|
|
31
|
+
globalCacheDir = path.join(process.env.HOME || '', '.cache/mops');
|
|
32
|
+
}
|
|
33
|
+
// XDG overrides
|
|
34
|
+
if (process.env.XDG_CONFIG_HOME) {
|
|
35
|
+
globalConfigDir = path.join(process.env.XDG_CONFIG_HOME, 'mops');
|
|
36
|
+
}
|
|
37
|
+
if (process.env.XDG_CACHE_HOME) {
|
|
38
|
+
globalCacheDir = path.join(process.env.XDG_CACHE_HOME, 'mops');
|
|
39
|
+
}
|
|
40
|
+
// temp: move old config to new location
|
|
41
|
+
let oldGlobalConfigDir = path.resolve(process.env.HOME || process.env.APPDATA || '/', 'mops');
|
|
42
|
+
if (fs.existsSync(oldGlobalConfigDir) && !fs.existsSync(globalConfigDir)) {
|
|
43
|
+
fs.mkdirSync(globalConfigDir, { recursive: true });
|
|
44
|
+
if (fs.existsSync(path.join(oldGlobalConfigDir, 'identity.pem'))) {
|
|
45
|
+
fs.copyFileSync(path.join(oldGlobalConfigDir, 'identity.pem'), path.join(globalConfigDir, 'identity.pem'));
|
|
46
|
+
}
|
|
47
|
+
if (fs.existsSync(path.join(oldGlobalConfigDir, 'identity.pem.encrypted'))) {
|
|
48
|
+
fs.copyFileSync(path.join(oldGlobalConfigDir, 'identity.pem.encrypted'), path.join(globalConfigDir, 'identity.pem.encrypted'));
|
|
49
|
+
}
|
|
50
|
+
console.log('Moved config to ' + chalk.green(globalConfigDir));
|
|
51
|
+
}
|
|
52
|
+
// temp: move old cache to new location
|
|
53
|
+
if (fs.existsSync(oldGlobalConfigDir) && !fs.existsSync(globalCacheDir)) {
|
|
54
|
+
fs.mkdirSync(globalCacheDir, { recursive: true });
|
|
55
|
+
ncp.ncp(path.join(oldGlobalConfigDir, 'packages'), path.join(globalCacheDir, 'packages'), {
|
|
56
|
+
stopOnErr: true,
|
|
57
|
+
clobber: false,
|
|
58
|
+
}, (err) => {
|
|
59
|
+
if (err) {
|
|
60
|
+
console.log('Error moving config: ', err);
|
|
61
|
+
fs.rmSync(globalCacheDir, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
console.log('Moved cache to ' + chalk.green(globalCacheDir));
|
|
65
|
+
}
|
|
66
|
+
export function setNetwork(network) {
|
|
67
|
+
fs.writeFileSync(networkFile, network);
|
|
68
|
+
}
|
|
69
|
+
export function getNetwork() {
|
|
70
|
+
let network = 'ic';
|
|
71
|
+
if (fs.existsSync(networkFile)) {
|
|
72
|
+
network = fs.readFileSync(networkFile).toString() || 'ic';
|
|
73
|
+
}
|
|
74
|
+
if (network === 'staging') {
|
|
75
|
+
return {
|
|
76
|
+
network,
|
|
77
|
+
host: 'https://icp-api.io',
|
|
78
|
+
canisterId: '2d2zu-vaaaa-aaaak-qb6pq-cai',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
else if (network === 'ic') {
|
|
82
|
+
return {
|
|
83
|
+
network,
|
|
84
|
+
host: 'https://icp-api.io',
|
|
85
|
+
canisterId: 'oknww-riaaa-aaaam-qaf6a-cai',
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
return {
|
|
90
|
+
network,
|
|
91
|
+
host: 'http://127.0.0.1:4943',
|
|
92
|
+
canisterId: '2d2zu-vaaaa-aaaak-qb6pq-cai',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export let getIdentity = async () => {
|
|
97
|
+
let identityPem = path.resolve(globalConfigDir, 'identity.pem');
|
|
98
|
+
let identityPemEncrypted = path.resolve(globalConfigDir, 'identity.pem.encrypted');
|
|
99
|
+
if (fs.existsSync(identityPemEncrypted)) {
|
|
100
|
+
let res = await prompts({
|
|
101
|
+
type: 'password',
|
|
102
|
+
name: 'value',
|
|
103
|
+
message: 'Enter password:'
|
|
104
|
+
});
|
|
105
|
+
return await decodeFile(identityPemEncrypted, res.value);
|
|
106
|
+
}
|
|
107
|
+
if (fs.existsSync(identityPem)) {
|
|
108
|
+
return decodeFile(identityPem);
|
|
109
|
+
}
|
|
110
|
+
return undefined;
|
|
111
|
+
};
|
|
112
|
+
export let mainActor = async (useIdentity = false) => {
|
|
113
|
+
let network = getNetwork().network;
|
|
114
|
+
let host = getNetwork().host;
|
|
115
|
+
let canisterId = getNetwork().canisterId;
|
|
116
|
+
let identity = useIdentity ? await getIdentity() : undefined;
|
|
117
|
+
// @ts-ignore exactOptionalPropertyTypes
|
|
118
|
+
let agent = new HttpAgent({ host, identity });
|
|
119
|
+
if (network === 'local') {
|
|
120
|
+
await agent.fetchRootKey();
|
|
121
|
+
}
|
|
122
|
+
return Actor.createActor(idlFactory, {
|
|
123
|
+
agent,
|
|
124
|
+
canisterId,
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
export let storageActor = async (storageId, useIdentity = false) => {
|
|
128
|
+
let network = getNetwork().network;
|
|
129
|
+
let host = getNetwork().host;
|
|
130
|
+
let identity = useIdentity && await getIdentity();
|
|
131
|
+
// @ts-ignore exactOptionalPropertyTypes
|
|
132
|
+
let agent = new HttpAgent({ host, identity });
|
|
133
|
+
if (network === 'local') {
|
|
134
|
+
await agent.fetchRootKey();
|
|
135
|
+
}
|
|
136
|
+
return Actor.createActor(storageIdlFactory, {
|
|
137
|
+
agent,
|
|
138
|
+
canisterId: storageId,
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
export function getClosestConfigFile(dir = process.cwd()) {
|
|
142
|
+
if (!path.basename(dir)) {
|
|
143
|
+
throw '';
|
|
144
|
+
}
|
|
145
|
+
let configFile = path.join(dir, 'mops.toml');
|
|
146
|
+
if (fs.existsSync(configFile)) {
|
|
147
|
+
return configFile;
|
|
148
|
+
}
|
|
149
|
+
return getClosestConfigFile(path.resolve(dir, '..'));
|
|
150
|
+
}
|
|
151
|
+
export function getRootDir() {
|
|
152
|
+
let configFile = getClosestConfigFile();
|
|
153
|
+
if (!configFile) {
|
|
154
|
+
return '';
|
|
155
|
+
}
|
|
156
|
+
return path.dirname(configFile);
|
|
157
|
+
}
|
|
158
|
+
export function checkConfigFile() {
|
|
159
|
+
let configFile = getClosestConfigFile();
|
|
160
|
+
if (!configFile) {
|
|
161
|
+
console.log(chalk.red('Error: ') + `Config file 'mops.toml' not found. Please run ${chalk.green('mops init')} first`);
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
export function progressBar(step, total) {
|
|
167
|
+
let done = Math.round(step / total * 10);
|
|
168
|
+
return `[${':'.repeat(done)}${' '.repeat(Math.max(0, 10 - done))}]`;
|
|
169
|
+
}
|
|
170
|
+
export async function getHighestVersion(pkgName) {
|
|
171
|
+
let actor = await mainActor();
|
|
172
|
+
return actor.getHighestVersion(pkgName);
|
|
173
|
+
}
|
|
174
|
+
export function parseGithubURL(href) {
|
|
175
|
+
const url = new URL(href);
|
|
176
|
+
const branch = url.hash?.substring(1) || 'master';
|
|
177
|
+
let [org, gitName] = url.pathname.split('/').filter(path => !!path);
|
|
178
|
+
if (gitName?.endsWith('.git')) {
|
|
179
|
+
gitName = gitName.substring(0, gitName.length - 4);
|
|
180
|
+
}
|
|
181
|
+
return { org, gitName, branch };
|
|
182
|
+
}
|
|
183
|
+
export function readConfig(configFile = getClosestConfigFile()) {
|
|
184
|
+
let text = fs.readFileSync(configFile).toString();
|
|
185
|
+
let toml = TOML.parse(text);
|
|
186
|
+
let processDeps = (deps) => {
|
|
187
|
+
Object.entries(deps).forEach(([name, data]) => {
|
|
188
|
+
if (!data || typeof data !== 'string') {
|
|
189
|
+
throw Error(`Invalid dependency value ${name} = "${data}"`);
|
|
190
|
+
}
|
|
191
|
+
if (data.startsWith('https://github.com/')) {
|
|
192
|
+
deps[name] = { name, repo: data, version: '' };
|
|
193
|
+
}
|
|
194
|
+
else if (data.match(/^(\.?\.)?\//)) {
|
|
195
|
+
deps[name] = { name, repo: '', path: data, version: '' };
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
deps[name] = { name, repo: '', version: data };
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
processDeps(toml.dependencies || {});
|
|
203
|
+
processDeps(toml['dev-dependencies'] || {});
|
|
204
|
+
return toml;
|
|
205
|
+
}
|
|
206
|
+
export function writeConfig(config, configFile = getClosestConfigFile()) {
|
|
207
|
+
let resConfig = { ...config };
|
|
208
|
+
let deps = resConfig.dependencies || {};
|
|
209
|
+
Object.entries(config.dependencies || {}).forEach(([name, { repo, path, version }]) => {
|
|
210
|
+
deps[name] = repo || path || version;
|
|
211
|
+
});
|
|
212
|
+
let devDeps = resConfig['dev-dependencies'] || {};
|
|
213
|
+
Object.entries(config['dev-dependencies'] || {}).forEach(([name, { repo, path, version }]) => {
|
|
214
|
+
devDeps[name] = repo || path || version;
|
|
215
|
+
});
|
|
216
|
+
let text = TOML.stringify(resConfig).trim();
|
|
217
|
+
if (fs.existsSync(configFile) && fs.readFileSync(configFile).toString().endsWith('\n')) {
|
|
218
|
+
text += '\n';
|
|
219
|
+
}
|
|
220
|
+
fs.writeFileSync(configFile, text);
|
|
221
|
+
}
|
|
222
|
+
export function formatDir(name, version) {
|
|
223
|
+
return path.join(getRootDir(), '.mops', `${name}@${version}`);
|
|
224
|
+
}
|
|
225
|
+
export function formatGithubDir(name, repo) {
|
|
226
|
+
const { branch } = parseGithubURL(repo);
|
|
227
|
+
return path.join(getRootDir(), '.mops/_github', `${name}@${branch}`);
|
|
228
|
+
}
|
|
229
|
+
export function readDfxJson() {
|
|
230
|
+
let dir = process.cwd();
|
|
231
|
+
let dfxJson = null;
|
|
232
|
+
for (let i = 0; i < 5; i++) {
|
|
233
|
+
let file = path.resolve(dir, 'dfx.json');
|
|
234
|
+
if (fs.existsSync(file)) {
|
|
235
|
+
dfxJson = JSON.parse(fs.readFileSync(file).toString());
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
dir = path.resolve(dir, '..');
|
|
239
|
+
}
|
|
240
|
+
return dfxJson;
|
|
241
|
+
}
|
|
242
|
+
// warn on minor mismatch
|
|
243
|
+
// err on major mismatch
|
|
244
|
+
export async function checkApiCompatibility() {
|
|
245
|
+
let actor = await mainActor();
|
|
246
|
+
let backendApiVer = await actor.getApiVersion();
|
|
247
|
+
if (backendApiVer.split('.')[0] !== apiVersion.split('.')[0]) {
|
|
248
|
+
console.log(chalk.red('ERR: ') + `CLI incompatible with backend. CLI v${apiVersion}, Backend v${backendApiVer}`);
|
|
249
|
+
console.log('Run ' + chalk.greenBright('npm i -g ic-mops') + ' to upgrade cli.');
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
else if (backendApiVer.split('.')[1] !== apiVersion.split('.')[1]) {
|
|
253
|
+
console.log('-'.repeat(50));
|
|
254
|
+
console.log(chalk.yellow('WARN: ') + `CLI probably incompatible with backend. CLI v${apiVersion}, Backend v${backendApiVer}`);
|
|
255
|
+
console.log('Recommended to run ' + chalk.greenBright('npm i -g ic-mops') + ' to upgrade cli.');
|
|
256
|
+
console.log('-'.repeat(50));
|
|
257
|
+
}
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ic-mops",
|
|
3
|
+
"version": "0.20.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"mops": "dist/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"*",
|
|
10
|
+
"!network.txt",
|
|
11
|
+
"!.mops",
|
|
12
|
+
"/templates"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://mops.one",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/ZenVoich/mops.git"
|
|
18
|
+
},
|
|
19
|
+
"author": "Zen Voich <zen.voich@gmail.com>",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=16.0.0"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"bundle": "esbuild --bundle --outfile=cli.js --platform=node --packages=external --target=node16 --format=esm ./dist/cli.js",
|
|
27
|
+
"copy": "cp -r declarations templates network.txt package.json dist | true",
|
|
28
|
+
"save-network": "cp -r dist/network.txt . | true",
|
|
29
|
+
"prepare": "npm run save-network && npm run build && npm run copy",
|
|
30
|
+
"check": "tsc --project tsconfig.json --noEmit",
|
|
31
|
+
"tsc": "tsc",
|
|
32
|
+
"esbuild": "esbuild"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@dfinity/agent": "^0.18.1",
|
|
36
|
+
"@dfinity/candid": "^0.18.1",
|
|
37
|
+
"@dfinity/identity": "^0.18.1",
|
|
38
|
+
"@dfinity/identity-secp256k1": "^0.18.1",
|
|
39
|
+
"@dfinity/principal": "^0.18.1",
|
|
40
|
+
"@iarna/toml": "^2.2.5",
|
|
41
|
+
"as-table": "^1.0.55",
|
|
42
|
+
"cacheable-request": "10.2.12",
|
|
43
|
+
"chalk": "^5.3.0",
|
|
44
|
+
"chokidar": "^3.5.3",
|
|
45
|
+
"commander": "^11.0.0",
|
|
46
|
+
"debounce": "^1.2.1",
|
|
47
|
+
"decompress": "^4.2.1",
|
|
48
|
+
"del": "^7.0.0",
|
|
49
|
+
"dhall-to-json-cli": "^1.7.6",
|
|
50
|
+
"eslint": "^8.45.0",
|
|
51
|
+
"execa": "7.1.1",
|
|
52
|
+
"get-folder-size": "^4.0.0",
|
|
53
|
+
"glob": "^10.3.3",
|
|
54
|
+
"globby": "^13.2.2",
|
|
55
|
+
"got": "13.0.0",
|
|
56
|
+
"log-update": "^5.0.1",
|
|
57
|
+
"minimatch": "^9.0.3",
|
|
58
|
+
"ncp": "^2.0.0",
|
|
59
|
+
"node-fetch": "^3.3.2",
|
|
60
|
+
"pem-file": "^1.0.1",
|
|
61
|
+
"prompts": "^2.4.2",
|
|
62
|
+
"stream-to-promise": "^3.0.0",
|
|
63
|
+
"tar": "^6.1.15"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@tsconfig/strictest": "^2.0.1",
|
|
67
|
+
"@types/debounce": "^1.2.1",
|
|
68
|
+
"@types/decompress": "^4.2.4",
|
|
69
|
+
"@types/glob": "^8.1.0",
|
|
70
|
+
"@types/ncp": "^2.0.5",
|
|
71
|
+
"@types/node": "^20.4.4",
|
|
72
|
+
"@types/prompts": "^2.4.4",
|
|
73
|
+
"@types/stream-to-promise": "^2.2.1",
|
|
74
|
+
"@types/tar": "^6.1.5",
|
|
75
|
+
"esbuild": "^0.18.16",
|
|
76
|
+
"tsx": "^3.12.7",
|
|
77
|
+
"typescript": "^5.1.6"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parallel(threads: number, items: any[], fn: CallableFunction): Promise<void>;
|
package/dist/parallel.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export async function parallel(threads, items, fn) {
|
|
2
|
+
return new Promise((resolve) => {
|
|
3
|
+
let busyThreads = 0;
|
|
4
|
+
items = items.slice();
|
|
5
|
+
let loop = () => {
|
|
6
|
+
if (!items.length) {
|
|
7
|
+
if (busyThreads === 0) {
|
|
8
|
+
resolve();
|
|
9
|
+
}
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (busyThreads >= threads) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
busyThreads++;
|
|
16
|
+
fn(items.shift()).then(() => {
|
|
17
|
+
busyThreads--;
|
|
18
|
+
loop();
|
|
19
|
+
});
|
|
20
|
+
loop();
|
|
21
|
+
};
|
|
22
|
+
loop();
|
|
23
|
+
});
|
|
24
|
+
}
|
package/dist/pem.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { Ed25519KeyIdentity } from '@dfinity/identity';
|
|
3
|
+
import { Secp256k1KeyIdentity } from '@dfinity/identity-secp256k1';
|
|
4
|
+
export declare function decodeFile(file: string, password?: string): Secp256k1KeyIdentity | Ed25519KeyIdentity;
|
|
5
|
+
export declare function encrypt(buffer: Buffer, password: string): Buffer;
|
package/dist/pem.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { Ed25519KeyIdentity } from '@dfinity/identity';
|
|
3
|
+
import { Secp256k1KeyIdentity } from '@dfinity/identity-secp256k1';
|
|
4
|
+
import pemfile from 'pem-file';
|
|
5
|
+
import crypto from 'crypto';
|
|
6
|
+
export function decodeFile(file, password) {
|
|
7
|
+
let rawKey = fs.readFileSync(file);
|
|
8
|
+
if (password) {
|
|
9
|
+
return decode(decrypt(rawKey, password));
|
|
10
|
+
}
|
|
11
|
+
return decode(rawKey);
|
|
12
|
+
}
|
|
13
|
+
function decode(rawKey) {
|
|
14
|
+
let buf = pemfile.decode(rawKey);
|
|
15
|
+
if (rawKey.includes('EC PRIVATE KEY')) {
|
|
16
|
+
if (buf.length != 118) {
|
|
17
|
+
throw 'expecting byte length 118 but got ' + buf.length;
|
|
18
|
+
}
|
|
19
|
+
return Secp256k1KeyIdentity.fromSecretKey(buf.subarray(7, 39));
|
|
20
|
+
}
|
|
21
|
+
if (buf.length != 85) {
|
|
22
|
+
throw 'expecting byte length 85 but got ' + buf.length;
|
|
23
|
+
}
|
|
24
|
+
let secretKey = Buffer.concat([buf.subarray(16, 48), buf.subarray(53, 85)]);
|
|
25
|
+
return Ed25519KeyIdentity.fromSecretKey(secretKey);
|
|
26
|
+
}
|
|
27
|
+
let algorithm = 'aes-256-ctr';
|
|
28
|
+
export function encrypt(buffer, password) {
|
|
29
|
+
let key = crypto.createHash('sha256').update(password).digest('base64').slice(0, 32);
|
|
30
|
+
// Create an initialization vector
|
|
31
|
+
let iv = crypto.randomBytes(16);
|
|
32
|
+
// Create a new cipher using the algorithm, key, and iv
|
|
33
|
+
let cipher = crypto.createCipheriv(algorithm, key, iv);
|
|
34
|
+
// Create the new (encrypted) buffer
|
|
35
|
+
let result = Buffer.concat([iv, cipher.update(buffer), cipher.final()]);
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
function decrypt(encrypted, password) {
|
|
39
|
+
let key = crypto.createHash('sha256').update(password).digest('base64').slice(0, 32);
|
|
40
|
+
// Get the iv: the first 16 bytes
|
|
41
|
+
let iv = encrypted.subarray(0, 16);
|
|
42
|
+
// Get the rest
|
|
43
|
+
encrypted = encrypted.subarray(16);
|
|
44
|
+
// Create a decipher
|
|
45
|
+
let decipher = crypto.createDecipheriv(algorithm, key, iv);
|
|
46
|
+
// Actually decrypt it
|
|
47
|
+
let result = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: mops test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
- master
|
|
8
|
+
pull_request:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v3
|
|
16
|
+
- uses: actions/setup-node@v3
|
|
17
|
+
with:
|
|
18
|
+
node-version: 18
|
|
19
|
+
|
|
20
|
+
- name: install moc
|
|
21
|
+
run: npx mocv use latest
|
|
22
|
+
|
|
23
|
+
- name: install mops
|
|
24
|
+
run: npm i ic-mops -g
|
|
25
|
+
|
|
26
|
+
- name: install mops packages
|
|
27
|
+
run: mops install
|
|
28
|
+
|
|
29
|
+
- name: run tests
|
|
30
|
+
run: mops test
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type Config = {
|
|
2
|
+
package?: {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
license?: string;
|
|
7
|
+
repository?: string;
|
|
8
|
+
keywords?: string[];
|
|
9
|
+
baseDir?: string;
|
|
10
|
+
readme?: string;
|
|
11
|
+
files?: string[];
|
|
12
|
+
homepage?: string;
|
|
13
|
+
documentation?: string;
|
|
14
|
+
dfx?: string;
|
|
15
|
+
moc?: string;
|
|
16
|
+
donation?: string;
|
|
17
|
+
};
|
|
18
|
+
dependencies?: Dependencies;
|
|
19
|
+
'dev-dependencies'?: Dependencies;
|
|
20
|
+
};
|
|
21
|
+
export type Dependencies = Record<string, Dependency>;
|
|
22
|
+
export type Dependency = {
|
|
23
|
+
name: string;
|
|
24
|
+
version?: string;
|
|
25
|
+
repo?: string;
|
|
26
|
+
path?: string;
|
|
27
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|