clever-tools 3.13.1 → 4.0.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/README.md +130 -37
- package/bin/clever.js +1427 -718
- package/package.json +62 -77
- package/src/clever-client/auth-bridge.js +9 -12
- package/src/clever-client/ng.js +1 -1
- package/src/clever-client/operators.js +7 -7
- package/src/command-options.js +6 -6
- package/src/command-promise-handler.js +6 -6
- package/src/commands/accesslogs.js +38 -29
- package/src/commands/activity.js +62 -40
- package/src/commands/addon.js +65 -69
- package/src/commands/applications.js +33 -31
- package/src/commands/cancel-deploy.js +7 -7
- package/src/commands/config.js +9 -7
- package/src/commands/console.js +3 -3
- package/src/commands/create.js +33 -32
- package/src/commands/curl.js +14 -36
- package/src/commands/database.js +10 -30
- package/src/commands/delete.js +8 -8
- package/src/commands/deploy.js +60 -46
- package/src/commands/diag.js +27 -25
- package/src/commands/domain.js +89 -91
- package/src/commands/drain.js +26 -14
- package/src/commands/emails.js +24 -28
- package/src/commands/env.js +18 -18
- package/src/commands/features.js +12 -18
- package/src/commands/keycloak.js +11 -11
- package/src/commands/kv.js +13 -13
- package/src/commands/link.js +9 -8
- package/src/commands/login.js +19 -27
- package/src/commands/logout.js +1 -1
- package/src/commands/logs.js +20 -12
- package/src/commands/makeDefault.js +5 -5
- package/src/commands/matomo.js +7 -7
- package/src/commands/metabase.js +9 -9
- package/src/commands/ng.js +32 -32
- package/src/commands/notify-email.js +11 -15
- package/src/commands/open.js +1 -1
- package/src/commands/otoroshi.js +11 -11
- package/src/commands/profile.js +8 -8
- package/src/commands/published-config.js +11 -11
- package/src/commands/restart.js +15 -8
- package/src/commands/scale.js +25 -16
- package/src/commands/service.js +28 -11
- package/src/commands/ssh-keys.js +25 -29
- package/src/commands/ssh.js +1 -2
- package/src/commands/status.js +31 -22
- package/src/commands/stop.js +3 -3
- package/src/commands/tcp-redirs.js +27 -26
- package/src/commands/tokens.js +44 -43
- package/src/commands/unlink.js +7 -5
- package/src/commands/version.js +2 -4
- package/src/commands/webhooks.js +8 -10
- package/src/experimental-features.js +7 -5
- package/src/format-table.js +46 -15
- package/src/initial-setup.js +2 -32
- package/src/initial-update-notifier.js +18 -0
- package/src/lib/has-param.js +16 -0
- package/src/lib/ng-print.js +21 -24
- package/src/lib/operator-commands.js +58 -53
- package/src/lib/prompts.js +5 -5
- package/src/lib/slugify.js +1 -1
- package/src/logger.js +26 -21
- package/src/models/activity.js +3 -3
- package/src/models/addon.js +54 -56
- package/src/models/app_configuration.js +34 -32
- package/src/models/application.js +90 -77
- package/src/models/application_configuration.js +19 -27
- package/src/models/configuration.js +30 -32
- package/src/models/deployments.js +9 -19
- package/src/models/domain.js +10 -9
- package/src/models/drain.js +16 -15
- package/src/models/exit-strategy-option.js +15 -5
- package/src/models/fs-utils.js +4 -3
- package/src/models/git.js +26 -32
- package/src/models/ids-resolver.js +37 -41
- package/src/models/isomorphic-http-with-agent.js +3 -3
- package/src/models/json-array.js +5 -6
- package/src/models/log-v4.js +44 -52
- package/src/models/log.js +40 -45
- package/src/models/namespaces.js +4 -4
- package/src/models/ng-resources.js +49 -39
- package/src/models/ng.js +41 -40
- package/src/models/node-dns-resolver.js +3 -3
- package/src/models/notification.js +7 -10
- package/src/models/operator.js +8 -10
- package/src/models/organisation.js +5 -8
- package/src/models/send-to-api.js +18 -11
- package/src/models/user.js +6 -5
- package/src/models/utils.js +5 -8
- package/src/models/variables.js +18 -20
- package/src/parsers.js +34 -34
- package/src/load-package-json.cjs +0 -5
package/package.json
CHANGED
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clever-tools",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Command Line Interface for Clever Cloud.",
|
|
5
|
-
"main": "bin/clever.js",
|
|
6
|
-
"type": "module",
|
|
7
5
|
"keywords": [
|
|
8
|
-
"clever-tools",
|
|
9
6
|
"cli",
|
|
10
|
-
"
|
|
7
|
+
"command-line",
|
|
8
|
+
"tool",
|
|
9
|
+
"clever-cloud",
|
|
10
|
+
"paas",
|
|
11
|
+
"deployment",
|
|
12
|
+
"cloud",
|
|
13
|
+
"devops",
|
|
14
|
+
"automation"
|
|
11
15
|
],
|
|
12
|
-
"
|
|
13
|
-
|
|
16
|
+
"homepage": "https://github.com/CleverCloud/clever-tools",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/CleverCloud/clever-tools.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/CleverCloud/clever-tools/issues"
|
|
14
23
|
},
|
|
15
|
-
"pkg-node-version": "18",
|
|
16
24
|
"author": "Clever Cloud <ci@clever-cloud.com>",
|
|
17
25
|
"license": "Apache-2.0",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "bin/clever.js",
|
|
18
28
|
"bin": {
|
|
19
29
|
"clever": "bin/clever.js",
|
|
30
|
+
"clever-tools": "bin/clever.js",
|
|
20
31
|
"install-clever-completion": "scripts/install-autocomplete.sh",
|
|
21
32
|
"uninstall-clever-completion": "scripts/uninstall-autocomplete.sh"
|
|
22
33
|
},
|
|
@@ -25,86 +36,60 @@
|
|
|
25
36
|
"src",
|
|
26
37
|
"scripts/*.sh"
|
|
27
38
|
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"fix-all": "npm run lint:fix && npm run format",
|
|
41
|
+
"format": "prettier . --write",
|
|
42
|
+
"format:check": "prettier . --check",
|
|
43
|
+
"install-local:cliparse": "(cd ../cliparse-node && npm pack) && mv ../cliparse-node/cliparse-*.tgz . && npm i -f ./cliparse-*.tgz",
|
|
44
|
+
"lint": "eslint",
|
|
45
|
+
"lint:fix": "eslint --fix",
|
|
46
|
+
"validate": "npm run lint && npm run format:check && npm run typecheck",
|
|
47
|
+
"typecheck": "tsc -p tsconfig.json"
|
|
48
|
+
},
|
|
28
49
|
"dependencies": {
|
|
29
|
-
"@clevercloud/client": "
|
|
30
|
-
"@inquirer/prompts": "7.
|
|
50
|
+
"@clevercloud/client": "11.0.1",
|
|
51
|
+
"@inquirer/prompts": "7.8.4",
|
|
52
|
+
"char-regex": "2.0.2",
|
|
31
53
|
"cliparse": "0.5.0",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"dedent": "1.5.3",
|
|
36
|
-
"eventsource": "1.1.0",
|
|
37
|
-
"ioredis": "5.4.1",
|
|
54
|
+
"dedent": "1.6.0",
|
|
55
|
+
"eventsource": "4.0.0",
|
|
56
|
+
"ioredis": "5.7.0",
|
|
38
57
|
"iso8601-duration": "2.1.2",
|
|
39
|
-
"isomorphic-git": "1.
|
|
58
|
+
"isomorphic-git": "1.33.1",
|
|
40
59
|
"linux-release-info": "3.0.0",
|
|
41
60
|
"lodash": "4.17.21",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"superagent": "6.1.0",
|
|
48
|
-
"text-table": "0.2.0",
|
|
49
|
-
"tldts": "6.1.30",
|
|
50
|
-
"update-notifier": "5.1.0",
|
|
51
|
-
"uuid": "8.3.2",
|
|
52
|
-
"ws": "7.4.6",
|
|
61
|
+
"open": "10.2.0",
|
|
62
|
+
"semver": "7.7.2",
|
|
63
|
+
"slugify": "1.6.6",
|
|
64
|
+
"tldts": "7.0.12",
|
|
65
|
+
"update-notifier": "7.3.1",
|
|
53
66
|
"xdg": "0.1.1"
|
|
54
67
|
},
|
|
55
68
|
"devDependencies": {
|
|
56
|
-
"@
|
|
57
|
-
"@
|
|
58
|
-
"@
|
|
69
|
+
"@aws-sdk/client-s3": "3.876.0",
|
|
70
|
+
"@clevercloud/eslint-config": "1.0.1",
|
|
71
|
+
"@commitlint/cli": "19.8.1",
|
|
72
|
+
"@commitlint/config-conventional": "19.8.1",
|
|
73
|
+
"@eslint/compat": "1.3.2",
|
|
74
|
+
"@rollup/plugin-commonjs": "28.0.6",
|
|
59
75
|
"@rollup/plugin-json": "6.1.0",
|
|
60
|
-
"@rollup/plugin-node-resolve": "
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"grunt": "1.4.1",
|
|
73
|
-
"grunt-cli": "1.4.3",
|
|
74
|
-
"grunt-http": "2.3.3",
|
|
75
|
-
"grunt-mocha-test": "0.13.3",
|
|
76
|
-
"magic-string": "0.30.11",
|
|
77
|
-
"mime-types": "2.1.35",
|
|
78
|
-
"mocha": "8.4.0",
|
|
79
|
-
"pkg": "5.8.1",
|
|
80
|
-
"rollup": "4.14.1",
|
|
81
|
-
"semver": "7.3.5"
|
|
82
|
-
},
|
|
83
|
-
"overrides": {
|
|
84
|
-
"pkg-fetch": "3.5.2"
|
|
85
|
-
},
|
|
86
|
-
"scripts": {
|
|
87
|
-
"build": "rollup -c rollup.config.js",
|
|
88
|
-
"pretest": "npm run lint",
|
|
89
|
-
"test": "grunt test",
|
|
90
|
-
"lint": "eslint bin src scripts",
|
|
91
|
-
"lint:fix": "eslint --fix bin src scripts",
|
|
92
|
-
"install-local:cliparse": "(cd ../cliparse-node && npm pack) && mv ../cliparse-node/cliparse-*.tgz . && npm i -f ./cliparse-*.tgz"
|
|
76
|
+
"@rollup/plugin-node-resolve": "16.0.1",
|
|
77
|
+
"@types/mime-types": "3.0.1",
|
|
78
|
+
"@yao-pkg/pkg": "6.6.0",
|
|
79
|
+
"eslint": "9.34.0",
|
|
80
|
+
"globals": "16.3.0",
|
|
81
|
+
"mime-types": "3.0.1",
|
|
82
|
+
"prettier": "3.6.2",
|
|
83
|
+
"prettier-plugin-organize-imports": "4.2.0",
|
|
84
|
+
"rollup": "4.49.0",
|
|
85
|
+
"simple-git": "3.28.0",
|
|
86
|
+
"tinyglobby": "0.2.14",
|
|
87
|
+
"typescript": "5.9.2"
|
|
93
88
|
},
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"url": "https://github.com/CleverCloud/clever-tools.git"
|
|
97
|
-
},
|
|
98
|
-
"bugs": {
|
|
99
|
-
"url": "https://github.com/CleverCloud/clever-tools/issues"
|
|
100
|
-
},
|
|
101
|
-
"homepage": "https://github.com/CleverCloud/clever-tools",
|
|
102
|
-
"pkg": {
|
|
103
|
-
"scripts": [
|
|
104
|
-
"src/**/*.js"
|
|
105
|
-
]
|
|
89
|
+
"engines": {
|
|
90
|
+
"node": ">=22"
|
|
106
91
|
},
|
|
107
92
|
"volta": {
|
|
108
|
-
"node": "
|
|
93
|
+
"node": "22.17.0"
|
|
109
94
|
}
|
|
110
95
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function createApiToken
|
|
1
|
+
export function createApiToken({ email, password, mfaCode, name, description = '', expirationDate }) {
|
|
2
2
|
return Promise.resolve({
|
|
3
3
|
method: 'post',
|
|
4
4
|
url: '/api-tokens',
|
|
@@ -7,7 +7,7 @@ export function createApiToken ({ email, password, mfaCode, name, description =
|
|
|
7
7
|
});
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export function listApiTokens
|
|
10
|
+
export function listApiTokens() {
|
|
11
11
|
return Promise.resolve({
|
|
12
12
|
method: 'get',
|
|
13
13
|
url: '/api-tokens',
|
|
@@ -15,7 +15,7 @@ export function listApiTokens () {
|
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export function updateApiToken
|
|
18
|
+
export function updateApiToken(apiTokenId, { name, description }) {
|
|
19
19
|
return Promise.resolve({
|
|
20
20
|
method: 'put',
|
|
21
21
|
url: `/api-tokens/${apiTokenId}`,
|
|
@@ -24,7 +24,7 @@ export function updateApiToken (apiTokenId, { name, description }) {
|
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export function deleteApiToken
|
|
27
|
+
export function deleteApiToken(apiTokenId) {
|
|
28
28
|
return Promise.resolve({
|
|
29
29
|
method: 'delete',
|
|
30
30
|
url: `/api-tokens/${apiTokenId}`,
|
|
@@ -32,13 +32,11 @@ export function deleteApiToken (apiTokenId) {
|
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export function addOauthHeaderPlaintext
|
|
36
|
-
|
|
35
|
+
export function addOauthHeaderPlaintext(tokens) {
|
|
37
36
|
return async function (requestParams) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
+ [
|
|
37
|
+
const authorizationHeader =
|
|
38
|
+
'OAuth ' +
|
|
39
|
+
[
|
|
42
40
|
`oauth_consumer_key="${tokens.OAUTH_CONSUMER_KEY}"`,
|
|
43
41
|
`oauth_token="${tokens.API_OAUTH_TOKEN}"`,
|
|
44
42
|
// %26 is URL escaped character "&"
|
|
@@ -47,8 +45,7 @@ export function addOauthHeaderPlaintext (tokens) {
|
|
|
47
45
|
// oauth_signature_method is not mandatory, it defaults to PLAINTEXT
|
|
48
46
|
// oauth_timestamp is not mandatory
|
|
49
47
|
// oauth_version is not mandatory, it defaults to 1.0
|
|
50
|
-
].join(', ')
|
|
51
|
-
);
|
|
48
|
+
].join(', ');
|
|
52
49
|
|
|
53
50
|
return {
|
|
54
51
|
...requestParams,
|
package/src/clever-client/ng.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @param {String} params.ownerId
|
|
7
7
|
* @param {String} params.query
|
|
8
8
|
*/
|
|
9
|
-
export function searchNetworkGroupOrResource
|
|
9
|
+
export function searchNetworkGroupOrResource(params) {
|
|
10
10
|
// no multipath for /self or /organisations/{id}
|
|
11
11
|
return Promise.resolve({
|
|
12
12
|
method: 'get',
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @param {String} params.provider
|
|
7
7
|
* @param {String} params.realId
|
|
8
8
|
*/
|
|
9
|
-
export function getOperator
|
|
9
|
+
export function getOperator(params) {
|
|
10
10
|
// no multipath for /self or /organisations/{id}
|
|
11
11
|
return Promise.resolve({
|
|
12
12
|
method: 'get',
|
|
@@ -23,7 +23,7 @@ export function getOperator (params) {
|
|
|
23
23
|
* @param {String} params.provider
|
|
24
24
|
* @param {String} params.realId
|
|
25
25
|
*/
|
|
26
|
-
export function rebootOperator
|
|
26
|
+
export function rebootOperator(params) {
|
|
27
27
|
// no multipath for /self or /organisations/{id}
|
|
28
28
|
return Promise.resolve({
|
|
29
29
|
method: 'post',
|
|
@@ -40,7 +40,7 @@ export function rebootOperator (params) {
|
|
|
40
40
|
* @param {String} params.provider
|
|
41
41
|
* @param {String} params.realId
|
|
42
42
|
*/
|
|
43
|
-
export function rebuildOperator
|
|
43
|
+
export function rebuildOperator(params) {
|
|
44
44
|
// no multipath for /self or /organisations/{id}
|
|
45
45
|
return Promise.resolve({
|
|
46
46
|
method: 'post',
|
|
@@ -57,7 +57,7 @@ export function rebuildOperator (params) {
|
|
|
57
57
|
* @param {String} params.provider
|
|
58
58
|
* @param {String} params.realId
|
|
59
59
|
*/
|
|
60
|
-
export function ngEnableOperator
|
|
60
|
+
export function ngEnableOperator(params) {
|
|
61
61
|
// no multipath for /self or /organisations/{id}
|
|
62
62
|
return Promise.resolve({
|
|
63
63
|
method: 'post',
|
|
@@ -74,7 +74,7 @@ export function ngEnableOperator (params) {
|
|
|
74
74
|
* @param {String} params.provider
|
|
75
75
|
* @param {String} params.realId
|
|
76
76
|
*/
|
|
77
|
-
export function ngDisableOperator
|
|
77
|
+
export function ngDisableOperator(params) {
|
|
78
78
|
// no multipath for /self or /organisations/{id}
|
|
79
79
|
return Promise.resolve({
|
|
80
80
|
method: 'delete',
|
|
@@ -91,7 +91,7 @@ export function ngDisableOperator (params) {
|
|
|
91
91
|
* @param {String} params.provider
|
|
92
92
|
* @param {String} params.realId
|
|
93
93
|
*/
|
|
94
|
-
export function versionCheck
|
|
94
|
+
export function versionCheck(params) {
|
|
95
95
|
// no multipath for /self or /organisations/{id}
|
|
96
96
|
return Promise.resolve({
|
|
97
97
|
method: 'get',
|
|
@@ -109,7 +109,7 @@ export function versionCheck (params) {
|
|
|
109
109
|
* @param {String} params.realId
|
|
110
110
|
* @param {Object} body
|
|
111
111
|
*/
|
|
112
|
-
export function versionUpdate
|
|
112
|
+
export function versionUpdate(params, body) {
|
|
113
113
|
// no multipath for /self or /organisations/{id}
|
|
114
114
|
return Promise.resolve({
|
|
115
115
|
method: 'post',
|
package/src/command-options.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import cliparse from 'cliparse';
|
|
2
2
|
|
|
3
|
-
export function getOutputFormatOption
|
|
3
|
+
export function getOutputFormatOption(formats = []) {
|
|
4
4
|
const availableFormats = ['human', 'json', ...formats];
|
|
5
5
|
return cliparse.option('format', {
|
|
6
6
|
aliases: ['F'],
|
|
@@ -12,13 +12,13 @@ export function getOutputFormatOption (formats = []) {
|
|
|
12
12
|
},
|
|
13
13
|
default: 'human',
|
|
14
14
|
description: `Output format (${availableFormats.join(', ')})`,
|
|
15
|
-
complete
|
|
15
|
+
complete() {
|
|
16
16
|
return cliparse.autocomplete.words(availableFormats);
|
|
17
17
|
},
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export function getSameCommitPolicyOption
|
|
21
|
+
export function getSameCommitPolicyOption() {
|
|
22
22
|
const availablePolicies = ['error', 'ignore', 'restart', 'rebuild'];
|
|
23
23
|
return cliparse.option('same-commit-policy', {
|
|
24
24
|
aliases: ['p'],
|
|
@@ -30,13 +30,13 @@ export function getSameCommitPolicyOption () {
|
|
|
30
30
|
},
|
|
31
31
|
default: 'error',
|
|
32
32
|
description: `What to do when local and remote commit are identical (${availablePolicies.join(', ')})`,
|
|
33
|
-
complete
|
|
33
|
+
complete() {
|
|
34
34
|
return cliparse.autocomplete.words(availablePolicies);
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export function getExitOnOption
|
|
39
|
+
export function getExitOnOption() {
|
|
40
40
|
const availableExitOn = ['deploy-start', 'deploy-end', 'never'];
|
|
41
41
|
return cliparse.option('exit-on', {
|
|
42
42
|
aliases: ['e'],
|
|
@@ -48,7 +48,7 @@ export function getExitOnOption () {
|
|
|
48
48
|
},
|
|
49
49
|
default: 'deploy-end',
|
|
50
50
|
description: `Step at which the logs streaming is ended, steps are: ${availableExitOn.join(', ')}`,
|
|
51
|
-
complete
|
|
51
|
+
complete() {
|
|
52
52
|
return cliparse.autocomplete.words(availableExitOn);
|
|
53
53
|
},
|
|
54
54
|
});
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { Logger } from './logger.js';
|
|
2
|
-
import { getPackageJson } from './load-package-json.cjs';
|
|
3
1
|
import semver from 'semver';
|
|
2
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
3
|
+
import { Logger } from './logger.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export function handleCommandPromise (promise) {
|
|
5
|
+
export function handleCommandPromise(promise) {
|
|
8
6
|
promise.catch((error) => {
|
|
9
7
|
Logger.error(error);
|
|
10
8
|
const semverIsOk = semver.satisfies(process.version, pkg.engines.node);
|
|
11
9
|
if (!semverIsOk) {
|
|
12
|
-
Logger.warn(
|
|
10
|
+
Logger.warn(
|
|
11
|
+
`You are using node ${process.version}, some of our commands require node ${pkg.engines.node}. The error may be caused by this.`,
|
|
12
|
+
);
|
|
13
13
|
}
|
|
14
14
|
process.exit(1);
|
|
15
15
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as Application from '../models/application.js';
|
|
2
|
-
import { Logger } from '../logger.js';
|
|
3
|
-
import { getHostAndTokens } from '../models/send-to-api.js';
|
|
4
1
|
import { ApplicationAccessLogStream } from '@clevercloud/client/esm/streams/access-logs.js';
|
|
5
|
-
import {
|
|
6
|
-
import colors from 'colors/safe.js';
|
|
2
|
+
import { styleText } from 'node:util';
|
|
7
3
|
import { formatTable } from '../format-table.js';
|
|
4
|
+
import { Logger } from '../logger.js';
|
|
5
|
+
import * as Application from '../models/application.js';
|
|
6
|
+
import { JsonArray } from '../models/json-array.js';
|
|
7
|
+
import { getHostAndTokens } from '../models/send-to-api.js';
|
|
8
8
|
import { truncateWithEllipsis } from '../models/utils.js';
|
|
9
9
|
|
|
10
10
|
// 2000 logs per 100ms maximum
|
|
@@ -12,8 +12,7 @@ const THROTTLE_ELEMENTS = 2000;
|
|
|
12
12
|
const THROTTLE_PER_IN_MILLISECONDS = 100;
|
|
13
13
|
const CITY_MAX_LENGTH = 20;
|
|
14
14
|
|
|
15
|
-
export async function accessLogs
|
|
16
|
-
|
|
15
|
+
export async function accessLogs(params) {
|
|
17
16
|
// TODO: drop when add-ons are supported in API
|
|
18
17
|
if (params.options.addon) {
|
|
19
18
|
throw new Error('Access Logs are not available for add-ons yet');
|
|
@@ -35,10 +34,10 @@ export async function accessLogs (params) {
|
|
|
35
34
|
});
|
|
36
35
|
|
|
37
36
|
if (format === 'human') {
|
|
38
|
-
Logger.warn(
|
|
37
|
+
Logger.warn(styleText('yellow', '/!\\ Access Logs feature is in Alpha testing phase'));
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
if (format === 'json' &&
|
|
40
|
+
if (format === 'json' && !until) {
|
|
42
41
|
throw new Error('JSON format only works with a limiting parameter such as `before`');
|
|
43
42
|
}
|
|
44
43
|
|
|
@@ -46,14 +45,14 @@ export async function accessLogs (params) {
|
|
|
46
45
|
const jsonArray = new JsonArray();
|
|
47
46
|
|
|
48
47
|
stream
|
|
49
|
-
.on('open', (
|
|
50
|
-
Logger.debug(
|
|
48
|
+
.on('open', () => {
|
|
49
|
+
Logger.debug(styleText('blue', `Logs stream (open) ${JSON.stringify({ appId })}`));
|
|
51
50
|
if (format === 'json') {
|
|
52
51
|
jsonArray.open();
|
|
53
52
|
}
|
|
54
53
|
})
|
|
55
54
|
.on('error', (event) => {
|
|
56
|
-
Logger.debug(
|
|
55
|
+
Logger.debug(styleText('red', `Logs stream (error) ${event.error.message}`));
|
|
57
56
|
})
|
|
58
57
|
.onLog((log) => {
|
|
59
58
|
switch (format) {
|
|
@@ -87,21 +86,26 @@ export async function accessLogs (params) {
|
|
|
87
86
|
Logger.debug(`stream closed: ${closeReason?.type}`);
|
|
88
87
|
}
|
|
89
88
|
|
|
90
|
-
function formatHuman
|
|
89
|
+
function formatHuman(log) {
|
|
91
90
|
const { date, http, source } = log;
|
|
92
91
|
const country = source.countryCode ?? '(unknown)';
|
|
93
92
|
const hasSourceCity = source.city ?? '';
|
|
94
93
|
|
|
95
|
-
return
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
return formatTable(
|
|
95
|
+
[
|
|
96
|
+
[
|
|
97
|
+
styleText('grey', date.toISOString(date)),
|
|
98
|
+
source.ip,
|
|
99
|
+
`${country}${hasSourceCity ? '/' + truncateWithEllipsis(CITY_MAX_LENGTH, source.city) : ''}`,
|
|
100
|
+
colorStatusCode(http.response.statusCode),
|
|
101
|
+
http.request.method.toString().padEnd(4, ' ') + ' ' + http.request.path,
|
|
102
|
+
],
|
|
103
|
+
],
|
|
104
|
+
ACCESSLOG_COLUMN_WIDTHS,
|
|
105
|
+
);
|
|
102
106
|
}
|
|
103
107
|
|
|
104
|
-
const
|
|
108
|
+
const ACCESSLOG_COLUMN_WIDTHS = [
|
|
105
109
|
'2024-06-24T08:05:43.880Z',
|
|
106
110
|
'255.255.255.255',
|
|
107
111
|
// country / city
|
|
@@ -110,20 +114,25 @@ const row = formatTable([
|
|
|
110
114
|
// longest method name
|
|
111
115
|
'OPTIONS',
|
|
112
116
|
// path
|
|
113
|
-
]
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @param {number} code
|
|
121
|
+
* @returns {string}
|
|
122
|
+
*/
|
|
123
|
+
function colorStatusCode(code) {
|
|
124
|
+
const codeString = code.toString();
|
|
116
125
|
if (code >= 500) {
|
|
117
|
-
return
|
|
126
|
+
return styleText('red', codeString);
|
|
118
127
|
}
|
|
119
128
|
if (code >= 400) {
|
|
120
|
-
return
|
|
129
|
+
return styleText('yellow', codeString);
|
|
121
130
|
}
|
|
122
131
|
if (code >= 300) {
|
|
123
|
-
return
|
|
132
|
+
return styleText('blue', codeString);
|
|
124
133
|
}
|
|
125
134
|
if (code >= 200) {
|
|
126
|
-
return
|
|
135
|
+
return styleText('green', codeString);
|
|
127
136
|
}
|
|
128
|
-
return
|
|
137
|
+
return codeString;
|
|
129
138
|
}
|