genlayer 0.12.2-beta.2 → 0.12.2
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/CHANGELOG.md +1 -5
- package/dist/index.js +375 -462
- package/esbuild.config.dev.js +1 -1
- package/esbuild.config.prod.js +2 -3
- package/package.json +2 -2
- package/src/commands/contracts/deploy.ts +25 -105
- package/src/commands/contracts/index.ts +1 -5
- package/src/commands/general/init.ts +1 -0
- package/src/lib/config/simulator.ts +2 -2
- package/tests/actions/deploy.test.ts +30 -200
- package/tests/commands/call.test.ts +0 -3
- package/tests/commands/deploy.test.ts +0 -11
package/esbuild.config.dev.js
CHANGED
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
banner: {
|
|
12
12
|
js: `const _importMetaUrl = new URL(import.meta.url).pathname;`,
|
|
13
13
|
},
|
|
14
|
-
external: ["commander", "dockerode", "dotenv", "ethers", "inquirer", "update-check", "ssh2"
|
|
14
|
+
external: ["commander", "dockerode", "dotenv", "ethers", "inquirer", "update-check", "ssh2"]
|
|
15
15
|
|
|
16
16
|
},
|
|
17
17
|
watch: true,
|
package/esbuild.config.prod.js
CHANGED
|
@@ -6,12 +6,11 @@ export default {
|
|
|
6
6
|
outfile: "dist/index.js",
|
|
7
7
|
platform: "node",
|
|
8
8
|
target: "es2020",
|
|
9
|
-
|
|
10
|
-
define: { "import.meta.url": "import.meta.url" },
|
|
9
|
+
define: { "import.meta.url": "_importMetaUrl" },
|
|
11
10
|
banner: {
|
|
12
11
|
js: `const _importMetaUrl = new URL(import.meta.url).pathname;`,
|
|
13
12
|
},
|
|
14
|
-
external: ["commander", "dockerode", "dotenv", "ethers", "inquirer", "update-check", "ssh2"
|
|
13
|
+
external: ["commander", "dockerode", "dotenv", "ethers", "inquirer", "update-check", "ssh2"]
|
|
15
14
|
},
|
|
16
15
|
watch: false,
|
|
17
16
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genlayer",
|
|
3
|
-
"version": "0.12.2
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "GenLayer Command Line Tool",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@typescript-eslint/parser": "^8.0.0",
|
|
46
46
|
"@vitest/coverage-v8": "^2.1.4",
|
|
47
47
|
"cross-env": "^7.0.3",
|
|
48
|
-
"esbuild": "
|
|
48
|
+
"esbuild": "^0.25.0",
|
|
49
49
|
"eslint": "^9.0.0",
|
|
50
50
|
"eslint-config-prettier": "^10.0.0",
|
|
51
51
|
"eslint-import-resolver-typescript": "^3.6.1",
|
|
@@ -1,25 +1,20 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
2
|
import { createClient, createAccount } from "genlayer-js";
|
|
4
3
|
import { simulator } from "genlayer-js/chains";
|
|
5
4
|
import type { GenLayerClient } from "genlayer-js/types";
|
|
6
5
|
import { getPrivateKey } from "../../lib/accounts/getPrivateKey";
|
|
7
|
-
import { BaseAction } from "../../lib/actions/BaseAction";
|
|
8
|
-
import { pathToFileURL } from "url";
|
|
9
|
-
import { TransactionStatus } from "genlayer-js/types";
|
|
10
|
-
import { buildSync } from "esbuild";
|
|
11
6
|
|
|
12
7
|
export interface DeployOptions {
|
|
13
8
|
contract?: string;
|
|
9
|
+
// network: string;
|
|
14
10
|
args?: any[];
|
|
11
|
+
kwargs?: string;
|
|
15
12
|
}
|
|
16
13
|
|
|
17
|
-
export class DeployAction
|
|
14
|
+
export class DeployAction {
|
|
18
15
|
private genlayerClient: GenLayerClient<typeof simulator>;
|
|
19
|
-
private readonly deployDir = path.resolve(process.cwd(), "deploy");
|
|
20
16
|
|
|
21
17
|
constructor() {
|
|
22
|
-
super();
|
|
23
18
|
this.genlayerClient = createClient({
|
|
24
19
|
chain: simulator,
|
|
25
20
|
endpoint: process.env.VITE_JSON_RPC_SERVER_URL,
|
|
@@ -34,119 +29,44 @@ export class DeployAction extends BaseAction {
|
|
|
34
29
|
return fs.readFileSync(contractPath, "utf-8");
|
|
35
30
|
}
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
const outFile = filePath.replace(/\.ts$/, ".compiled.js");
|
|
39
|
-
this.startSpinner(`Transpiling TypeScript file: ${filePath}`);
|
|
40
|
-
try {
|
|
41
|
-
buildSync({
|
|
42
|
-
entryPoints: [filePath],
|
|
43
|
-
outfile: outFile,
|
|
44
|
-
bundle: false,
|
|
45
|
-
platform: "node",
|
|
46
|
-
format: "esm",
|
|
47
|
-
target: "es2020",
|
|
48
|
-
sourcemap: false,
|
|
49
|
-
});
|
|
50
|
-
await this.executeJsScript(filePath, outFile);
|
|
51
|
-
} catch (error) {
|
|
52
|
-
this.failSpinner(`Error executing: ${filePath}`, error);
|
|
53
|
-
} finally {
|
|
54
|
-
fs.unlinkSync(outFile);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
32
|
+
async deploy(options: DeployOptions): Promise<void> {
|
|
57
33
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.failSpinner(`No "default" function found in: ${filePath}`);
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
await module.default(this.genlayerClient);
|
|
67
|
-
this.succeedSpinner(`Successfully executed: ${filePath}`);
|
|
68
|
-
} catch (error) {
|
|
69
|
-
this.failSpinner(`Error executing: ${filePath}`, error);
|
|
34
|
+
const argsUsed = options.args && options.args.length > 0;
|
|
35
|
+
const kwargsUsed = options.kwargs && options.kwargs.trim() !== "";
|
|
36
|
+
|
|
37
|
+
if (argsUsed && kwargsUsed) {
|
|
38
|
+
throw new Error("Invalid usage: Please specify either `args` or `kwargs`, but not both.");
|
|
70
39
|
}
|
|
71
|
-
}
|
|
72
40
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (!fs.existsSync(this.deployDir)) {
|
|
76
|
-
this.failSpinner("No deploy folder found.");
|
|
41
|
+
if (!options.contract) {
|
|
42
|
+
console.error("No contract specified for deployment.");
|
|
77
43
|
return;
|
|
78
44
|
}
|
|
79
|
-
const files = fs.readdirSync(this.deployDir)
|
|
80
|
-
.filter(file => file.endsWith(".ts") || file.endsWith(".js"))
|
|
81
|
-
.sort((a, b) => {
|
|
82
|
-
const numA = parseInt(a.split("_")[0]);
|
|
83
|
-
const numB = parseInt(b.split("_")[0]);
|
|
84
45
|
|
|
85
|
-
|
|
86
|
-
if (!isNaN(numA)) return -1;
|
|
87
|
-
if (!isNaN(numB)) return 1;
|
|
88
|
-
return a.localeCompare(b);
|
|
89
|
-
});
|
|
46
|
+
const contractCode = this.readContractCode(options.contract);
|
|
90
47
|
|
|
91
|
-
if (
|
|
92
|
-
|
|
48
|
+
if (!contractCode) {
|
|
49
|
+
console.error("Contract code is empty.");
|
|
93
50
|
return;
|
|
94
51
|
}
|
|
95
52
|
|
|
96
|
-
|
|
53
|
+
const leaderOnly = false;
|
|
54
|
+
let deployParams: any = { code: contractCode, args: options.args, leaderOnly };
|
|
97
55
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this.setSpinnerText(`Executing script: ${filePath}`);
|
|
101
|
-
try {
|
|
102
|
-
if (file.endsWith(".ts")) {
|
|
103
|
-
await this.executeTsScript(filePath);
|
|
104
|
-
} else {
|
|
105
|
-
await this.executeJsScript(filePath);
|
|
106
|
-
}
|
|
107
|
-
} catch (error) {
|
|
108
|
-
this.failSpinner(`Error executing script: ${filePath}`, error);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
56
|
+
console.log("Starting contract deployment...");
|
|
57
|
+
console.log("Deployment Parameters:", deployParams);
|
|
112
58
|
|
|
113
|
-
async deploy(options: DeployOptions): Promise<void> {
|
|
114
59
|
try {
|
|
115
|
-
this.
|
|
116
|
-
await this.genlayerClient.initializeConsensusSmartContract();
|
|
117
|
-
|
|
118
|
-
if (!options.contract) {
|
|
119
|
-
this.failSpinner("No contract specified for deployment.");
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
this.setSpinnerText("Reading contract code...");
|
|
123
|
-
const contractCode = this.readContractCode(options.contract);
|
|
124
|
-
|
|
125
|
-
if (!contractCode) {
|
|
126
|
-
this.failSpinner("Contract code is empty.");
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const leaderOnly = false;
|
|
131
|
-
const deployParams: any = { code: contractCode, args: options.args, leaderOnly };
|
|
132
|
-
|
|
133
|
-
this.setSpinnerText("Starting contract deployment...");
|
|
134
|
-
this.log("Deployment Parameters:", deployParams);
|
|
60
|
+
const hash = await this.genlayerClient.deployContract(deployParams) as any;
|
|
135
61
|
|
|
136
|
-
const
|
|
137
|
-
const result = await this.genlayerClient.waitForTransactionReceipt({
|
|
138
|
-
hash,
|
|
139
|
-
retries: 15,
|
|
140
|
-
interval: 2000,
|
|
141
|
-
status: TransactionStatus.ACCEPTED,
|
|
142
|
-
});
|
|
62
|
+
const result = await this.genlayerClient.waitForTransactionReceipt({hash, retries: 15, interval: 2000})
|
|
143
63
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
});
|
|
64
|
+
console.log("Contract deployed successfully.");
|
|
65
|
+
console.log("Transaction Hash:", hash);
|
|
66
|
+
console.log("Contract Address:", result.data?.contract_address);
|
|
148
67
|
} catch (error) {
|
|
149
|
-
|
|
68
|
+
console.error("Error deploying contract:", error);
|
|
69
|
+
throw new Error("Contract deployment failed.");
|
|
150
70
|
}
|
|
151
71
|
}
|
|
152
72
|
}
|
|
@@ -12,11 +12,7 @@ export function initializeContractsCommands(program: Command) {
|
|
|
12
12
|
.option("--args <args...>", "Positional arguments for the contract (space-separated, use quotes for multi-word arguments)", [])
|
|
13
13
|
.action(async (options: DeployOptions) => {
|
|
14
14
|
const deployer = new DeployAction();
|
|
15
|
-
|
|
16
|
-
await deployer.deploy(options);
|
|
17
|
-
}else {
|
|
18
|
-
await deployer.deployScripts();
|
|
19
|
-
}
|
|
15
|
+
await deployer.deploy(options);
|
|
20
16
|
});
|
|
21
17
|
|
|
22
18
|
program
|
|
@@ -94,6 +94,7 @@ export class InitAction extends BaseAction {
|
|
|
94
94
|
const selectedLlmProviders = llmProvidersAnswer.selectedLlmProviders as AiProviders[];
|
|
95
95
|
|
|
96
96
|
let defaultOllamaModel = this.getConfig().defaultOllamaModel;
|
|
97
|
+
AI_PROVIDERS_CONFIG.ollama.hint = `(This will download and run a local instance of ${defaultOllamaModel})`;
|
|
97
98
|
const aiProvidersEnvVars: Record<string, string> = {};
|
|
98
99
|
const configurableAiProviders = selectedLlmProviders.filter(
|
|
99
100
|
(provider: AiProviders) => AI_PROVIDERS_CONFIG[provider].envVar
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const localnetCompatibleVersion = "v0.
|
|
1
|
+
export const localnetCompatibleVersion = "v0.42.0";
|
|
2
2
|
export const DEFAULT_JSON_RPC_URL = "http://localhost:4000/api";
|
|
3
3
|
export const CONTAINERS_NAME_PREFIX = "/genlayer-";
|
|
4
4
|
export const IMAGES_NAME_PREFIX = "yeagerai";
|
|
@@ -32,7 +32,7 @@ export type AiProvidersConfigType = {
|
|
|
32
32
|
export const AI_PROVIDERS_CONFIG: AiProvidersConfigType = {
|
|
33
33
|
ollama: {
|
|
34
34
|
name: "Ollama",
|
|
35
|
-
hint: "(
|
|
35
|
+
hint: "(This will download and run a local instance of Llama 3)",
|
|
36
36
|
cliOptionValue: "ollama",
|
|
37
37
|
},
|
|
38
38
|
openai: {
|
|
@@ -3,22 +3,16 @@ import fs from "fs";
|
|
|
3
3
|
import { createClient, createAccount } from "genlayer-js";
|
|
4
4
|
import { DeployAction, DeployOptions } from "../../src/commands/contracts/deploy";
|
|
5
5
|
import { getPrivateKey } from "../../src/lib/accounts/getPrivateKey";
|
|
6
|
-
import { buildSync } from "esbuild";
|
|
7
|
-
import { pathToFileURL } from "url";
|
|
8
6
|
|
|
9
7
|
vi.mock("fs");
|
|
10
8
|
vi.mock("genlayer-js");
|
|
11
|
-
vi.mock("esbuild", () => ({
|
|
12
|
-
buildSync: vi.fn(),
|
|
13
|
-
}));
|
|
14
9
|
vi.mock("../../src/lib/accounts/getPrivateKey");
|
|
15
10
|
|
|
16
|
-
describe("
|
|
11
|
+
describe("Deploy Action", () => {
|
|
17
12
|
let deployer: DeployAction;
|
|
18
13
|
const mockClient = {
|
|
19
14
|
deployContract: vi.fn(),
|
|
20
|
-
waitForTransactionReceipt: vi.fn()
|
|
21
|
-
initializeConsensusSmartContract: vi.fn(),
|
|
15
|
+
waitForTransactionReceipt: vi.fn()
|
|
22
16
|
};
|
|
23
17
|
|
|
24
18
|
const mockPrivateKey = "mocked_private_key";
|
|
@@ -29,12 +23,6 @@ describe("DeployAction", () => {
|
|
|
29
23
|
vi.mocked(createAccount).mockReturnValue({ privateKey: mockPrivateKey } as any);
|
|
30
24
|
vi.mocked(getPrivateKey).mockReturnValue(mockPrivateKey);
|
|
31
25
|
deployer = new DeployAction();
|
|
32
|
-
|
|
33
|
-
vi.spyOn(deployer as any, "startSpinner").mockImplementation(() => {});
|
|
34
|
-
vi.spyOn(deployer as any, "succeedSpinner").mockImplementation(() => {});
|
|
35
|
-
vi.spyOn(deployer as any, "failSpinner").mockImplementation(() => {});
|
|
36
|
-
vi.spyOn(deployer as any, "setSpinnerText").mockImplementation(() => {});
|
|
37
|
-
vi.spyOn(deployer as any, "log").mockImplementation(() => {});
|
|
38
26
|
});
|
|
39
27
|
|
|
40
28
|
afterEach(() => {
|
|
@@ -64,6 +52,7 @@ describe("DeployAction", () => {
|
|
|
64
52
|
expect(fs.existsSync).toHaveBeenCalledWith(contractPath);
|
|
65
53
|
});
|
|
66
54
|
|
|
55
|
+
|
|
67
56
|
test("deploys contract with args", async () => {
|
|
68
57
|
const options: DeployOptions = {
|
|
69
58
|
contract: "/mocked/contract/path",
|
|
@@ -74,9 +63,7 @@ describe("DeployAction", () => {
|
|
|
74
63
|
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
75
64
|
vi.mocked(fs.readFileSync).mockReturnValue(contractContent);
|
|
76
65
|
vi.mocked(mockClient.deployContract).mockResolvedValue("mocked_tx_hash");
|
|
77
|
-
vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue({
|
|
78
|
-
data: { contract_address: "0xdasdsadasdasdada" },
|
|
79
|
-
});
|
|
66
|
+
vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue({data: {contractAddress: '0xdasdsadasdasdada'}});
|
|
80
67
|
|
|
81
68
|
await deployer.deploy(options);
|
|
82
69
|
|
|
@@ -86,15 +73,31 @@ describe("DeployAction", () => {
|
|
|
86
73
|
args: [1, 2, 3],
|
|
87
74
|
leaderOnly: false,
|
|
88
75
|
});
|
|
89
|
-
expect(mockClient.deployContract).
|
|
76
|
+
expect(mockClient.deployContract).toHaveResolvedWith("mocked_tx_hash");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("throws error for both args and kwargs", async () => {
|
|
80
|
+
const options: DeployOptions = {
|
|
81
|
+
contract: "/mocked/contract/path",
|
|
82
|
+
args: [1, 2, 3],
|
|
83
|
+
kwargs: "key1=value1,key2=42",
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
await expect(deployer.deploy(options)).rejects.toThrowError(
|
|
87
|
+
"Invalid usage: Please specify either `args` or `kwargs`, but not both."
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
expect(fs.readFileSync).not.toHaveBeenCalled();
|
|
91
|
+
expect(mockClient.deployContract).not.toHaveBeenCalled();
|
|
90
92
|
});
|
|
91
93
|
|
|
92
94
|
test("throws error for missing contract", async () => {
|
|
93
|
-
const options: DeployOptions = {
|
|
95
|
+
const options: DeployOptions = {
|
|
96
|
+
};
|
|
94
97
|
|
|
95
98
|
await deployer.deploy(options);
|
|
96
99
|
|
|
97
|
-
expect(
|
|
100
|
+
expect(fs.readFileSync).not.toHaveBeenCalled();
|
|
98
101
|
expect(mockClient.deployContract).not.toHaveBeenCalled();
|
|
99
102
|
});
|
|
100
103
|
|
|
@@ -111,13 +114,15 @@ describe("DeployAction", () => {
|
|
|
111
114
|
new Error("Mocked deployment error")
|
|
112
115
|
);
|
|
113
116
|
|
|
114
|
-
await deployer.deploy(options)
|
|
117
|
+
await expect(deployer.deploy(options)).rejects.toThrowError(
|
|
118
|
+
"Contract deployment failed."
|
|
119
|
+
);
|
|
115
120
|
|
|
116
|
-
expect(
|
|
121
|
+
expect(fs.readFileSync).toHaveBeenCalledWith(options.contract, "utf-8");
|
|
117
122
|
expect(mockClient.deployContract).toHaveBeenCalled();
|
|
118
123
|
});
|
|
119
124
|
|
|
120
|
-
test("
|
|
125
|
+
test("throws error if contract code is empty", async () => {
|
|
121
126
|
const options: DeployOptions = {
|
|
122
127
|
contract: "/mocked/contract/path",
|
|
123
128
|
};
|
|
@@ -127,183 +132,8 @@ describe("DeployAction", () => {
|
|
|
127
132
|
|
|
128
133
|
await deployer.deploy(options);
|
|
129
134
|
|
|
130
|
-
expect(
|
|
135
|
+
expect(fs.existsSync).toHaveBeenCalledWith(options.contract);
|
|
136
|
+
expect(fs.readFileSync).toHaveBeenCalledWith(options.contract, "utf-8");
|
|
131
137
|
expect(mockClient.deployContract).not.toHaveBeenCalled();
|
|
132
138
|
});
|
|
133
|
-
|
|
134
|
-
test("deployScripts executes scripts in order", async () => {
|
|
135
|
-
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
136
|
-
vi.mocked(fs.readdirSync).mockReturnValue([
|
|
137
|
-
"1_first.ts",
|
|
138
|
-
"2_second.js",
|
|
139
|
-
"10_last.ts",
|
|
140
|
-
] as any);
|
|
141
|
-
|
|
142
|
-
vi.spyOn(deployer as any, "executeTsScript").mockResolvedValue(undefined);
|
|
143
|
-
vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined);
|
|
144
|
-
|
|
145
|
-
await deployer.deployScripts();
|
|
146
|
-
|
|
147
|
-
expect(deployer["setSpinnerText"]).toHaveBeenCalledWith("Found 3 deploy scripts. Executing...");
|
|
148
|
-
expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringMatching(/1_first.ts/));
|
|
149
|
-
expect(deployer["executeJsScript"]).toHaveBeenCalledWith(expect.stringMatching(/2_second.js/));
|
|
150
|
-
expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringMatching(/10_last.ts/));
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
test("executeTsScript transpiles and executes TypeScript", async () => {
|
|
154
|
-
const filePath = "/mocked/script.ts";
|
|
155
|
-
const outFile = "/mocked/script.compiled.js";
|
|
156
|
-
|
|
157
|
-
vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined);
|
|
158
|
-
vi.mocked(buildSync).mockImplementation((() => {}) as any);
|
|
159
|
-
|
|
160
|
-
await deployer["executeTsScript"](filePath);
|
|
161
|
-
|
|
162
|
-
expect(deployer["startSpinner"]).toHaveBeenCalledWith(`Transpiling TypeScript file: ${filePath}`);
|
|
163
|
-
expect(buildSync).toHaveBeenCalledWith({
|
|
164
|
-
entryPoints: [filePath],
|
|
165
|
-
outfile: outFile,
|
|
166
|
-
bundle: false,
|
|
167
|
-
platform: "node",
|
|
168
|
-
format: "esm",
|
|
169
|
-
target: "es2020",
|
|
170
|
-
sourcemap: false,
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
expect(deployer["executeJsScript"]).toHaveBeenCalledWith(filePath, outFile);
|
|
174
|
-
expect(fs.unlinkSync).toHaveBeenCalledWith(outFile);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
test("deployScripts fails when deploy folder is missing", async () => {
|
|
178
|
-
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
179
|
-
|
|
180
|
-
await deployer.deployScripts();
|
|
181
|
-
|
|
182
|
-
expect(deployer["failSpinner"]).toHaveBeenCalledWith("No deploy folder found.");
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test("deployScripts sorts and executes scripts correctly", async () => {
|
|
186
|
-
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
187
|
-
vi.mocked(fs.readdirSync).mockReturnValue([
|
|
188
|
-
"10_last.ts",
|
|
189
|
-
"2_second.js",
|
|
190
|
-
"1_first.ts"
|
|
191
|
-
] as any);
|
|
192
|
-
|
|
193
|
-
vi.spyOn(deployer as any, "executeTsScript").mockResolvedValue(undefined);
|
|
194
|
-
vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined);
|
|
195
|
-
|
|
196
|
-
await deployer.deployScripts();
|
|
197
|
-
|
|
198
|
-
expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("1_first.ts"));
|
|
199
|
-
expect(deployer["executeJsScript"]).toHaveBeenCalledWith(expect.stringContaining("2_second.js"));
|
|
200
|
-
expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("10_last.ts"));
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test("deployScripts fails when no scripts are found", async () => {
|
|
204
|
-
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
205
|
-
vi.mocked(fs.readdirSync).mockReturnValue([]);
|
|
206
|
-
|
|
207
|
-
await deployer.deployScripts();
|
|
208
|
-
|
|
209
|
-
expect(deployer["failSpinner"]).toHaveBeenCalledWith("No deploy scripts found.");
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
test("deployScripts handles script execution errors", async () => {
|
|
213
|
-
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
214
|
-
vi.mocked(fs.readdirSync).mockReturnValue(["1_failing.ts"] as any);
|
|
215
|
-
vi.spyOn(deployer as any, "executeTsScript").mockRejectedValue(new Error("Script error"));
|
|
216
|
-
|
|
217
|
-
await deployer.deployScripts();
|
|
218
|
-
|
|
219
|
-
expect(deployer["failSpinner"]).toHaveBeenCalledWith(
|
|
220
|
-
expect.stringContaining("Error executing script:"),
|
|
221
|
-
expect.any(Error)
|
|
222
|
-
);
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
test("executeJsScript fails gracefully", async () => {
|
|
226
|
-
const filePath = "/mocked/script.js";
|
|
227
|
-
|
|
228
|
-
await deployer["executeJsScript"](filePath);
|
|
229
|
-
|
|
230
|
-
expect(deployer["failSpinner"]).toHaveBeenCalledWith(
|
|
231
|
-
expect.stringContaining("Error executing:"),
|
|
232
|
-
expect.any(Error)
|
|
233
|
-
);
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
test("deploy fails when contract code is empty", async () => {
|
|
237
|
-
const options: DeployOptions = { contract: "/mocked/contract/path" };
|
|
238
|
-
|
|
239
|
-
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
240
|
-
vi.mocked(fs.readFileSync).mockReturnValue("");
|
|
241
|
-
|
|
242
|
-
await deployer.deploy(options);
|
|
243
|
-
|
|
244
|
-
expect(deployer["failSpinner"]).toHaveBeenCalledWith("Contract code is empty.");
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
test("deployScripts correctly sorts mixed numbered and non-numbered scripts", async () => {
|
|
248
|
-
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
249
|
-
vi.mocked(fs.readdirSync).mockReturnValue([
|
|
250
|
-
"script.ts",
|
|
251
|
-
"2alpha_script.ts",
|
|
252
|
-
"3alpha_script.ts",
|
|
253
|
-
"blpha_script.ts",
|
|
254
|
-
"clpha_script.ts"
|
|
255
|
-
] as any);
|
|
256
|
-
|
|
257
|
-
vi.spyOn(deployer as any, "executeTsScript").mockResolvedValue(undefined);
|
|
258
|
-
vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined);
|
|
259
|
-
|
|
260
|
-
await deployer.deployScripts();
|
|
261
|
-
|
|
262
|
-
expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("script.ts"));
|
|
263
|
-
expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("2alpha_script.ts"));
|
|
264
|
-
expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("3alpha_script.ts"));
|
|
265
|
-
expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("blpha_script.ts"));
|
|
266
|
-
expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("clpha_script.ts"));
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
test("executeJsScript fails if module has no default export", async () => {
|
|
270
|
-
const filePath = "/mocked/script.js";
|
|
271
|
-
|
|
272
|
-
vi.doMock(pathToFileURL(filePath).href, () => ({ default: "Not a function" }));
|
|
273
|
-
|
|
274
|
-
await deployer["executeJsScript"](filePath);
|
|
275
|
-
|
|
276
|
-
expect(deployer["failSpinner"]).toHaveBeenCalledWith(
|
|
277
|
-
expect.stringContaining("No \"default\" function found in:"),
|
|
278
|
-
);
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
test("executeJsScript successfully executes a script", async () => {
|
|
282
|
-
const filePath = "/mocked/script.js";
|
|
283
|
-
const mockFn = vi.fn(); // This mock function simulates the script execution
|
|
284
|
-
|
|
285
|
-
vi.doMock(pathToFileURL(filePath).href, () => ({ default: mockFn }));
|
|
286
|
-
|
|
287
|
-
await deployer["executeJsScript"](filePath);
|
|
288
|
-
|
|
289
|
-
expect(mockFn).toHaveBeenCalledWith(deployer["genlayerClient"]);
|
|
290
|
-
|
|
291
|
-
expect(deployer["succeedSpinner"]).toHaveBeenCalledWith(`Successfully executed: ${filePath}`);
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
test("executeTsScript fails when buildSync throws an error", async () => {
|
|
295
|
-
const filePath = "/mocked/script.ts";
|
|
296
|
-
const error = new Error("Build failed");
|
|
297
|
-
|
|
298
|
-
vi.mocked(buildSync).mockImplementation(() => {
|
|
299
|
-
throw error; // Simulate an error during transpilation
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
await deployer["executeTsScript"](filePath);
|
|
303
|
-
|
|
304
|
-
expect(deployer["failSpinner"]).toHaveBeenCalledWith(
|
|
305
|
-
`Error executing: ${filePath}`,
|
|
306
|
-
error
|
|
307
|
-
);
|
|
308
|
-
});
|
|
309
139
|
});
|
|
@@ -4,9 +4,6 @@ import { vi, describe, beforeEach, afterEach, test, expect } from "vitest";
|
|
|
4
4
|
import { initializeContractsCommands } from "../../src/commands/contracts";
|
|
5
5
|
|
|
6
6
|
vi.mock("../../src/commands/contracts/call");
|
|
7
|
-
vi.mock("esbuild", () => ({
|
|
8
|
-
buildSync: vi.fn(),
|
|
9
|
-
}));
|
|
10
7
|
|
|
11
8
|
describe("call command", () => {
|
|
12
9
|
let program: Command;
|
|
@@ -4,9 +4,6 @@ import { initializeContractsCommands } from "../../src/commands/contracts";
|
|
|
4
4
|
import { DeployAction } from "../../src/commands/contracts/deploy";
|
|
5
5
|
|
|
6
6
|
vi.mock("../../src/commands/contracts/deploy");
|
|
7
|
-
vi.mock("esbuild", () => ({
|
|
8
|
-
buildSync: vi.fn(),
|
|
9
|
-
}));
|
|
10
7
|
|
|
11
8
|
describe("deploy command", () => {
|
|
12
9
|
let program: Command;
|
|
@@ -69,12 +66,4 @@ describe("deploy command", () => {
|
|
|
69
66
|
program.parse(["node", "test", "deploy", "--contract", "./path/to/contract"])
|
|
70
67
|
).not.toThrow();
|
|
71
68
|
});
|
|
72
|
-
|
|
73
|
-
test("DeployAction.deployScripts is called without throwing errors", async () => {
|
|
74
|
-
program.parse(["node", "test", "deploy"]);
|
|
75
|
-
vi.mocked(DeployAction.prototype.deployScripts).mockResolvedValueOnce(undefined);
|
|
76
|
-
expect(() =>
|
|
77
|
-
program.parse(["node", "test", "deploy"])
|
|
78
|
-
).not.toThrow();
|
|
79
|
-
});
|
|
80
69
|
});
|