netlify-cli 17.5.2 → 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 +240 -1021
- package/package.json +3 -3
- package/src/lib/images/proxy.mjs +27 -24
- package/src/utils/proxy.mjs +1 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
3
|
"description": "Netlify command line tool",
|
|
4
|
-
"version": "17.5.
|
|
4
|
+
"version": "17.5.3",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"@bugsnag/js": "7.20.2",
|
|
48
48
|
"@fastify/static": "6.10.2",
|
|
49
49
|
"@netlify/blobs": "6.3.0",
|
|
50
|
-
"@netlify/build": "29.
|
|
50
|
+
"@netlify/build": "29.27.0",
|
|
51
51
|
"@netlify/build-info": "7.11.1",
|
|
52
52
|
"@netlify/config": "20.10.0",
|
|
53
53
|
"@netlify/edge-bundler": "10.1.3",
|
|
54
54
|
"@netlify/local-functions-proxy": "1.1.1",
|
|
55
|
-
"@netlify/zip-it-and-ship-it": "9.26.
|
|
55
|
+
"@netlify/zip-it-and-ship-it": "9.26.2",
|
|
56
56
|
"@octokit/rest": "19.0.13",
|
|
57
57
|
"ansi-escapes": "6.2.0",
|
|
58
58
|
"ansi-styles": "6.2.1",
|
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;
|