netlify-cli 27.11.1 → 27.12.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/dist/commands/base-command.js +2 -2
- package/dist/commands/deploy/deploy.js +5 -1
- package/dist/commands/dev/dev.js +1 -2
- package/dist/commands/env/env-clone.js +1 -1
- package/dist/commands/env/env-set.js +1 -1
- package/dist/commands/env/env-unset.js +1 -1
- package/dist/commands/functions/functions-create.js +3 -93
- package/dist/commands/init/index.js +6 -1
- package/dist/commands/init/init.d.ts +3 -1
- package/dist/commands/init/init.js +22 -2
- package/dist/commands/serve/serve.js +1 -2
- package/dist/commands/sites/sites-list.js +1 -1
- package/dist/commands/unlink/unlink.js +1 -1
- package/dist/lib/edge-functions/registry.js +0 -1
- package/dist/lib/exec-fetcher.js +1 -1
- package/dist/lib/functions/form-submissions-handler.js +2 -1
- package/dist/recipes/ai-context/context.js +2 -2
- package/dist/utils/dev.d.ts +0 -1
- package/dist/utils/dev.js +1 -27
- package/dist/utils/env/index.js +1 -3
- package/dist/utils/get-repo-data.js +1 -1
- package/dist/utils/init/agent-skills.d.ts +96 -0
- package/dist/utils/init/agent-skills.js +653 -0
- package/dist/utils/parse-raw-flags.js +1 -1
- package/dist/utils/proxy-server.d.ts +1 -2
- package/dist/utils/proxy-server.js +1 -2
- package/dist/utils/proxy.d.ts +1 -1
- package/dist/utils/proxy.js +7 -35
- package/dist/utils/types.d.ts +1 -1
- package/package.json +9 -10
- package/dist/utils/addons/prepare.d.ts +0 -13
- package/dist/utils/addons/prepare.js +0 -26
package/dist/utils/proxy.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { $TSFixMe } from '../commands/types.js';
|
|
|
4
4
|
import { type NormalizedCachedConfigConfig } from './command-helpers.js';
|
|
5
5
|
import type { ServerSettings, SiteInfo } from './types.js';
|
|
6
6
|
export declare const getProxyUrl: (settings: Pick<ServerSettings, 'https' | 'port'>) => string;
|
|
7
|
-
export declare const startProxy: ({ accountId,
|
|
7
|
+
export declare const startProxy: ({ accountId, aiGatewayContext, api, blobsContext, command, config, configPath, debug, disableEdgeFunctions, env, functionsRegistry, geoCountry, geolocationMode, getUpdatedConfig, inspectSettings, offline, projectDir, repositoryRoot, settings, siteInfo, state, watchIgnore, deployEnvironment, }: {
|
|
8
8
|
command: BaseCommand;
|
|
9
9
|
config: NormalizedCachedConfigConfig;
|
|
10
10
|
settings: ServerSettings;
|
package/dist/utils/proxy.js
CHANGED
|
@@ -15,7 +15,7 @@ import { FileWatcher, fromWebResponse, mockLocation, renderFunctionErrorPage } f
|
|
|
15
15
|
import { ImageHandler } from '@netlify/images';
|
|
16
16
|
import { ServerHandler } from '@netlify/server-dev';
|
|
17
17
|
import { runBeforeProcessExit } from './shell.js';
|
|
18
|
-
import
|
|
18
|
+
import { parse as parseContentType } from 'content-type';
|
|
19
19
|
import generateETag from 'etag';
|
|
20
20
|
import getAvailablePort from 'get-port';
|
|
21
21
|
import httpProxy from 'http-proxy';
|
|
@@ -99,18 +99,13 @@ function isInternal(url) {
|
|
|
99
99
|
function isFunction(functionsPort, url) {
|
|
100
100
|
return functionsPort && url.match(DEFAULT_FUNCTION_URL_EXPRESSION);
|
|
101
101
|
}
|
|
102
|
-
function getAddonUrl(addonsUrls, req) {
|
|
103
|
-
const matches = req.url?.match(/^\/.netlify\/([^/]+)(\/.*)/);
|
|
104
|
-
const addonUrl = matches && addonsUrls[matches[1]];
|
|
105
|
-
return addonUrl ? `${addonUrl}${matches[2]}` : null;
|
|
106
|
-
}
|
|
107
102
|
const getStatic = async function (pathname, publicFolder) {
|
|
108
103
|
const alternatives = [pathname, ...alternativePathsFor(pathname)].map((filePath) => path.resolve(publicFolder, filePath.slice(1)));
|
|
109
104
|
const file = await locatePath(alternatives);
|
|
110
105
|
if (file === undefined) {
|
|
111
106
|
return false;
|
|
112
107
|
}
|
|
113
|
-
return `/${path.relative(publicFolder, file)}`;
|
|
108
|
+
return `/${path.relative(publicFolder, file).split(path.sep).join('/')}`;
|
|
114
109
|
};
|
|
115
110
|
const isEndpointExists = async function (endpoint, origin) {
|
|
116
111
|
const url = new URL(endpoint, origin);
|
|
@@ -137,12 +132,6 @@ const proxyToExternalUrl = function ({ dest, destURL, req, res, }) {
|
|
|
137
132
|
});
|
|
138
133
|
void handler(req, res, () => { });
|
|
139
134
|
};
|
|
140
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'addonUrl' implicitly has an 'any'... Remove this comment to see the full error message
|
|
141
|
-
const handleAddonUrl = function ({ addonUrl, req, res }) {
|
|
142
|
-
const dest = new URL(addonUrl);
|
|
143
|
-
const destURL = stripOrigin(dest);
|
|
144
|
-
proxyToExternalUrl({ req, res, dest, destURL });
|
|
145
|
-
};
|
|
146
135
|
const isRedirect = function (match) {
|
|
147
136
|
return 'status' in match && match.status != null && match.status >= 300 && match.status <= 400;
|
|
148
137
|
};
|
|
@@ -218,11 +207,6 @@ const serveRedirect = async function ({ env, functionsRegistry, imageProxy, matc
|
|
|
218
207
|
if (isFunction(options.functionsPort, req.url)) {
|
|
219
208
|
return proxy.web(req, res, { target: options.functionsServer });
|
|
220
209
|
}
|
|
221
|
-
const urlForAddons = getAddonUrl(options.addonsUrls, req);
|
|
222
|
-
if (urlForAddons) {
|
|
223
|
-
handleAddonUrl({ req, res, addonUrl: urlForAddons });
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
210
|
const originalURL = req.url;
|
|
227
211
|
const reqUrl = reqToURL(req, req.url);
|
|
228
212
|
const isHiddenProxy = match.proxyHeaders &&
|
|
@@ -277,7 +261,7 @@ const serveRedirect = async function ({ env, functionsRegistry, imageProxy, matc
|
|
|
277
261
|
res.end(`Redirecting to ${destURL}`);
|
|
278
262
|
return;
|
|
279
263
|
}
|
|
280
|
-
const ct = req.headers['content-type']
|
|
264
|
+
const ct = parseContentType(req.headers['content-type'] ?? '').type;
|
|
281
265
|
if (req.method === 'POST' &&
|
|
282
266
|
!isInternal(req.url) &&
|
|
283
267
|
!isInternal(destURL) &&
|
|
@@ -310,11 +294,6 @@ const serveRedirect = async function ({ env, functionsRegistry, imageProxy, matc
|
|
|
310
294
|
if (isImageRequest(req)) {
|
|
311
295
|
return imageProxy(req, res);
|
|
312
296
|
}
|
|
313
|
-
const addonUrl = getAddonUrl(options.addonsUrls, req);
|
|
314
|
-
if (addonUrl) {
|
|
315
|
-
handleAddonUrl({ req, res, addonUrl });
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
297
|
return proxy.web(req, res, { ...options, status: statusValue });
|
|
319
298
|
}
|
|
320
299
|
return proxy.web(req, res, options);
|
|
@@ -436,7 +415,7 @@ const initializeProxy = async function ({ config, configPath, distDir, env, host
|
|
|
436
415
|
// The request has failed but we might still have a matching redirect
|
|
437
416
|
// rule (without `force`) that should kick in. This is how we mimic the
|
|
438
417
|
// file shadowing behavior from the CDN.
|
|
439
|
-
if (options
|
|
418
|
+
if (options?.match) {
|
|
440
419
|
return serveRedirect({
|
|
441
420
|
// We don't want to match functions at this point because any redirects
|
|
442
421
|
// to functions will have already been processed, so we don't supply a
|
|
@@ -568,7 +547,7 @@ const initializeProxy = async function ({ config, configPath, distDir, env, host
|
|
|
568
547
|
};
|
|
569
548
|
return handlers;
|
|
570
549
|
};
|
|
571
|
-
const onRequest = async ({
|
|
550
|
+
const onRequest = async ({ api, edgeFunctionsProxy, env, functionsRegistry, functionsServer, imageProxy, proxy, rewriter, serverHandler, settings, siteInfo, }, req, res) => {
|
|
572
551
|
req.originalBody =
|
|
573
552
|
req.method && ['GET', 'OPTIONS', 'HEAD'].includes(req.method) ? null : await createStreamPromise(req, BYTES_LIMIT);
|
|
574
553
|
if (isImageRequest(req)) {
|
|
@@ -592,11 +571,6 @@ const onRequest = async ({ addonsUrls, api, edgeFunctionsProxy, env, functionsRe
|
|
|
592
571
|
}
|
|
593
572
|
return proxy.web(req, res, { headers, target: functionsServer });
|
|
594
573
|
}
|
|
595
|
-
const addonUrl = getAddonUrl(addonsUrls, req);
|
|
596
|
-
if (addonUrl) {
|
|
597
|
-
handleAddonUrl({ req, res, addonUrl });
|
|
598
|
-
return;
|
|
599
|
-
}
|
|
600
574
|
if (serverHandler) {
|
|
601
575
|
try {
|
|
602
576
|
const requestURL = reqToURL(req, req.url);
|
|
@@ -634,7 +608,6 @@ const onRequest = async ({ addonsUrls, api, edgeFunctionsProxy, env, functionsRe
|
|
|
634
608
|
const match = await rewriter(req);
|
|
635
609
|
const options = {
|
|
636
610
|
match,
|
|
637
|
-
addonsUrls,
|
|
638
611
|
target: `http://${settings.frameworkHost && isIPv6(settings.frameworkHost) ? `[${settings.frameworkHost}]` : settings.frameworkHost}:${settings.frameworkPort}`,
|
|
639
612
|
detectTarget: settings.detectFrameworkHost,
|
|
640
613
|
targetHostname: settings.frameworkHost,
|
|
@@ -668,7 +641,7 @@ const onRequest = async ({ addonsUrls, api, edgeFunctionsProxy, env, functionsRe
|
|
|
668
641
|
// @ts-expect-error TS(7031) FIXME: Binding element 'statusCode' implicitly has an 'an... Remove this comment to see the full error message
|
|
669
642
|
req[shouldGenerateETag] = ({ statusCode }) => statusCode >= 200 && statusCode < 300;
|
|
670
643
|
const hasFormSubmissionHandler = functionsRegistry && getFormHandler({ functionsRegistry, logWarning: false });
|
|
671
|
-
const ct = req.headers['content-type']
|
|
644
|
+
const ct = parseContentType(req.headers['content-type'] ?? '').type;
|
|
672
645
|
if (hasFormSubmissionHandler &&
|
|
673
646
|
functionsServer &&
|
|
674
647
|
req.method === 'POST' &&
|
|
@@ -683,7 +656,7 @@ export const getProxyUrl = function (settings) {
|
|
|
683
656
|
const scheme = settings.https ? 'https' : 'http';
|
|
684
657
|
return `${scheme}://localhost:${settings.port}`;
|
|
685
658
|
};
|
|
686
|
-
export const startProxy = async function ({ accountId,
|
|
659
|
+
export const startProxy = async function ({ accountId, aiGatewayContext, api, blobsContext, command, config, configPath, debug, disableEdgeFunctions, env, functionsRegistry, geoCountry, geolocationMode, getUpdatedConfig, inspectSettings, offline, projectDir, repositoryRoot, settings, siteInfo, state, watchIgnore, deployEnvironment, }) {
|
|
687
660
|
const secondaryServerPort = settings.https ? await getAvailablePort() : null;
|
|
688
661
|
const functionsServer = settings.functionsPort ? `http://127.0.0.1:${settings.functionsPort}` : null;
|
|
689
662
|
let edgeFunctionsProxy;
|
|
@@ -767,7 +740,6 @@ export const startProxy = async function ({ accountId, addonsUrls, aiGatewayCont
|
|
|
767
740
|
rewriter,
|
|
768
741
|
serverHandler,
|
|
769
742
|
settings,
|
|
770
|
-
addonsUrls,
|
|
771
743
|
functionsRegistry,
|
|
772
744
|
functionsServer,
|
|
773
745
|
edgeFunctionsProxy,
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -196,7 +196,7 @@ export type MinimalAccount = {
|
|
|
196
196
|
members_count: number;
|
|
197
197
|
};
|
|
198
198
|
type EnvironmentVariableScope = 'builds' | 'functions' | 'runtime' | 'post_processing';
|
|
199
|
-
export type EnvironmentVariableSource = 'account' | '
|
|
199
|
+
export type EnvironmentVariableSource = 'account' | 'configFile' | 'general' | 'internal' | 'ui';
|
|
200
200
|
export type EnvironmentVariables = Record<string, {
|
|
201
201
|
sources: EnvironmentVariableSource[];
|
|
202
202
|
value: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netlify-cli",
|
|
3
|
-
"version": "27.
|
|
3
|
+
"version": "27.12.0",
|
|
4
4
|
"description": "Netlify command line tool",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -63,14 +63,14 @@
|
|
|
63
63
|
"@netlify/dev": "^5.1.6",
|
|
64
64
|
"@netlify/dev-utils": "^6.0.3",
|
|
65
65
|
"@netlify/edge-bundler": "^16.1.2",
|
|
66
|
-
"@netlify/edge-functions": "^4.0.
|
|
66
|
+
"@netlify/edge-functions": "^4.0.2",
|
|
67
67
|
"@netlify/edge-functions-bootstrap": "^3.2.0",
|
|
68
68
|
"@netlify/headers-parser": "^10.1.1",
|
|
69
|
-
"@netlify/images": "^2.0.
|
|
69
|
+
"@netlify/images": "^2.0.3",
|
|
70
70
|
"@netlify/local-functions-proxy": "^2.0.3",
|
|
71
71
|
"@netlify/redirect-matcher": "^0.4.2",
|
|
72
72
|
"@netlify/redirect-parser": "^16.1.1",
|
|
73
|
-
"@netlify/server-dev": "^0.1.
|
|
73
|
+
"@netlify/server-dev": "^0.1.3",
|
|
74
74
|
"@netlify/zip-it-and-ship-it": "^16.3.0",
|
|
75
75
|
"@opentelemetry/api": "~1.9.0",
|
|
76
76
|
"@pnpm/tabtab": "^0.5.4",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"clean-deep": "^3.4.0",
|
|
86
86
|
"commander": "^12.1.0",
|
|
87
87
|
"comment-json": "^5.0.0",
|
|
88
|
-
"content-type": "^1.
|
|
88
|
+
"content-type": "^3.1.1",
|
|
89
89
|
"cookie": "^2.0.0",
|
|
90
90
|
"cron-parser": "^5.0.0",
|
|
91
91
|
"debug": "^4.4.3",
|
|
@@ -153,12 +153,11 @@
|
|
|
153
153
|
"@eslint/compat": "^1.4.1",
|
|
154
154
|
"@eslint/js": "^9.36.0",
|
|
155
155
|
"@netlify/functions": "^6.0.0",
|
|
156
|
-
"@netlify/types": "^3.
|
|
156
|
+
"@netlify/types": "^3.2.0",
|
|
157
157
|
"@sindresorhus/slugify": "^3.0.0",
|
|
158
158
|
"@tsconfig/node22": "22.0.5",
|
|
159
159
|
"@tsconfig/recommended": "^1.0.13",
|
|
160
160
|
"@types/backoff": "^2.5.5",
|
|
161
|
-
"@types/content-type": "^1.1.9",
|
|
162
161
|
"@types/debug": "^4.1.12",
|
|
163
162
|
"@types/envinfo": "^7.8.4",
|
|
164
163
|
"@types/eslint-config-prettier": "^6.11.3",
|
|
@@ -183,7 +182,7 @@
|
|
|
183
182
|
"@types/write-file-atomic": "^4.0.3",
|
|
184
183
|
"@types/ws": "^8.18.1",
|
|
185
184
|
"@types/yauzl": "^2.10.3",
|
|
186
|
-
"@vitest/coverage-v8": "^
|
|
185
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
187
186
|
"@vitest/eslint-plugin": "1.3.13",
|
|
188
187
|
"c8": "^10.1.3",
|
|
189
188
|
"cheerio": "^1.1.2",
|
|
@@ -197,7 +196,7 @@
|
|
|
197
196
|
"memfs": "^4.56.10",
|
|
198
197
|
"nock": "^14.0.10",
|
|
199
198
|
"npm-run-all2": "^8.0.4",
|
|
200
|
-
"oxfmt": "0.
|
|
199
|
+
"oxfmt": "0.72.0",
|
|
201
200
|
"p-timeout": "^7.0.0",
|
|
202
201
|
"picomatch": "^4.0.4",
|
|
203
202
|
"pkg-pr-new": "^0.0.86",
|
|
@@ -211,7 +210,7 @@
|
|
|
211
210
|
"typescript-eslint": "~8.65.0",
|
|
212
211
|
"typescript-native": "npm:typescript@~7.0.2",
|
|
213
212
|
"verdaccio": "^6.3.2",
|
|
214
|
-
"vitest": "^
|
|
213
|
+
"vitest": "^4.1.11"
|
|
215
214
|
},
|
|
216
215
|
"engines": {
|
|
217
216
|
"node": ">=22.13.0"
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export declare const getCurrentAddon: ({ addonName, addons }: {
|
|
2
|
-
addonName: any;
|
|
3
|
-
addons: any;
|
|
4
|
-
}) => any;
|
|
5
|
-
export declare const getSiteData: ({ api, siteId }: {
|
|
6
|
-
api: any;
|
|
7
|
-
siteId: any;
|
|
8
|
-
}) => Promise<any>;
|
|
9
|
-
export declare const getAddons: ({ api, siteId }: {
|
|
10
|
-
api: any;
|
|
11
|
-
siteId: any;
|
|
12
|
-
}) => Promise<any>;
|
|
13
|
-
//# sourceMappingURL=prepare.d.ts.map
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { logAndThrowError } from '../command-helpers.js';
|
|
2
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'addonName' implicitly has an 'any... Remove this comment to see the full error message
|
|
3
|
-
export const getCurrentAddon = ({ addonName, addons }) => addons.find((addon) => addon.service_slug === addonName);
|
|
4
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
5
|
-
export const getSiteData = async ({ api, siteId }) => {
|
|
6
|
-
let siteData;
|
|
7
|
-
try {
|
|
8
|
-
siteData = await api.getSite({ siteId });
|
|
9
|
-
}
|
|
10
|
-
catch (error_) {
|
|
11
|
-
return logAndThrowError(`Failed getting list of project data: ${error_.message}`);
|
|
12
|
-
}
|
|
13
|
-
return siteData;
|
|
14
|
-
};
|
|
15
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
16
|
-
export const getAddons = async ({ api, siteId }) => {
|
|
17
|
-
let addons;
|
|
18
|
-
try {
|
|
19
|
-
addons = await api.listServiceInstancesForSite({ siteId });
|
|
20
|
-
}
|
|
21
|
-
catch (error_) {
|
|
22
|
-
return logAndThrowError(`Failed getting list of addons: ${error_.message}`);
|
|
23
|
-
}
|
|
24
|
-
return addons;
|
|
25
|
-
};
|
|
26
|
-
//# sourceMappingURL=prepare.js.map
|