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,47 @@
|
|
|
1
|
+
const { generateCommandsHelp, generateExamplesHelp } = require('../../utils')
|
|
2
|
+
|
|
3
|
+
const { createEnvGetCommand } = require('./env-get')
|
|
4
|
+
const { createEnvImportCommand } = require('./env-import')
|
|
5
|
+
const { createEnvListCommand } = require('./env-list')
|
|
6
|
+
const { createEnvSetCommand } = require('./env-set')
|
|
7
|
+
const { createEnvUnsetCommand } = require('./env-unset')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The env command
|
|
11
|
+
* @param {import('commander').OptionValues} options
|
|
12
|
+
* @param {import('../base-command').BaseCommand} command
|
|
13
|
+
*/
|
|
14
|
+
const env = (options, command) => {
|
|
15
|
+
command.help()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates the `netlify env` command
|
|
20
|
+
* @param {import('../base-command').BaseCommand} program
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
const createEnvCommand = (program) => {
|
|
24
|
+
createEnvGetCommand(program)
|
|
25
|
+
createEnvImportCommand(program)
|
|
26
|
+
createEnvListCommand(program)
|
|
27
|
+
createEnvSetCommand(program)
|
|
28
|
+
createEnvUnsetCommand(program)
|
|
29
|
+
|
|
30
|
+
return program
|
|
31
|
+
.command('env')
|
|
32
|
+
.description('(Beta) Control environment variables for the current site')
|
|
33
|
+
.addHelpText(
|
|
34
|
+
'after',
|
|
35
|
+
generateExamplesHelp([
|
|
36
|
+
'netlify env:list',
|
|
37
|
+
'netlify env:get VAR_NAME',
|
|
38
|
+
'netlify env:set VAR_NAME value',
|
|
39
|
+
'netlify env:unset VAR_NAME',
|
|
40
|
+
'netlify env:import fileName',
|
|
41
|
+
]),
|
|
42
|
+
)
|
|
43
|
+
.addHelpText('after', generateCommandsHelp('env', program))
|
|
44
|
+
.action(env)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
module.exports = { createEnvCommand }
|
|
@@ -1,25 +1,5 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const Command = require('../../utils/command')
|
|
3
|
-
const showHelp = require('../../utils/show-help')
|
|
1
|
+
const { createEnvCommand } = require('./env')
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const { args, flags } = this.parse(EnvCommand)
|
|
8
|
-
|
|
9
|
-
// Show help on empty sub command
|
|
10
|
-
if (isEmptyCommand(flags, args)) {
|
|
11
|
-
showHelp(this.id)
|
|
12
|
-
}
|
|
13
|
-
}
|
|
3
|
+
module.exports = {
|
|
4
|
+
createEnvCommand,
|
|
14
5
|
}
|
|
15
|
-
|
|
16
|
-
EnvCommand.description = `(Beta) Control environment variables for the current site`
|
|
17
|
-
EnvCommand.examples = [
|
|
18
|
-
'netlify env:list',
|
|
19
|
-
'netlify env:get VAR_NAME',
|
|
20
|
-
'netlify env:set VAR_NAME value',
|
|
21
|
-
'netlify env:unset VAR_NAME',
|
|
22
|
-
'netlify env:import fileName',
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
module.exports = EnvCommand
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
const { mkdir } = require('fs').promises
|
|
4
|
+
|
|
5
|
+
const { zipFunctions } = require('@netlify/zip-it-and-ship-it')
|
|
6
|
+
|
|
7
|
+
const { NETLIFYDEVERR, NETLIFYDEVLOG, exit, getFunctionsDir, log } = require('../../utils')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The functions:build command
|
|
11
|
+
* @param {import('commander').OptionValues} options
|
|
12
|
+
* @param {import('../base-command').BaseCommand} command
|
|
13
|
+
*/
|
|
14
|
+
const functionsBuild = async (options, command) => {
|
|
15
|
+
const { config } = command.netlify
|
|
16
|
+
|
|
17
|
+
const src = options.src || config.build.functionsSource
|
|
18
|
+
const dst = getFunctionsDir({ options, config })
|
|
19
|
+
|
|
20
|
+
if (src === dst) {
|
|
21
|
+
log(`${NETLIFYDEVERR} Source and destination for function build can't be the same`)
|
|
22
|
+
exit(1)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!src || !dst) {
|
|
26
|
+
if (!src)
|
|
27
|
+
log(
|
|
28
|
+
`${NETLIFYDEVERR} Error: You must specify a source folder with a --src flag or a functionsSource field in your config`,
|
|
29
|
+
)
|
|
30
|
+
if (!dst)
|
|
31
|
+
log(
|
|
32
|
+
`${NETLIFYDEVERR} Error: You must specify a destination functions folder with a --functions flag or a functions field in your config`,
|
|
33
|
+
)
|
|
34
|
+
exit(1)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
await mkdir(dst, { recursive: true })
|
|
38
|
+
|
|
39
|
+
log(`${NETLIFYDEVLOG} Building functions`)
|
|
40
|
+
// @ts-ignore Seems that the typings of zip it and ship it are not correct
|
|
41
|
+
zipFunctions(src, dst, { skipGo: true })
|
|
42
|
+
log(`${NETLIFYDEVLOG} Functions built to `, dst)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Creates the `netlify functions:build` command
|
|
47
|
+
* @param {import('../base-command').BaseCommand} program
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
const createFunctionsBuildCommand = (program) =>
|
|
51
|
+
program
|
|
52
|
+
.command('functions:build')
|
|
53
|
+
.alias('function:build')
|
|
54
|
+
.description('Build functions locally')
|
|
55
|
+
.option('-f, --function <directory>', 'Specify a functions directory to build to')
|
|
56
|
+
.option('-s, --src <directory>', 'Specify the source directory for the functions')
|
|
57
|
+
.action(functionsBuild)
|
|
58
|
+
|
|
59
|
+
module.exports = { createFunctionsBuildCommand }
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
const cp = require('child_process')
|
|
2
3
|
const fs = require('fs')
|
|
4
|
+
const { mkdir } = require('fs').promises
|
|
3
5
|
const path = require('path')
|
|
4
6
|
const process = require('process')
|
|
5
7
|
const { promisify } = require('util')
|
|
6
8
|
|
|
7
|
-
const { flags: flagsLib } = require('@oclif/command')
|
|
8
|
-
const chalk = require('chalk')
|
|
9
9
|
const copy = promisify(require('copy-template-dir'))
|
|
10
|
-
const execa = require('execa')
|
|
11
10
|
const findUp = require('find-up')
|
|
12
11
|
const fuzzy = require('fuzzy')
|
|
13
12
|
const inquirer = require('inquirer')
|
|
@@ -15,13 +14,20 @@ const inquirerAutocompletePrompt = require('inquirer-autocomplete-prompt')
|
|
|
15
14
|
const fetch = require('node-fetch')
|
|
16
15
|
const ora = require('ora')
|
|
17
16
|
|
|
18
|
-
const {
|
|
17
|
+
const {
|
|
18
|
+
NETLIFYDEVERR,
|
|
19
|
+
NETLIFYDEVLOG,
|
|
20
|
+
NETLIFYDEVWARN,
|
|
21
|
+
chalk,
|
|
22
|
+
error,
|
|
23
|
+
execa,
|
|
24
|
+
generateExamplesHelp,
|
|
25
|
+
injectEnvVariables,
|
|
26
|
+
log,
|
|
27
|
+
readRepoURL,
|
|
28
|
+
validateRepoURL,
|
|
29
|
+
} = require('../../utils')
|
|
19
30
|
const { getAddons, getCurrentAddon, getSiteData } = require('../../utils/addons/prepare')
|
|
20
|
-
const Command = require('../../utils/command')
|
|
21
|
-
const { error, log } = require('../../utils/command-helpers')
|
|
22
|
-
const { injectEnvVariables } = require('../../utils/dev')
|
|
23
|
-
const { NETLIFYDEVERR, NETLIFYDEVLOG, NETLIFYDEVWARN } = require('../../utils/logo')
|
|
24
|
-
const { readRepoURL, validateRepoURL } = require('../../utils/read-repo-url')
|
|
25
31
|
|
|
26
32
|
const templatesDir = path.resolve(__dirname, '../../functions-templates')
|
|
27
33
|
|
|
@@ -37,58 +43,22 @@ const languages = [
|
|
|
37
43
|
]
|
|
38
44
|
|
|
39
45
|
/**
|
|
40
|
-
*
|
|
46
|
+
* prompt for a name if name not supplied
|
|
47
|
+
* @param {string} argumentName
|
|
48
|
+
* @param {import('commander').OptionValues} options
|
|
49
|
+
* @param {string} [defaultName]
|
|
50
|
+
* @returns
|
|
41
51
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const functionsDir = await ensureFunctionDirExists(this)
|
|
47
|
-
|
|
48
|
-
/* either download from URL or scaffold from template */
|
|
49
|
-
const mainFunc = flags.url ? downloadFromURL : scaffoldFromTemplate
|
|
50
|
-
await mainFunc(this, flags, args, functionsDir)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
FunctionsCreateCommand.args = [
|
|
55
|
-
{
|
|
56
|
-
name: 'name',
|
|
57
|
-
description: 'name of your new function file inside your functions directory',
|
|
58
|
-
},
|
|
59
|
-
]
|
|
60
|
-
|
|
61
|
-
FunctionsCreateCommand.description = `Create a new function locally`
|
|
62
|
-
|
|
63
|
-
FunctionsCreateCommand.examples = [
|
|
64
|
-
'netlify functions:create',
|
|
65
|
-
'netlify functions:create hello-world',
|
|
66
|
-
'netlify functions:create --name hello-world',
|
|
67
|
-
]
|
|
68
|
-
FunctionsCreateCommand.aliases = ['function:create']
|
|
69
|
-
FunctionsCreateCommand.flags = {
|
|
70
|
-
name: flagsLib.string({ char: 'n', description: 'function name' }),
|
|
71
|
-
url: flagsLib.string({ char: 'u', description: 'pull template from URL' }),
|
|
72
|
-
language: flagsLib.string({ char: 'l', description: 'function language' }),
|
|
73
|
-
...FunctionsCreateCommand.flags,
|
|
74
|
-
}
|
|
75
|
-
module.exports = FunctionsCreateCommand
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* all subsections of code called from the main logic flow above
|
|
79
|
-
*/
|
|
80
|
-
|
|
81
|
-
// prompt for a name if name not supplied
|
|
82
|
-
const getNameFromArgs = async function (args, flags, defaultName) {
|
|
83
|
-
if (flags.name) {
|
|
84
|
-
if (args.name) {
|
|
52
|
+
const getNameFromArgs = async function (argumentName, options, defaultName) {
|
|
53
|
+
if (options.name) {
|
|
54
|
+
if (argumentName) {
|
|
85
55
|
throw new Error('function name specified in both flag and arg format, pick one')
|
|
86
56
|
}
|
|
87
|
-
return
|
|
57
|
+
return options.name
|
|
88
58
|
}
|
|
89
59
|
|
|
90
|
-
if (
|
|
91
|
-
return
|
|
60
|
+
if (argumentName) {
|
|
61
|
+
return argumentName
|
|
92
62
|
}
|
|
93
63
|
|
|
94
64
|
const { name } = await inquirer.prompt([
|
|
@@ -155,7 +125,10 @@ const formatRegistryArrayForInquirer = function (lang) {
|
|
|
155
125
|
return registry
|
|
156
126
|
}
|
|
157
127
|
|
|
158
|
-
|
|
128
|
+
/**
|
|
129
|
+
* pick template from our existing templates
|
|
130
|
+
* @param {import('commander').OptionValues} config
|
|
131
|
+
*/
|
|
159
132
|
const pickTemplate = async function ({ language: languageFromFlag }) {
|
|
160
133
|
const specialCommands = [
|
|
161
134
|
new inquirer.Separator(),
|
|
@@ -218,11 +191,11 @@ const DEFAULT_PRIORITY = 999
|
|
|
218
191
|
|
|
219
192
|
/**
|
|
220
193
|
* Get functions directory (and make it if necessary)
|
|
221
|
-
* @param {
|
|
222
|
-
* @returns {string
|
|
194
|
+
* @param {import('../base-command').BaseCommand} command
|
|
195
|
+
* @returns {Promise<string|never>} - functions directory or throws an error
|
|
223
196
|
*/
|
|
224
|
-
const ensureFunctionDirExists = async function (
|
|
225
|
-
const { api, config, site } =
|
|
197
|
+
const ensureFunctionDirExists = async function (command) {
|
|
198
|
+
const { api, config, site } = command.netlify
|
|
226
199
|
const siteId = site.id
|
|
227
200
|
let functionsDirHolder = config.functionsDirectory
|
|
228
201
|
|
|
@@ -248,6 +221,7 @@ const ensureFunctionDirExists = async function (context) {
|
|
|
248
221
|
try {
|
|
249
222
|
log(`${NETLIFYDEVLOG} updating site settings with ${chalk.magenta.inverse(functionsDirHolder)}`)
|
|
250
223
|
|
|
224
|
+
// @ts-ignore Typings of API are not correct
|
|
251
225
|
await api.updateSite({
|
|
252
226
|
siteId: site.id,
|
|
253
227
|
body: {
|
|
@@ -278,11 +252,17 @@ const ensureFunctionDirExists = async function (context) {
|
|
|
278
252
|
return functionsDirHolder
|
|
279
253
|
}
|
|
280
254
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
255
|
+
/**
|
|
256
|
+
* Download files from a given github URL
|
|
257
|
+
* @param {import('../base-command').BaseCommand} command
|
|
258
|
+
* @param {import('commander').OptionValues} options
|
|
259
|
+
* @param {string} argumentName
|
|
260
|
+
* @param {string} functionsDir
|
|
261
|
+
*/
|
|
262
|
+
const downloadFromURL = async function (command, options, argumentName, functionsDir) {
|
|
263
|
+
const folderContents = await readRepoURL(options.url)
|
|
264
|
+
const [functionName] = options.url.split('/').slice(-1)
|
|
265
|
+
const nameToUse = await getNameFromArgs(argumentName, options, functionName)
|
|
286
266
|
|
|
287
267
|
const fnFolder = path.join(functionsDir, nameToUse)
|
|
288
268
|
if (fs.existsSync(`${fnFolder}.js`) && fs.lstatSync(`${fnFolder}.js`).isFile()) {
|
|
@@ -293,7 +273,7 @@ const downloadFromURL = async function (context, flags, args, functionsDir) {
|
|
|
293
273
|
}
|
|
294
274
|
|
|
295
275
|
try {
|
|
296
|
-
|
|
276
|
+
await mkdir(fnFolder, { recursive: true })
|
|
297
277
|
} catch {
|
|
298
278
|
// Ignore
|
|
299
279
|
}
|
|
@@ -321,8 +301,8 @@ const downloadFromURL = async function (context, flags, args, functionsDir) {
|
|
|
321
301
|
// eslint-disable-next-line node/global-require, import/no-dynamic-require
|
|
322
302
|
const { onComplete, addons = [] } = require(fnTemplateFile)
|
|
323
303
|
|
|
324
|
-
await installAddons(
|
|
325
|
-
await handleOnComplete({
|
|
304
|
+
await installAddons(command, addons, path.resolve(fnFolder))
|
|
305
|
+
await handleOnComplete({ command, onComplete })
|
|
326
306
|
// delete
|
|
327
307
|
fs.unlinkSync(fnTemplateFile)
|
|
328
308
|
}
|
|
@@ -385,10 +365,16 @@ const installDeps = async ({ functionPackageJson, functionPath, functionsDir })
|
|
|
385
365
|
}
|
|
386
366
|
}
|
|
387
367
|
|
|
388
|
-
|
|
389
|
-
|
|
368
|
+
/**
|
|
369
|
+
* no --url flag specified, pick from a provided template
|
|
370
|
+
* @param {import('../base-command').BaseCommand} command
|
|
371
|
+
* @param {import('commander').OptionValues} options
|
|
372
|
+
* @param {string} argumentName
|
|
373
|
+
* @param {string} functionsDir
|
|
374
|
+
*/
|
|
375
|
+
const scaffoldFromTemplate = async function (command, options, argumentName, functionsDir) {
|
|
390
376
|
// pull the rest of the metadata from the template
|
|
391
|
-
const chosenTemplate = await pickTemplate(
|
|
377
|
+
const chosenTemplate = await pickTemplate(options)
|
|
392
378
|
if (chosenTemplate === 'url') {
|
|
393
379
|
const { chosenUrl } = await inquirer.prompt([
|
|
394
380
|
{
|
|
@@ -400,11 +386,11 @@ const scaffoldFromTemplate = async function (context, flags, args, functionsDir)
|
|
|
400
386
|
// this has some nuance i have ignored, eg crossenv and i18n concerns
|
|
401
387
|
},
|
|
402
388
|
])
|
|
403
|
-
|
|
389
|
+
options.url = chosenUrl.trim()
|
|
404
390
|
try {
|
|
405
|
-
await downloadFromURL(
|
|
391
|
+
await downloadFromURL(command, options, argumentName, functionsDir)
|
|
406
392
|
} catch (error_) {
|
|
407
|
-
error(`$${NETLIFYDEVERR} Error downloading from URL: ${
|
|
393
|
+
error(`$${NETLIFYDEVERR} Error downloading from URL: ${options.url}`)
|
|
408
394
|
error(error_)
|
|
409
395
|
process.exit(1)
|
|
410
396
|
}
|
|
@@ -420,7 +406,7 @@ const scaffoldFromTemplate = async function (context, flags, args, functionsDir)
|
|
|
420
406
|
)
|
|
421
407
|
}
|
|
422
408
|
|
|
423
|
-
const name = await getNameFromArgs(
|
|
409
|
+
const name = await getNameFromArgs(argumentName, options, templateName)
|
|
424
410
|
|
|
425
411
|
log(`${NETLIFYDEVLOG} Creating function ${chalk.cyan.inverse(name)}`)
|
|
426
412
|
const functionPath = ensureFunctionPathIsOk(functionsDir, name)
|
|
@@ -436,7 +422,7 @@ const scaffoldFromTemplate = async function (context, flags, args, functionsDir)
|
|
|
436
422
|
const filename = path.basename(filePath)
|
|
437
423
|
|
|
438
424
|
if (!omittedFromOutput.has(filename)) {
|
|
439
|
-
|
|
425
|
+
log(`${NETLIFYDEVLOG} ${chalk.greenBright('Created')} ${filePath}`)
|
|
440
426
|
}
|
|
441
427
|
|
|
442
428
|
fs.chmodSync(path.resolve(filePath), TEMPLATE_PERMISSIONS)
|
|
@@ -458,8 +444,8 @@ const scaffoldFromTemplate = async function (context, flags, args, functionsDir)
|
|
|
458
444
|
spinner.succeed(`Installed dependencies for ${name}`)
|
|
459
445
|
}
|
|
460
446
|
|
|
461
|
-
await installAddons(
|
|
462
|
-
await handleOnComplete({
|
|
447
|
+
await installAddons(command, addons, path.resolve(functionPath))
|
|
448
|
+
await handleOnComplete({ command, onComplete })
|
|
463
449
|
}
|
|
464
450
|
}
|
|
465
451
|
|
|
@@ -484,20 +470,27 @@ const createFunctionAddon = async function ({ addonName, addons, api, siteData,
|
|
|
484
470
|
}
|
|
485
471
|
}
|
|
486
472
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
const handleOnComplete = async ({
|
|
473
|
+
/**
|
|
474
|
+
*
|
|
475
|
+
* @param {object} config
|
|
476
|
+
* @param {import('../base-command').BaseCommand} config.command
|
|
477
|
+
* @param {(command: import('../base-command').BaseCommand) => any} config.onComplete
|
|
478
|
+
*/
|
|
479
|
+
const handleOnComplete = async ({ command, onComplete }) => {
|
|
494
480
|
if (onComplete) {
|
|
495
|
-
await
|
|
496
|
-
await onComplete.call(
|
|
481
|
+
await injectEnvVariables({ env: command.netlify.cachedConfig.env, site: command.netlify.site })
|
|
482
|
+
await onComplete.call(command)
|
|
497
483
|
}
|
|
498
484
|
}
|
|
499
|
-
|
|
500
|
-
|
|
485
|
+
/**
|
|
486
|
+
*
|
|
487
|
+
* @param {object} config
|
|
488
|
+
* @param {*} config.addonCreated
|
|
489
|
+
* @param {*} config.addonDidInstall
|
|
490
|
+
* @param {import('../base-command').BaseCommand} config.command
|
|
491
|
+
* @param {string} config.fnPath
|
|
492
|
+
*/
|
|
493
|
+
const handleAddonDidInstall = async ({ addonCreated, addonDidInstall, command, fnPath }) => {
|
|
501
494
|
if (!addonCreated || !addonDidInstall) {
|
|
502
495
|
return
|
|
503
496
|
}
|
|
@@ -515,16 +508,23 @@ const handleAddonDidInstall = async ({ addonCreated, addonDidInstall, context, f
|
|
|
515
508
|
return
|
|
516
509
|
}
|
|
517
510
|
|
|
518
|
-
await
|
|
511
|
+
await injectEnvVariables({ env: command.netlify.cachedConfig.env, site: command.netlify.site })
|
|
519
512
|
addonDidInstall(fnPath)
|
|
520
513
|
}
|
|
521
514
|
|
|
522
|
-
|
|
515
|
+
/**
|
|
516
|
+
*
|
|
517
|
+
* @param {import('../base-command').BaseCommand} command
|
|
518
|
+
* @param {*} functionAddons
|
|
519
|
+
* @param {*} fnPath
|
|
520
|
+
* @returns
|
|
521
|
+
*/
|
|
522
|
+
const installAddons = async function (command, functionAddons, fnPath) {
|
|
523
523
|
if (functionAddons.length === 0) {
|
|
524
524
|
return
|
|
525
525
|
}
|
|
526
526
|
|
|
527
|
-
const { api, site } =
|
|
527
|
+
const { api, site } = command.netlify
|
|
528
528
|
const siteId = site.id
|
|
529
529
|
if (!siteId) {
|
|
530
530
|
log('No site id found, please run inside a site directory or `netlify link`')
|
|
@@ -545,7 +545,7 @@ const installAddons = async function (context, functionAddons, fnPath) {
|
|
|
545
545
|
siteData,
|
|
546
546
|
})
|
|
547
547
|
|
|
548
|
-
await handleAddonDidInstall({ addonCreated, addonDidInstall,
|
|
548
|
+
await handleAddonDidInstall({ addonCreated, addonDidInstall, command, fnPath })
|
|
549
549
|
} catch (error_) {
|
|
550
550
|
error(`${NETLIFYDEVERR} Error installing addon: `, error_)
|
|
551
551
|
}
|
|
@@ -563,3 +563,42 @@ const ensureFunctionPathIsOk = function (functionsDir, name) {
|
|
|
563
563
|
}
|
|
564
564
|
return functionPath
|
|
565
565
|
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* The functions:create command
|
|
569
|
+
* @param {import('commander').OptionValues} options
|
|
570
|
+
* @param {import('../base-command').BaseCommand} command
|
|
571
|
+
*/
|
|
572
|
+
const functionsCreate = async (name, options, command) => {
|
|
573
|
+
const functionsDir = await ensureFunctionDirExists(command)
|
|
574
|
+
|
|
575
|
+
/* either download from URL or scaffold from template */
|
|
576
|
+
const mainFunc = options.url ? downloadFromURL : scaffoldFromTemplate
|
|
577
|
+
await mainFunc(command, options, name, functionsDir)
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Creates the `netlify functions:create` command
|
|
582
|
+
* @param {import('../base-command').BaseCommand} program
|
|
583
|
+
* @returns
|
|
584
|
+
*/
|
|
585
|
+
const createFunctionsCreateCommand = (program) =>
|
|
586
|
+
program
|
|
587
|
+
.command('functions:create')
|
|
588
|
+
.alias('function:create')
|
|
589
|
+
.argument('[name]', 'name of your new function file inside your functions directory')
|
|
590
|
+
.description('Create a new function locally')
|
|
591
|
+
.option('-n, --name <name>', 'function name')
|
|
592
|
+
.option('-u, --url <url>', 'pull template from URL')
|
|
593
|
+
.option('-l, --language <lang>', 'function language')
|
|
594
|
+
.addHelpText(
|
|
595
|
+
'after',
|
|
596
|
+
generateExamplesHelp([
|
|
597
|
+
'netlify functions:create',
|
|
598
|
+
'netlify functions:create hello-world',
|
|
599
|
+
'netlify functions:create --name hello-world',
|
|
600
|
+
]),
|
|
601
|
+
)
|
|
602
|
+
.action(functionsCreate)
|
|
603
|
+
|
|
604
|
+
module.exports = { createFunctionsCreateCommand }
|