netlify-cli 15.10.0 → 16.0.0-alpha.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/bin/run.mjs +6 -5
- package/npm-shrinkwrap.json +628 -42
- package/package.json +4 -5
- package/src/commands/base-command.mjs +295 -118
- package/src/commands/build/build.mjs +9 -1
- package/src/commands/deploy/deploy.mjs +42 -18
- package/src/commands/dev/dev.mjs +22 -17
- package/src/commands/functions/functions-create.mjs +118 -89
- package/src/commands/functions/functions-invoke.mjs +10 -7
- package/src/commands/functions/functions-list.mjs +3 -3
- package/src/commands/functions/functions-serve.mjs +1 -0
- package/src/commands/init/init.mjs +1 -1
- package/src/commands/link/link.mjs +5 -5
- package/src/commands/serve/serve.mjs +10 -6
- package/src/commands/sites/sites-create-template.mjs +1 -1
- package/src/commands/sites/sites-create.mjs +1 -1
- package/src/functions-templates/javascript/google-analytics/package.json +1 -1
- package/src/functions-templates/typescript/scheduled-function/package.json +1 -1
- package/src/lib/edge-functions/deploy.mjs +11 -4
- package/src/lib/edge-functions/internal.mjs +5 -3
- package/src/lib/edge-functions/proxy.mjs +29 -5
- package/src/lib/functions/netlify-function.mjs +26 -1
- package/src/lib/functions/registry.mjs +14 -26
- package/src/lib/functions/runtimes/js/builders/zisi.mjs +20 -3
- package/src/lib/functions/runtimes/js/worker.mjs +1 -1
- package/src/lib/functions/server.mjs +3 -2
- package/src/lib/spinner.mjs +1 -1
- package/src/recipes/vscode/index.mjs +24 -6
- package/src/utils/build-info.mjs +100 -0
- package/src/utils/command-helpers.mjs +16 -7
- package/src/utils/deploy/deploy-site.mjs +4 -4
- package/src/utils/deploy/hash-fns.mjs +2 -2
- package/src/utils/detect-server-settings.mjs +133 -245
- package/src/utils/framework-server.mjs +6 -5
- package/src/utils/functions/functions.mjs +8 -5
- package/src/utils/get-repo-data.mjs +5 -6
- package/src/utils/init/config-github.mjs +2 -2
- package/src/utils/init/config-manual.mjs +24 -7
- package/src/utils/init/utils.mjs +68 -68
- package/src/utils/proxy-server.mjs +7 -4
- package/src/utils/proxy.mjs +4 -3
- package/src/utils/read-repo-url.mjs +4 -0
- package/src/utils/run-build.mjs +58 -32
- package/src/utils/shell.mjs +24 -7
- package/src/utils/state-config.mjs +5 -1
- package/src/utils/static-server.mjs +4 -0
- package/src/utils/init/frameworks.mjs +0 -23
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import fuzzy from 'fuzzy'
|
|
4
|
+
import inquirer from 'inquirer'
|
|
5
|
+
|
|
6
|
+
import { chalk, log } from './command-helpers.mjs'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Filters the inquirer settings based on the input
|
|
10
|
+
* @param {ReturnType<typeof formatSettingsArrForInquirer>} scriptInquirerOptions
|
|
11
|
+
* @param {string} input
|
|
12
|
+
*/
|
|
13
|
+
const filterSettings = function (scriptInquirerOptions, input) {
|
|
14
|
+
const filterOptions = scriptInquirerOptions.map((scriptInquirerOption) => scriptInquirerOption.name)
|
|
15
|
+
// TODO: remove once https://github.com/sindresorhus/eslint-plugin-unicorn/issues/1394 is fixed
|
|
16
|
+
// eslint-disable-next-line unicorn/no-array-method-this-argument
|
|
17
|
+
const filteredSettings = fuzzy.filter(input, filterOptions)
|
|
18
|
+
const filteredSettingNames = new Set(
|
|
19
|
+
filteredSettings.map((filteredSetting) => (input ? filteredSetting.string : filteredSetting)),
|
|
20
|
+
)
|
|
21
|
+
return scriptInquirerOptions.filter((t) => filteredSettingNames.has(t.name))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** @typedef {import('@netlify/build-info').Settings} Settings */
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {Settings[]} settings
|
|
28
|
+
* @param {'dev' | 'build'} type The type of command (dev or build)
|
|
29
|
+
*/
|
|
30
|
+
const formatSettingsArrForInquirer = function (settings, type = 'dev') {
|
|
31
|
+
return settings.map((setting) => {
|
|
32
|
+
const cmd = type === 'dev' ? setting.devCommand : setting.buildCommand
|
|
33
|
+
return {
|
|
34
|
+
name: `[${chalk.yellow(setting.framework.name)}] '${cmd}'`,
|
|
35
|
+
value: { ...setting, commands: [cmd] },
|
|
36
|
+
short: `${setting.name}-${cmd}`,
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Uses @netlify/build-info to detect the dev settings and port based on the framework
|
|
43
|
+
* and the build system that is used.
|
|
44
|
+
* @param {import('../commands/base-command.mjs').default} command
|
|
45
|
+
* @param {'dev' | 'build'} type The type of command (dev or build)
|
|
46
|
+
* @returns {Promise<Settings | undefined>}
|
|
47
|
+
*/
|
|
48
|
+
export const detectFrameworkSettings = async (command, type = 'dev') => {
|
|
49
|
+
const { relConfigFilePath } = command.netlify
|
|
50
|
+
const settings = await detectBuildSettings(command)
|
|
51
|
+
if (settings.length === 1) {
|
|
52
|
+
return settings[0]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (settings.length > 1) {
|
|
56
|
+
/** multiple matching detectors, make the user choose */
|
|
57
|
+
const scriptInquirerOptions = formatSettingsArrForInquirer(settings, type)
|
|
58
|
+
/** @type {{chosenSettings: Settings}} */
|
|
59
|
+
const { chosenSettings } = await inquirer.prompt({
|
|
60
|
+
name: 'chosenSettings',
|
|
61
|
+
message: `Multiple possible ${type} commands found`,
|
|
62
|
+
type: 'autocomplete',
|
|
63
|
+
source(/** @type {string} */ _, input = '') {
|
|
64
|
+
if (!input) return scriptInquirerOptions
|
|
65
|
+
// only show filtered results
|
|
66
|
+
return filterSettings(scriptInquirerOptions, input)
|
|
67
|
+
},
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
log(`
|
|
71
|
+
Update your ${relConfigFilePath} to avoid this selection prompt next time:
|
|
72
|
+
|
|
73
|
+
[build]
|
|
74
|
+
command = "${chosenSettings.buildCommand}"
|
|
75
|
+
publish = "${chosenSettings.dist}"
|
|
76
|
+
|
|
77
|
+
[dev]
|
|
78
|
+
command = "${chosenSettings.devCommand}"
|
|
79
|
+
`)
|
|
80
|
+
return chosenSettings
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Detects and filters the build setting for a project and a command
|
|
86
|
+
* @param {import('../commands/base-command.mjs').default} command
|
|
87
|
+
*/
|
|
88
|
+
export const detectBuildSettings = async (command) => {
|
|
89
|
+
const { project, workspacePackage } = command
|
|
90
|
+
const buildSettings = await project.getBuildSettings(project.workspace ? workspacePackage : '')
|
|
91
|
+
return buildSettings
|
|
92
|
+
.filter((setting) => {
|
|
93
|
+
if (project.workspace && project.relativeBaseDirectory && setting.packagePath) {
|
|
94
|
+
return project.relativeBaseDirectory.startsWith(setting.packagePath)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return true
|
|
98
|
+
})
|
|
99
|
+
.filter((setting) => setting.devCommand)
|
|
100
|
+
}
|
|
@@ -24,7 +24,7 @@ const argv = process.argv.slice(2)
|
|
|
24
24
|
* Chalk instance for CLI that can be initialized with no colors mode
|
|
25
25
|
* needed for json outputs where we don't want to have colors
|
|
26
26
|
* @param {boolean} noColors - disable chalk colors
|
|
27
|
-
* @return {
|
|
27
|
+
* @return {import('chalk').ChalkInstance} - default or custom chalk instance
|
|
28
28
|
*/
|
|
29
29
|
const safeChalk = function (noColors) {
|
|
30
30
|
if (noColors) {
|
|
@@ -174,12 +174,18 @@ export const warn = (message = '') => {
|
|
|
174
174
|
|
|
175
175
|
/**
|
|
176
176
|
* throws an error or log it
|
|
177
|
-
* @param {
|
|
177
|
+
* @param {unknown} message
|
|
178
178
|
* @param {object} [options]
|
|
179
179
|
* @param {boolean} [options.exit]
|
|
180
180
|
*/
|
|
181
181
|
export const error = (message = '', options = {}) => {
|
|
182
|
-
const err =
|
|
182
|
+
const err =
|
|
183
|
+
message instanceof Error
|
|
184
|
+
? message
|
|
185
|
+
: // eslint-disable-next-line unicorn/no-nested-ternary
|
|
186
|
+
typeof message === 'string'
|
|
187
|
+
? new Error(message)
|
|
188
|
+
: /** @type {Error} */ ({ message, stack: undefined, name: 'Error' })
|
|
183
189
|
|
|
184
190
|
if (options.exit === false) {
|
|
185
191
|
const bang = chalk.red(BANG)
|
|
@@ -198,10 +204,13 @@ export const exit = (code = 0) => {
|
|
|
198
204
|
process.exit(code)
|
|
199
205
|
}
|
|
200
206
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
207
|
+
/**
|
|
208
|
+
* When `build.publish` is not set by the user, the CLI behavior differs in
|
|
209
|
+
* several ways. It detects it by checking if `build.publish` is `undefined`.
|
|
210
|
+
* However, `@netlify/config` adds a default value to `build.publish`.
|
|
211
|
+
* This removes 'publish' and 'publishOrigin' in this case.
|
|
212
|
+
* @param {*} config
|
|
213
|
+
*/
|
|
205
214
|
export const normalizeConfig = (config) => {
|
|
206
215
|
// Unused var here is in order to omit 'publish' from build config
|
|
207
216
|
// eslint-disable-next-line no-unused-vars
|
|
@@ -39,7 +39,6 @@ export const deploySite = async (
|
|
|
39
39
|
maxRetry = DEFAULT_MAX_RETRY,
|
|
40
40
|
// API calls this the 'title'
|
|
41
41
|
message: title,
|
|
42
|
-
rootDir,
|
|
43
42
|
siteEnv,
|
|
44
43
|
skipFunctionsCache,
|
|
45
44
|
statusCb = () => {
|
|
@@ -47,6 +46,7 @@ export const deploySite = async (
|
|
|
47
46
|
},
|
|
48
47
|
syncFileLimit = DEFAULT_SYNC_LIMIT,
|
|
49
48
|
tmpDir = temporaryDirectory(),
|
|
49
|
+
workingDir,
|
|
50
50
|
} = {},
|
|
51
51
|
) => {
|
|
52
52
|
statusCb({
|
|
@@ -55,7 +55,7 @@ export const deploySite = async (
|
|
|
55
55
|
phase: 'start',
|
|
56
56
|
})
|
|
57
57
|
|
|
58
|
-
const edgeFunctionsDistPath = await getDistPathIfExists(
|
|
58
|
+
const edgeFunctionsDistPath = await getDistPathIfExists(workingDir)
|
|
59
59
|
const [{ files, filesShaMap }, { fnConfig, fnShaMap, functionSchedules, functions, functionsWithNativeModules }] =
|
|
60
60
|
await Promise.all([
|
|
61
61
|
hashFiles({
|
|
@@ -64,7 +64,7 @@ export const deploySite = async (
|
|
|
64
64
|
directories: [configPath, dir, edgeFunctionsDistPath].filter(Boolean),
|
|
65
65
|
filter,
|
|
66
66
|
hashAlgorithm,
|
|
67
|
-
normalizer: deployFileNormalizer.bind(null,
|
|
67
|
+
normalizer: deployFileNormalizer.bind(null, workingDir),
|
|
68
68
|
statusCb,
|
|
69
69
|
}),
|
|
70
70
|
hashFns(fnDir, {
|
|
@@ -74,7 +74,7 @@ export const deploySite = async (
|
|
|
74
74
|
hashAlgorithm,
|
|
75
75
|
statusCb,
|
|
76
76
|
assetType,
|
|
77
|
-
|
|
77
|
+
workingDir,
|
|
78
78
|
manifestPath,
|
|
79
79
|
skipFunctionsCache,
|
|
80
80
|
siteEnv,
|
|
@@ -20,10 +20,10 @@ const getFunctionZips = async ({
|
|
|
20
20
|
directories,
|
|
21
21
|
functionsConfig,
|
|
22
22
|
manifestPath,
|
|
23
|
-
rootDir,
|
|
24
23
|
skipFunctionsCache,
|
|
25
24
|
statusCb,
|
|
26
25
|
tmpDir,
|
|
26
|
+
workingDir,
|
|
27
27
|
}) => {
|
|
28
28
|
statusCb({
|
|
29
29
|
type: 'functions-manifest',
|
|
@@ -68,7 +68,7 @@ const getFunctionZips = async ({
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
return await zipFunctions(directories, tmpDir, {
|
|
71
|
-
basePath:
|
|
71
|
+
basePath: workingDir,
|
|
72
72
|
configFileDirectories: [getPathInProject([INTERNAL_FUNCTIONS_FOLDER])],
|
|
73
73
|
config: functionsConfig,
|
|
74
74
|
})
|