genlayer 0.18.2 → 0.18.4

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.18.4 (2025-06-27)
4
+
5
+ ### Bug Fixes
6
+
7
+ * refactor log output formatting and address spinner display ([#228](https://github.com/yeagerai/genlayer-cli/issues/228)) ([ea0ac10](https://github.com/yeagerai/genlayer-cli/commit/ea0ac100cdbed0cf184ae1eaf1d9c0fd580fc92c))
8
+
9
+ ## 0.18.3 (2025-05-29)
10
+
3
11
  ## 0.18.2 (2025-05-29)
4
12
 
5
13
  ## 0.18.2-beta.0 (2025-05-29)
@@ -0,0 +1,117 @@
1
+ # Contributing to GenLayer CLI
2
+
3
+ We're thrilled that you're interested in contributing to the GenLayer CLI! This document will guide you through the contribution process.
4
+
5
+ ## What is the GenLayer CLI?
6
+
7
+ The GenLayer CLI is a command-line tool designed to:
8
+ 1. Streamline the setup and local execution of the GenLayer simulator. It automates the process of downloading and launching the GenLayer simulator, making it easy to start simulating and testing locally with minimal setup.
9
+ 2. Deploy Intelligent Contracts on any network, read their state and send transactions to them.
10
+ 3. Perform Validators operations
11
+
12
+ ## How You Can Contribute?
13
+
14
+ Contributions to the GenLayer CLI are welcome in several forms:
15
+
16
+ ### Testing the CLI and Providing Feedback
17
+
18
+ Help us make the CLI better by testing and giving feedback:
19
+
20
+ - Start by installing the CLI globally using the command:
21
+ ```sh
22
+ $ npm install -g genlayer
23
+ ```
24
+ - Try out the CLI features and tell us what you think through our [feedback form](https://forms.gle/ZbbxHsZrJxKucurB7) or on our [Discord Channel](https://discord.gg/8Jm4v89VAu).
25
+ - If you find any issues, please report them on our [GitHub issues page](https://github.com/yeagerai/genlayer-cli/issues).
26
+
27
+ ### Sharing New Ideas and Use Cases
28
+
29
+ Have ideas for new features or use cases? We're eager to hear them! But first:
30
+
31
+ - Ensure you have the CLI installed to explore existing functionality.
32
+ - After familiarizing yourself with the CLI, contribute your unique use case and share your ideas in our [Discord channel](https://discord.gg/8Jm4v89VAu).
33
+
34
+ ### Bug fixing and Feature development
35
+
36
+ #### 1. Set yourself up to start coding
37
+
38
+ - **1.1. Pick an issue**: Select one from the project GitHub repository [issue list](https://github.com/yeagerai/genlayer-cli/issues) and assign it to yourself.
39
+
40
+ - **1.2. Create a branch**: create the branch that you will work on by using the link provided in the issue details page (right panel at the bottom - section "Development")
41
+
42
+ - **1.3. Setup the CLI locally**: clone the repository and install dependencies
43
+
44
+ ```sh
45
+ $ git clone https://github.com/yeagerai/genlayer-cli.git
46
+ $ cd genlayer-cli
47
+ $ npm install
48
+ ```
49
+
50
+ - **1.4. Run the CLI in dev mode**: to run the CLI in development mode with hot reload enabled:
51
+
52
+ ```sh
53
+ $ npm run dev
54
+ ```
55
+
56
+ - **1.5. Test the CLI locally**: to test the CLI commands locally during development:
57
+
58
+ ```sh
59
+ $ node dist/index.js <command>
60
+ ```
61
+
62
+ For example:
63
+ ```sh
64
+ $ node dist/index.js init
65
+ $ node dist/index.js up
66
+ $ node dist/index.js validators get
67
+ ```
68
+
69
+ - **1.6. Run unit tests**:
70
+ The GenLayer CLI uses Jest in combination with ts-jest to handle testing of TypeScript files. The configuration is tailored to support ES Modules (ESM), aligning with the latest JavaScript standards and ensuring compatibility with modern tooling and Node.js features.
71
+
72
+ ##### Running Tests
73
+
74
+ To run the tests, use the following command:
75
+
76
+ ```bash
77
+ npm run test
78
+ ```
79
+
80
+ This command sets the appropriate Node.js options to handle ES Modules and watches for changes in the test files, making it suitable for development.
81
+
82
+ ##### Test Configuration
83
+
84
+ Our `jest.config.js` is set up as follows:
85
+
86
+ - ES Module Support: Configured to treat .ts files as ES Modules.
87
+ - Test Environment: Uses Node.js as the testing environment.
88
+ - Transformation: Utilizes ts-jest with an ESM preset to process TypeScript files.
89
+
90
+ Tests are located in the tests/ directory and should be named using the following pattern: [filename].test.ts. When writing tests, you can use all Jest functionalities such as describe, test, expect, and Jest mocks for testing asynchronous functions, component interactions, or API calls.
91
+
92
+ #### 2. Submit your solution
93
+
94
+ - **2.1. Prettier Formatter on Save File**: Configure IDE extensions to format your code with [Prettier](https://prettier.io/) before submitting it.
95
+ - **2.2. Code solution**: implement the solution in the code.
96
+ - **2.3. Run tests**: Ensure all tests pass before submitting:
97
+ ```sh
98
+ $ npm run test
99
+ ```
100
+ - **2.4. Pull Request**: Submit your changes through a pull request (PR). Fill the entire PR template and set the PR title as a valid conventional commit.
101
+ - **2.5. Check PR and issue linking**: if the issue and the PR are not linked, you can do it manually in the right panel of the Pull Request details page.
102
+ - **2.6. Peer Review**: One or more core contributors will review your PR. They may suggest changes or improvements.
103
+ - **2.7. Approval and Merge**: After approval from the reviewers, you can merge your PR with a squash and merge type of action.
104
+
105
+
106
+ ### Improving Documentation
107
+
108
+ To contribute to our docs, visit our [Documentation Repository](https://github.com/yeagerai/genlayer-docs) to create new issues or contribute to existing issues.
109
+
110
+ ## Community
111
+
112
+ Connect with the GenLayer community to discuss, collaborate, and share insights:
113
+
114
+ - **[Discord Channel](https://discord.gg/8Jm4v89VAu)**: Our primary hub for discussions, support, and announcements.
115
+ - **[Telegram Group](https://t.me/genlayer)**: For more informal chats and quick updates.
116
+
117
+ Your continuous feedback drives better product development. Please engage with us regularly to test, discuss, and improve the GenLayer CLI.
package/README.md CHANGED
@@ -14,77 +14,275 @@ npm install -g genlayer
14
14
 
15
15
  ## Usage
16
16
 
17
- To initialize and start the GenLayer simulator, run the following command:
17
+ Each command includes syntax, usage information, and examples to help you effectively use the CLI for interacting with the GenLayer environment.
18
+
19
+ ### Command line syntax
20
+
21
+ General syntax for using the GenLayer CLI:
18
22
 
19
23
  ```bash
20
- genlayer init
24
+ genlayer command [command options] [arguments...]
21
25
  ```
22
26
 
23
- This command will download the necessary components and start the simulator. Once initialized, you will be ready to execute further commands (to be implemented) to interact with the simulator.
27
+ ### Commands and usage
24
28
 
25
- ## Contributing
29
+ #### Initialize
26
30
 
27
- Contributions to the GenLayer CLI are welcome! Please feel free to fork the repository, make your changes, and submit a pull request. We appreciate your efforts to improve the software.
31
+ Prepares and verifies your environment to run the GenLayer Studio.
28
32
 
29
- ### Running the CLI from the repository
33
+ ```bash
34
+ USAGE:
35
+ genlayer init [options]
36
+
37
+ OPTIONS:
38
+ --numValidators <numValidators> Number of validators (default: "5")
39
+ --headless Headless mode (default: false)
40
+ --reset-db Reset Database (default: false)
41
+ --localnet-version <localnetVersion> Select a specific localnet version
42
+ --ollama Enable Ollama container (default: false)
43
+
44
+ EXAMPLES:
45
+ genlayer init
46
+ genlayer init --numValidators 10 --headless --reset-db --localnet-version v0.10.2
47
+ genlayer init --ollama
48
+ ```
30
49
 
31
- First, install the dependencies and start the build process
50
+ ##### Version Compatibility
51
+
52
+ The GenLayer CLI always uses the latest compatible version of the environment, ensuring that you benefit from the most recent features, bug fixes, and optimizations without requiring manual updates. If a specific version is needed, you can specify it using the --localnet-version option when initializing the environment.
32
53
 
33
54
  ```bash
34
- npm install
35
- npm run dev
55
+ genlayer init --localnet-version v0.10.2
36
56
  ```
37
57
 
38
- This will continuously rebuild the CLI from the source
58
+ #### Start GenLayer environment
39
59
 
40
- Then in another window execute the CLI commands like so:
60
+ Launches the GenLayer environment and the Studio, initializing a fresh set of database and accounts.
41
61
 
42
62
  ```bash
43
- node dist/index.js init
63
+ USAGE:
64
+ genlayer up [options]
65
+
66
+ OPTIONS:
67
+ --reset-validators Remove all current validators and create new random ones (default: false)
68
+ --numValidators <numValidators> Number of validators (default: "5")
69
+ --headless Headless mode (default: false)
70
+ --reset-db Reset Database (default: false)
71
+ --ollama Enable Ollama container (default: false)
72
+
73
+ EXAMPLES:
74
+ genlayer up
75
+ genlayer up --reset-validators --numValidators 8 --headless --reset-db
76
+ genlayer up --ollama
77
+ ```
78
+
79
+ #### Stop GenLayer environment
80
+
81
+ Stops all running GenLayer Localnet services.
82
+
83
+ ```bash
84
+ USAGE:
85
+ genlayer stop
44
86
  ```
45
87
 
46
- ## Testing
88
+ #### Create a New GenLayer Project
89
+
90
+ Initialize a new GenLayer project using a local template.
47
91
 
48
- ### Overview
92
+ ```bash
93
+ USAGE:
94
+ genlayer new <projectName> [options]
49
95
 
50
- The GenLayer CLI uses Jest in combination with ts-jest to handle testing of TypeScript files. The configuration is tailored to support ES Modules (ESM), aligning with the latest JavaScript standards and ensuring compatibility with modern tooling and Node.js features.
96
+ OPTIONS:
97
+ --path <directory> Specify the directory for the new project (default: ".")
98
+ --overwrite Overwrite existing directory if it exists (default: false)
99
+
100
+ EXAMPLES:
101
+ genlayer new myProject
102
+ genlayer new myProject --path ./customDir
103
+ genlayer new myProject --overwrite
104
+ ```
51
105
 
52
- ### Running Tests
106
+ #### Manage CLI Configuration
53
107
 
54
- To run the tests, use the following command:
108
+ Configure the GenLayer CLI settings.
55
109
 
56
110
  ```bash
57
- npm run test
111
+ USAGE:
112
+ genlayer config <command> [options]
113
+
114
+ COMMANDS:
115
+ set <key=value> Set a configuration value
116
+ get [key] Get the current configuration
117
+ reset <key> Reset a configuration value to its default
118
+
119
+ EXAMPLES:
120
+ genlayer config get
121
+ genlayer config get defaultOllamaModel
122
+ genlayer config set defaultOllamaModel=deepseek-r1
123
+ genlayer config reset keyPairPath
58
124
  ```
59
125
 
60
- This command sets the appropriate Node.js options to handle ES Modules and watches for changes in the test files, making it suitable for development.
126
+ #### Network Management
61
127
 
62
- ### Test Configuration
128
+ Set the network to use for contract operations.
63
129
 
64
- Our `jest.config.js` is set up as follows:
130
+ ```bash
131
+ USAGE:
132
+ genlayer network [network]
65
133
 
66
- - ES Module Support: Configured to treat .ts files as ES Modules.
67
- - Test Environment: Uses Node.js as the testing environment.
68
- - Transformation: Utilizes ts-jest with an ESM preset to process TypeScript files.
134
+ EXAMPLES:
135
+ genlayer network
136
+ genlayer network testnet
137
+ genlayer network mainnet
138
+ ```
69
139
 
70
- Tests are located in the tests/ directory and should be named using the following pattern: [filename].test.ts. When writing tests, you can use all Jest functionalities such as describe, test, expect, and Jest mocks for testing asynchronous functions, component interactions, or API calls.
140
+ #### Deploy and Call Intelligent Contracts
71
141
 
72
- ## License
142
+ Deploy and interact with intelligent contracts.
73
143
 
74
- This project is licensed under the ... License - see the [LICENSE](LICENSE) file for details.
144
+ ```bash
145
+ USAGE:
146
+ genlayer deploy [options]
147
+ genlayer call <contractAddress> <method> [options]
148
+ genlayer write <contractAddress> <method> [options]
149
+
150
+ OPTIONS (deploy):
151
+ --contract <contractPath> (Optional) Path to the intelligent contract to deploy
152
+ --rpc <rpcUrl> RPC URL for the network
153
+ --args <args...> Positional arguments for the contract (space-separated, use quotes for multi-word arguments)
154
+
155
+ OPTIONS (call):
156
+ --rpc <rpcUrl> RPC URL for the network
157
+ --args <args...> Positional arguments for the method (space-separated, use quotes for multi-word arguments)
158
+
159
+ OPTIONS (write):
160
+ --rpc <rpcUrl> RPC URL for the network
161
+ --args <args...> Positional arguments for the method (space-separated, use quotes for multi-word arguments)
162
+
163
+ EXAMPLES:
164
+ genlayer deploy
165
+ genlayer deploy --contract ./my_contract.gpy
166
+ genlayer deploy --contract ./my_contract.gpy --args "arg1" "arg2" 123
167
+ genlayer call 0x123456789abcdef greet --args "Hello World!"
168
+ genlayer write 0x123456789abcdef updateValue --args 42
169
+ ```
170
+
171
+ ##### Deploy Behavior
172
+ - If `--contract` is specified, the command will **deploy the given contract**.
173
+ - If `--contract` is omitted, the CLI will **search for scripts inside the `deploy` folder**, sort them, and execute them sequentially.
174
+
175
+ ##### Call vs Write
176
+ - `call` - Calls a contract method without sending a transaction or changing the state (read-only)
177
+ - `write` - Sends a transaction to a contract method that modifies the state
178
+
179
+ #### Keypair Management
180
+
181
+ Generate and manage keypairs.
182
+
183
+ ```bash
184
+ USAGE:
185
+ genlayer keygen create [options]
75
186
 
76
- ## Credits
187
+ OPTIONS:
188
+ --output <path> Path to save the keypair (default: "./keypair.json")
189
+ --overwrite Overwrite the existing file if it already exists (default: false)
77
190
 
78
- - TBD
191
+ EXAMPLES:
192
+ genlayer keygen create
193
+ genlayer keygen create --output ./my_key.json --overwrite
194
+ ```
195
+
196
+ #### Update Resources
197
+
198
+ Manage and update models or configurations.
199
+
200
+ ```bash
201
+ USAGE:
202
+ genlayer update ollama [options]
203
+
204
+ OPTIONS:
205
+ --model [model-name] Specify the model to update or pull
206
+ --remove Remove the specified model instead of updating
207
+
208
+ EXAMPLES:
209
+ genlayer update ollama
210
+ genlayer update ollama --model deepseek-r1
211
+ genlayer update ollama --model deepseek-r1 --remove
212
+ ```
213
+
214
+ #### Validator Management
215
+
216
+ Manage validator operations.
217
+
218
+ ```bash
219
+ USAGE:
220
+ genlayer validators <command> [options]
221
+
222
+ COMMANDS:
223
+ get [--address <validatorAddress>] Retrieve details of a specific validator or all validators
224
+ delete [--address <validatorAddress>] Delete a specific validator or all validators
225
+ count Count all validators
226
+ update <validatorAddress> [options] Update a validator details
227
+ create-random [options] Create random validators
228
+ create [options] Create a new validator
229
+
230
+ OPTIONS (update):
231
+ --stake <stake> New stake for the validator
232
+ --provider <provider> New provider for the validator
233
+ --model <model> New model for the validator
234
+ --config <config> New JSON config for the validator
235
+
236
+ OPTIONS (create-random):
237
+ --count <count> Number of validators to create (default: "1")
238
+ --providers <providers...> Space-separated list of provider names (e.g., openai ollama)
239
+ --models <models...> Space-separated list of model names (e.g., gpt-4 gpt-4o)
240
+
241
+ OPTIONS (create):
242
+ --stake <stake> Stake amount for the validator (default: "1")
243
+ --config <config> Optional JSON configuration for the validator
244
+ --provider <provider> Specify the provider for the validator
245
+ --model <model> Specify the model for the validator
246
+
247
+ EXAMPLES:
248
+ genlayer validators get
249
+ genlayer validators get --address 0x123456789abcdef
250
+
251
+ genlayer validators count
252
+ genlayer validators delete --address 0x123456789abcdef
253
+ genlayer validators update 0x123456789abcdef --stake 100 --provider openai --model gpt-4
254
+
255
+ genlayer validators create
256
+ genlayer validators create --stake 50 --provider openai --model gpt-4
257
+ genlayer validators create-random --count 3 --providers openai --models gpt-4 gpt-4o
258
+ ```
259
+
260
+ ### Running the CLI from the repository
261
+
262
+ First, install the dependencies and start the build process
79
263
 
80
- ## Contact
264
+ ```bash
265
+ npm install
266
+ npm run dev
267
+ ```
81
268
 
82
- - TBD
269
+ This will continuously rebuild the CLI from the source
83
270
 
84
- ## Further Development
271
+ Then in another window execute the CLI commands like so:
85
272
 
86
- Further commands are planned for implementation to enhance interaction with the GenLayer simulator. Stay tuned for updates.
273
+ ```bash
274
+ node dist/index.js init
275
+ ```
87
276
 
88
- ## Feedback
277
+ ## Documentation
278
+
279
+ For detailed information on how to use GenLayer CLI, please refer to our [documentation](https://docs.genlayer.com/).
280
+
281
+ ## Contributing
282
+
283
+ We welcome contributions to GenLayerJS SDK! Whether it's new features, improved infrastructure, or better documentation, your input is valuable. Please read our [CONTRIBUTING](https://github.com/yeagerai/genlayer-js/blob/main/CONTRIBUTING.md) guide for guidelines on how to submit your contributions.
284
+
285
+ ## License
286
+
287
+ This project is licensed under the ... License - see the [LICENSE](LICENSE) file for details.
89
288
 
90
- If you have any feedback, please reach out to us at the contact provided above.
package/dist/index.js CHANGED
@@ -17723,7 +17723,7 @@ var require_semver2 = __commonJS({
17723
17723
  import { program } from "commander";
17724
17724
 
17725
17725
  // package.json
17726
- var version = "0.18.2";
17726
+ var version = "0.18.4";
17727
17727
  var package_default = {
17728
17728
  name: "genlayer",
17729
17729
  version,
@@ -20658,6 +20658,7 @@ function ora(options) {
20658
20658
 
20659
20659
  // src/lib/actions/BaseAction.ts
20660
20660
  import inquirer from "inquirer";
20661
+ import { inspect } from "util";
20661
20662
 
20662
20663
  // src/lib/accounts/KeypairManager.ts
20663
20664
  import { writeFileSync, existsSync, readFileSync } from "fs";
@@ -40979,18 +40980,10 @@ var BaseAction = class extends ConfigFileManager {
40979
40980
  }
40980
40981
  }
40981
40982
  formatOutput(data) {
40982
- if (data instanceof Error) {
40983
- const errorDetails = {
40984
- name: data.name,
40985
- message: data.message,
40986
- ...Object.keys(data).length ? data : {}
40987
- };
40988
- return JSON.stringify(errorDetails, null, 2);
40989
- }
40990
- if (data instanceof Map) {
40991
- data = Object.fromEntries(data);
40983
+ if (typeof data === "string") {
40984
+ return data;
40992
40985
  }
40993
- return typeof data === "object" ? JSON.stringify(data, null, 2) : String(data);
40986
+ return inspect(data, { depth: null, colors: false });
40994
40987
  }
40995
40988
  log(message, data) {
40996
40989
  console.log(source_default.white(`
@@ -41023,10 +41016,12 @@ ${message}`));
41023
41016
  }
41024
41017
  succeedSpinner(message, data) {
41025
41018
  if (data !== void 0) this.log("Result:", data);
41019
+ console.log("");
41026
41020
  this.spinner.succeed(source_default.green(message));
41027
41021
  }
41028
41022
  failSpinner(message, error) {
41029
41023
  if (error) this.log("Error:", error);
41024
+ console.log("");
41030
41025
  this.spinner.fail(source_default.red(message));
41031
41026
  }
41032
41027
  stopSpinner() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genlayer",
3
- "version": "0.18.2",
3
+ "version": "0.18.4",
4
4
  "description": "GenLayer Command Line Tool",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -2,6 +2,7 @@ import {ConfigFileManager} from "../../lib/config/ConfigFileManager";
2
2
  import ora, {Ora} from "ora";
3
3
  import chalk from "chalk";
4
4
  import inquirer from "inquirer";
5
+ import { inspect } from "util";
5
6
  import {KeypairManager} from "../accounts/KeypairManager";
6
7
  import {createClient, createAccount} from "genlayer-js";
7
8
  import {localnet} from "genlayer-js/chains";
@@ -58,20 +59,10 @@ export class BaseAction extends ConfigFileManager {
58
59
  }
59
60
 
60
61
  private formatOutput(data: any): string {
61
- if (data instanceof Error) {
62
- const errorDetails = {
63
- name: data.name,
64
- message: data.message,
65
- ...(Object.keys(data).length ? data : {}),
66
- };
67
- return JSON.stringify(errorDetails, null, 2);
62
+ if (typeof data === "string") {
63
+ return data;
68
64
  }
69
-
70
- if (data instanceof Map) {
71
- data = Object.fromEntries(data);
72
- }
73
-
74
- return typeof data === "object" ? JSON.stringify(data, null, 2) : String(data);
65
+ return inspect(data, { depth: null, colors: false });
75
66
  }
76
67
 
77
68
  protected log(message: string, data?: any): void {
@@ -106,11 +97,13 @@ export class BaseAction extends ConfigFileManager {
106
97
 
107
98
  protected succeedSpinner(message: string, data?: any): void {
108
99
  if (data !== undefined) this.log("Result:", data);
100
+ console.log('');
109
101
  this.spinner.succeed(chalk.green(message));
110
102
  }
111
103
 
112
- protected failSpinner(message: string, error?: any): void {
104
+ protected failSpinner(message: string, error?:any): void {
113
105
  if (error) this.log("Error:", error);
106
+ console.log('');
114
107
  this.spinner.fail(chalk.red(message));
115
108
  }
116
109
 
@@ -121,4 +114,4 @@ export class BaseAction extends ConfigFileManager {
121
114
  protected setSpinnerText(message: string): void {
122
115
  this.spinner.text = chalk.blue(message);
123
116
  }
124
- }
117
+ }
@@ -3,6 +3,7 @@ import {BaseAction} from "../../src/lib/actions/BaseAction";
3
3
  import inquirer from "inquirer";
4
4
  import ora, {Ora} from "ora";
5
5
  import chalk from "chalk";
6
+ import {inspect} from "util";
6
7
 
7
8
  vi.mock("inquirer");
8
9
  vi.mock("ora");
@@ -42,11 +43,17 @@ describe("BaseAction", () => {
42
43
 
43
44
  test("should succeed the spinner with a message", () => {
44
45
  baseAction["succeedSpinner"]("Success");
46
+ expect(consoleSpy).toHaveBeenCalledWith("");
45
47
  expect(mockSpinner.succeed).toHaveBeenCalledWith(expect.stringContaining("Success"));
46
48
  });
47
49
 
48
50
  test("should fail the spinner with an error message", () => {
49
- baseAction["failSpinner"]("Failure", new Error("Something went wrong"));
51
+ const error = new Error("Something went wrong");
52
+ baseAction["failSpinner"]("Failure", error);
53
+
54
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
55
+ expect(consoleSpy).toHaveBeenCalledWith(inspect(error, {depth: null, colors: false}));
56
+ expect(consoleSpy).toHaveBeenCalledWith("");
50
57
  expect(mockSpinner.fail).toHaveBeenCalledWith(expect.stringContaining("Failure"));
51
58
  });
52
59
 
@@ -108,7 +115,7 @@ describe("BaseAction", () => {
108
115
  baseAction["logSuccess"]("Success message", data);
109
116
 
110
117
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("✔ Success message"));
111
- expect(consoleSpy).toHaveBeenCalledWith(chalk.green(JSON.stringify(data, null, 2)));
118
+ expect(consoleSpy).toHaveBeenCalledWith(chalk.green(inspect(data, {depth: null, colors: false})));
112
119
  });
113
120
 
114
121
  test("should log an error message with error details", () => {
@@ -117,18 +124,7 @@ describe("BaseAction", () => {
117
124
  baseAction["logError"]("Error message", error);
118
125
 
119
126
  expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining("✖ Error message"));
120
- expect(consoleErrorSpy).toHaveBeenCalledWith(
121
- chalk.red(
122
- JSON.stringify(
123
- {
124
- name: error.name,
125
- message: error.message,
126
- },
127
- null,
128
- 2,
129
- ),
130
- ),
131
- );
127
+ expect(consoleErrorSpy).toHaveBeenCalledWith(chalk.red(inspect(error, {depth: null, colors: false})));
132
128
  });
133
129
 
134
130
  test("should log an info message with data", () => {
@@ -137,7 +133,7 @@ describe("BaseAction", () => {
137
133
  baseAction["logInfo"]("Info message", data);
138
134
 
139
135
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("ℹ Info message"));
140
- expect(consoleSpy).toHaveBeenCalledWith(chalk.blue(JSON.stringify(data, null, 2)));
136
+ expect(consoleSpy).toHaveBeenCalledWith(chalk.blue(inspect(data, {depth: null, colors: false})));
141
137
  });
142
138
 
143
139
  test("should log a warning message with data", () => {
@@ -146,7 +142,7 @@ describe("BaseAction", () => {
146
142
  baseAction["logWarning"]("Warning message", data);
147
143
 
148
144
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("⚠ Warning message"));
149
- expect(consoleSpy).toHaveBeenCalledWith(chalk.yellow(JSON.stringify(data, null, 2)));
145
+ expect(consoleSpy).toHaveBeenCalledWith(chalk.yellow(inspect(data, {depth: null, colors: false})));
150
146
  });
151
147
 
152
148
  test("should succeed the spinner with a message and log result if data is provided", () => {
@@ -155,52 +151,17 @@ describe("BaseAction", () => {
155
151
  baseAction["succeedSpinner"]("Success", mockData);
156
152
 
157
153
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Result:"));
158
- expect(consoleSpy).toHaveBeenCalledWith(JSON.stringify(mockData, null, 2));
154
+ expect(consoleSpy).toHaveBeenCalledWith(inspect(mockData, {depth: null, colors: false}));
155
+ expect(consoleSpy).toHaveBeenCalledWith("");
159
156
  expect(mockSpinner.succeed).toHaveBeenCalledWith(expect.stringContaining("Success"));
160
157
  });
161
158
 
162
- test("should format an Error instance with name, message, and additional properties", () => {
163
- const error = new Error("Something went wrong");
164
- (error as any).code = 500;
165
-
166
- const result = (baseAction as any).formatOutput(error);
167
- expect(result).toBe(JSON.stringify({name: "Error", message: "Something went wrong", code: 500}, null, 2));
168
- });
169
-
170
- test("should format an object as JSON string", () => {
171
- const data = {key: "value", num: 42};
172
- const result = (baseAction as any).formatOutput(data);
173
-
174
- expect(result).toBe(JSON.stringify(data, null, 2));
175
- });
176
-
177
159
  test("should return a string representation of a primitive", () => {
178
160
  expect((baseAction as any).formatOutput("Hello")).toBe("Hello");
179
161
  expect((baseAction as any).formatOutput(42)).toBe("42");
180
162
  expect((baseAction as any).formatOutput(true)).toBe("true");
181
163
  });
182
164
 
183
- test("should format a Map object correctly", () => {
184
- const testMap = new Map<string, any>([
185
- ["key1", "value1"],
186
- ["key2", 42],
187
- ["key3", {nested: "object"}],
188
- ]);
189
-
190
- const result = (baseAction as any).formatOutput(testMap);
191
- const expected = JSON.stringify(
192
- {
193
- key1: "value1",
194
- key2: 42,
195
- key3: {nested: "object"},
196
- },
197
- null,
198
- 2,
199
- );
200
-
201
- expect(result).toBe(expected);
202
- });
203
-
204
165
  const mockPrivateKey = "mocked_private_key";
205
166
 
206
167
  beforeEach(() => {
@@ -240,4 +201,34 @@ describe("BaseAction", () => {
240
201
 
241
202
  await expect(baseAction["getPrivateKey"]()).rejects.toThrow("process exited");
242
203
  });
204
+
205
+ describe("formatOutput", () => {
206
+ test("should return string as is", () => {
207
+ expect((baseAction as any).formatOutput("Hello")).toBe("Hello");
208
+ });
209
+
210
+ test("should format an object", () => {
211
+ const data = {key: "value", num: 42};
212
+ const result = (baseAction as any).formatOutput(data);
213
+ expect(result).toBe("{ key: 'value', num: 42 }");
214
+ });
215
+
216
+ test("should format an error object", () => {
217
+ const error = new Error("Test Error");
218
+ const result = (baseAction as any).formatOutput(error);
219
+ expect(result).toContain("Error: Test Error");
220
+ });
221
+
222
+ test("should format a Map object", () => {
223
+ const testMap = new Map([["key1", "value1"]]);
224
+ const result = (baseAction as any).formatOutput(testMap);
225
+ expect(result).toBe("Map(1) { 'key1' => 'value1' }");
226
+ });
227
+
228
+ test("should format a BigInt object", () => {
229
+ const bigIntValue = BigInt(9007199254740991);
230
+ const result = (baseAction as any).formatOutput(bigIntValue);
231
+ expect(result).toBe("9007199254740991n");
232
+ });
233
+ });
243
234
  });