puter-cli 1.5.3 → 1.5.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/.env.example +3 -0
- package/CHANGELOG.md +10 -0
- package/README.md +7 -10
- package/package.json +6 -4
- package/src/commands/shell.js +13 -1
- package/src/commands/sites.js +6 -9
- package/src/commons.js +6 -2
- package/src/executor.js +6 -2
- package/src/modules/ErrorModule.js +33 -0
- package/tests/utils.test.js +7 -6
package/.env.example
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -4,8 +4,18 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
#### [v1.5.4](https://github.com/HeyPuter/puter-cli/compare/v1.5.3...v1.5.4)
|
|
8
|
+
|
|
9
|
+
- Remove "subdomain deletion" under Known Issues in README.md [`#8`](https://github.com/HeyPuter/puter-cli/pull/8)
|
|
10
|
+
- dev: add last-error command, context, and modules [`#7`](https://github.com/HeyPuter/puter-cli/pull/7)
|
|
11
|
+
- fix: delete a subdomain error message [`ed676dc`](https://github.com/HeyPuter/puter-cli/commit/ed676dc9d1364fabf242098e142a84c305dff177)
|
|
12
|
+
- ci: fix timezone issue [`8ee6a66`](https://github.com/HeyPuter/puter-cli/commit/8ee6a66db36f7ca00eb81a12c8bac094e057f534)
|
|
13
|
+
- ci: simplify timezone check [`ecf3bb9`](https://github.com/HeyPuter/puter-cli/commit/ecf3bb98bec5c093c23772280e3ee52aab8f3e8f)
|
|
14
|
+
|
|
7
15
|
#### [v1.5.3](https://github.com/HeyPuter/puter-cli/compare/v1.5.2...v1.5.3)
|
|
8
16
|
|
|
17
|
+
> 7 February 2025
|
|
18
|
+
|
|
9
19
|
- refactor: early return in fallback behavior [`#6`](https://github.com/HeyPuter/puter-cli/pull/6)
|
|
10
20
|
- fix: ignore undefined appDir when listing sites [`#5`](https://github.com/HeyPuter/puter-cli/pull/5)
|
|
11
21
|
- fix: use array args when calling DeleteSubdomain [`#4`](https://github.com/HeyPuter/puter-cli/pull/4)
|
package/README.md
CHANGED
|
@@ -273,7 +273,12 @@ If you want to customize this tool you can follow these steps:
|
|
|
273
273
|
```bash
|
|
274
274
|
npm install
|
|
275
275
|
```
|
|
276
|
-
3.
|
|
276
|
+
3. Set your own variable environnements:
|
|
277
|
+
```
|
|
278
|
+
cp .env.example .env
|
|
279
|
+
# update your own values in .env file
|
|
280
|
+
```
|
|
281
|
+
4. Link the CLI globally:
|
|
277
282
|
```bash
|
|
278
283
|
npm link
|
|
279
284
|
```
|
|
@@ -282,15 +287,7 @@ If you want to customize this tool you can follow these steps:
|
|
|
282
287
|
|
|
283
288
|
## Known issues:
|
|
284
289
|
|
|
285
|
-
Most
|
|
286
|
-
|
|
287
|
-
## Delete a subdomain
|
|
288
|
-
When you try to delete a subdomain which you own, you'll get `Permission denied`:
|
|
289
|
-
```bash
|
|
290
|
-
Failed to delete subdomain: Permission denied.
|
|
291
|
-
Site ID: "sd-b019b654-e06f-48a8-917e-ae1e83825ab7" may already be deleted!
|
|
292
|
-
```
|
|
293
|
-
However, the query is executed successfully in the cloud and the subdomain is actually deleted.
|
|
290
|
+
Most features are working fine. If you have any issues with this project or the Puter SDK, please let us know:
|
|
294
291
|
|
|
295
292
|
## Interactive Shell prompt:
|
|
296
293
|
If you want to stay in the interactive shell you should provide "-f" (aka: force delete) argument, when want to delete any object:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "puter-cli",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"description": "Command line interface for Puter cloud platform",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"scripts": {
|
|
12
12
|
"start": "node bin/index.js",
|
|
13
|
-
"test": "vitest run tests/*",
|
|
14
|
-
"test:watch": "vitest --watch tests/*",
|
|
13
|
+
"test": "TZ=UTC vitest run tests/*",
|
|
14
|
+
"test:watch": "TZ=UTC vitest --watch tests/*",
|
|
15
15
|
"version": "auto-changelog -p && git add CHANGELOG.md",
|
|
16
|
-
"coverage": "vitest run --coverage"
|
|
16
|
+
"coverage": "TZ=UTC vitest run --coverage"
|
|
17
17
|
},
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">=18.0.0"
|
|
@@ -26,11 +26,13 @@
|
|
|
26
26
|
"author": "Ibrahim.H",
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"@heyputer/putility": "^1.0.2",
|
|
29
30
|
"chalk": "^5.3.0",
|
|
30
31
|
"cli-table3": "^0.6.5",
|
|
31
32
|
"commander": "^13.0.0",
|
|
32
33
|
"conf": "^12.0.0",
|
|
33
34
|
"cross-spawn": "^7.0.3",
|
|
35
|
+
"dotenv": "^16.4.7",
|
|
34
36
|
"glob": "^11.0.0",
|
|
35
37
|
"inquirer": "^9.2.12",
|
|
36
38
|
"minimatch": "^10.0.1",
|
package/src/commands/shell.js
CHANGED
|
@@ -4,6 +4,8 @@ import Conf from 'conf';
|
|
|
4
4
|
import { execCommand, getPrompt } from '../executor.js';
|
|
5
5
|
import { getAuthToken, login } from './auth.js';
|
|
6
6
|
import { PROJECT_NAME } from '../commons.js';
|
|
7
|
+
import ErrorModule from '../modules/ErrorModule.js';
|
|
8
|
+
import putility, { AdvancedBase } from '@heyputer/putility';
|
|
7
9
|
|
|
8
10
|
const config = new Conf({ projectName: PROJECT_NAME });
|
|
9
11
|
|
|
@@ -32,6 +34,16 @@ export async function startShell() {
|
|
|
32
34
|
process.exit(0);
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
const modules = [
|
|
38
|
+
ErrorModule,
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const context = new putility.libs.context.Context({
|
|
42
|
+
events: new putility.libs.event.Emitter(),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
for ( const module of modules ) module({ context });
|
|
46
|
+
|
|
35
47
|
try {
|
|
36
48
|
console.log(chalk.green('Welcome to Puter-CLI! Type "help" for available commands.'));
|
|
37
49
|
rl.setPrompt(getPrompt());
|
|
@@ -41,7 +53,7 @@ export async function startShell() {
|
|
|
41
53
|
const trimmedLine = line.trim();
|
|
42
54
|
if (trimmedLine) {
|
|
43
55
|
try {
|
|
44
|
-
await execCommand(trimmedLine);
|
|
56
|
+
await execCommand(context, trimmedLine);
|
|
45
57
|
} catch (error) {
|
|
46
58
|
console.error(chalk.red(error.message));
|
|
47
59
|
}
|
package/src/commands/sites.js
CHANGED
|
@@ -5,12 +5,13 @@ import { getCurrentUserName, getCurrentDirectory } from './auth.js';
|
|
|
5
5
|
import { API_BASE, getHeaders, generateAppName, resolvePath, isValidAppName } from '../commons.js';
|
|
6
6
|
import { displayNonNullValues, formatDate, isValidAppUuid } from '../utils.js';
|
|
7
7
|
import { getSubdomains, createSubdomain, deleteSubdomain } from './subdomains.js';
|
|
8
|
+
import { ErrorAPI } from '../modules/ErrorModule.js';
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Listing subdomains
|
|
12
13
|
*/
|
|
13
|
-
export async function listSites(args = {}) {
|
|
14
|
+
export async function listSites(args = {}, context) {
|
|
14
15
|
try {
|
|
15
16
|
const data = await getSubdomains(args);
|
|
16
17
|
|
|
@@ -57,6 +58,7 @@ export async function listSites(args = {}) {
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
} catch (error) {
|
|
61
|
+
context.events.emit('error', { error });
|
|
60
62
|
console.error(chalk.red('Error listing sites:'), error.message);
|
|
61
63
|
throw error;
|
|
62
64
|
}
|
|
@@ -121,14 +123,9 @@ export async function infoSite(args = []) {
|
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
const data = await response.json();
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (Object.keys(data).length === 0){
|
|
128
|
-
console.log(chalk.green(`Site ID: "${uuid}" should be deleted.`));
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
console.log(chalk.yellow(`Site ID: "${uuid}" may already be deleted!`));
|
|
126
|
+
console.log(data);
|
|
127
|
+
|
|
128
|
+
console.log(chalk.green(`Site ID: "${uuid}" has been deleted.`));
|
|
132
129
|
} catch (error) {
|
|
133
130
|
console.error(chalk.red('Error deleting site:'), error.message);
|
|
134
131
|
return false;
|
package/src/commons.js
CHANGED
|
@@ -4,10 +4,14 @@ import { formatSize } from './utils.js';
|
|
|
4
4
|
import { readFile } from 'fs/promises';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { dirname, join } from 'path';
|
|
7
|
+
import dotenv from 'dotenv';
|
|
8
|
+
|
|
9
|
+
dotenv.config();
|
|
7
10
|
|
|
8
11
|
export const PROJECT_NAME = 'puter-cli';
|
|
9
|
-
|
|
10
|
-
export const
|
|
12
|
+
// If you haven't defined your own values in .env file, we'll assume you're running Puter on a local instance:
|
|
13
|
+
export const API_BASE = process.env.PUTER_API_BASE || 'http://api.puter.localhost:4100';
|
|
14
|
+
export const BASE_URL = process.env.PUTER_BASE_URL || 'http://puter.localhost:4100';
|
|
11
15
|
|
|
12
16
|
/**
|
|
13
17
|
* Get headers with the correct Content-Type for multipart form data.
|
package/src/executor.js
CHANGED
|
@@ -12,6 +12,7 @@ import inquirer from 'inquirer';
|
|
|
12
12
|
import { exec } from 'node:child_process';
|
|
13
13
|
import { parseArgs } from './utils.js';
|
|
14
14
|
import { rl } from './commands/shell.js';
|
|
15
|
+
import { ErrorAPI } from './modules/ErrorModule.js';
|
|
15
16
|
|
|
16
17
|
const config = new Conf({ projectName: PROJECT_NAME });
|
|
17
18
|
|
|
@@ -61,6 +62,9 @@ const commands = {
|
|
|
61
62
|
rl.write(commandToCopy);
|
|
62
63
|
}
|
|
63
64
|
},
|
|
65
|
+
'last-error': async (_, context) => {
|
|
66
|
+
context[ErrorAPI].showLast();
|
|
67
|
+
},
|
|
64
68
|
'app:create': async (rawArgs) => {
|
|
65
69
|
try {
|
|
66
70
|
const args = parseArgs(rawArgs.join(' '));
|
|
@@ -150,7 +154,7 @@ const commands = {
|
|
|
150
154
|
* Execute a command
|
|
151
155
|
* @param {string} input The command line input
|
|
152
156
|
*/
|
|
153
|
-
export async function execCommand(input) {
|
|
157
|
+
export async function execCommand(context, input) {
|
|
154
158
|
const [cmd, ...args] = input.split(' ');
|
|
155
159
|
|
|
156
160
|
|
|
@@ -184,7 +188,7 @@ export async function execCommand(input) {
|
|
|
184
188
|
}
|
|
185
189
|
if (commands[cmd]) {
|
|
186
190
|
try {
|
|
187
|
-
await commands[cmd](args);
|
|
191
|
+
await commands[cmd](args, context);
|
|
188
192
|
} catch (error) {
|
|
189
193
|
console.error(chalk.red(`Error executing command: ${error.message}`));
|
|
190
194
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const ERROR_BUFFER_LIMIT = 20;
|
|
2
|
+
|
|
3
|
+
export const ErrorAPI = Symbol('ErrorAPI');
|
|
4
|
+
|
|
5
|
+
export default ({ context }) => {
|
|
6
|
+
// State Variables
|
|
7
|
+
const errors = [];
|
|
8
|
+
|
|
9
|
+
context.events.on('error', (error) => {
|
|
10
|
+
context[ErrorAPI].report(error);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Module Methods
|
|
14
|
+
context[ErrorAPI] = {
|
|
15
|
+
// Add an error to the error history
|
|
16
|
+
report (error) {
|
|
17
|
+
errors.push(error);
|
|
18
|
+
if (errors.length > ERROR_BUFFER_LIMIT) {
|
|
19
|
+
errors = errors.slice(errors.length - ERROR_BUFFER_LIMIT);
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
// Print the last error from the error history,
|
|
23
|
+
// and remove it from the history
|
|
24
|
+
showLast () {
|
|
25
|
+
const err = errors.pop();
|
|
26
|
+
if (err) {
|
|
27
|
+
console.error(err);
|
|
28
|
+
} else {
|
|
29
|
+
console.log('No errors to report');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
};
|
package/tests/utils.test.js
CHANGED
|
@@ -15,14 +15,15 @@ describe('formatDate', () => {
|
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
it('should handle different date and time', () => {
|
|
18
|
-
const dateString = '2023-01-
|
|
19
|
-
const expected = '01/01/2023,
|
|
18
|
+
const dateString = '2023-01-01T01:30:05.000Z';
|
|
19
|
+
const expected = '01/01/2023, 01:30:05';
|
|
20
20
|
expect(formatDate(dateString)).toBe(expected);
|
|
21
21
|
});
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
|
|
23
|
+
it('should handle invalid date', () => {
|
|
24
|
+
const dateString = 'invalid-date';
|
|
25
|
+
expect(formatDate(dateString)).toBe('Invalid Date');
|
|
26
|
+
});
|
|
26
27
|
});
|
|
27
28
|
|
|
28
29
|
describe('formatDateTime', () => {
|