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
|
@@ -42,7 +42,6 @@ skipFunctionsCache, statusCb = () => {
|
|
|
42
42
|
}, syncFileLimit = DEFAULT_SYNC_LIMIT, tmpDir = temporaryDirectory(),
|
|
43
43
|
// @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
|
|
44
44
|
workingDir, } = {}) => {
|
|
45
|
-
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
46
45
|
statusCb({
|
|
47
46
|
type: 'hashing',
|
|
48
47
|
msg: `Hashing files...`,
|
|
@@ -85,7 +84,6 @@ workingDir, } = {}) => {
|
|
|
85
84
|
functionsCount > 0 && `${functionsCount} functions`,
|
|
86
85
|
edgeFunctionsCount > 0 && 'edge functions',
|
|
87
86
|
]);
|
|
88
|
-
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
89
87
|
statusCb({
|
|
90
88
|
type: 'hashing',
|
|
91
89
|
msg: `Finished hashing ${stats}`,
|
|
@@ -108,7 +106,6 @@ instead of manual deployment.
|
|
|
108
106
|
|
|
109
107
|
For more information, visit https://ntl.fyi/cli-native-modules.`);
|
|
110
108
|
}
|
|
111
|
-
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
112
109
|
statusCb({
|
|
113
110
|
type: 'create-deploy',
|
|
114
111
|
msg: 'CDN diffing files...',
|
|
@@ -132,7 +129,6 @@ For more information, visit https://ntl.fyi/cli-native-modules.`);
|
|
|
132
129
|
if (deployParams.body.async)
|
|
133
130
|
deploy = await waitForDiff(api, deploy.id, siteId, deployTimeout);
|
|
134
131
|
const { required: requiredFiles, required_functions: requiredFns } = deploy;
|
|
135
|
-
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
136
132
|
statusCb({
|
|
137
133
|
type: 'create-deploy',
|
|
138
134
|
msg: `CDN requesting ${requiredFiles.length} files${Array.isArray(requiredFns) ? ` and ${requiredFns.length} functions` : ''}`,
|
|
@@ -142,14 +138,12 @@ For more information, visit https://ntl.fyi/cli-native-modules.`);
|
|
|
142
138
|
const functionsUploadList = getUploadList(requiredFns, fnShaMap);
|
|
143
139
|
const uploadList = [...filesUploadList, ...functionsUploadList];
|
|
144
140
|
await uploadFiles(api, deployId, uploadList, { concurrentUpload, statusCb, maxRetry });
|
|
145
|
-
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
146
141
|
statusCb({
|
|
147
142
|
type: 'wait-for-deploy',
|
|
148
143
|
msg: 'Waiting for deploy to go live...',
|
|
149
144
|
phase: 'start',
|
|
150
145
|
});
|
|
151
146
|
deploy = await waitForDeploy(api, deployId, siteId, deployTimeout);
|
|
152
|
-
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
153
147
|
statusCb({
|
|
154
148
|
type: 'wait-for-deploy',
|
|
155
149
|
msg: draft ? 'Draft deploy is live!' : 'Deploy is live!',
|
|
@@ -6,21 +6,9 @@ import getPort from 'get-port';
|
|
|
6
6
|
import { detectFrameworkSettings } from './build-info.js';
|
|
7
7
|
import { NETLIFYDEVWARN, chalk, log } from './command-helpers.js';
|
|
8
8
|
import { acquirePort } from './dev.js';
|
|
9
|
-
import { getInternalFunctionsDir } from './functions/functions.js';
|
|
10
9
|
import { getPluginsToAutoInstall } from './init/utils.js';
|
|
11
|
-
/** @param {string} str */
|
|
12
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'str' implicitly has an 'any' type.
|
|
13
10
|
const formatProperty = (str) => chalk.magenta(`'${str}'`);
|
|
14
|
-
/** @param {string} str */
|
|
15
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'str' implicitly has an 'any' type.
|
|
16
11
|
const formatValue = (str) => chalk.green(`'${str}'`);
|
|
17
|
-
/**
|
|
18
|
-
* @param {object} options
|
|
19
|
-
* @param {string} options.keyFile
|
|
20
|
-
* @param {string} options.certFile
|
|
21
|
-
* @returns {Promise<{ key: string, cert: string, keyFilePath: string, certFilePath: string }>}
|
|
22
|
-
*/
|
|
23
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
|
|
24
12
|
const readHttpsSettings = async (options) => {
|
|
25
13
|
if (typeof options !== 'object' || !options.keyFile || !options.certFile) {
|
|
26
14
|
throw new TypeError(`https options should be an object with ${formatProperty('keyFile')} and ${formatProperty('certFile')} string properties`);
|
|
@@ -43,23 +31,13 @@ const readHttpsSettings = async (options) => {
|
|
|
43
31
|
};
|
|
44
32
|
/**
|
|
45
33
|
* Validates a property inside the devConfig to be of a given type
|
|
46
|
-
* @param {import('../commands/dev/types.js').DevConfig} devConfig The devConfig
|
|
47
|
-
* @param {keyof import('../commands/dev/types.js').DevConfig} property The property to validate
|
|
48
|
-
* @param {'string' | 'number'} type The type it should have
|
|
49
34
|
*/
|
|
50
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'devConfig' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
51
35
|
function validateProperty(devConfig, property, type) {
|
|
52
36
|
if (devConfig[property] && typeof devConfig[property] !== type) {
|
|
53
37
|
const formattedProperty = formatProperty(property);
|
|
54
38
|
throw new TypeError(`Invalid ${formattedProperty} option provided in config. The value of ${formattedProperty} option must be of type ${type}`);
|
|
55
39
|
}
|
|
56
40
|
}
|
|
57
|
-
/**
|
|
58
|
-
*
|
|
59
|
-
* @param {object} config
|
|
60
|
-
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
|
|
61
|
-
*/
|
|
62
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'devConfig' implicitly has an 'any... Remove this comment to see the full error message
|
|
63
41
|
const validateFrameworkConfig = ({ devConfig }) => {
|
|
64
42
|
validateProperty(devConfig, 'command', 'string');
|
|
65
43
|
validateProperty(devConfig, 'port', 'number');
|
|
@@ -68,12 +46,6 @@ const validateFrameworkConfig = ({ devConfig }) => {
|
|
|
68
46
|
throw new Error(`${formatProperty('port')} and ${formatProperty('targetPort')} options cannot have same values. Please consult the documentation for more details: https://ntl.fyi/ports-and-netlify-dev`);
|
|
69
47
|
}
|
|
70
48
|
};
|
|
71
|
-
/**
|
|
72
|
-
* @param {object} config
|
|
73
|
-
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
|
|
74
|
-
* @param {number=} config.detectedPort
|
|
75
|
-
*/
|
|
76
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'detectedPort' implicitly has an '... Remove this comment to see the full error message
|
|
77
49
|
const validateConfiguredPort = ({ detectedPort, devConfig }) => {
|
|
78
50
|
if (devConfig.port && devConfig.port === detectedPort) {
|
|
79
51
|
const formattedPort = formatProperty('port');
|
|
@@ -84,21 +56,13 @@ const DEFAULT_PORT = 8888;
|
|
|
84
56
|
const DEFAULT_STATIC_PORT = 3999;
|
|
85
57
|
/**
|
|
86
58
|
* Logs a message that it was unable to determine the dist directory and falls back to the workingDir
|
|
87
|
-
* @param {string} workingDir
|
|
88
59
|
*/
|
|
89
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'workingDir' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
90
60
|
const getDefaultDist = (workingDir) => {
|
|
91
61
|
log(`${NETLIFYDEVWARN} Unable to determine public folder to serve files from. Using current working directory`);
|
|
92
62
|
log(`${NETLIFYDEVWARN} Setup a netlify.toml file with a [dev] section to specify your dev server settings.`);
|
|
93
63
|
log(`${NETLIFYDEVWARN} See docs at: https://cli.netlify.com/netlify-dev#project-detection`);
|
|
94
64
|
return workingDir;
|
|
95
65
|
};
|
|
96
|
-
/**
|
|
97
|
-
* @param {object} config
|
|
98
|
-
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
|
|
99
|
-
* @returns {Promise<number>}
|
|
100
|
-
*/
|
|
101
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'devConfig' implicitly has an 'any... Remove this comment to see the full error message
|
|
102
66
|
const getStaticServerPort = async ({ devConfig }) => {
|
|
103
67
|
const port = await acquirePort({
|
|
104
68
|
configuredPort: devConfig.staticServerPort,
|
|
@@ -107,16 +71,7 @@ const getStaticServerPort = async ({ devConfig }) => {
|
|
|
107
71
|
});
|
|
108
72
|
return port;
|
|
109
73
|
};
|
|
110
|
-
|
|
111
|
-
*
|
|
112
|
-
* @param {object} config
|
|
113
|
-
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
|
|
114
|
-
* @param {import('commander').OptionValues} config.flags
|
|
115
|
-
* @param {string} config.workingDir
|
|
116
|
-
* @returns {Promise<Omit<import('./types.js').BaseServerSettings, 'command'> & {command?: string}>}
|
|
117
|
-
*/
|
|
118
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'devConfig' implicitly has an 'any... Remove this comment to see the full error message
|
|
119
|
-
const handleStaticServer = async ({ devConfig, flags, workingDir }) => {
|
|
74
|
+
const handleStaticServer = async ({ devConfig, flags, workingDir, }) => {
|
|
120
75
|
validateProperty(devConfig, 'staticServerPort', 'number');
|
|
121
76
|
if (flags.dir) {
|
|
122
77
|
log(`${NETLIFYDEVWARN} Using simple static server because ${formatProperty('--dir')} flag was specified`);
|
|
@@ -139,11 +94,8 @@ const handleStaticServer = async ({ devConfig, flags, workingDir }) => {
|
|
|
139
94
|
};
|
|
140
95
|
/**
|
|
141
96
|
* Retrieves the settings from a framework
|
|
142
|
-
* @param {import('@netlify/build-info').Settings} [settings]
|
|
143
|
-
* @returns {import('./types.js').BaseServerSettings | undefined}
|
|
144
97
|
*/
|
|
145
|
-
|
|
146
|
-
const getSettingsFromDetectedSettings = (settings) => {
|
|
98
|
+
const getSettingsFromDetectedSettings = (command, settings) => {
|
|
147
99
|
if (!settings) {
|
|
148
100
|
return;
|
|
149
101
|
}
|
|
@@ -155,23 +107,15 @@ const getSettingsFromDetectedSettings = (settings) => {
|
|
|
155
107
|
framework: settings.framework.name,
|
|
156
108
|
env: settings.env,
|
|
157
109
|
pollingStrategies: settings.pollingStrategies,
|
|
158
|
-
plugins: getPluginsToAutoInstall(settings.plugins_from_config_file, settings.plugins_recommended),
|
|
110
|
+
plugins: getPluginsToAutoInstall(command, settings.plugins_from_config_file, settings.plugins_recommended),
|
|
111
|
+
clearPublishDirectory: settings.clearPublishDirectory,
|
|
159
112
|
};
|
|
160
113
|
};
|
|
161
|
-
/**
|
|
162
|
-
* @param {import('../commands/dev/types.js').DevConfig} devConfig
|
|
163
|
-
*/
|
|
164
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'devConfig' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
165
114
|
const hasCommandAndTargetPort = (devConfig) => devConfig.command && devConfig.targetPort;
|
|
166
115
|
/**
|
|
167
116
|
* Creates settings for the custom framework
|
|
168
|
-
* @param {object} config
|
|
169
|
-
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
|
|
170
|
-
* @param {string} config.workingDir
|
|
171
|
-
* @returns {import('./types.js').BaseServerSettings}
|
|
172
117
|
*/
|
|
173
|
-
|
|
174
|
-
const handleCustomFramework = ({ devConfig, workingDir }) => {
|
|
118
|
+
const handleCustomFramework = ({ devConfig, workingDir, }) => {
|
|
175
119
|
if (!hasCommandAndTargetPort(devConfig)) {
|
|
176
120
|
throw new Error(`${formatProperty('command')} and ${formatProperty('targetPort')} properties are required when ${formatProperty('framework')} is set to ${formatValue('#custom')}`);
|
|
177
121
|
}
|
|
@@ -185,60 +129,36 @@ const handleCustomFramework = ({ devConfig, workingDir }) => {
|
|
|
185
129
|
};
|
|
186
130
|
/**
|
|
187
131
|
* Merges the framework settings with the devConfig
|
|
188
|
-
* @param {object} config
|
|
189
|
-
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
|
|
190
|
-
* @param {string} config.workingDir
|
|
191
|
-
* @param {Partial<import('./types.js').BaseServerSettings>=} config.frameworkSettings
|
|
192
132
|
*/
|
|
193
|
-
|
|
194
|
-
const mergeSettings = async ({ devConfig, frameworkSettings = {}, workingDir }) => {
|
|
195
|
-
// @ts-expect-error TS(2339) FIXME: Property 'command' does not exist on type '{}'.
|
|
133
|
+
const mergeSettings = async ({ devConfig, frameworkSettings = {}, workingDir, }) => {
|
|
196
134
|
const command = devConfig.command || frameworkSettings.command;
|
|
197
|
-
// @ts-expect-error TS(2339) FIXME: Property 'frameworkPort' does not exist on type '{... Remove this comment to see the full error message
|
|
198
135
|
const frameworkPort = devConfig.targetPort || frameworkSettings.frameworkPort;
|
|
199
|
-
// if the framework doesn't start a server, we use a static one
|
|
200
136
|
const useStaticServer = !(command && frameworkPort);
|
|
201
137
|
return {
|
|
202
|
-
// @ts-expect-error TS(2339) FIXME: Property 'baseDirectory' does not exist on type '{... Remove this comment to see the full error message
|
|
203
138
|
baseDirectory: devConfig.base || frameworkSettings.baseDirectory,
|
|
204
139
|
command,
|
|
205
140
|
frameworkPort: useStaticServer ? await getStaticServerPort({ devConfig }) : frameworkPort,
|
|
206
|
-
// @ts-expect-error TS(2339) FIXME: Property 'dist' does not exist on type '{}'.
|
|
207
141
|
dist: devConfig.publish || frameworkSettings.dist || getDefaultDist(workingDir),
|
|
208
|
-
// @ts-expect-error TS(2339) FIXME: Property 'framework' does not exist on type '{}'.
|
|
209
142
|
framework: frameworkSettings.framework,
|
|
210
|
-
// @ts-expect-error TS(2339) FIXME: Property 'env' does not exist on type '{}'.
|
|
211
143
|
env: frameworkSettings.env,
|
|
212
|
-
// @ts-expect-error TS(2339) FIXME: Property 'pollingStrategies' does not exist on typ... Remove this comment to see the full error message
|
|
213
144
|
pollingStrategies: frameworkSettings.pollingStrategies || [],
|
|
214
145
|
useStaticServer,
|
|
146
|
+
clearPublishDirectory: frameworkSettings.clearPublishDirectory,
|
|
215
147
|
};
|
|
216
148
|
};
|
|
217
149
|
/**
|
|
218
150
|
* Handles a forced framework and retrieves the settings for it
|
|
219
|
-
* @param {object} config
|
|
220
|
-
* @param {import('../commands/dev/types.js').DevConfig} config.devConfig
|
|
221
|
-
* @param {import('@netlify/build-info').Project} config.project
|
|
222
|
-
* @param {string} config.workingDir
|
|
223
|
-
* @param {string=} config.workspacePackage
|
|
224
|
-
* @returns {Promise<import('./types.js').BaseServerSettings>}
|
|
225
151
|
*/
|
|
226
|
-
|
|
227
|
-
const handleForcedFramework = async ({ devConfig, project, workingDir, workspacePackage }) => {
|
|
152
|
+
const handleForcedFramework = async (options) => {
|
|
228
153
|
// this throws if `devConfig.framework` is not a supported framework
|
|
229
|
-
const framework = await getFramework(devConfig.framework, project);
|
|
230
|
-
const settings = await getSettings(framework, project, workspacePackage || '');
|
|
231
|
-
const frameworkSettings = getSettingsFromDetectedSettings(settings);
|
|
232
|
-
return mergeSettings({ devConfig, workingDir, frameworkSettings });
|
|
154
|
+
const framework = await getFramework(options.devConfig.framework, options.project);
|
|
155
|
+
const settings = await getSettings(framework, options.project, options.workspacePackage || '');
|
|
156
|
+
const frameworkSettings = getSettingsFromDetectedSettings(options.command, settings);
|
|
157
|
+
return mergeSettings({ devConfig: options.devConfig, workingDir: options.workingDir, frameworkSettings });
|
|
233
158
|
};
|
|
234
159
|
/**
|
|
235
160
|
* Get the server settings based on the flags and the devConfig
|
|
236
|
-
* @param {import('../commands/dev/types.js').DevConfig} devConfig
|
|
237
|
-
* @param {import('commander').OptionValues} flags
|
|
238
|
-
* @param {import('../commands/base-command.js').default} command
|
|
239
|
-
* @returns {Promise<import('./types.js').ServerSettings>}
|
|
240
161
|
*/
|
|
241
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'devConfig' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
242
162
|
const detectServerSettings = async (devConfig, flags, command) => {
|
|
243
163
|
validateProperty(devConfig, 'framework', 'string');
|
|
244
164
|
/** @type {Partial<import('./types.js').BaseServerSettings>} */
|
|
@@ -251,7 +171,7 @@ const detectServerSettings = async (devConfig, flags, command) => {
|
|
|
251
171
|
// this is the default CLI behavior
|
|
252
172
|
const runDetection = !hasCommandAndTargetPort(devConfig);
|
|
253
173
|
const frameworkSettings = runDetection
|
|
254
|
-
? getSettingsFromDetectedSettings(await detectFrameworkSettings(command, 'dev'))
|
|
174
|
+
? getSettingsFromDetectedSettings(command, await detectFrameworkSettings(command, 'dev'))
|
|
255
175
|
: undefined;
|
|
256
176
|
if (frameworkSettings === undefined && runDetection) {
|
|
257
177
|
log(`${NETLIFYDEVWARN} No app server detected. Using simple static server`);
|
|
@@ -273,6 +193,7 @@ const detectServerSettings = async (devConfig, flags, command) => {
|
|
|
273
193
|
validateFrameworkConfig({ devConfig });
|
|
274
194
|
// this is when the user explicitly configures a framework, e.g. `framework = "gatsby"`
|
|
275
195
|
settings = await handleForcedFramework({
|
|
196
|
+
command,
|
|
276
197
|
devConfig,
|
|
277
198
|
project: command.project,
|
|
278
199
|
workingDir: command.workingDir,
|
|
@@ -288,25 +209,19 @@ const detectServerSettings = async (devConfig, flags, command) => {
|
|
|
288
209
|
});
|
|
289
210
|
// @ts-expect-error TS(2339) FIXME: Property 'functions' does not exist on type '{}'.
|
|
290
211
|
const functionsDir = devConfig.functions || settings.functions;
|
|
291
|
-
// @ts-expect-error TS(2345) FIXME: Argument of type '{ base: any; }' is not assignabl... Remove this comment to see the full error message
|
|
292
|
-
const internalFunctionsDir = await getInternalFunctionsDir({ base: command.workingDir });
|
|
293
|
-
const shouldStartFunctionsServer = Boolean(functionsDir || internalFunctionsDir);
|
|
294
212
|
return {
|
|
295
213
|
...settings,
|
|
296
214
|
port: acquiredPort,
|
|
297
215
|
jwtSecret: devConfig.jwtSecret || 'secret',
|
|
298
216
|
jwtRolePath: devConfig.jwtRolePath || 'app_metadata.authorization.roles',
|
|
299
217
|
functions: functionsDir,
|
|
300
|
-
|
|
218
|
+
functionsPort: await getPort({ port: devConfig.functionsPort || 0 }),
|
|
301
219
|
...(devConfig.https && { https: await readHttpsSettings(devConfig.https) }),
|
|
302
220
|
};
|
|
303
221
|
};
|
|
304
222
|
/**
|
|
305
223
|
* Returns a copy of the provided config with any plugins provided by the
|
|
306
224
|
* server settings
|
|
307
|
-
* @param {*} config
|
|
308
|
-
* @param {Partial<import('./types.js').ServerSettings>} settings
|
|
309
|
-
* @returns {*} Modified config
|
|
310
225
|
*/
|
|
311
226
|
// @ts-expect-error TS(7006) FIXME: Parameter 'config' implicitly has an 'any' type.
|
|
312
227
|
export const getConfigWithPlugins = (config, settings) => {
|
|
@@ -321,7 +236,6 @@ export const getConfigWithPlugins = (config, settings) => {
|
|
|
321
236
|
// @ts-expect-error TS(7006) FIXME: Parameter 'plugin' implicitly has an 'any' type.
|
|
322
237
|
const existingPluginNames = new Set(existingPlugins.map((plugin) => plugin.package));
|
|
323
238
|
const newPlugins = settings.plugins
|
|
324
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'pluginName' implicitly has an 'any' typ... Remove this comment to see the full error message
|
|
325
239
|
.map((pluginName) => {
|
|
326
240
|
if (existingPluginNames.has(pluginName)) {
|
|
327
241
|
return;
|
package/src/utils/execa.js
CHANGED
|
@@ -2,10 +2,7 @@ import { env } from 'process';
|
|
|
2
2
|
import execaLib from 'execa';
|
|
3
3
|
// This is a thin layer on top of `execa` that allows consumers to provide an
|
|
4
4
|
// alternative path to the module location, making it easier to mock its logic
|
|
5
|
-
// in tests (see `tests/utils/
|
|
6
|
-
/**
|
|
7
|
-
* @type {import('execa')}
|
|
8
|
-
*/
|
|
5
|
+
// in tests (see `tests/utils/moc
|
|
9
6
|
// eslint-disable-next-line import/no-mutable-exports
|
|
10
7
|
let execa;
|
|
11
8
|
if (env.NETLIFY_CLI_EXECA_PATH) {
|
|
@@ -7,14 +7,8 @@
|
|
|
7
7
|
* Instead, we return that the feature flag is enabled if it isn't
|
|
8
8
|
* specifically set to false in the response
|
|
9
9
|
* @param {*} siteInfo
|
|
10
|
-
* @param {string} flagName
|
|
11
10
|
*
|
|
12
11
|
* @returns {boolean}
|
|
13
12
|
*/
|
|
14
13
|
// @ts-expect-error TS(7006) FIXME: Parameter 'flagName' implicitly has an 'any' type.
|
|
15
|
-
export const isFeatureFlagEnabled = (flagName, siteInfo) =>
|
|
16
|
-
if (siteInfo.feature_flags && siteInfo.feature_flags[flagName] !== false) {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
return false;
|
|
20
|
-
};
|
|
14
|
+
export const isFeatureFlagEnabled = (flagName, siteInfo) => Boolean(siteInfo.feature_flags && siteInfo.feature_flags[flagName] !== false);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { rm } from 'node:fs/promises';
|
|
1
2
|
import waitPort from 'wait-port';
|
|
2
3
|
import { startSpinner, stopSpinner } from '../lib/spinner.js';
|
|
3
4
|
import { error, exit, log, NETLIFYDEVERR, NETLIFYDEVLOG } from './command-helpers.js';
|
|
@@ -5,19 +6,10 @@ import { runCommand } from './shell.js';
|
|
|
5
6
|
import { startStaticServer } from './static-server.js';
|
|
6
7
|
// 10 minutes
|
|
7
8
|
const FRAMEWORK_PORT_TIMEOUT = 6e5;
|
|
8
|
-
/**
|
|
9
|
-
* @typedef StartReturnObject
|
|
10
|
-
* @property {4 | 6 | undefined=} ipVersion The version the open port was found on
|
|
11
|
-
*/
|
|
12
9
|
/**
|
|
13
10
|
* Start a static server if the `useStaticServer` is provided or a framework specific server
|
|
14
|
-
* @param {object} config
|
|
15
|
-
* @param {import('./types.js').ServerSettings} config.settings
|
|
16
|
-
* @param {string} config.cwd
|
|
17
|
-
* @returns {Promise<StartReturnObject>}
|
|
18
11
|
*/
|
|
19
|
-
|
|
20
|
-
export const startFrameworkServer = async function ({ cwd, settings }) {
|
|
12
|
+
export const startFrameworkServer = async function ({ cwd, settings, }) {
|
|
21
13
|
if (settings.useStaticServer) {
|
|
22
14
|
if (settings.command) {
|
|
23
15
|
runCommand(settings.command, { env: settings.env, cwd });
|
|
@@ -29,10 +21,14 @@ export const startFrameworkServer = async function ({ cwd, settings }) {
|
|
|
29
21
|
const spinner = startSpinner({
|
|
30
22
|
text: `Waiting for framework port ${settings.frameworkPort}. This can be configured using the 'targetPort' property in the netlify.toml`,
|
|
31
23
|
});
|
|
24
|
+
if (settings.clearPublishDirectory && settings.dist) {
|
|
25
|
+
await rm(settings.dist, { recursive: true, force: true });
|
|
26
|
+
}
|
|
32
27
|
runCommand(settings.command, { env: settings.env, spinner, cwd });
|
|
33
28
|
let port;
|
|
34
29
|
try {
|
|
35
30
|
port = await waitPort({
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
36
32
|
port: settings.frameworkPort,
|
|
37
33
|
host: 'localhost',
|
|
38
34
|
output: 'silent',
|
|
@@ -33,18 +33,11 @@ export const getFunctionsServePath = ({ base, packagePath = '' }) => {
|
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
35
|
* Retrieves the internal functions directory and creates it if ensureExists is provided
|
|
36
|
-
* @param {object} config
|
|
37
|
-
* @param {string} config.base
|
|
38
|
-
* @param {boolean=} config.ensureExists
|
|
39
|
-
* @param {string} config.packagePath
|
|
40
|
-
* @returns
|
|
41
36
|
*/
|
|
42
|
-
|
|
43
|
-
export const getInternalFunctionsDir = async ({ base, ensureExists, packagePath = '' }) => {
|
|
37
|
+
export const getInternalFunctionsDir = async ({ base, ensureExists, packagePath = '', }) => {
|
|
44
38
|
const path = resolve(base, packagePath, getPathInProject([INTERNAL_FUNCTIONS_FOLDER]));
|
|
45
39
|
if (ensureExists) {
|
|
46
40
|
await fs.mkdir(path, { recursive: true });
|
|
47
41
|
}
|
|
48
|
-
|
|
49
|
-
return isDirectory ? path : null;
|
|
42
|
+
return path;
|
|
50
43
|
};
|
package/src/utils/init/utils.js
CHANGED
|
@@ -7,35 +7,32 @@ import { normalizeBackslash } from '../../lib/path.js';
|
|
|
7
7
|
import { detectBuildSettings } from '../build-info.js';
|
|
8
8
|
import { chalk, error as failAndExit, log, warn } from '../command-helpers.js';
|
|
9
9
|
import { getRecommendPlugins, getUIPlugins } from './plugins.js';
|
|
10
|
-
|
|
11
|
-
// expected to be "automatically" installed. Even though
|
|
12
|
-
// they can be installed on package/toml, we always
|
|
13
|
-
// want them installed in the site settings. When installed
|
|
14
|
-
// there our build will automatically install the latest without
|
|
15
|
-
// user management of the versioning.
|
|
16
|
-
const pluginsToAlwaysInstall = new Set(['@netlify/plugin-nextjs']);
|
|
10
|
+
const formatTitle = (title) => chalk.cyan(title);
|
|
17
11
|
/**
|
|
18
12
|
* Retrieve a list of plugins to auto install
|
|
19
|
-
* @param
|
|
20
|
-
*
|
|
13
|
+
* @param pluginsToAlwaysInstall these plugins represent runtimes that are
|
|
14
|
+
* expected to be "automatically" installed. Even though
|
|
15
|
+
* they can be installed on package/toml, we always
|
|
16
|
+
* want them installed in the site settings. When installed
|
|
17
|
+
* there our build will automatically install the latest without
|
|
18
|
+
* user management of the versioning.
|
|
19
|
+
* @param pluginsInstalled
|
|
20
|
+
* @param pluginsRecommended
|
|
21
21
|
* @returns
|
|
22
22
|
*/
|
|
23
|
-
export const getPluginsToAutoInstall = (pluginsInstalled = [], pluginsRecommended = []) =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* @param {*} config
|
|
29
|
-
* @param {import('../../commands/base-command.js').default} command
|
|
30
|
-
*/
|
|
31
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'settings' implicitly has an 'any' type.
|
|
23
|
+
export const getPluginsToAutoInstall = (command, pluginsInstalled = [], pluginsRecommended = []) => {
|
|
24
|
+
const nextRuntime = '@netlify/plugin-nextjs';
|
|
25
|
+
const pluginsToAlwaysInstall = new Set([nextRuntime]);
|
|
26
|
+
return pluginsRecommended.reduce((acc, plugin) => pluginsInstalled.includes(plugin) && !pluginsToAlwaysInstall.has(plugin) ? acc : [...acc, plugin], []);
|
|
27
|
+
};
|
|
32
28
|
const normalizeSettings = (settings, config, command) => {
|
|
33
|
-
const plugins = getPluginsToAutoInstall(settings.plugins_from_config_file, settings.plugins_recommended);
|
|
29
|
+
const plugins = getPluginsToAutoInstall(command, settings.plugins_from_config_file, settings.plugins_recommended);
|
|
34
30
|
const recommendedPlugins = getRecommendPlugins(plugins, config);
|
|
35
31
|
return {
|
|
36
32
|
defaultBaseDir: settings.baseDirectory ?? command.project.relativeBaseDirectory ?? '',
|
|
37
33
|
defaultBuildCmd: config.build.command || settings.buildCommand,
|
|
38
34
|
defaultBuildDir: settings.dist,
|
|
35
|
+
// @ts-expect-error types need to be fixed on @netlify/build
|
|
39
36
|
defaultFunctionsDir: config.build.functions || 'netlify/functions',
|
|
40
37
|
recommendedPlugins,
|
|
41
38
|
};
|
|
@@ -75,21 +72,14 @@ const getPromptInputs = ({ defaultBaseDir, defaultBuildCmd, defaultBuildDir }) =
|
|
|
75
72
|
].filter(Boolean);
|
|
76
73
|
return inputs.filter(Boolean);
|
|
77
74
|
};
|
|
78
|
-
/**
|
|
79
|
-
* @param {object} param0
|
|
80
|
-
* @param {*} param0.config
|
|
81
|
-
* @param {import('../../commands/base-command.js').default} param0.command
|
|
82
|
-
*/
|
|
83
|
-
// @ts-expect-error TS(7031) FIXME: Binding element 'command' implicitly has an 'any' ... Remove this comment to see the full error message
|
|
84
75
|
export const getBuildSettings = async ({ command, config }) => {
|
|
85
76
|
const settings = await detectBuildSettings(command);
|
|
86
77
|
// TODO: add prompt for asking to choose the build command
|
|
87
|
-
/** @type {Partial<import('@netlify/build-info').Settings>} */
|
|
88
78
|
// eslint-disable-next-line unicorn/explicit-length-check
|
|
89
79
|
const setting = settings.length > 0 ? settings[0] : {};
|
|
90
80
|
const { defaultBaseDir, defaultBuildCmd, defaultBuildDir, defaultFunctionsDir, recommendedPlugins } = await normalizeSettings(setting, config, command);
|
|
91
81
|
if (recommendedPlugins.length !== 0 && setting.framework?.name) {
|
|
92
|
-
log(`Configuring ${formatTitle(setting.framework
|
|
82
|
+
log(`Configuring ${formatTitle(setting.framework.name)} runtime...`);
|
|
93
83
|
log();
|
|
94
84
|
}
|
|
95
85
|
const { baseDir, buildCmd, buildDir } = await inquirer.prompt(getPromptInputs({
|
|
@@ -174,11 +164,6 @@ export const formatErrorMessage = ({ error, message }) => {
|
|
|
174
164
|
const errorMessage = error.json ? `${error.message} - ${JSON.stringify(error.json)}` : error.message;
|
|
175
165
|
return `${message} with error: ${chalk.red(errorMessage)}`;
|
|
176
166
|
};
|
|
177
|
-
/**
|
|
178
|
-
* @param {string} title
|
|
179
|
-
*/
|
|
180
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'title' implicitly has an 'any' type.
|
|
181
|
-
const formatTitle = (title) => chalk.cyan(title);
|
|
182
167
|
// @ts-expect-error TS(7031) FIXME: Binding element 'api' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
183
168
|
export const createDeployKey = async ({ api }) => {
|
|
184
169
|
try {
|
package/src/utils/live-tunnel.js
CHANGED
|
@@ -6,7 +6,6 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
6
6
|
import { fetchLatestVersion, shouldFetchLatestVersion } from '../lib/exec-fetcher.js';
|
|
7
7
|
import { getPathInHome } from '../lib/settings.js';
|
|
8
8
|
import { NETLIFYDEVERR, NETLIFYDEVLOG, chalk, log } from './command-helpers.js';
|
|
9
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
|
|
10
9
|
import execa from './execa.js';
|
|
11
10
|
const PACKAGE_NAME = 'live-tunnel-client';
|
|
12
11
|
const EXEC_NAME = PACKAGE_NAME;
|
|
@@ -45,7 +44,6 @@ const connectTunnel = function ({ localPort, netlifyApiToken, session }) {
|
|
|
45
44
|
args.push('-v');
|
|
46
45
|
log(execPath, args);
|
|
47
46
|
}
|
|
48
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
49
47
|
const ps = execa(execPath, args, { stdio: 'inherit' });
|
|
50
48
|
// @ts-expect-error TS(7006) FIXME: Parameter 'code' implicitly has an 'any' type.
|
|
51
49
|
ps.on('close', (code) => process.exit(code));
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import semver from 'semver';
|
|
2
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
|
|
3
2
|
import execa from '../execa.js';
|
|
4
3
|
export const checkLFSFilters = async function () {
|
|
5
4
|
try {
|
|
6
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
7
5
|
const { stdout } = await execa('git', ['config', '--get-regexp', 'filter.lfs']);
|
|
8
6
|
return stdout.length !== 0;
|
|
9
7
|
}
|
|
@@ -13,7 +11,6 @@ export const checkLFSFilters = async function () {
|
|
|
13
11
|
};
|
|
14
12
|
const getHelperVersion = async function () {
|
|
15
13
|
try {
|
|
16
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
17
14
|
const { stdout } = await execa('git-credential-netlify', ['version']);
|
|
18
15
|
return stdout;
|
|
19
16
|
}
|
|
@@ -28,7 +25,6 @@ export const checkHelperVersion = async function () {
|
|
|
28
25
|
};
|
|
29
26
|
export const checkGitVersion = async function () {
|
|
30
27
|
try {
|
|
31
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
32
28
|
const { stdout } = await execa('git', ['--version']);
|
|
33
29
|
return stdout.split(' ').pop();
|
|
34
30
|
}
|
|
@@ -38,7 +34,6 @@ export const checkGitVersion = async function () {
|
|
|
38
34
|
};
|
|
39
35
|
const getLFSVersion = async function () {
|
|
40
36
|
try {
|
|
41
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
42
37
|
const { stdout } = await execa('git-lfs', ['version']);
|
|
43
38
|
return stdout;
|
|
44
39
|
}
|
package/src/utils/sites/utils.js
CHANGED
|
@@ -35,7 +35,6 @@ export const validateTemplate = async ({ ghToken, templateName }) => {
|
|
|
35
35
|
const data = await response.json();
|
|
36
36
|
return { exists: true, isTemplate: data.is_template };
|
|
37
37
|
};
|
|
38
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'templateName' implicitly has an 'any' t... Remove this comment to see the full error message
|
|
39
38
|
export const createRepo = async (templateName, ghToken, siteName) => {
|
|
40
39
|
const resp = await fetch(`https://api.github.com/repos/${templateName}/generate`, {
|
|
41
40
|
method: 'POST',
|
|
@@ -3,7 +3,6 @@ import { dirname, join } from 'path';
|
|
|
3
3
|
import process, { version as nodejsVersion } from 'process';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import { isCI } from 'ci-info';
|
|
6
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
|
|
7
6
|
import execa from '../execa.js';
|
|
8
7
|
import getGlobalConfig from '../get-global-config.js';
|
|
9
8
|
import { cliVersion } from './utils.js';
|
|
@@ -46,7 +45,6 @@ export const reportError = async function (error, config = {}) {
|
|
|
46
45
|
});
|
|
47
46
|
// spawn detached child process to handle send and wait for the http request to finish
|
|
48
47
|
// otherwise it can get canceled
|
|
49
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
50
48
|
await execa(process.execPath, [join(dirPath, 'request.js'), options], {
|
|
51
49
|
detached: true,
|
|
52
50
|
stdio: 'ignore',
|
|
@@ -2,32 +2,24 @@ import { dirname, join } from 'path';
|
|
|
2
2
|
import process, { version as nodejsVersion } from 'process';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { isCI } from 'ci-info';
|
|
5
|
-
// @ts-expect-error TS(7034) FIXME: Variable 'execa' implicitly has type 'any' in some... Remove this comment to see the full error message
|
|
6
5
|
import execa from '../execa.js';
|
|
7
6
|
import getGlobalConfig from '../get-global-config.js';
|
|
8
7
|
import { isTelemetryDisabled, cliVersion } from './utils.js';
|
|
9
8
|
import isValidEventName from './validation.js';
|
|
10
9
|
const dirPath = dirname(fileURLToPath(import.meta.url));
|
|
11
|
-
/**
|
|
12
|
-
* @param {'track' | 'identify'} type
|
|
13
|
-
* @param {object} payload
|
|
14
|
-
*/
|
|
15
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'type' implicitly has an 'any' type.
|
|
16
10
|
function send(type, payload) {
|
|
17
11
|
const requestFile = join(dirPath, 'request.js');
|
|
18
12
|
const options = JSON.stringify({
|
|
19
13
|
data: payload,
|
|
20
14
|
type,
|
|
21
15
|
});
|
|
22
|
-
const args =
|
|
16
|
+
const args = [process.execPath, [requestFile, options]];
|
|
23
17
|
if (process.env.NETLIFY_TEST_TELEMETRY_WAIT === 'true') {
|
|
24
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
25
18
|
return execa(...args, {
|
|
26
19
|
stdio: 'inherit',
|
|
27
20
|
});
|
|
28
21
|
}
|
|
29
22
|
// spawn detached child process to handle send
|
|
30
|
-
// @ts-expect-error TS(7005) FIXME: Variable 'execa' implicitly has an 'any' type.
|
|
31
23
|
execa(...args, {
|
|
32
24
|
detached: true,
|
|
33
25
|
stdio: 'ignore',
|
|
@@ -46,10 +38,7 @@ const eventConfig = {
|
|
|
46
38
|
};
|
|
47
39
|
/**
|
|
48
40
|
* Tracks a custom event with the provided payload
|
|
49
|
-
* @param {string} eventName
|
|
50
|
-
* @param {{status?: string, duration?: number, [key: string]: unknown}} [payload]
|
|
51
41
|
*/
|
|
52
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'eventName' implicitly has an 'any' type... Remove this comment to see the full error message
|
|
53
42
|
export async function track(eventName, payload = {}) {
|
|
54
43
|
if (isCI) {
|
|
55
44
|
return;
|
|
@@ -69,7 +58,6 @@ export async function track(eventName, payload = {}) {
|
|
|
69
58
|
if (!isValid(eventName, eventConfig)) {
|
|
70
59
|
return false;
|
|
71
60
|
}
|
|
72
|
-
// @ts-expect-error TS(2339) FIXME: Property 'duration' does not exist on type '{}'.
|
|
73
61
|
const { duration, status, ...properties } = payload;
|
|
74
62
|
const defaultData = {
|
|
75
63
|
event: eventName,
|
|
@@ -81,14 +69,6 @@ export async function track(eventName, payload = {}) {
|
|
|
81
69
|
};
|
|
82
70
|
return send('track', defaultData);
|
|
83
71
|
}
|
|
84
|
-
/**
|
|
85
|
-
* @param {object} payload
|
|
86
|
-
* @param {string} payload.name
|
|
87
|
-
* @param {string} payload.email
|
|
88
|
-
* @param {string} payload.userId
|
|
89
|
-
* @returns
|
|
90
|
-
*/
|
|
91
|
-
// @ts-expect-error TS(7006) FIXME: Parameter 'payload' implicitly has an 'any' type.
|
|
92
72
|
export async function identify(payload) {
|
|
93
73
|
if (isCI) {
|
|
94
74
|
return;
|