netlify-cli 17.3.1 → 17.4.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 +3 -139
- package/npm-shrinkwrap.json +82 -82
- package/package.json +16 -15
- package/src/commands/addons/addons-auth.mjs +27 -30
- package/src/commands/addons/addons-config.mjs +145 -154
- package/src/commands/addons/addons-create.mjs +94 -108
- package/src/commands/addons/addons-delete.mjs +36 -41
- package/src/commands/addons/addons-list.mjs +38 -42
- package/src/commands/addons/addons.mjs +26 -28
- package/src/commands/addons/index.mjs +1 -1
- package/src/commands/api/api.mjs +45 -53
- package/src/commands/api/index.mjs +1 -1
- package/src/commands/base-command.mjs +597 -684
- package/src/commands/blobs/blobs-delete.mjs +35 -0
- package/src/commands/blobs/blobs-get.mjs +44 -0
- package/src/commands/blobs/blobs-list.mjs +48 -0
- package/src/commands/blobs/blobs-set.mjs +54 -0
- package/src/commands/blobs/blobs.mjs +32 -0
- package/src/commands/blobs/index.mjs +1 -0
- package/src/commands/build/build.mjs +55 -67
- package/src/commands/build/index.mjs +1 -1
- package/src/commands/completion/completion.mjs +41 -46
- package/src/commands/completion/index.mjs +1 -1
- package/src/commands/deploy/deploy.mjs +675 -710
- package/src/commands/deploy/index.mjs +1 -1
- package/src/commands/dev/dev-exec.mjs +20 -32
- package/src/commands/dev/dev.mjs +217 -302
- package/src/commands/dev/index.mjs +1 -1
- package/src/commands/dev/types.d.ts +30 -0
- package/src/commands/env/env-clone.mjs +157 -184
- package/src/commands/env/env-get.mjs +49 -68
- package/src/commands/env/env-import.mjs +100 -119
- package/src/commands/env/env-list.mjs +104 -129
- package/src/commands/env/env-set.mjs +160 -185
- package/src/commands/env/env-unset.mjs +104 -122
- package/src/commands/env/env.mjs +28 -30
- package/src/commands/env/index.mjs +1 -1
- package/src/commands/functions/functions-build.mjs +29 -41
- package/src/commands/functions/functions-create.mjs +533 -601
- package/src/commands/functions/functions-invoke.mjs +193 -216
- package/src/commands/functions/functions-list.mjs +45 -55
- package/src/commands/functions/functions-serve.mjs +51 -61
- package/src/commands/functions/functions.mjs +26 -32
- package/src/commands/functions/index.mjs +1 -1
- package/src/commands/index.mjs +2 -2
- package/src/commands/init/index.mjs +1 -1
- package/src/commands/init/init.mjs +138 -167
- package/src/commands/integration/deploy.mjs +337 -399
- package/src/commands/integration/index.mjs +12 -13
- package/src/commands/link/index.mjs +1 -1
- package/src/commands/link/link.mjs +298 -317
- package/src/commands/lm/index.mjs +1 -1
- package/src/commands/lm/lm-info.mjs +23 -31
- package/src/commands/lm/lm-install.mjs +13 -17
- package/src/commands/lm/lm-setup.mjs +80 -84
- package/src/commands/lm/lm-uninstall.mjs +7 -12
- package/src/commands/lm/lm.mjs +18 -22
- package/src/commands/login/index.mjs +1 -1
- package/src/commands/login/login.mjs +35 -41
- package/src/commands/logout/index.mjs +1 -1
- package/src/commands/logout/logout.mjs +25 -31
- package/src/commands/main.mjs +166 -201
- package/src/commands/open/index.mjs +1 -1
- package/src/commands/open/open-admin.mjs +15 -18
- package/src/commands/open/open-site.mjs +16 -19
- package/src/commands/open/open.mjs +24 -27
- package/src/commands/recipes/common.mjs +23 -34
- package/src/commands/recipes/index.mjs +1 -1
- package/src/commands/recipes/recipes-list.mjs +13 -20
- package/src/commands/recipes/recipes.mjs +59 -72
- package/src/commands/serve/index.mjs +1 -1
- package/src/commands/serve/serve.mjs +142 -189
- package/src/commands/sites/index.mjs +2 -2
- package/src/commands/sites/sites-create-template.mjs +214 -236
- package/src/commands/sites/sites-create.mjs +145 -157
- package/src/commands/sites/sites-delete.mjs +75 -81
- package/src/commands/sites/sites-list.mjs +63 -66
- package/src/commands/sites/sites.mjs +18 -20
- package/src/commands/status/index.mjs +1 -1
- package/src/commands/status/status-hooks.mjs +32 -34
- package/src/commands/status/status.mjs +99 -106
- package/src/commands/switch/index.mjs +1 -1
- package/src/commands/switch/switch.mjs +32 -37
- package/src/commands/types.d.ts +31 -0
- package/src/commands/unlink/index.mjs +1 -1
- package/src/commands/unlink/unlink.mjs +23 -29
- package/src/commands/watch/index.mjs +1 -1
- package/src/commands/watch/watch.mjs +91 -105
- package/src/functions-templates/javascript/hello/{{name}}.js +2 -3
- package/src/lib/account.mjs +4 -5
- package/src/lib/api.mjs +22 -20
- package/src/lib/blobs/blobs.mjs +36 -45
- package/src/lib/build.mjs +82 -85
- package/src/lib/completion/constants.mjs +2 -4
- package/src/lib/completion/generate-autocompletion.mjs +33 -36
- package/src/lib/completion/get-autocompletion.mjs +31 -35
- package/src/lib/completion/index.mjs +1 -1
- package/src/lib/completion/script.mjs +12 -19
- package/src/lib/edge-functions/bootstrap.mjs +3 -5
- package/src/lib/edge-functions/consts.mjs +9 -10
- package/src/lib/edge-functions/deploy.mjs +28 -34
- package/src/lib/edge-functions/editor-helper.mjs +29 -42
- package/src/lib/edge-functions/headers.mjs +24 -26
- package/src/lib/edge-functions/internal.mjs +38 -44
- package/src/lib/edge-functions/proxy.mjs +229 -228
- package/src/lib/edge-functions/registry.mjs +473 -574
- package/src/lib/exec-fetcher.mjs +115 -122
- package/src/lib/fs.mjs +28 -27
- package/src/lib/functions/background.mjs +16 -20
- package/src/lib/functions/config.mjs +12 -9
- package/src/lib/functions/form-submissions-handler.mjs +143 -149
- package/src/lib/functions/local-proxy.mjs +40 -44
- package/src/lib/functions/memoized-build.mjs +19 -21
- package/src/lib/functions/netlify-function.mjs +269 -249
- package/src/lib/functions/registry.mjs +509 -568
- package/src/lib/functions/runtimes/go/index.mjs +62 -71
- package/src/lib/functions/runtimes/index.mjs +8 -15
- package/src/lib/functions/runtimes/js/builders/netlify-lambda.mjs +55 -64
- package/src/lib/functions/runtimes/js/builders/zisi.mjs +135 -154
- package/src/lib/functions/runtimes/js/constants.mjs +1 -1
- package/src/lib/functions/runtimes/js/index.mjs +92 -109
- package/src/lib/functions/runtimes/js/worker.mjs +43 -45
- package/src/lib/functions/runtimes/rust/index.mjs +64 -73
- package/src/lib/functions/scheduled.mjs +70 -88
- package/src/lib/functions/server.mjs +269 -327
- package/src/lib/functions/synchronous.mjs +118 -147
- package/src/lib/functions/utils.mjs +38 -46
- package/src/lib/geo-location.mjs +69 -81
- package/src/lib/http-agent.mjs +87 -90
- package/src/lib/images/proxy.mjs +97 -89
- package/src/lib/log.mjs +6 -9
- package/src/lib/path.mjs +2 -1
- package/src/lib/render-error-template.mjs +19 -20
- package/src/lib/settings.mjs +17 -19
- package/src/lib/spinner.mjs +21 -23
- package/src/lib/string.mjs +4 -2
- package/src/recipes/vscode/index.mjs +69 -85
- package/src/recipes/vscode/settings.mjs +53 -58
- package/src/utils/addons/compare.mjs +31 -32
- package/src/utils/addons/diffs/index.mjs +16 -17
- package/src/utils/addons/diffs/options.mjs +99 -101
- package/src/utils/addons/prepare.mjs +100 -97
- package/src/utils/addons/prompts.mjs +73 -76
- package/src/utils/addons/render.mjs +33 -36
- package/src/utils/addons/validation.mjs +19 -15
- package/src/utils/banner.mjs +11 -16
- package/src/utils/build-info.mjs +65 -66
- package/src/utils/command-helpers.mjs +185 -199
- package/src/utils/create-deferred.mjs +9 -12
- package/src/utils/create-stream-promise.mjs +54 -47
- package/src/utils/deploy/constants.mjs +9 -11
- package/src/utils/deploy/deploy-site.mjs +162 -182
- package/src/utils/deploy/hash-config.mjs +21 -21
- package/src/utils/deploy/hash-files.mjs +34 -38
- package/src/utils/deploy/hash-fns.mjs +149 -154
- package/src/utils/deploy/hasher-segments.mjs +58 -52
- package/src/utils/deploy/upload-files.mjs +99 -113
- package/src/utils/deploy/util.mjs +85 -91
- package/src/utils/detect-server-settings.mjs +236 -268
- package/src/utils/dev.mjs +163 -178
- package/src/utils/dot-env.mjs +37 -42
- package/src/utils/env/index.mjs +148 -148
- package/src/utils/execa.mjs +9 -13
- package/src/utils/feature-flags.mjs +6 -5
- package/src/utils/framework-server.mjs +43 -52
- package/src/utils/functions/constants.mjs +1 -1
- package/src/utils/functions/functions.mjs +30 -40
- package/src/utils/functions/get-functions.mjs +28 -29
- package/src/utils/functions/index.mjs +3 -3
- package/src/utils/get-global-config.mjs +33 -36
- package/src/utils/get-package-json.mjs +14 -15
- package/src/utils/get-repo-data.mjs +54 -64
- package/src/utils/get-site.mjs +14 -14
- package/src/utils/gh-auth.mjs +79 -100
- package/src/utils/gitignore.mjs +37 -40
- package/src/utils/headers.mjs +33 -35
- package/src/utils/hooks/requires-site-info.mjs +26 -22
- package/src/utils/init/config-github.mjs +207 -219
- package/src/utils/init/config-manual.mjs +83 -100
- package/src/utils/init/config.mjs +25 -26
- package/src/utils/init/node-version.mjs +23 -30
- package/src/utils/init/plugins.mjs +12 -8
- package/src/utils/init/utils.mjs +152 -172
- package/src/utils/live-tunnel.mjs +118 -141
- package/src/utils/lm/install.mjs +220 -259
- package/src/utils/lm/requirements.mjs +54 -63
- package/src/utils/lm/steps.mjs +31 -31
- package/src/utils/lm/ui.mjs +13 -20
- package/src/utils/open-browser.mjs +31 -32
- package/src/utils/parse-raw-flags.mjs +39 -35
- package/src/utils/proxy-server.mjs +84 -71
- package/src/utils/proxy.mjs +696 -750
- package/src/utils/read-repo-url.mjs +48 -47
- package/src/utils/redirects.mjs +49 -49
- package/src/utils/request-id.mjs +2 -4
- package/src/utils/rules-proxy.mjs +96 -100
- package/src/utils/run-build.mjs +109 -132
- package/src/utils/shell.mjs +99 -106
- package/src/utils/sign-redirect.mjs +14 -14
- package/src/utils/sites/utils.mjs +48 -55
- package/src/utils/state-config.mjs +101 -101
- package/src/utils/static-server.mjs +28 -34
- package/src/utils/telemetry/index.mjs +2 -2
- package/src/utils/telemetry/report-error.mjs +45 -49
- package/src/utils/telemetry/request.mjs +36 -43
- package/src/utils/telemetry/telemetry.mjs +90 -105
- package/src/utils/telemetry/utils.mjs +5 -6
- package/src/utils/telemetry/validation.mjs +55 -53
- package/src/utils/types.d.ts +46 -0
- package/src/utils/validation.mjs +10 -13
|
@@ -1,85 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import { chalk, logPadded, NETLIFYDEVERR } from '../../utils/command-helpers.mjs'
|
|
7
|
-
import renderErrorTemplate from '../render-error-template.mjs'
|
|
8
|
-
|
|
9
|
-
import { detectAwsSdkError } from './utils.mjs'
|
|
10
|
-
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import { isStream } from 'is-stream';
|
|
3
|
+
import { chalk, logPadded, NETLIFYDEVERR } from '../../utils/command-helpers.mjs';
|
|
4
|
+
import renderErrorTemplate from '../render-error-template.mjs';
|
|
5
|
+
import { detectAwsSdkError } from './utils.mjs';
|
|
11
6
|
/**
|
|
12
7
|
* @typedef InvocationError
|
|
13
8
|
* @property {string} errorType
|
|
14
9
|
* @property {string} errorMessage
|
|
15
10
|
* @property {Array<string>} stackTrace
|
|
16
11
|
*/
|
|
17
|
-
|
|
12
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'headers' implicitly has an 'any' type.
|
|
18
13
|
const addHeaders = (headers, response) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
Object.entries(headers).forEach(([key, value]) => {
|
|
24
|
-
response.setHeader(key, value)
|
|
25
|
-
})
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const handleSynchronousFunction = function ({
|
|
29
|
-
error: invocationError,
|
|
30
|
-
functionName,
|
|
31
|
-
request,
|
|
32
|
-
response,
|
|
33
|
-
result,
|
|
34
|
-
}) {
|
|
35
|
-
if (invocationError) {
|
|
36
|
-
const error = getNormalizedError(invocationError)
|
|
37
|
-
|
|
38
|
-
logPadded(
|
|
39
|
-
`${NETLIFYDEVERR} Function ${chalk.yellow(functionName)} has returned an error: ${
|
|
40
|
-
error.errorMessage
|
|
41
|
-
}\n${chalk.dim(error.stackTrace.join('\n'))}`,
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
return handleErr(invocationError, request, response)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const { error } = validateLambdaResponse(result)
|
|
48
|
-
if (error) {
|
|
49
|
-
logPadded(`${NETLIFYDEVERR} ${error}`)
|
|
50
|
-
|
|
51
|
-
return handleErr(error, request, response)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
response.statusCode = result.statusCode
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
addHeaders(result.headers, response)
|
|
58
|
-
addHeaders(result.multiValueHeaders, response)
|
|
59
|
-
} catch (headersError) {
|
|
60
|
-
const normalizedError = getNormalizedError(headersError)
|
|
61
|
-
|
|
62
|
-
logPadded(
|
|
63
|
-
`${NETLIFYDEVERR} Failed to set header in function ${chalk.yellow(functionName)}: ${
|
|
64
|
-
normalizedError.errorMessage
|
|
65
|
-
}`,
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
return handleErr(headersError, request, response)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (result.body) {
|
|
72
|
-
if (isStream(result.body)) {
|
|
73
|
-
result.body.pipe(response)
|
|
74
|
-
|
|
75
|
-
return
|
|
14
|
+
if (!headers) {
|
|
15
|
+
return;
|
|
76
16
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
17
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
18
|
+
response.setHeader(key, value);
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
export const handleSynchronousFunction = function ({
|
|
22
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'invocationError' implicitly has a... Remove this comment to see the full error message
|
|
23
|
+
error: invocationError,
|
|
24
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'functionName' implicitly has an '... Remove this comment to see the full error message
|
|
25
|
+
functionName,
|
|
26
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'request' implicitly has an 'any' ... Remove this comment to see the full error message
|
|
27
|
+
request,
|
|
28
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'response' implicitly has an 'any'... Remove this comment to see the full error message
|
|
29
|
+
response,
|
|
30
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'result' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
31
|
+
result, }) {
|
|
32
|
+
if (invocationError) {
|
|
33
|
+
const error = getNormalizedError(invocationError);
|
|
34
|
+
logPadded(`${NETLIFYDEVERR} Function ${chalk.yellow(functionName)} has returned an error: ${error.errorMessage}\n${chalk.dim(error.stackTrace.join('\n'))}`);
|
|
35
|
+
return handleErr(invocationError, request, response);
|
|
36
|
+
}
|
|
37
|
+
const { error } = validateLambdaResponse(result);
|
|
38
|
+
if (error) {
|
|
39
|
+
logPadded(`${NETLIFYDEVERR} ${error}`);
|
|
40
|
+
return handleErr(error, request, response);
|
|
41
|
+
}
|
|
42
|
+
response.statusCode = result.statusCode;
|
|
43
|
+
try {
|
|
44
|
+
addHeaders(result.headers, response);
|
|
45
|
+
addHeaders(result.multiValueHeaders, response);
|
|
46
|
+
}
|
|
47
|
+
catch (headersError) {
|
|
48
|
+
const normalizedError = getNormalizedError(headersError);
|
|
49
|
+
logPadded(`${NETLIFYDEVERR} Failed to set header in function ${chalk.yellow(functionName)}: ${normalizedError.errorMessage}`);
|
|
50
|
+
return handleErr(headersError, request, response);
|
|
51
|
+
}
|
|
52
|
+
if (result.body) {
|
|
53
|
+
if (isStream(result.body)) {
|
|
54
|
+
result.body.pipe(response);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
response.write(result.isBase64Encoded ? Buffer.from(result.body, 'base64') : result.body);
|
|
58
|
+
}
|
|
59
|
+
response.end();
|
|
60
|
+
};
|
|
83
61
|
/**
|
|
84
62
|
* Accepts an error generated by `lambda-local` or an instance of `Error` and
|
|
85
63
|
* returns a normalized error that we can treat in the same way.
|
|
@@ -87,83 +65,76 @@ export const handleSynchronousFunction = function ({
|
|
|
87
65
|
* @param {InvocationError|Error} error
|
|
88
66
|
* @returns {InvocationError}
|
|
89
67
|
*/
|
|
68
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'error' implicitly has an 'any' type.
|
|
90
69
|
const getNormalizedError = (error) => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
70
|
+
if (error instanceof Error) {
|
|
71
|
+
const normalizedError = {
|
|
72
|
+
errorMessage: error.message,
|
|
73
|
+
errorType: error.name,
|
|
74
|
+
stackTrace: error.stack ? error.stack.split('\n') : [],
|
|
75
|
+
};
|
|
76
|
+
if ('code' in error && error.code === 'ERR_REQUIRE_ESM') {
|
|
77
|
+
return {
|
|
78
|
+
...normalizedError,
|
|
79
|
+
errorMessage: 'a CommonJS file cannot import ES modules. Consider switching your function to ES modules. For more information, refer to https://ntl.fyi/functions-runtime.',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return normalizedError;
|
|
104
83
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
stackTrace,
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
84
|
+
// Formatting stack trace lines in the same way that Node.js formats native
|
|
85
|
+
// errors.
|
|
86
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'line' implicitly has an 'any' type.
|
|
87
|
+
const stackTrace = error.stackTrace.map((line) => ` at ${line}`);
|
|
88
|
+
return {
|
|
89
|
+
errorType: error.errorType,
|
|
90
|
+
errorMessage: error.errorMessage,
|
|
91
|
+
stackTrace,
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'rawError' implicitly has an 'any' type.
|
|
120
95
|
const formatLambdaLocalError = (rawError, acceptsHTML) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
96
|
+
const error = getNormalizedError(rawError);
|
|
97
|
+
if (acceptsHTML) {
|
|
98
|
+
return JSON.stringify({
|
|
99
|
+
...error,
|
|
100
|
+
stackTrace: undefined,
|
|
101
|
+
trace: error.stackTrace,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return `${error.errorType}: ${error.errorMessage}\n ${error.stackTrace.join('\n')}`;
|
|
105
|
+
};
|
|
106
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'err' implicitly has an 'any' type.
|
|
134
107
|
const handleErr = async (err, request, response) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
108
|
+
// @ts-expect-error TS(2345) FIXME: Argument of type '{ err: any; }' is not assignable... Remove this comment to see the full error message
|
|
109
|
+
detectAwsSdkError({ err });
|
|
110
|
+
const acceptsHtml = request.headers && request.headers.accept && request.headers.accept.includes('text/html');
|
|
111
|
+
const errorString = typeof err === 'string' ? err : formatLambdaLocalError(err, acceptsHtml);
|
|
112
|
+
response.statusCode = 500;
|
|
113
|
+
if (acceptsHtml) {
|
|
114
|
+
response.setHeader('Content-Type', 'text/html');
|
|
115
|
+
response.end(await renderErrorTemplate(errorString, './templates/function-error.html', 'function'));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
response.end(errorString);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'lambdaResponse' implicitly has an 'any'... Remove this comment to see the full error message
|
|
150
122
|
const validateLambdaResponse = (lambdaResponse) => {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
if (lambdaResponse === null) {
|
|
155
|
-
return {
|
|
156
|
-
error: 'no lambda response. check your function code again. make sure to return a promise or use the callback.',
|
|
123
|
+
if (lambdaResponse === undefined) {
|
|
124
|
+
return { error: 'lambda response was undefined. check your function code again' };
|
|
157
125
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
126
|
+
if (lambdaResponse === null) {
|
|
127
|
+
return {
|
|
128
|
+
error: 'no lambda response. check your function code again. make sure to return a promise or use the callback.',
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (!Number(lambdaResponse.statusCode)) {
|
|
132
|
+
return {
|
|
133
|
+
error: `Your function response must have a numerical statusCode. You gave: ${lambdaResponse.statusCode}`,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (lambdaResponse.body && typeof lambdaResponse.body !== 'string' && !isStream(lambdaResponse.body)) {
|
|
137
|
+
return { error: `Your function response must have a string or a stream body. You gave: ${lambdaResponse.body}` };
|
|
162
138
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
return { error: `Your function response must have a string or a stream body. You gave: ${lambdaResponse.body}` }
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return {}
|
|
169
|
-
}
|
|
139
|
+
return {};
|
|
140
|
+
};
|
|
@@ -1,54 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { chalk, warn } from '../../utils/command-helpers.mjs';
|
|
2
|
+
import { MISSING_AWS_SDK_WARNING } from '../log.mjs';
|
|
3
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'error' implicitly has an 'any' ty... Remove this comment to see the full error message
|
|
5
4
|
export const detectAwsSdkError = ({ error }) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export const formatLambdaError = (err) => chalk.red(`${err.errorType}: ${err.errorMessage}`)
|
|
14
|
-
|
|
5
|
+
const isAwsSdkError = error && error.errorMessage && error.errorMessage.includes("Cannot find module 'aws-sdk'");
|
|
6
|
+
if (isAwsSdkError) {
|
|
7
|
+
warn(MISSING_AWS_SDK_WARNING);
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'err' implicitly has an 'any' type.
|
|
11
|
+
export const formatLambdaError = (err) => chalk.red(`${err.errorType}: ${err.errorMessage}`);
|
|
15
12
|
// should be equivalent to https://github.com/netlify/proxy/blob/main/pkg/functions/request.go#L105
|
|
16
13
|
const exceptionsList = new Set([
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
])
|
|
25
|
-
|
|
14
|
+
'application/csp-report',
|
|
15
|
+
'application/graphql',
|
|
16
|
+
'application/json',
|
|
17
|
+
'application/javascript',
|
|
18
|
+
'application/x-www-form-urlencoded',
|
|
19
|
+
'application/x-ndjson',
|
|
20
|
+
'application/xml',
|
|
21
|
+
]);
|
|
26
22
|
/**
|
|
27
23
|
* @param {string | undefined} contentType
|
|
28
24
|
* @returns {boolean}
|
|
29
25
|
*/
|
|
26
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'contentType' implicitly has an 'any' ty... Remove this comment to see the full error message
|
|
30
27
|
export const shouldBase64Encode = function (contentType) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return true
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export const styleFunctionName = (name) => chalk.magenta(name)
|
|
28
|
+
if (!contentType) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
const [contentTypeSegment] = contentType.split(';');
|
|
32
|
+
contentType = contentTypeSegment;
|
|
33
|
+
contentType = contentType.toLowerCase();
|
|
34
|
+
if (contentType.startsWith('text/')) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (contentType.endsWith('+json') || contentType.endsWith('+xml')) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (exceptionsList.has(contentType)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
};
|
|
45
|
+
// @ts-expect-error TS(7006) FIXME: Parameter 'name' implicitly has an 'any' type.
|
|
46
|
+
export const styleFunctionName = (name) => chalk.magenta(name);
|
package/src/lib/geo-location.mjs
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
// @ts-
|
|
2
|
-
import fetch from 'node-fetch'
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const STATE_GEO_PROPERTY = 'geolocation'
|
|
1
|
+
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'node... Remove this comment to see the full error message
|
|
2
|
+
import fetch from 'node-fetch';
|
|
3
|
+
const API_URL = 'https://netlifind.netlify.app';
|
|
4
|
+
const STATE_GEO_PROPERTY = 'geolocation';
|
|
6
5
|
// 24 hours
|
|
7
|
-
const CACHE_TTL = 8.64e7
|
|
8
|
-
|
|
6
|
+
const CACHE_TTL = 8.64e7;
|
|
9
7
|
// 10 seconds
|
|
10
|
-
const REQUEST_TIMEOUT = 1e4
|
|
11
|
-
|
|
8
|
+
const REQUEST_TIMEOUT = 1e4;
|
|
12
9
|
/**
|
|
13
10
|
* @typedef GeoLocation
|
|
14
11
|
* @type {object}
|
|
@@ -23,16 +20,14 @@ const REQUEST_TIMEOUT = 1e4
|
|
|
23
20
|
* @property {number} latitude
|
|
24
21
|
* @property {string} timezone
|
|
25
22
|
*/
|
|
26
|
-
|
|
27
23
|
export const mockLocation = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
24
|
+
city: 'San Francisco',
|
|
25
|
+
country: { code: 'US', name: 'United States' },
|
|
26
|
+
subdivision: { code: 'CA', name: 'California' },
|
|
27
|
+
longitude: 0,
|
|
28
|
+
latitude: 0,
|
|
29
|
+
timezone: 'UTC',
|
|
30
|
+
};
|
|
36
31
|
/**
|
|
37
32
|
* Returns geolocation data from a remote API, the local cache, or a mock
|
|
38
33
|
* location, depending on the mode selected.
|
|
@@ -44,76 +39,69 @@ export const mockLocation = {
|
|
|
44
39
|
* @param {import('../utils/state-config.mjs').default} params.state
|
|
45
40
|
* @returns {Promise<GeoLocation>}
|
|
46
41
|
*/
|
|
42
|
+
// @ts-expect-error TS(7031) FIXME: Binding element 'geoCountry' implicitly has an 'an... Remove this comment to see the full error message
|
|
47
43
|
export const getGeoLocation = async ({ geoCountry, mode, offline, state }) => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// If `--country` was used, we also set `--mode=mock`.
|
|
51
|
-
if (geoCountry) {
|
|
52
|
-
mode = 'mock'
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// If we have cached geolocation data and the `--geo` option is set to
|
|
56
|
-
// `cache`, let's try to use it.
|
|
57
|
-
// Or, if the country we're trying to mock is the same one as we have in the
|
|
58
|
-
// cache, let's use the cache instead of the mock.
|
|
59
|
-
if (cacheObject !== undefined && (mode === 'cache' || cacheObject.data.country.code === geoCountry)) {
|
|
60
|
-
const age = Date.now() - cacheObject.timestamp
|
|
61
|
-
|
|
62
|
-
// Let's use the cached data if it's not older than the TTL. Also, if the
|
|
63
|
-
// `--offline` option was used, it's best to use the cached location than
|
|
64
|
-
// the mock one.
|
|
65
|
-
if (age < CACHE_TTL || offline) {
|
|
66
|
-
return cacheObject.data
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// If the `--geo` option is set to `mock`, we use the default mock location.
|
|
71
|
-
// If the `--offline` option was used, we can't talk to the API, so let's
|
|
72
|
-
// also use the mock location. Otherwise, use the country code passed in by
|
|
73
|
-
// the user.
|
|
74
|
-
if (mode === 'mock' || offline || geoCountry) {
|
|
44
|
+
const cacheObject = state.get(STATE_GEO_PROPERTY);
|
|
45
|
+
// If `--country` was used, we also set `--mode=mock`.
|
|
75
46
|
if (geoCountry) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
47
|
+
mode = 'mock';
|
|
48
|
+
}
|
|
49
|
+
// If we have cached geolocation data and the `--geo` option is set to
|
|
50
|
+
// `cache`, let's try to use it.
|
|
51
|
+
// Or, if the country we're trying to mock is the same one as we have in the
|
|
52
|
+
// cache, let's use the cache instead of the mock.
|
|
53
|
+
if (cacheObject !== undefined && (mode === 'cache' || cacheObject.data.country.code === geoCountry)) {
|
|
54
|
+
const age = Date.now() - cacheObject.timestamp;
|
|
55
|
+
// Let's use the cached data if it's not older than the TTL. Also, if the
|
|
56
|
+
// `--offline` option was used, it's best to use the cached location than
|
|
57
|
+
// the mock one.
|
|
58
|
+
if (age < CACHE_TTL || offline) {
|
|
59
|
+
return cacheObject.data;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// If the `--geo` option is set to `mock`, we use the default mock location.
|
|
63
|
+
// If the `--offline` option was used, we can't talk to the API, so let's
|
|
64
|
+
// also use the mock location. Otherwise, use the country code passed in by
|
|
65
|
+
// the user.
|
|
66
|
+
if (mode === 'mock' || offline || geoCountry) {
|
|
67
|
+
if (geoCountry) {
|
|
68
|
+
return {
|
|
69
|
+
city: 'Mock City',
|
|
70
|
+
country: { code: geoCountry, name: 'Mock Country' },
|
|
71
|
+
subdivision: { code: 'SD', name: 'Mock Subdivision' },
|
|
72
|
+
longitude: 0,
|
|
73
|
+
latitude: 0,
|
|
74
|
+
timezone: 'UTC',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return mockLocation;
|
|
78
|
+
}
|
|
79
|
+
// Trying to retrieve geolocation data from the API and caching it locally.
|
|
80
|
+
try {
|
|
81
|
+
const data = await getGeoLocationFromAPI();
|
|
82
|
+
const newCacheObject = {
|
|
83
|
+
data,
|
|
84
|
+
timestamp: Date.now(),
|
|
85
|
+
};
|
|
86
|
+
state.set(STATE_GEO_PROPERTY, newCacheObject);
|
|
87
|
+
return data;
|
|
84
88
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
const data = await getGeoLocationFromAPI()
|
|
91
|
-
const newCacheObject = {
|
|
92
|
-
data,
|
|
93
|
-
timestamp: Date.now(),
|
|
89
|
+
catch {
|
|
90
|
+
// We couldn't get geolocation data from the API, so let's return the
|
|
91
|
+
// mock location.
|
|
92
|
+
return mockLocation;
|
|
94
93
|
}
|
|
95
|
-
|
|
96
|
-
state.set(STATE_GEO_PROPERTY, newCacheObject)
|
|
97
|
-
|
|
98
|
-
return data
|
|
99
|
-
} catch {
|
|
100
|
-
// We couldn't get geolocation data from the API, so let's return the
|
|
101
|
-
// mock location.
|
|
102
|
-
return mockLocation
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
94
|
+
};
|
|
106
95
|
/**
|
|
107
96
|
* Returns geolocation data from a remote API
|
|
108
97
|
*
|
|
109
98
|
* @returns {Promise<GeoLocation>}
|
|
110
99
|
*/
|
|
111
100
|
const getGeoLocationFromAPI = async () => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
101
|
+
const res = await fetch(API_URL, {
|
|
102
|
+
method: 'GET',
|
|
103
|
+
timeout: REQUEST_TIMEOUT,
|
|
104
|
+
});
|
|
105
|
+
const { geo } = await res.json();
|
|
106
|
+
return geo;
|
|
107
|
+
};
|