netlify-cli 17.10.1 → 17.11.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/npm-shrinkwrap.json +956 -203
- package/package.json +2 -3
- package/src/commands/base-command.js +47 -102
- package/src/commands/deploy/deploy.js +5 -8
- package/src/commands/dev/dev.js +0 -1
- package/src/commands/functions/functions-create.js +0 -4
- package/src/commands/link/link.js +0 -5
- package/src/commands/lm/lm-setup.js +0 -2
- package/src/commands/main.js +0 -2
- package/src/commands/serve/serve.js +3 -1
- package/src/commands/sites/sites-create-template.js +0 -3
- package/src/lib/blobs/blobs.js +1 -1
- package/src/lib/edge-functions/proxy.js +2 -21
- package/src/lib/edge-functions/registry.js +42 -10
- package/src/lib/exec-fetcher.js +0 -2
- package/src/lib/functions/local-proxy.js +1 -3
- package/src/lib/functions/netlify-function.js +3 -3
- package/src/lib/functions/registry.js +17 -27
- package/src/lib/functions/runtimes/go/index.js +0 -3
- package/src/lib/functions/runtimes/index.js +0 -34
- package/src/lib/functions/runtimes/js/builders/netlify-lambda.js +10 -10
- package/src/lib/functions/runtimes/rust/index.js +0 -2
- package/src/lib/functions/server.js +23 -13
- package/src/utils/banner.js +2 -3
- package/src/utils/build-info.js +22 -39
- package/src/utils/command-helpers.js +3 -11
- package/src/utils/deploy/deploy-site.js +0 -6
- package/src/utils/detect-server-settings.js +15 -101
- package/src/utils/execa.js +1 -4
- package/src/utils/feature-flags.js +1 -7
- package/src/utils/framework-server.js +6 -10
- package/src/utils/functions/functions.js +2 -9
- package/src/utils/init/utils.js +17 -32
- package/src/utils/live-tunnel.js +0 -2
- package/src/utils/lm/requirements.js +0 -5
- package/src/utils/sites/utils.js +0 -1
- package/src/utils/telemetry/report-error.js +0 -2
- package/src/utils/telemetry/telemetry.js +1 -21
- package/src/lib/edge-functions/internal.js +0 -46
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.
|
|
4
|
+
"version": "17.11.0",
|
|
5
5
|
"author": "Netlify Inc.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@netlify/build": "29.31.0",
|
|
50
50
|
"@netlify/build-info": "7.11.3",
|
|
51
51
|
"@netlify/config": "20.10.0",
|
|
52
|
-
"@netlify/edge-bundler": "
|
|
52
|
+
"@netlify/edge-bundler": "11.0.0",
|
|
53
53
|
"@netlify/local-functions-proxy": "1.1.1",
|
|
54
54
|
"@netlify/zip-it-and-ship-it": "9.28.1",
|
|
55
55
|
"@octokit/rest": "19.0.13",
|
|
@@ -115,7 +115,6 @@
|
|
|
115
115
|
"lodash": "4.17.21",
|
|
116
116
|
"log-symbols": "5.1.0",
|
|
117
117
|
"log-update": "5.0.1",
|
|
118
|
-
"minimist": "1.2.8",
|
|
119
118
|
"multiparty": "4.2.3",
|
|
120
119
|
"netlify": "13.1.11",
|
|
121
120
|
"netlify-headers-parser": "7.1.2",
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _BaseCommand_noBaseOptions;
|
|
1
13
|
import { existsSync } from 'fs';
|
|
2
14
|
import { join, relative, resolve } from 'path';
|
|
3
15
|
import process from 'process';
|
|
@@ -41,33 +53,22 @@ const HELP_SEPARATOR_WIDTH = 5;
|
|
|
41
53
|
* workspace aware.
|
|
42
54
|
*/
|
|
43
55
|
const COMMANDS_WITHOUT_WORKSPACE_OPTIONS = new Set(['api', 'recipes', 'completion', 'status', 'switch', 'login', 'lm']);
|
|
44
|
-
/**
|
|
45
|
-
* Formats a help list correctly with the correct indent
|
|
46
|
-
* @param {string[]} textArray
|
|
47
|
-
* @returns
|
|
48
|
-
*/
|
|
49
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'textArray' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
56
|
+
/** Formats a help list correctly with the correct indent */
|
|
50
57
|
const formatHelpList = (textArray) => textArray.join('\n').replace(/^/gm, ' '.repeat(HELP_INDENT_WIDTH));
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
* @param {bigint} startTime
|
|
54
|
-
* @returns
|
|
55
|
-
*/
|
|
56
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'startTime' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
57
|
-
const getDuration = function (startTime) {
|
|
58
|
+
/** Get the duration between a start time and the current time */
|
|
59
|
+
const getDuration = (startTime) => {
|
|
58
60
|
const durationNs = process.hrtime.bigint() - startTime;
|
|
59
61
|
return Math.round(Number(durationNs / BigInt(NANO_SECS_TO_MSECS)));
|
|
60
62
|
};
|
|
61
63
|
/**
|
|
62
64
|
* Retrieves a workspace package based of the filter flag that is provided.
|
|
63
65
|
* If the filter flag does not match a workspace package or is not defined then it will prompt with an autocomplete to select a package
|
|
64
|
-
* @param {Project} project
|
|
65
|
-
* @param {string=} filter
|
|
66
|
-
* @returns {Promise<string>}
|
|
67
66
|
*/
|
|
68
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'project' implicitly has an 'any' type.
|
|
69
67
|
async function selectWorkspace(project, filter) {
|
|
70
|
-
//
|
|
68
|
+
// don't show prompt for workspace selection if there is only one package
|
|
69
|
+
if (project.workspace?.packages && project.workspace.packages.length === 1) {
|
|
70
|
+
return project.workspace.packages[0].path;
|
|
71
|
+
}
|
|
71
72
|
const selected = project.workspace?.packages.find((pkg) => {
|
|
72
73
|
if (project.relativeBaseDirectory &&
|
|
73
74
|
project.relativeBaseDirectory.length !== 0 &&
|
|
@@ -86,9 +87,7 @@ async function selectWorkspace(project, filter) {
|
|
|
86
87
|
message: 'Select the site you want to work with',
|
|
87
88
|
// @ts-expect-error TS(7006) FIXME: Parameter '_' implicitly has an 'any' type.
|
|
88
89
|
source: (/** @type {string} */ _, input = '') => (project.workspace?.packages || [])
|
|
89
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'pkg' implicitly has an 'any' type.
|
|
90
90
|
.filter((pkg) => pkg.path.includes(input))
|
|
91
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'pkg' implicitly has an 'any' type.
|
|
92
91
|
.map((pkg) => ({
|
|
93
92
|
name: `${pkg.name ? `${chalk.bold(pkg.name)} ` : ''}${pkg.path} ${chalk.dim(`--filter ${pkg.name || pkg.path}`)}`,
|
|
94
93
|
value: pkg.path,
|
|
@@ -105,10 +104,9 @@ async function getRepositoryRoot(cwd) {
|
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
106
|
/** Base command class that provides tracking and config initialization */
|
|
108
|
-
|
|
107
|
+
class BaseCommand extends Command {
|
|
109
108
|
constructor() {
|
|
110
109
|
super(...arguments);
|
|
111
|
-
/** @type {{ startTime: bigint, payload?: any}} */
|
|
112
110
|
this.analytics = { startTime: process.hrtime.bigint() };
|
|
113
111
|
/**
|
|
114
112
|
* The working directory that is used for reading the `netlify.toml` file and storing the state.
|
|
@@ -118,18 +116,16 @@ export default class BaseCommand extends Command {
|
|
|
118
116
|
// here we actually want to disable the lint rule as its value is set
|
|
119
117
|
// eslint-disable-next-line workspace/no-process-cwd
|
|
120
118
|
this.workingDir = process.cwd();
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
_BaseCommand_noBaseOptions.set(this, false
|
|
120
|
+
/** don't show help options on command overview (mostly used on top commands like `addons` where options only apply on children) */
|
|
121
|
+
);
|
|
122
|
+
/** The examples list for the command (used inside doc generation and help page) */
|
|
124
123
|
this.examples = [];
|
|
125
124
|
}
|
|
126
125
|
/**
|
|
127
126
|
* IMPORTANT this function will be called for each command!
|
|
128
127
|
* Don't do anything expensive in there.
|
|
129
|
-
* @param {string} name The command name
|
|
130
|
-
* @returns
|
|
131
128
|
*/
|
|
132
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'name' implicitly has an 'any' type.
|
|
133
129
|
createCommand(name) {
|
|
134
130
|
const base = new BaseCommand(name)
|
|
135
131
|
// If --silent or --json flag passed disable logger
|
|
@@ -167,22 +163,15 @@ export default class BaseCommand extends Command {
|
|
|
167
163
|
}
|
|
168
164
|
/** don't show help options on command overview (mostly used on top commands like `addons` where options only apply on children) */
|
|
169
165
|
noHelpOptions() {
|
|
170
|
-
this
|
|
166
|
+
__classPrivateFieldSet(this, _BaseCommand_noBaseOptions, true, "f");
|
|
171
167
|
return this;
|
|
172
168
|
}
|
|
173
|
-
/**
|
|
174
|
-
* Set examples for the command
|
|
175
|
-
* @param {string[]} examples
|
|
176
|
-
*/
|
|
177
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'examples' implicitly has an 'any' type.
|
|
169
|
+
/** Set examples for the command */
|
|
178
170
|
addExamples(examples) {
|
|
179
171
|
this.examples = examples;
|
|
180
172
|
return this;
|
|
181
173
|
}
|
|
182
|
-
/**
|
|
183
|
-
* Overrides the help output of commander with custom styling
|
|
184
|
-
* @returns {import('commander').Help}
|
|
185
|
-
*/
|
|
174
|
+
/** Overrides the help output of commander with custom styling */
|
|
186
175
|
createHelp() {
|
|
187
176
|
const help = super.createHelp();
|
|
188
177
|
help.commandUsage = (command) => {
|
|
@@ -209,12 +198,7 @@ export default class BaseCommand extends Command {
|
|
|
209
198
|
.sort((a, b) => a.name().localeCompare(b.name())) || []);
|
|
210
199
|
};
|
|
211
200
|
help.longestSubcommandTermLength = (command) => getCommands(command).reduce((max, cmd) => Math.max(max, cmd.name().length), 0);
|
|
212
|
-
/**
|
|
213
|
-
* override the longestOptionTermLength to react on hide options flag
|
|
214
|
-
* @param {BaseCommand} command
|
|
215
|
-
* @param {import('commander').Help} helper
|
|
216
|
-
* @returns {number}
|
|
217
|
-
*/
|
|
201
|
+
/** override the longestOptionTermLength to react on hide options flag */
|
|
218
202
|
help.longestOptionTermLength = (command, helper) =>
|
|
219
203
|
// @ts-expect-error TS(2551) FIXME: Property 'noBaseOptions' does not exist on type 'C... Remove this comment to see the full error message
|
|
220
204
|
(command.noBaseOptions === false &&
|
|
@@ -224,14 +208,7 @@ export default class BaseCommand extends Command {
|
|
|
224
208
|
const parentCommand = this.name() === 'netlify' ? command : command.parent;
|
|
225
209
|
const termWidth = helper.padWidth(command, helper);
|
|
226
210
|
const helpWidth = helper.helpWidth || FALLBACK_HELP_CMD_WIDTH;
|
|
227
|
-
|
|
228
|
-
* formats a term correctly
|
|
229
|
-
* @param {string} term
|
|
230
|
-
* @param {string} [description]
|
|
231
|
-
* @param {boolean} [isCommand]
|
|
232
|
-
* @returns {string}
|
|
233
|
-
*/
|
|
234
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'term' implicitly has an 'any' type.
|
|
211
|
+
// formats a term correctly
|
|
235
212
|
const formatItem = (term, description, isCommand = false) => {
|
|
236
213
|
const bang = isCommand ? `${HELP_$} ` : '';
|
|
237
214
|
if (description) {
|
|
@@ -241,22 +218,17 @@ export default class BaseCommand extends Command {
|
|
|
241
218
|
}
|
|
242
219
|
return `${bang}${term}`;
|
|
243
220
|
};
|
|
244
|
-
/** @type {string[]} */
|
|
245
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'output' implicitly has type 'any[]' in s... Remove this comment to see the full error message
|
|
246
221
|
let output = [];
|
|
247
222
|
// Description
|
|
248
223
|
const [topDescription, ...commandDescription] = (helper.commandDescription(command) || '').split('\n');
|
|
249
224
|
if (topDescription.length !== 0) {
|
|
250
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'output' implicitly has an 'any[]' type.
|
|
251
225
|
output = [...output, topDescription, ''];
|
|
252
226
|
}
|
|
253
227
|
// on the parent help command the version should be displayed
|
|
254
228
|
if (this.name() === 'netlify') {
|
|
255
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'output' implicitly has an 'any[]' type.
|
|
256
229
|
output = [...output, chalk.bold('VERSION'), formatHelpList([formatItem(USER_AGENT)]), ''];
|
|
257
230
|
}
|
|
258
231
|
// Usage
|
|
259
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'output' implicitly has an 'any[]' type.
|
|
260
232
|
output = [...output, chalk.bold('USAGE'), helper.commandUsage(command), ''];
|
|
261
233
|
// Arguments
|
|
262
234
|
const argumentList = helper
|
|
@@ -265,7 +237,7 @@ export default class BaseCommand extends Command {
|
|
|
265
237
|
if (argumentList.length !== 0) {
|
|
266
238
|
output = [...output, chalk.bold('ARGUMENTS'), formatHelpList(argumentList), ''];
|
|
267
239
|
}
|
|
268
|
-
if (command
|
|
240
|
+
if (__classPrivateFieldGet(command, _BaseCommand_noBaseOptions, "f") === false) {
|
|
269
241
|
// Options
|
|
270
242
|
const optionList = helper
|
|
271
243
|
.visibleOptions(command)
|
|
@@ -302,14 +274,9 @@ export default class BaseCommand extends Command {
|
|
|
302
274
|
};
|
|
303
275
|
return help;
|
|
304
276
|
}
|
|
305
|
-
/**
|
|
306
|
-
* Will be called on the end of an action to track the metrics
|
|
307
|
-
* @param {*} [error_]
|
|
308
|
-
*/
|
|
309
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'error_' implicitly has an 'any' type.
|
|
277
|
+
/** Will be called on the end of an action to track the metrics */
|
|
310
278
|
async onEnd(error_) {
|
|
311
|
-
|
|
312
|
-
const { payload, startTime } = this.analytics;
|
|
279
|
+
const { payload = {}, startTime } = this.analytics;
|
|
313
280
|
const duration = getDuration(startTime);
|
|
314
281
|
const status = error_ === undefined ? 'success' : 'error';
|
|
315
282
|
const command = Array.isArray(this.args) ? this.args[0] : this.name();
|
|
@@ -324,7 +291,6 @@ export default class BaseCommand extends Command {
|
|
|
324
291
|
}
|
|
325
292
|
catch { }
|
|
326
293
|
if (error_ !== undefined) {
|
|
327
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type 'string | Error' is not assignabl... Remove this comment to see the full error message
|
|
328
294
|
error(error_ instanceof Error ? error_ : format(error_), { exit: false });
|
|
329
295
|
exit(1);
|
|
330
296
|
}
|
|
@@ -387,23 +353,16 @@ export default class BaseCommand extends Command {
|
|
|
387
353
|
log();
|
|
388
354
|
return accessToken;
|
|
389
355
|
}
|
|
390
|
-
/**
|
|
391
|
-
* Adds some data to the analytics payload
|
|
392
|
-
* @param {Record<string, unknown>} payload
|
|
393
|
-
*/
|
|
394
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'payload' implicitly has an 'any' type.
|
|
356
|
+
/** Adds some data to the analytics payload */
|
|
395
357
|
setAnalyticsPayload(payload) {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
358
|
+
this.analytics = {
|
|
359
|
+
...this.analytics,
|
|
360
|
+
payload: { ...this.analytics.payload, ...payload },
|
|
361
|
+
};
|
|
400
362
|
}
|
|
401
363
|
/**
|
|
402
364
|
* Initializes the options and parses the configuration needs to be called on start of a command function
|
|
403
|
-
* @param {BaseCommand} actionCommand The command of the action that is run (`this.` gets the parent command)
|
|
404
|
-
* @private
|
|
405
365
|
*/
|
|
406
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'actionCommand' implicitly has an 'any' ... Remove this comment to see the full error message
|
|
407
366
|
async init(actionCommand) {
|
|
408
367
|
debug(`${actionCommand.name()}:init`)('start');
|
|
409
368
|
const flags = actionCommand.opts();
|
|
@@ -431,7 +390,6 @@ export default class BaseCommand extends Command {
|
|
|
431
390
|
});
|
|
432
391
|
});
|
|
433
392
|
const frameworks = await this.project.detectFrameworks();
|
|
434
|
-
/** @type { string|undefined} */
|
|
435
393
|
let packageConfig = flags.config ? resolve(flags.config) : undefined;
|
|
436
394
|
// check if we have detected multiple projects inside which one we have to perform our operations.
|
|
437
395
|
// only ask to select one if on the workspace root
|
|
@@ -457,11 +415,8 @@ export default class BaseCommand extends Command {
|
|
|
457
415
|
};
|
|
458
416
|
if (process.env.NETLIFY_API_URL) {
|
|
459
417
|
const apiUrl = new URL(process.env.NETLIFY_API_URL);
|
|
460
|
-
// @ts-expect-error TS(2339) FIXME: Property 'scheme' does not exist on type '{ userAg... Remove this comment to see the full error message
|
|
461
418
|
apiUrlOpts.scheme = apiUrl.protocol.slice(0, -1);
|
|
462
|
-
// @ts-expect-error TS(2339) FIXME: Property 'host' does not exist on type '{ userAgen... Remove this comment to see the full error message
|
|
463
419
|
apiUrlOpts.host = apiUrl.host;
|
|
464
|
-
// @ts-expect-error TS(2339) FIXME: Property 'pathPrefix' does not exist on type '{ us... Remove this comment to see the full error message
|
|
465
420
|
apiUrlOpts.pathPrefix =
|
|
466
421
|
process.env.NETLIFY_API_URL === `${apiUrl.protocol}//${apiUrl.host}` ? '/api/v1' : apiUrl.pathname;
|
|
467
422
|
}
|
|
@@ -486,6 +441,7 @@ export default class BaseCommand extends Command {
|
|
|
486
441
|
certificateFile: flags.httpProxyCertificateFilename,
|
|
487
442
|
});
|
|
488
443
|
const apiOpts = { ...apiUrlOpts, agent };
|
|
444
|
+
// TODO: remove typecast once we have proper types for the API
|
|
489
445
|
const api = new NetlifyAPI(token || '', apiOpts);
|
|
490
446
|
// If a user passes a site name as an option instead of a site ID to options.site, the siteInfo object
|
|
491
447
|
// will only have the property siteInfo.id. Checking for one of the other properties ensures that we can do
|
|
@@ -501,7 +457,6 @@ export default class BaseCommand extends Command {
|
|
|
501
457
|
// ==================================================
|
|
502
458
|
// Perform analytics reporting
|
|
503
459
|
// ==================================================
|
|
504
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'framework' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
505
460
|
const frameworkIDs = frameworks?.map((framework) => framework.id);
|
|
506
461
|
if (frameworkIDs?.length !== 0) {
|
|
507
462
|
this.setAnalyticsPayload({ frameworks: frameworkIDs });
|
|
@@ -509,7 +464,6 @@ export default class BaseCommand extends Command {
|
|
|
509
464
|
this.setAnalyticsPayload({
|
|
510
465
|
monorepo: Boolean(this.project.workspace),
|
|
511
466
|
packageManager: this.project.packageManager?.name,
|
|
512
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'id' implicitly has an 'any' type.
|
|
513
467
|
buildSystem: this.project.buildSystems.map(({ id }) => id),
|
|
514
468
|
});
|
|
515
469
|
// set the project and the netlify api object on the command,
|
|
@@ -553,22 +507,7 @@ export default class BaseCommand extends Command {
|
|
|
553
507
|
};
|
|
554
508
|
debug(`${this.name()}:init`)('end');
|
|
555
509
|
}
|
|
556
|
-
/**
|
|
557
|
-
* Find and resolve the Netlify configuration
|
|
558
|
-
* @param {object} config
|
|
559
|
-
* @param {string} config.cwd
|
|
560
|
-
* @param {string|null=} config.token
|
|
561
|
-
* @param {*} config.state
|
|
562
|
-
* @param {boolean=} config.offline
|
|
563
|
-
* @param {string=} config.configFilePath An optional path to the netlify configuration file e.g. netlify.toml
|
|
564
|
-
* @param {string=} config.packagePath
|
|
565
|
-
* @param {string=} config.repositoryRoot
|
|
566
|
-
* @param {string=} config.host
|
|
567
|
-
* @param {string=} config.pathPrefix
|
|
568
|
-
* @param {string=} config.scheme
|
|
569
|
-
* @returns {ReturnType<typeof resolveConfig>}
|
|
570
|
-
*/
|
|
571
|
-
// @ts-expect-error TS(7023) FIXME: 'getConfig' implicitly has return type 'any' becau... Remove this comment to see the full error message
|
|
510
|
+
/** Find and resolve the Netlify configuration */
|
|
572
511
|
async getConfig(config) {
|
|
573
512
|
// the flags that are passed to the command like `--debug` or `--offline`
|
|
574
513
|
const flags = this.opts();
|
|
@@ -617,10 +556,16 @@ export default class BaseCommand extends Command {
|
|
|
617
556
|
* Returns the context that should be used in case one hasn't been explicitly
|
|
618
557
|
* set. The default context is `dev` most of the time, but some commands may
|
|
619
558
|
* wish to override that.
|
|
620
|
-
*
|
|
621
|
-
* @returns {'production' | 'dev'}
|
|
622
559
|
*/
|
|
623
560
|
getDefaultContext() {
|
|
624
561
|
return this.name() === 'serve' ? 'production' : 'dev';
|
|
625
562
|
}
|
|
563
|
+
/**
|
|
564
|
+
* Retrieve feature flags for this site
|
|
565
|
+
*/
|
|
566
|
+
getFeatureFlag(flagName) {
|
|
567
|
+
return this.netlify.siteInfo.feature_flags?.[flagName] || null;
|
|
568
|
+
}
|
|
626
569
|
}
|
|
570
|
+
_BaseCommand_noBaseOptions = new WeakMap();
|
|
571
|
+
export default BaseCommand;
|
|
@@ -359,9 +359,7 @@ deployTimeout,
|
|
|
359
359
|
// @ts-expect-error TS(7031) FIXME: Binding element 'deployToProduction' implicitly ha... Remove this comment to see the full error message
|
|
360
360
|
deployToProduction,
|
|
361
361
|
// @ts-expect-error TS(7031) FIXME: Binding element 'functionsConfig' implicitly has a... Remove this comment to see the full error message
|
|
362
|
-
functionsConfig,
|
|
363
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'functionsFolder' implicitly has a... Remove this comment to see the full error message
|
|
364
|
-
functionsFolder,
|
|
362
|
+
functionsConfig, functionsFolder,
|
|
365
363
|
// @ts-expect-error TS(7031) FIXME: Binding element 'options' implicitly has an 'a... Remove this comment to see the full error message
|
|
366
364
|
options,
|
|
367
365
|
// @ts-expect-error TS(7031) FIXME: Binding element 'packagePath' implicitly has an 'a... Remove this comment to see the full error message
|
|
@@ -390,12 +388,11 @@ title, }) => {
|
|
|
390
388
|
const draft = !deployToProduction && !alias;
|
|
391
389
|
results = await api.createSiteDeploy({ siteId, title, body: { draft, branch: alias } });
|
|
392
390
|
deployId = results.id;
|
|
393
|
-
|
|
394
|
-
const internalFunctionsFolder = await getInternalFunctionsDir({ base: site.root, packagePath });
|
|
391
|
+
const internalFunctionsFolder = await getInternalFunctionsDir({ base: site.root, packagePath, ensureExists: true });
|
|
395
392
|
// The order of the directories matter: zip-it-and-ship-it will prioritize
|
|
396
393
|
// functions from the rightmost directories. In this case, we want user
|
|
397
394
|
// functions to take precedence over internal functions.
|
|
398
|
-
const functionDirectories = [internalFunctionsFolder, functionsFolder].filter(Boolean);
|
|
395
|
+
const functionDirectories = [internalFunctionsFolder, functionsFolder].filter((folder) => Boolean(folder));
|
|
399
396
|
const manifestPath = skipFunctionsCache ? null : await getFunctionsManifestPath({ base: site.root, packagePath });
|
|
400
397
|
const redirectsPath = `${deployFolder}/_redirects`;
|
|
401
398
|
const headersPath = `${deployFolder}/_headers`;
|
|
@@ -414,11 +411,10 @@ title, }) => {
|
|
|
414
411
|
config.headers = headers;
|
|
415
412
|
uploadDeployBlobs({ deployId, siteId, silent, options, cachedConfig: command.netlify.cachedConfig });
|
|
416
413
|
results = await deploySite(api, siteId, deployFolder, {
|
|
414
|
+
// @ts-expect-error FIXME
|
|
417
415
|
config,
|
|
418
|
-
// @ts-expect-error TS(2322) FIXME: Type 'any[]' is not assignable to type 'never[]'.
|
|
419
416
|
fnDir: functionDirectories,
|
|
420
417
|
functionsConfig,
|
|
421
|
-
// @ts-expect-error TS(2322) FIXME: Type '(event: any) => void' is not assignable to t... Remove this comment to see the full error message
|
|
422
418
|
statusCb: silent ? () => { } : deployProgressCb(),
|
|
423
419
|
deployTimeout,
|
|
424
420
|
syncFileLimit: SYNC_FILE_LIMIT,
|
|
@@ -640,6 +636,7 @@ workingDir, }) => {
|
|
|
640
636
|
siteEnv,
|
|
641
637
|
});
|
|
642
638
|
const results = await runDeploy({
|
|
639
|
+
// @ts-expect-error FIXME
|
|
643
640
|
alias,
|
|
644
641
|
api,
|
|
645
642
|
command,
|
package/src/commands/dev/dev.js
CHANGED
|
@@ -65,7 +65,6 @@ export const dev = async (options, command) => {
|
|
|
65
65
|
const { api, cachedConfig, config, repositoryRoot, site, siteInfo, state } = command.netlify;
|
|
66
66
|
config.dev = { ...config.dev };
|
|
67
67
|
config.build = { ...config.build };
|
|
68
|
-
/** @type {import('./types.js').DevConfig} */
|
|
69
68
|
const devConfig = {
|
|
70
69
|
framework: '#auto',
|
|
71
70
|
autoLaunch: Boolean(options.open),
|
|
@@ -18,7 +18,6 @@ import { fileExistsAsync } from '../../lib/fs.js';
|
|
|
18
18
|
import { getAddons, getCurrentAddon, getSiteData } from '../../utils/addons/prepare.js';
|
|
19
19
|
import { NETLIFYDEVERR, NETLIFYDEVLOG, NETLIFYDEVWARN, chalk, error, log } from '../../utils/command-helpers.js';
|
|
20
20
|
import { getDotEnvVariables, injectEnvVariables } from '../../utils/dev.js';
|
|
21
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
|
|
22
21
|
import execa from '../../utils/execa.js';
|
|
23
22
|
import { readRepoURL, validateRepoURL } from '../../utils/read-repo-url.js';
|
|
24
23
|
const copyTemplateDir = promisify(copyTemplateDirOriginal);
|
|
@@ -364,7 +363,6 @@ const installDeps = async ({ functionPackageJson, functionPath, functionsDir })
|
|
|
364
363
|
// of keeping that file in the function directory and running `npm install`
|
|
365
364
|
// from there.
|
|
366
365
|
if (!sitePackageJson) {
|
|
367
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
368
366
|
await execa('npm', ['i', ...npmInstallFlags], { cwd: functionPath });
|
|
369
367
|
return;
|
|
370
368
|
}
|
|
@@ -373,11 +371,9 @@ const installDeps = async ({ functionPackageJson, functionPath, functionsDir })
|
|
|
373
371
|
const devDependencies = getNpmInstallPackages(siteDevDependencies, functionDevDependencies);
|
|
374
372
|
const npmInstallPath = path.dirname(sitePackageJson);
|
|
375
373
|
if (dependencies.length !== 0) {
|
|
376
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
377
374
|
await execa('npm', ['i', ...dependencies, '--save', ...npmInstallFlags], { cwd: npmInstallPath });
|
|
378
375
|
}
|
|
379
376
|
if (devDependencies.length !== 0) {
|
|
380
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
381
377
|
await execa('npm', ['i', ...devDependencies, '--save-dev', ...npmInstallFlags], { cwd: npmInstallPath });
|
|
382
378
|
}
|
|
383
379
|
// We installed the function's dependencies in the site-level `package.json`,
|
|
@@ -193,7 +193,6 @@ or run ${chalk.cyanBright('netlify sites:create')} to create a site.`);
|
|
|
193
193
|
catch (error_) {
|
|
194
194
|
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
195
195
|
if (error_.status === 404) {
|
|
196
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
197
196
|
error(new Error(`Site ID '${siteId}' not found`));
|
|
198
197
|
}
|
|
199
198
|
else {
|
|
@@ -207,7 +206,6 @@ or run ${chalk.cyanBright('netlify sites:create')} to create a site.`);
|
|
|
207
206
|
return;
|
|
208
207
|
}
|
|
209
208
|
if (!site) {
|
|
210
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
211
209
|
error(new Error(`No site found`));
|
|
212
210
|
}
|
|
213
211
|
// Save site ID to config
|
|
@@ -253,7 +251,6 @@ export const link = async (options, command) => {
|
|
|
253
251
|
catch (error_) {
|
|
254
252
|
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
255
253
|
if (error_.status === 404) {
|
|
256
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
257
254
|
error(new Error(`Site id ${options.id} not found`));
|
|
258
255
|
}
|
|
259
256
|
else {
|
|
@@ -284,7 +281,6 @@ export const link = async (options, command) => {
|
|
|
284
281
|
catch (error_) {
|
|
285
282
|
// @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
|
|
286
283
|
if (error_.status === 404) {
|
|
287
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
288
284
|
error(new Error(`${options.name} not found`));
|
|
289
285
|
}
|
|
290
286
|
else {
|
|
@@ -293,7 +289,6 @@ export const link = async (options, command) => {
|
|
|
293
289
|
}
|
|
294
290
|
}
|
|
295
291
|
if (results.length === 0) {
|
|
296
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type 'Error' is not assignable to para... Remove this comment to see the full error message
|
|
297
292
|
error(new Error(`No sites found named ${options.name}`));
|
|
298
293
|
}
|
|
299
294
|
const [firstSiteData] = results;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Listr } from 'listr2';
|
|
2
2
|
import { error } from '../../utils/command-helpers.js';
|
|
3
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
|
|
4
3
|
import execa from '../../utils/execa.js';
|
|
5
4
|
import { installPlatform } from '../../utils/lm/install.js';
|
|
6
5
|
import { checkHelperVersion } from '../../utils/lm/requirements.js';
|
|
@@ -45,7 +44,6 @@ const provisionService = async function (siteId, api) {
|
|
|
45
44
|
const configureLFSURL = async function (siteId, api) {
|
|
46
45
|
const siteInfo = await api.getSite({ siteId });
|
|
47
46
|
const url = `https://${siteInfo.id_domain}/.netlify/large-media`;
|
|
48
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
49
47
|
return execa('git', ['config', '-f', '.lfsconfig', 'lfs.url', url]);
|
|
50
48
|
};
|
|
51
49
|
export const lmSetup = async (options, command) => {
|
package/src/commands/main.js
CHANGED
|
@@ -5,7 +5,6 @@ import envinfo from 'envinfo';
|
|
|
5
5
|
import { closest } from 'fastest-levenshtein';
|
|
6
6
|
import inquirer from 'inquirer';
|
|
7
7
|
import { BANG, chalk, error, exit, log, NETLIFY_CYAN, USER_AGENT, warn } from '../utils/command-helpers.js';
|
|
8
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
|
|
9
8
|
import execa from '../utils/execa.js';
|
|
10
9
|
import getGlobalConfig from '../utils/get-global-config.js';
|
|
11
10
|
import getPackageJson from '../utils/get-package-json.js';
|
|
@@ -138,7 +137,6 @@ const mainCommand = async function (options, command) {
|
|
|
138
137
|
if (!applySuggestion) {
|
|
139
138
|
error(`Run ${NETLIFY_CYAN(`${command.name()} help`)} for a list of available commands.`);
|
|
140
139
|
}
|
|
141
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
142
140
|
await execa(process.argv[0], [process.argv[1], suggestion], { stdio: 'inherit' });
|
|
143
141
|
};
|
|
144
142
|
/**
|
|
@@ -16,7 +16,6 @@ export const serve = async (options, command) => {
|
|
|
16
16
|
const { api, cachedConfig, config, repositoryRoot, site, siteInfo, state } = command.netlify;
|
|
17
17
|
config.dev = { ...config.dev };
|
|
18
18
|
config.build = { ...config.build };
|
|
19
|
-
/** @type {import('../dev/types').DevConfig} */
|
|
20
19
|
const devConfig = {
|
|
21
20
|
...(config.functionsDirectory && { functions: config.functionsDirectory }),
|
|
22
21
|
...(config.build.publish && { publish: config.build.publish }),
|
|
@@ -41,6 +40,9 @@ export const serve = async (options, command) => {
|
|
|
41
40
|
site,
|
|
42
41
|
siteInfo,
|
|
43
42
|
});
|
|
43
|
+
if (!site.root) {
|
|
44
|
+
throw new Error('Site root not found');
|
|
45
|
+
}
|
|
44
46
|
// Ensure the internal functions directory exists so that the functions
|
|
45
47
|
// server and registry are initialized, and any functions created by
|
|
46
48
|
// Netlify Build are loaded.
|
|
@@ -4,7 +4,6 @@ import pick from 'lodash/pick.js';
|
|
|
4
4
|
import parseGitHubUrl from 'parse-github-url';
|
|
5
5
|
import { render } from 'prettyjson';
|
|
6
6
|
import { chalk, error, getTerminalLink, log, logJson, warn } from '../../utils/command-helpers.js';
|
|
7
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
|
|
8
7
|
import execa from '../../utils/execa.js';
|
|
9
8
|
import getRepoData from '../../utils/get-repo-data.js';
|
|
10
9
|
import { getGitHubToken } from '../../utils/init/config-github.js';
|
|
@@ -166,9 +165,7 @@ export const sitesCreateTemplate = async (repository, options, command) => {
|
|
|
166
165
|
});
|
|
167
166
|
if (cloneConfirm) {
|
|
168
167
|
log();
|
|
169
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
170
168
|
await execa('git', ['clone', repoResp.clone_url, `${repoResp.name}`]);
|
|
171
|
-
// @ts-expect-error TS(2532) FIXME: Object is possibly 'undefined'.
|
|
172
169
|
log(`🚀 Repository cloned successfully. You can find it under the ${chalk.magenta(repoResp.name)} folder`);
|
|
173
170
|
}
|
|
174
171
|
if (options.withCi) {
|
package/src/lib/blobs/blobs.js
CHANGED
|
@@ -12,7 +12,7 @@ const printLocalBlobsNotice = () => {
|
|
|
12
12
|
log(`${NETLIFYDEVLOG} Netlify Blobs running in sandbox mode for local development. Refer to https://ntl.fyi/local-blobs for more information.`);
|
|
13
13
|
};
|
|
14
14
|
const startBlobsServer = async (debug, projectRoot, token) => {
|
|
15
|
-
const directory = path.resolve(projectRoot, getPathInProject(['blobs-
|
|
15
|
+
const directory = path.resolve(projectRoot, getPathInProject(['blobs-serve']));
|
|
16
16
|
const server = new BlobsServer({
|
|
17
17
|
debug,
|
|
18
18
|
directory,
|
|
@@ -10,7 +10,6 @@ import { startSpinner, stopSpinner } from '../spinner.js';
|
|
|
10
10
|
import { getBootstrapURL } from './bootstrap.js';
|
|
11
11
|
import { DIST_IMPORT_MAP_PATH, EDGE_FUNCTIONS_SERVE_FOLDER } from './consts.js';
|
|
12
12
|
import { headers, getFeatureFlagsHeader, getInvocationMetadataHeader } from './headers.js';
|
|
13
|
-
import { getInternalFunctions } from './internal.js';
|
|
14
13
|
import { EdgeFunctionsRegistry } from './registry.js';
|
|
15
14
|
const headersSymbol = Symbol('Edge Functions Headers');
|
|
16
15
|
const LOCAL_HOST = '127.0.0.1';
|
|
@@ -111,9 +110,6 @@ settings,
|
|
|
111
110
|
siteInfo,
|
|
112
111
|
// @ts-expect-error TS(7031) FIXME: Binding element 'state' implicitly has an 'any' ty... Remove this comment to see the full error message
|
|
113
112
|
state, }) => {
|
|
114
|
-
const { functions: internalFunctions,
|
|
115
|
-
// @ts-expect-error TS(2339) FIXME: Property 'importMap' does not exist on type '{ fun... Remove this comment to see the full error message
|
|
116
|
-
importMap, path: internalFunctionsPath, } = await getInternalFunctions(projectDir);
|
|
117
113
|
const userFunctionsPath = config.build.edge_functions;
|
|
118
114
|
const isolatePort = await getAvailablePort();
|
|
119
115
|
const buildFeatureFlags = {
|
|
@@ -132,18 +128,13 @@ state, }) => {
|
|
|
132
128
|
env: configEnv,
|
|
133
129
|
featureFlags: buildFeatureFlags,
|
|
134
130
|
getUpdatedConfig,
|
|
135
|
-
importMaps: [importMap].filter(Boolean),
|
|
136
131
|
inspectSettings,
|
|
137
|
-
internalDirectory: internalFunctionsPath,
|
|
138
|
-
internalFunctions,
|
|
139
132
|
port: isolatePort,
|
|
140
133
|
projectDir,
|
|
141
134
|
repositoryRoot,
|
|
142
135
|
});
|
|
143
|
-
const hasEdgeFunctions = userFunctionsPath !== undefined || internalFunctionsPath;
|
|
144
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'req' implicitly has an 'any' type.
|
|
145
136
|
return async (req) => {
|
|
146
|
-
if (req.headers[headers.Passthrough] !== undefined
|
|
137
|
+
if (req.headers[headers.Passthrough] !== undefined) {
|
|
147
138
|
return;
|
|
148
139
|
}
|
|
149
140
|
const [geoLocation, registry] = await Promise.all([
|
|
@@ -199,22 +190,14 @@ env: configEnv,
|
|
|
199
190
|
featureFlags,
|
|
200
191
|
// @ts-expect-error TS(7031) FIXME: Binding element 'getUpdatedConfig' implicitly has ... Remove this comment to see the full error message
|
|
201
192
|
getUpdatedConfig,
|
|
202
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'importMaps' implicitly has an 'an... Remove this comment to see the full error message
|
|
203
|
-
importMaps,
|
|
204
193
|
// @ts-expect-error TS(7031) FIXME: Binding element 'inspectSettings' implicitly has a... Remove this comment to see the full error message
|
|
205
194
|
inspectSettings,
|
|
206
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'internalDirectory' implicitly has... Remove this comment to see the full error message
|
|
207
|
-
internalDirectory,
|
|
208
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'internalFunctions' implicitly has... Remove this comment to see the full error message
|
|
209
|
-
internalFunctions,
|
|
210
195
|
// @ts-expect-error TS(7031) FIXME: Binding element 'port' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
211
196
|
port,
|
|
212
197
|
// @ts-expect-error TS(7031) FIXME: Binding element 'projectDir' implicitly has an 'an... Remove this comment to see the full error message
|
|
213
198
|
projectDir,
|
|
214
199
|
// @ts-expect-error TS(7031) FIXME: Binding element 'repositoryRoot' implicitly has an... Remove this comment to see the full error message
|
|
215
200
|
repositoryRoot, }) => {
|
|
216
|
-
// Merging internal with user-defined import maps.
|
|
217
|
-
const importMapPaths = [...importMaps, config.functions['*'].deno_import_map];
|
|
218
201
|
try {
|
|
219
202
|
const distImportMapPath = getPathInProject([DIST_IMPORT_MAP_PATH]);
|
|
220
203
|
const servePath = resolve(projectDir, getPathInProject([EDGE_FUNCTIONS_SERVE_FOLDER]));
|
|
@@ -228,7 +211,6 @@ repositoryRoot, }) => {
|
|
|
228
211
|
featureFlags,
|
|
229
212
|
formatExportTypeError: (name) => `${NETLIFYDEVERR} ${chalk.red('Failed')} to load Edge Function ${chalk.yellow(name)}. The file does not seem to have a function as the default export.`,
|
|
230
213
|
formatImportError: (name) => `${NETLIFYDEVERR} ${chalk.red('Failed')} to run Edge Function ${chalk.yellow(name)}:`,
|
|
231
|
-
importMapPaths,
|
|
232
214
|
inspectSettings,
|
|
233
215
|
port,
|
|
234
216
|
rootPath: repositoryRoot,
|
|
@@ -242,8 +224,7 @@ repositoryRoot, }) => {
|
|
|
242
224
|
directories: [directory].filter(Boolean),
|
|
243
225
|
env: configEnv,
|
|
244
226
|
getUpdatedConfig,
|
|
245
|
-
|
|
246
|
-
internalFunctions,
|
|
227
|
+
importMapFromTOML: config.functions['*'].deno_import_map,
|
|
247
228
|
projectDir,
|
|
248
229
|
runIsolate,
|
|
249
230
|
servePath,
|