netlify-cli 8.0.10 → 8.1.0-rc
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 +81 -3
- package/npm-shrinkwrap.json +471 -2182
- package/package.json +12 -35
- package/src/commands/addons/addons-auth.js +50 -0
- package/src/commands/addons/addons-config.js +180 -0
- package/src/commands/addons/addons-create.js +129 -0
- package/src/commands/addons/addons-delete.js +59 -0
- package/src/commands/addons/addons-list.js +62 -0
- package/src/commands/addons/addons.js +49 -0
- package/src/commands/addons/index.js +3 -24
- package/src/commands/api/api.js +83 -0
- package/src/commands/api/index.js +5 -0
- package/src/commands/base-command.js +322 -0
- package/src/commands/build/build.js +58 -0
- package/src/commands/build/index.js +3 -61
- package/src/commands/completion/completion.js +18 -0
- package/src/commands/completion/index.js +5 -0
- package/src/commands/{deploy.js → deploy/deploy.js} +306 -278
- package/src/commands/deploy/index.js +5 -0
- package/src/commands/dev/dev-exec.js +39 -0
- package/src/commands/dev/dev-trace.js +50 -0
- package/src/commands/dev/dev.js +349 -0
- package/src/commands/dev/index.js +3 -335
- package/src/commands/env/env-get.js +51 -0
- package/src/commands/env/env-import.js +93 -0
- package/src/commands/env/env-list.js +63 -0
- package/src/commands/env/env-set.js +67 -0
- package/src/commands/env/env-unset.js +66 -0
- package/src/commands/env/env.js +47 -0
- package/src/commands/env/index.js +3 -23
- package/src/commands/functions/functions-build.js +59 -0
- package/src/commands/functions/{create.js → functions-create.js} +133 -94
- package/src/commands/functions/functions-invoke.js +276 -0
- package/src/commands/functions/functions-list.js +107 -0
- package/src/commands/functions/functions-serve.js +63 -0
- package/src/commands/functions/functions.js +53 -0
- package/src/commands/functions/index.js +3 -45
- package/src/commands/index.js +5 -0
- package/src/commands/init/index.js +6 -0
- package/src/commands/{init.js → init/init.js} +79 -68
- package/src/commands/link/index.js +6 -0
- package/src/{utils/link/link-by-prompt.js → commands/link/link.js} +153 -14
- package/src/commands/lm/index.js +3 -19
- package/src/commands/lm/lm-info.js +42 -0
- package/src/commands/lm/lm-install.js +36 -0
- package/src/commands/lm/lm-setup.js +106 -0
- package/src/commands/lm/lm-uninstall.js +25 -0
- package/src/commands/lm/lm.js +39 -0
- package/src/commands/login/index.js +6 -0
- package/src/commands/login/login.js +52 -0
- package/src/commands/logout/index.js +5 -0
- package/src/commands/logout/logout.js +43 -0
- package/src/commands/main.js +117 -0
- package/src/commands/open/index.js +3 -39
- package/src/commands/open/open-admin.js +56 -0
- package/src/commands/open/open-site.js +49 -0
- package/src/commands/open/open.js +42 -0
- package/src/commands/sites/index.js +5 -20
- package/src/commands/sites/sites-create.js +184 -0
- package/src/commands/sites/sites-delete.js +108 -0
- package/src/commands/sites/sites-list.js +89 -0
- package/src/commands/sites/sites.js +36 -0
- package/src/commands/status/index.js +3 -118
- package/src/commands/status/status-hooks.js +73 -0
- package/src/commands/status/status.js +125 -0
- package/src/commands/switch/index.js +5 -0
- package/src/commands/switch/switch.js +50 -0
- package/src/commands/unlink/index.js +5 -0
- package/src/commands/unlink/unlink.js +48 -0
- package/src/commands/watch/index.js +5 -0
- package/src/commands/watch/watch.js +121 -0
- package/src/lib/build.js +21 -7
- package/src/lib/exec-fetcher.js +5 -3
- package/src/lib/fs.js +54 -36
- package/src/lib/functions/background.js +1 -1
- package/src/lib/functions/form-submissions-handler.js +2 -1
- package/src/lib/functions/local-proxy.js +2 -1
- package/src/lib/functions/netlify-function.js +4 -1
- package/src/lib/functions/registry.js +4 -6
- package/src/lib/functions/runtimes/go/index.js +2 -1
- package/src/lib/functions/runtimes/js/builders/netlify-lambda.js +6 -4
- package/src/lib/functions/runtimes/js/builders/zisi.js +3 -3
- package/src/lib/functions/runtimes/rust/index.js +4 -3
- package/src/lib/functions/server.js +2 -3
- package/src/lib/functions/synchronous.js +2 -1
- package/src/lib/functions/utils.js +2 -3
- package/src/lib/functions/watcher.js +1 -0
- package/src/lib/http-agent.js +5 -5
- package/src/lib/log.js +2 -1
- package/src/lib/spinner.js +22 -0
- package/src/utils/addons/diffs/index.js +1 -0
- package/src/utils/addons/diffs/options.js +3 -1
- package/src/utils/addons/prepare.js +13 -6
- package/src/utils/addons/prompts.js +2 -1
- package/src/utils/addons/render.js +3 -1
- package/src/utils/command-helpers.js +156 -43
- package/src/utils/create-stream-promise.js +5 -5
- package/src/utils/deferred.js +1 -0
- package/src/utils/deploy/deploy-site.js +1 -1
- package/src/utils/deploy/index.js +4 -0
- package/src/utils/detect-server-settings.js +10 -12
- package/src/utils/dev.js +18 -10
- package/src/utils/dot-env.js +4 -2
- package/src/utils/{edge-handlers.js → functions/edge-handlers.js} +8 -7
- package/src/utils/functions/functions.js +36 -0
- package/src/utils/{get-functions.js → functions/get-functions.js} +2 -1
- package/src/utils/functions/index.js +8 -26
- package/src/utils/get-global-config.js +3 -2
- package/src/utils/get-repo-data.js +1 -0
- package/src/utils/gh-auth.js +1 -0
- package/src/utils/gitignore.js +7 -5
- package/src/utils/header.js +2 -2
- package/src/utils/headers.js +1 -2
- package/src/utils/index.js +42 -0
- package/src/utils/init/config-github.js +12 -5
- package/src/utils/init/config-manual.js +9 -2
- package/src/utils/init/config.js +13 -7
- package/src/utils/init/frameworks.js +1 -0
- package/src/utils/init/node-version.js +4 -2
- package/src/utils/init/plugins.js +1 -0
- package/src/utils/init/utils.js +10 -6
- package/src/utils/live-tunnel.js +3 -4
- package/src/utils/lm/install.js +10 -15
- package/src/utils/lm/requirements.js +3 -1
- package/src/utils/lm/steps.js +1 -1
- package/src/utils/lm/ui.js +7 -3
- package/src/utils/open-browser.js +8 -2
- package/src/utils/parse-raw-flags.js +4 -4
- package/src/utils/proxy.js +7 -5
- package/src/utils/read-repo-url.js +1 -0
- package/src/utils/redirects.js +2 -2
- package/src/utils/rules-proxy.js +4 -2
- package/src/utils/state-config.js +1 -1
- package/src/utils/telemetry/index.js +2 -113
- package/src/utils/telemetry/request.js +3 -1
- package/src/utils/telemetry/telemetry.js +117 -0
- package/src/utils/telemetry/validation.js +13 -12
- package/src/utils/traffic-mesh.js +3 -3
- package/oclif.manifest.json +0 -1
- package/src/commands/addons/auth.js +0 -42
- package/src/commands/addons/config.js +0 -177
- package/src/commands/addons/create.js +0 -127
- package/src/commands/addons/delete.js +0 -69
- package/src/commands/addons/list.js +0 -54
- package/src/commands/api.js +0 -84
- package/src/commands/dev/exec.js +0 -32
- package/src/commands/dev/trace.js +0 -61
- package/src/commands/env/get.js +0 -44
- package/src/commands/env/import.js +0 -90
- package/src/commands/env/list.js +0 -49
- package/src/commands/env/set.js +0 -64
- package/src/commands/env/unset.js +0 -58
- package/src/commands/functions/build.js +0 -60
- package/src/commands/functions/invoke.js +0 -277
- package/src/commands/functions/list.js +0 -102
- package/src/commands/functions/serve.js +0 -70
- package/src/commands/link.js +0 -133
- package/src/commands/lm/info.js +0 -36
- package/src/commands/lm/install.js +0 -30
- package/src/commands/lm/setup.js +0 -107
- package/src/commands/lm/uninstall.js +0 -17
- package/src/commands/login.js +0 -54
- package/src/commands/logout.js +0 -37
- package/src/commands/open/admin.js +0 -51
- package/src/commands/open/site.js +0 -43
- package/src/commands/sites/create.js +0 -191
- package/src/commands/sites/delete.js +0 -116
- package/src/commands/sites/list.js +0 -84
- package/src/commands/status/hooks.js +0 -60
- package/src/commands/switch.js +0 -44
- package/src/commands/unlink.js +0 -38
- package/src/commands/watch.js +0 -115
- package/src/hooks/init.js +0 -46
- package/src/index.js +0 -25
- package/src/lib/help.js +0 -26
- package/src/utils/chalk.js +0 -16
- package/src/utils/check-command-inputs.js +0 -21
- package/src/utils/command.js +0 -261
- package/src/utils/detect-functions-builder.js +0 -25
- package/src/utils/difference.js +0 -4
- package/src/utils/logo.js +0 -11
- package/src/utils/show-help.js +0 -5
- package/src/utils/telemetry/tracked-command.js +0 -51
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const execa = require('execa')
|
|
2
|
+
|
|
3
|
+
const { generateDescriptionHelp, generateExamplesHelp, injectEnvVariables } = require('../../utils')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The dev:exec command
|
|
7
|
+
* @param {import('commander').OptionValues} options
|
|
8
|
+
* @param {import('../base-command').BaseCommand} command
|
|
9
|
+
*/
|
|
10
|
+
const devExec = async (cmd, options, command) => {
|
|
11
|
+
const { cachedConfig, site } = command.netlify
|
|
12
|
+
await injectEnvVariables({ env: cachedConfig.env, site })
|
|
13
|
+
|
|
14
|
+
await execa(cmd, command.args.slice(1), {
|
|
15
|
+
stdio: 'inherit',
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates the `netlify dev:exec` command
|
|
21
|
+
* @param {import('../base-command').BaseCommand} program
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
24
|
+
const createDevExecCommand = (program) =>
|
|
25
|
+
program
|
|
26
|
+
.command('dev:exec')
|
|
27
|
+
.argument('<...cmd>')
|
|
28
|
+
.description('Exec command')
|
|
29
|
+
.allowExcessArguments(true)
|
|
30
|
+
.addHelpText(
|
|
31
|
+
'after',
|
|
32
|
+
generateDescriptionHelp(
|
|
33
|
+
'Runs a command within the netlify dev environment, e.g. with env variables from any installed addons',
|
|
34
|
+
),
|
|
35
|
+
)
|
|
36
|
+
.addHelpText('after', generateExamplesHelp(['netlify dev:exec npm run bootstrap']))
|
|
37
|
+
.action(devExec)
|
|
38
|
+
|
|
39
|
+
module.exports = { createDevExecCommand }
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
const process = require('process')
|
|
3
|
+
|
|
4
|
+
const { generateExamplesHelp, runProcess } = require('../../utils')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The dev:trace command
|
|
8
|
+
* @returns {Promise<void>}
|
|
9
|
+
*/
|
|
10
|
+
const devTrace = async () => {
|
|
11
|
+
const args = ['trace', ...process.argv.slice(3)]
|
|
12
|
+
const { subprocess } = runProcess({ args })
|
|
13
|
+
await subprocess
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Creates the `netlify dev:trace` command
|
|
18
|
+
* @param {import('../base-command').BaseCommand} program
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
21
|
+
const createDevTraceCommand = (program) =>
|
|
22
|
+
program
|
|
23
|
+
.command('dev:trace')
|
|
24
|
+
.argument('<url>', 'Sets the request URL')
|
|
25
|
+
.description('Trace command')
|
|
26
|
+
.option('-X, --request <method>', 'Specifies a custom request method [default: GET]')
|
|
27
|
+
.option('-b, --cookie <cookie>', 'Request cookie, this flag can be used multiple times. Example: "nf_jwt=token"')
|
|
28
|
+
.option(
|
|
29
|
+
'-H, --header <header>',
|
|
30
|
+
'Request header, this flag can be used multiple times. Example: "Host: netlify.test"',
|
|
31
|
+
)
|
|
32
|
+
.option('-w, --watch <path>', 'Path to the publish directory')
|
|
33
|
+
.addHelpText(
|
|
34
|
+
'after',
|
|
35
|
+
`Simulates Netlify's Edge routing logic to match specific requests.
|
|
36
|
+
This command is designed to mimic cURL's command line, so the flags are more familiar.`,
|
|
37
|
+
)
|
|
38
|
+
.addHelpText(
|
|
39
|
+
'after',
|
|
40
|
+
generateExamplesHelp([
|
|
41
|
+
'netlify dev:trace http://localhost/routing-path',
|
|
42
|
+
'netlify dev:trace -w dist-directory http://localhost/routing-path',
|
|
43
|
+
'netlify dev:trace -X POST http://localhost/routing-path',
|
|
44
|
+
'netlify dev:trace -H "Accept-Language es" http://localhost/routing-path',
|
|
45
|
+
'netlify dev:trace --cookie nf_jwt=token http://localhost/routing-path',
|
|
46
|
+
]),
|
|
47
|
+
)
|
|
48
|
+
.action(devTrace)
|
|
49
|
+
|
|
50
|
+
module.exports = { createDevTraceCommand }
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const process = require('process')
|
|
4
|
+
const { promisify } = require('util')
|
|
5
|
+
|
|
6
|
+
const boxen = require('boxen')
|
|
7
|
+
const execa = require('execa')
|
|
8
|
+
const StaticServer = require('static-server')
|
|
9
|
+
const stripAnsiCc = require('strip-ansi-control-characters')
|
|
10
|
+
const waitPort = require('wait-port')
|
|
11
|
+
|
|
12
|
+
const { startFunctionsServer } = require('../../lib/functions/server')
|
|
13
|
+
const {
|
|
14
|
+
NETLIFYDEV,
|
|
15
|
+
NETLIFYDEVERR,
|
|
16
|
+
NETLIFYDEVLOG,
|
|
17
|
+
NETLIFYDEVWARN,
|
|
18
|
+
chalk,
|
|
19
|
+
detectServerSettings,
|
|
20
|
+
exit,
|
|
21
|
+
generateDescriptionHelp,
|
|
22
|
+
generateExamplesHelp,
|
|
23
|
+
getSiteInformation,
|
|
24
|
+
injectEnvVariables,
|
|
25
|
+
log,
|
|
26
|
+
openBrowser,
|
|
27
|
+
startForwardProxy,
|
|
28
|
+
startLiveTunnel,
|
|
29
|
+
startProxy,
|
|
30
|
+
warn,
|
|
31
|
+
} = require('../../utils')
|
|
32
|
+
|
|
33
|
+
const { createDevExecCommand } = require('./dev-exec')
|
|
34
|
+
const { createDevTraceCommand } = require('./dev-trace')
|
|
35
|
+
|
|
36
|
+
const startStaticServer = async ({ settings }) => {
|
|
37
|
+
const server = new StaticServer({
|
|
38
|
+
rootPath: settings.dist,
|
|
39
|
+
name: 'netlify-dev',
|
|
40
|
+
port: settings.frameworkPort,
|
|
41
|
+
templates: {
|
|
42
|
+
notFound: path.join(settings.dist, '404.html'),
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
await promisify(server.start.bind(server))()
|
|
47
|
+
log(`\n${NETLIFYDEVLOG} Static server listening to`, settings.frameworkPort)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const isNonExistingCommandError = ({ command, error }) => {
|
|
51
|
+
// `ENOENT` is only returned for non Windows systems
|
|
52
|
+
// See https://github.com/sindresorhus/execa/pull/447
|
|
53
|
+
if (error.code === 'ENOENT') {
|
|
54
|
+
return true
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// if the command is a package manager we let it report the error
|
|
58
|
+
if (['yarn', 'npm'].includes(command)) {
|
|
59
|
+
return false
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// this only works on English versions of Windows
|
|
63
|
+
return (
|
|
64
|
+
typeof error.message === 'string' && error.message.includes('is not recognized as an internal or external command')
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Run a command and pipe stdout, stderr and stdin
|
|
70
|
+
* @param {string} command
|
|
71
|
+
* @param {NodeJS.ProcessEnv} env
|
|
72
|
+
* @returns {execa.ExecaChildProcess<string>}
|
|
73
|
+
*/
|
|
74
|
+
const runCommand = (command, env = {}) => {
|
|
75
|
+
const commandProcess = execa.command(command, {
|
|
76
|
+
preferLocal: true,
|
|
77
|
+
// we use reject=false to avoid rejecting synchronously when the command doesn't exist
|
|
78
|
+
reject: false,
|
|
79
|
+
env,
|
|
80
|
+
// windowsHide needs to be false for child process to terminate properly on Windows
|
|
81
|
+
windowsHide: false,
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
commandProcess.stdout.pipe(stripAnsiCc.stream()).pipe(process.stdout)
|
|
85
|
+
commandProcess.stderr.pipe(stripAnsiCc.stream()).pipe(process.stderr)
|
|
86
|
+
process.stdin.pipe(commandProcess.stdin)
|
|
87
|
+
|
|
88
|
+
// we can't try->await->catch since we don't want to block on the framework server which
|
|
89
|
+
// is a long running process
|
|
90
|
+
// eslint-disable-next-line promise/catch-or-return,promise/prefer-await-to-then
|
|
91
|
+
commandProcess.then(async () => {
|
|
92
|
+
const result = await commandProcess
|
|
93
|
+
const [commandWithoutArgs] = command.split(' ')
|
|
94
|
+
// eslint-disable-next-line promise/always-return
|
|
95
|
+
if (result.failed && isNonExistingCommandError({ command: commandWithoutArgs, error: result })) {
|
|
96
|
+
log(
|
|
97
|
+
NETLIFYDEVERR,
|
|
98
|
+
`Failed running command: ${command}. Please verify ${chalk.magenta(`'${commandWithoutArgs}'`)} exists`,
|
|
99
|
+
)
|
|
100
|
+
} else {
|
|
101
|
+
const errorMessage = result.failed
|
|
102
|
+
? `${NETLIFYDEVERR} ${result.shortMessage}`
|
|
103
|
+
: `${NETLIFYDEVWARN} "${command}" exited with code ${result.exitCode}`
|
|
104
|
+
|
|
105
|
+
log(`${errorMessage}. Shutting down Netlify Dev server`)
|
|
106
|
+
}
|
|
107
|
+
process.exit(1)
|
|
108
|
+
})
|
|
109
|
+
;['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP', 'exit'].forEach((signal) => {
|
|
110
|
+
process.on(signal, () => {
|
|
111
|
+
commandProcess.kill('SIGTERM', { forceKillAfterTimeout: 500 })
|
|
112
|
+
process.exit()
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
return commandProcess
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Start a static server if the `useStaticServer` is provided or a framework specific server
|
|
121
|
+
* @param {object} config
|
|
122
|
+
* @param {Partial<import('../../utils/types').ServerSettings>} config.settings
|
|
123
|
+
* @returns {Promise<void>}
|
|
124
|
+
*/
|
|
125
|
+
const startFrameworkServer = async function ({ settings }) {
|
|
126
|
+
if (settings.useStaticServer) {
|
|
127
|
+
if (settings.command) {
|
|
128
|
+
runCommand(settings.command, settings.env)
|
|
129
|
+
}
|
|
130
|
+
return await startStaticServer({ settings })
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
log(`${NETLIFYDEVLOG} Starting Netlify Dev with ${settings.framework || 'custom config'}`)
|
|
134
|
+
|
|
135
|
+
runCommand(settings.command, settings.env)
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
const open = await waitPort({
|
|
139
|
+
port: settings.frameworkPort,
|
|
140
|
+
output: 'silent',
|
|
141
|
+
timeout: FRAMEWORK_PORT_TIMEOUT,
|
|
142
|
+
...(settings.pollingStrategies.includes('HTTP') && { protocol: 'http' }),
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
if (!open) {
|
|
146
|
+
throw new Error(`Timed out waiting for port '${settings.frameworkPort}' to be open`)
|
|
147
|
+
}
|
|
148
|
+
} catch {
|
|
149
|
+
log(NETLIFYDEVERR, `Netlify Dev could not connect to localhost:${settings.frameworkPort}.`)
|
|
150
|
+
log(NETLIFYDEVERR, `Please make sure your framework server is running on port ${settings.frameworkPort}`)
|
|
151
|
+
exit(1)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 10 minutes
|
|
156
|
+
const FRAMEWORK_PORT_TIMEOUT = 6e5
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
*
|
|
160
|
+
* @param {object} config
|
|
161
|
+
* @param {*} config.addonsUrls
|
|
162
|
+
* @param {import('commander').OptionValues} config.options
|
|
163
|
+
* @param {*} config.settings
|
|
164
|
+
* @param {*} config.site
|
|
165
|
+
* @returns
|
|
166
|
+
*/
|
|
167
|
+
const startProxyServer = async ({ addonsUrls, options, settings, site }) => {
|
|
168
|
+
let url
|
|
169
|
+
if (options.edgeHandlers || options.trafficMesh) {
|
|
170
|
+
url = await startForwardProxy({
|
|
171
|
+
port: settings.port,
|
|
172
|
+
frameworkPort: settings.frameworkPort,
|
|
173
|
+
functionsPort: settings.functionsPort,
|
|
174
|
+
publishDir: settings.dist,
|
|
175
|
+
debug: options.debug,
|
|
176
|
+
locationDb: options.locationDb,
|
|
177
|
+
jwtRolesPath: settings.jwtRolePath,
|
|
178
|
+
jwtSecret: settings.jwtSecret,
|
|
179
|
+
})
|
|
180
|
+
if (!url) {
|
|
181
|
+
log(NETLIFYDEVERR, `Unable to start forward proxy on port '${settings.port}'`)
|
|
182
|
+
exit(1)
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
url = await startProxy(settings, addonsUrls, site.configPath, site.root)
|
|
186
|
+
if (!url) {
|
|
187
|
+
log(NETLIFYDEVERR, `Unable to start proxy server on port '${settings.port}'`)
|
|
188
|
+
exit(1)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return url
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
*
|
|
196
|
+
* @param {object} config
|
|
197
|
+
* @param {*} config.api
|
|
198
|
+
* @param {import('commander').OptionValues} config.options
|
|
199
|
+
* @param {*} config.settings
|
|
200
|
+
* @param {*} config.site
|
|
201
|
+
* @returns
|
|
202
|
+
*/
|
|
203
|
+
const handleLiveTunnel = async ({ api, options, settings, site }) => {
|
|
204
|
+
if (options.live) {
|
|
205
|
+
const sessionUrl = await startLiveTunnel({
|
|
206
|
+
siteId: site.id,
|
|
207
|
+
netlifyApiToken: api.accessToken,
|
|
208
|
+
localPort: settings.port,
|
|
209
|
+
})
|
|
210
|
+
process.env.BASE_URL = sessionUrl
|
|
211
|
+
return sessionUrl
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const printBanner = ({ url }) => {
|
|
216
|
+
const banner = chalk.bold(`${NETLIFYDEVLOG} Server now ready on ${url}`)
|
|
217
|
+
|
|
218
|
+
log(
|
|
219
|
+
boxen(banner, {
|
|
220
|
+
padding: 1,
|
|
221
|
+
margin: 1,
|
|
222
|
+
align: 'center',
|
|
223
|
+
borderColor: '#00c7b7',
|
|
224
|
+
}),
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* The dev command
|
|
230
|
+
* @param {import('commander').OptionValues} options
|
|
231
|
+
* @param {import('../base-command').BaseCommand} command
|
|
232
|
+
*/
|
|
233
|
+
const dev = async (options, command) => {
|
|
234
|
+
log(`${NETLIFYDEV}`)
|
|
235
|
+
const { api, config, site, siteInfo } = command.netlify
|
|
236
|
+
config.dev = { ...config.dev }
|
|
237
|
+
config.build = { ...config.build }
|
|
238
|
+
/** @type {import('./types').DevConfig} */
|
|
239
|
+
const devConfig = {
|
|
240
|
+
framework: '#auto',
|
|
241
|
+
...(config.functionsDirectory && { functions: config.functionsDirectory }),
|
|
242
|
+
...(config.build.publish && { publish: config.build.publish }),
|
|
243
|
+
...config.dev,
|
|
244
|
+
...options,
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (options.trafficMesh) {
|
|
248
|
+
warn(
|
|
249
|
+
'--trafficMesh and -t are deprecated and will be removed in the near future. Please use --edgeHandlers or -e instead.',
|
|
250
|
+
)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
await injectEnvVariables({ env: command.netlify.cachedConfig.env, site })
|
|
254
|
+
const { addonsUrls, capabilities, siteUrl, timeouts } = await getSiteInformation({
|
|
255
|
+
// inherited from base command --offline
|
|
256
|
+
offline: options.offline,
|
|
257
|
+
api,
|
|
258
|
+
site,
|
|
259
|
+
siteInfo,
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
/** @type {Partial<import('../../utils/types').ServerSettings>} */
|
|
263
|
+
let settings = {}
|
|
264
|
+
try {
|
|
265
|
+
settings = await detectServerSettings(devConfig, options, site.root)
|
|
266
|
+
} catch (error) {
|
|
267
|
+
log(NETLIFYDEVERR, error.message)
|
|
268
|
+
exit(1)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
command.setAnalyticsPayload({ projectType: settings.framework || 'custom', live: options.live })
|
|
272
|
+
|
|
273
|
+
await startFunctionsServer({
|
|
274
|
+
config,
|
|
275
|
+
settings,
|
|
276
|
+
site,
|
|
277
|
+
siteUrl,
|
|
278
|
+
capabilities,
|
|
279
|
+
timeouts,
|
|
280
|
+
})
|
|
281
|
+
await startFrameworkServer({ settings })
|
|
282
|
+
|
|
283
|
+
let url = await startProxyServer({ options, settings, site, addonsUrls })
|
|
284
|
+
|
|
285
|
+
const liveTunnelUrl = await handleLiveTunnel({ options, site, api, settings })
|
|
286
|
+
url = liveTunnelUrl || url
|
|
287
|
+
|
|
288
|
+
if (devConfig.autoLaunch !== false) {
|
|
289
|
+
await openBrowser({ url, silentBrowserNoneError: true })
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
process.env.URL = url
|
|
293
|
+
process.env.DEPLOY_URL = url
|
|
294
|
+
|
|
295
|
+
printBanner({ url })
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Creates the `netlify dev` command
|
|
300
|
+
* @param {import('../base-command').BaseCommand} program
|
|
301
|
+
* @returns
|
|
302
|
+
*/
|
|
303
|
+
const createDevCommand = (program) => {
|
|
304
|
+
createDevExecCommand(program)
|
|
305
|
+
createDevTraceCommand(program)
|
|
306
|
+
|
|
307
|
+
return (
|
|
308
|
+
program
|
|
309
|
+
.command('dev')
|
|
310
|
+
.description('Local dev server')
|
|
311
|
+
.option('-c ,--command <command>', 'command to run')
|
|
312
|
+
.option('-p ,--port <port>', 'port of netlify dev', (value) => Number.parseInt(value))
|
|
313
|
+
.option('--targetPort <port>', 'port of target app server', (value) => Number.parseInt(value))
|
|
314
|
+
.option('--framework <name>', 'framework to use. Defaults to #auto which automatically detects a framework')
|
|
315
|
+
// TODO: hidden
|
|
316
|
+
.option(
|
|
317
|
+
'--staticServerPort <port>',
|
|
318
|
+
'port of the static app server used when no framework is detected',
|
|
319
|
+
(value) => Number.parseInt(value),
|
|
320
|
+
)
|
|
321
|
+
.option('-d ,--dir <path>', 'dir with static files')
|
|
322
|
+
.option('-f ,--functions <folder>', 'specify a functions folder to serve')
|
|
323
|
+
.option('-o ,--offline', 'disables any features that require network access')
|
|
324
|
+
.option('-l, --live', 'start a public live session', false)
|
|
325
|
+
// TODO: hidden
|
|
326
|
+
.option('-e ,--edgeHandlers', 'activates the Edge Handlers runtime')
|
|
327
|
+
// TODO: hidden
|
|
328
|
+
.option(
|
|
329
|
+
'-t ,--trafficMesh',
|
|
330
|
+
'(DEPRECATED: use --edgeHandlers or -e instead) uses Traffic Mesh for proxying requests',
|
|
331
|
+
)
|
|
332
|
+
// TODO: hidden
|
|
333
|
+
.option('-g ,--locationDb <path>', 'specify the path to a local GeoIP location database in MMDB format')
|
|
334
|
+
.addHelpText(
|
|
335
|
+
'after',
|
|
336
|
+
generateDescriptionHelp(`The dev command will run a local dev server with Netlify's proxy and redirect rules`),
|
|
337
|
+
)
|
|
338
|
+
.addHelpText(
|
|
339
|
+
'after',
|
|
340
|
+
generateExamplesHelp([
|
|
341
|
+
'netlify dev',
|
|
342
|
+
'netlify dev -d public',
|
|
343
|
+
'netlify dev -c "hugo server -w" --targetPort 1313',
|
|
344
|
+
]),
|
|
345
|
+
)
|
|
346
|
+
.action(dev)
|
|
347
|
+
)
|
|
348
|
+
}
|
|
349
|
+
module.exports = { createDevCommand }
|