netlify-cli 17.5.1 → 17.5.3
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/npm-shrinkwrap.json +433 -433
- package/package.json +5 -5
- package/src/commands/completion/completion.mjs +2 -2
- package/src/commands/dev/dev.mjs +2 -2
- package/src/commands/functions/functions-create.mjs +4 -4
- package/src/commands/serve/serve.mjs +9 -2
- package/src/commands/sites/sites-create-template.mjs +2 -2
- package/src/lib/edge-functions/registry.mjs +306 -487
- package/src/lib/exec-fetcher.mjs +4 -4
- package/src/lib/functions/form-submissions-handler.mjs +1 -0
- package/src/lib/functions/registry.mjs +0 -1
- package/src/lib/images/proxy.mjs +27 -24
- package/src/utils/build-info.mjs +2 -2
- package/src/utils/command-helpers.mjs +8 -19
- package/src/utils/init/utils.mjs +1 -1
- package/src/utils/proxy.mjs +1 -0
- package/src/utils/shell.mjs +2 -2
- package/src/utils/telemetry/telemetry.mjs +1 -1
package/src/lib/exec-fetcher.mjs
CHANGED
|
@@ -108,10 +108,10 @@ export const fetchLatestVersion = async ({ destination, execName, extension, lat
|
|
|
108
108
|
};
|
|
109
109
|
const options = getOptions();
|
|
110
110
|
const fetch = latestVersion
|
|
111
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type '{ headers: { Authorization: stri... Remove this comment to see the full error message
|
|
112
|
-
|
|
113
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type '{ repository: string; package: s... Remove this comment to see the full error message
|
|
114
|
-
|
|
111
|
+
? // @ts-expect-error TS(2345) FIXME: Argument of type '{ headers: { Authorization: stri... Remove this comment to see the full error message
|
|
112
|
+
fetchVersion({ ...release, version: latestVersion }, options)
|
|
113
|
+
: // @ts-expect-error TS(2345) FIXME: Argument of type '{ repository: string; package: s... Remove this comment to see the full error message
|
|
114
|
+
fetchLatest(release, options);
|
|
115
115
|
try {
|
|
116
116
|
await fetch;
|
|
117
117
|
}
|
|
@@ -57,6 +57,7 @@ export const createFormSubmissionHandler = function ({ functionsRegistry, siteUr
|
|
|
57
57
|
}
|
|
58
58
|
else if (ct.type === 'multipart/form-data') {
|
|
59
59
|
try {
|
|
60
|
+
;
|
|
60
61
|
[fields, files] = await new Promise((resolve, reject) => {
|
|
61
62
|
const form = new multiparty.Form({ encoding: ct.parameters.charset || 'utf8' });
|
|
62
63
|
// @ts-expect-error TS(7006) FIXME: Parameter 'err' implicitly has an 'any' type.
|
|
@@ -215,7 +215,6 @@ export class FunctionsRegistry {
|
|
|
215
215
|
// we create a new watcher and watch them.
|
|
216
216
|
if (srcFilesDiff.added.size !== 0) {
|
|
217
217
|
const filesToWatch = [...srcFilesDiff.added, ...includedFiles];
|
|
218
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type '{ onChange: () => void; }' is no... Remove this comment to see the full error message
|
|
219
218
|
const newWatcher = await watchDebounced(filesToWatch, {
|
|
220
219
|
onChange: () => {
|
|
221
220
|
this.buildFunctionAndWatchFiles(func, false);
|
package/src/lib/images/proxy.mjs
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import { createIPX, ipxFSStorage, ipxHttpStorage, createIPXNodeServer } from 'ipx';
|
|
3
3
|
import { log, NETLIFYDEVERR } from '../../utils/command-helpers.mjs';
|
|
4
|
+
import { getProxyUrl } from '../../utils/proxy.mjs';
|
|
4
5
|
export const IMAGE_URL_PATTERN = '/.netlify/images';
|
|
5
6
|
// @ts-expect-error TS(7006) FIXME: Parameter 'config' implicitly has an 'any' type.
|
|
6
7
|
export const parseAllDomains = function (config) {
|
|
8
|
+
const remoteDomains = [];
|
|
9
|
+
const errors = [];
|
|
7
10
|
const domains = config?.images?.remote_images;
|
|
8
11
|
if (!domains) {
|
|
9
|
-
return { errors
|
|
12
|
+
return { errors, remoteDomains };
|
|
10
13
|
}
|
|
11
|
-
const remoteDomains = [];
|
|
12
|
-
const errors = [];
|
|
13
14
|
for (const patternString of domains) {
|
|
14
15
|
try {
|
|
15
16
|
const url = new URL(patternString);
|
|
@@ -17,21 +18,23 @@ export const parseAllDomains = function (config) {
|
|
|
17
18
|
remoteDomains.push(url.hostname);
|
|
18
19
|
}
|
|
19
20
|
else {
|
|
20
|
-
errors.push(`The URL '${patternString}' does not have a valid hostname.`);
|
|
21
|
+
errors.push({ message: `The URL '${patternString}' does not have a valid hostname.` });
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
catch (error) {
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
if (error instanceof Error) {
|
|
26
|
+
errors.push({ message: `Invalid URL '${patternString}': ${error.message}` });
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
errors.push({ message: `Invalid URL '${patternString}': An unknown error occurred` });
|
|
30
|
+
}
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
return { errors, remoteDomains };
|
|
29
34
|
};
|
|
30
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'message' implicitly has an 'any' ... Remove this comment to see the full error message
|
|
31
35
|
const getErrorMessage = function ({ message }) {
|
|
32
36
|
return message;
|
|
33
37
|
};
|
|
34
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'errors' implicitly has an 'any' type.
|
|
35
38
|
export const handleImageDomainsErrors = async function (errors) {
|
|
36
39
|
if (errors.length === 0) {
|
|
37
40
|
return;
|
|
@@ -48,57 +51,57 @@ export const parseRemoteImageDomains = async function ({ config }) {
|
|
|
48
51
|
await handleImageDomainsErrors(errors);
|
|
49
52
|
return remoteDomains;
|
|
50
53
|
};
|
|
51
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'req' implicitly has an 'any' type.
|
|
52
54
|
export const isImageRequest = function (req) {
|
|
53
55
|
return req.url.startsWith(IMAGE_URL_PATTERN);
|
|
54
56
|
};
|
|
55
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'query' implicitly has an 'any' type.
|
|
56
57
|
export const transformImageParams = function (query) {
|
|
57
58
|
const params = {};
|
|
58
59
|
const width = query.w || query.width || null;
|
|
59
60
|
const height = query.h || query.height || null;
|
|
60
61
|
if (width && height) {
|
|
61
|
-
// @ts-expect-error TS(2339) FIXME: Property 's' does not exist on type '{}'.
|
|
62
62
|
// eslint-disable-next-line id-length
|
|
63
63
|
params.s = `${width}x${height}`;
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
66
|
-
// @ts-expect-error TS(2339) FIXME: Property 'w' does not exist on type '{}'.
|
|
67
66
|
// eslint-disable-next-line id-length
|
|
68
67
|
params.w = width;
|
|
69
|
-
// @ts-expect-error TS(2339) FIXME: Property 'j' does not exist on type '{}'.
|
|
70
68
|
// eslint-disable-next-line id-length
|
|
71
69
|
params.h = height;
|
|
72
70
|
}
|
|
73
|
-
// @ts-expect-error TS(2339) FIXME: Property 'quality' does not exist on type '{}'.
|
|
74
71
|
params.quality = query.q || query.quality || null;
|
|
75
|
-
// @ts-expect-error TS(2339) FIXME: Property 'format' does not exist on type '{}'.
|
|
76
72
|
params.format = query.fm || null;
|
|
77
73
|
const fit = query.fit || null;
|
|
78
|
-
// @ts-expect-error TS(2339) FIXME: Property 'fit' does not exist on type '{}'.
|
|
79
74
|
params.fit = fit === 'contain' ? 'inside' : fit;
|
|
80
|
-
// @ts-expect-error TS(2339) FIXME: Property 'position' does not exist on type '{}'.
|
|
81
75
|
params.position = query.position || null;
|
|
82
76
|
return Object.entries(params)
|
|
83
77
|
.filter(([, value]) => value !== null)
|
|
84
78
|
.map(([key, value]) => `${key}_${value}`)
|
|
85
79
|
.join(',');
|
|
86
80
|
};
|
|
87
|
-
|
|
88
|
-
export const initializeProxy = async function ({ config }) {
|
|
81
|
+
export const initializeProxy = async function ({ config, settings, }) {
|
|
89
82
|
const remoteDomains = await parseRemoteImageDomains({ config });
|
|
83
|
+
const devServerUrl = getProxyUrl(settings);
|
|
90
84
|
const ipx = createIPX({
|
|
91
85
|
storage: ipxFSStorage({ dir: config?.build?.publish ?? './public' }),
|
|
92
|
-
httpStorage: ipxHttpStorage({ domains: remoteDomains }),
|
|
86
|
+
httpStorage: ipxHttpStorage({ domains: [...remoteDomains, devServerUrl] }),
|
|
93
87
|
});
|
|
94
88
|
const handler = createIPXNodeServer(ipx);
|
|
95
89
|
const app = express();
|
|
96
90
|
app.use(IMAGE_URL_PATTERN, async (req, res) => {
|
|
97
91
|
const { url, ...query } = req.query;
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
92
|
+
const sourceImagePath = url;
|
|
93
|
+
const modifiers = (await transformImageParams(query)) || `_`;
|
|
94
|
+
if (!sourceImagePath.startsWith('http://') && !sourceImagePath.startsWith('https://')) {
|
|
95
|
+
// Construct the full URL for relative paths to request from development server
|
|
96
|
+
const sourceImagePathWithLeadingSlash = sourceImagePath.startsWith('/') ? sourceImagePath : `/${sourceImagePath}`;
|
|
97
|
+
const fullImageUrl = `${devServerUrl}/${encodeURIComponent(sourceImagePathWithLeadingSlash)}`;
|
|
98
|
+
console.log(`fullImageUrl: ${fullImageUrl}`);
|
|
99
|
+
req.url = `/${modifiers}/${fullImageUrl}`;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// If the image is remote, we can just pass the URL as is
|
|
103
|
+
req.url = `/${modifiers}/${encodeURIComponent(sourceImagePath)}`;
|
|
104
|
+
}
|
|
102
105
|
handler(req, res);
|
|
103
106
|
});
|
|
104
107
|
return app;
|
package/src/utils/build-info.mjs
CHANGED
|
@@ -86,7 +86,7 @@ command = "${chosenSettings.devCommand}"
|
|
|
86
86
|
export const detectBuildSettings = async (command) => {
|
|
87
87
|
const { project, workspacePackage } = command;
|
|
88
88
|
const buildSettings = await project.getBuildSettings(project.workspace ? workspacePackage : '');
|
|
89
|
-
return buildSettings
|
|
89
|
+
return (buildSettings
|
|
90
90
|
// @ts-expect-error TS(7006) FIXME: Parameter 'setting' implicitly has an 'any' type.
|
|
91
91
|
.filter((setting) => {
|
|
92
92
|
if (project.workspace && project.relativeBaseDirectory && setting.packagePath) {
|
|
@@ -95,5 +95,5 @@ export const detectBuildSettings = async (command) => {
|
|
|
95
95
|
return true;
|
|
96
96
|
})
|
|
97
97
|
// @ts-expect-error TS(7006) FIXME: Parameter 'setting' implicitly has an 'any' type.
|
|
98
|
-
.filter((setting) => setting.devCommand);
|
|
98
|
+
.filter((setting) => setting.devCommand));
|
|
99
99
|
};
|
|
@@ -209,41 +209,23 @@ export const normalizeConfig = (config) => {
|
|
|
209
209
|
const DEBOUNCE_WAIT = 100;
|
|
210
210
|
/**
|
|
211
211
|
* Adds a file watcher to a path or set of paths and debounces the events.
|
|
212
|
-
*
|
|
213
|
-
* @param {string | string[]} target
|
|
214
|
-
* @param {Object} opts
|
|
215
|
-
* @param {number} [opts.depth]
|
|
216
|
-
* @param {Array<string|RegExp>} [opts.ignored]
|
|
217
|
-
* @param {(paths: string[]) => any} [opts.onAdd]
|
|
218
|
-
* @param {(paths: string[]) => any} [opts.onChange]
|
|
219
|
-
* @param {(paths: string[]) => any} [opts.onUnlink]
|
|
220
212
|
*/
|
|
221
|
-
export const watchDebounced = async (
|
|
222
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'target' implicitly has an 'any' type.
|
|
223
|
-
target,
|
|
224
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'depth' implicitly has an 'any' ty... Remove this comment to see the full error message
|
|
225
|
-
{ depth, ignored = [], onAdd = () => { }, onChange = () => { }, onUnlink = () => { } }) => {
|
|
213
|
+
export const watchDebounced = async (target, { depth, ignored = [], onAdd = noOp, onChange = noOp, onUnlink = noOp }) => {
|
|
226
214
|
const baseIgnores = [/\/(node_modules|.git)\//];
|
|
227
215
|
const watcher = chokidar.watch(target, { depth, ignored: [...baseIgnores, ...ignored], ignoreInitial: true });
|
|
228
216
|
await once(watcher, 'ready');
|
|
229
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'onChangeQueue' implicitly has type 'any[... Remove this comment to see the full error message
|
|
230
217
|
let onChangeQueue = [];
|
|
231
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'onAddQueue' implicitly has type 'any[]' ... Remove this comment to see the full error message
|
|
232
218
|
let onAddQueue = [];
|
|
233
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'onUnlinkQueue' implicitly has type 'any[... Remove this comment to see the full error message
|
|
234
219
|
let onUnlinkQueue = [];
|
|
235
220
|
const debouncedOnChange = debounce(() => {
|
|
236
|
-
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
237
221
|
onChange(onChangeQueue);
|
|
238
222
|
onChangeQueue = [];
|
|
239
223
|
}, DEBOUNCE_WAIT);
|
|
240
224
|
const debouncedOnAdd = debounce(() => {
|
|
241
|
-
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
242
225
|
onAdd(onAddQueue);
|
|
243
226
|
onAddQueue = [];
|
|
244
227
|
}, DEBOUNCE_WAIT);
|
|
245
228
|
const debouncedOnUnlink = debounce(() => {
|
|
246
|
-
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
247
229
|
onUnlink(onUnlinkQueue);
|
|
248
230
|
onUnlinkQueue = [];
|
|
249
231
|
}, DEBOUNCE_WAIT);
|
|
@@ -271,3 +253,10 @@ target,
|
|
|
271
253
|
// @ts-expect-error TS(7006) FIXME: Parameter 'text' implicitly has an 'any' type.
|
|
272
254
|
export const getTerminalLink = (text, url) => terminalLink(text, url, { fallback: () => `${text} (${url})` });
|
|
273
255
|
export const isNodeError = (err) => error instanceof Error;
|
|
256
|
+
// FIXME: tsc is throwing the following error:
|
|
257
|
+
// @ts-expect-error TS7060: This syntax is reserved in files with the .mts or .cts extension. Add a trailing comma or explicit constraint.
|
|
258
|
+
// Adding a trailing comma to the generic type fixes the problem, but annoyingly Prettier is undoing that.
|
|
259
|
+
export const nonNullable = (value) => value !== null && value !== undefined;
|
|
260
|
+
export const noOp = () => {
|
|
261
|
+
// no-op
|
|
262
|
+
};
|
package/src/utils/init/utils.mjs
CHANGED
|
@@ -21,7 +21,7 @@ const pluginsToAlwaysInstall = new Set(['@netlify/plugin-nextjs']);
|
|
|
21
21
|
* @returns
|
|
22
22
|
*/
|
|
23
23
|
export const getPluginsToAutoInstall = (pluginsInstalled = [], pluginsRecommended = []) => pluginsRecommended.reduce((acc, plugin) => pluginsInstalled.includes(plugin) && !pluginsToAlwaysInstall.has(plugin) ? acc : [...acc, plugin],
|
|
24
|
-
/** @type {string[]} */
|
|
24
|
+
/** @type {string[]} */ []);
|
|
25
25
|
/**
|
|
26
26
|
*
|
|
27
27
|
* @param {Partial<import('@netlify/build-info').Settings>} settings
|
package/src/utils/proxy.mjs
CHANGED
package/src/utils/shell.mjs
CHANGED
|
@@ -95,8 +95,8 @@ export const runCommand = (command, options = {}) => {
|
|
|
95
95
|
}
|
|
96
96
|
else {
|
|
97
97
|
const errorMessage = result.failed
|
|
98
|
-
// @ts-expect-error TS(2339) FIXME: Property 'shortMessage' does not exist on type 'Ex... Remove this comment to see the full error message
|
|
99
|
-
|
|
98
|
+
? // @ts-expect-error TS(2339) FIXME: Property 'shortMessage' does not exist on type 'Ex... Remove this comment to see the full error message
|
|
99
|
+
`${NETLIFYDEVERR} ${result.shortMessage}`
|
|
100
100
|
: `${NETLIFYDEVWARN} "${command}" exited with code ${result.exitCode}`;
|
|
101
101
|
log(`${errorMessage}. Shutting down Netlify Dev server`);
|
|
102
102
|
}
|
|
@@ -19,7 +19,7 @@ function send(type, payload) {
|
|
|
19
19
|
data: payload,
|
|
20
20
|
type,
|
|
21
21
|
});
|
|
22
|
-
const args = /** @type {const} */
|
|
22
|
+
const args = /** @type {const} */ [process.execPath, [requestFile, options]];
|
|
23
23
|
if (process.env.NETLIFY_TEST_TELEMETRY_WAIT === 'true') {
|
|
24
24
|
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
25
25
|
return execa(...args, {
|