netlify-cli 8.1.0 → 8.1.5
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/README.md +12 -13
- package/bin/run +38 -2
- package/npm-shrinkwrap.json +1256 -4181
- package/package.json +15 -39
- package/scripts/postinstall.js +13 -0
- 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 +131 -0
- package/src/commands/addons/addons-delete.js +60 -0
- package/src/commands/addons/addons-list.js +62 -0
- package/src/commands/addons/addons.js +44 -0
- package/src/commands/addons/index.js +3 -24
- package/src/commands/api/api.js +75 -0
- package/src/commands/api/index.js +5 -0
- package/src/commands/base-command.js +502 -0
- package/src/commands/build/build.js +58 -0
- package/src/commands/build/index.js +3 -61
- package/src/commands/completion/completion.js +56 -0
- package/src/commands/completion/index.js +5 -0
- package/src/commands/{deploy.js → deploy/deploy.js} +295 -275
- package/src/commands/deploy/index.js +5 -0
- package/src/commands/dev/dev-exec.js +35 -0
- package/src/commands/dev/dev-trace.js +47 -0
- package/src/commands/dev/dev.js +340 -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 +42 -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} +130 -94
- package/src/commands/functions/functions-invoke.js +273 -0
- package/src/commands/functions/functions-list.js +106 -0
- package/src/commands/functions/functions-serve.js +63 -0
- package/src/commands/functions/functions.js +47 -0
- package/src/commands/functions/index.js +3 -45
- package/src/commands/index.js +7 -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} +141 -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 +33 -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 +34 -0
- package/src/commands/login/index.js +6 -0
- package/src/commands/login/login.js +55 -0
- package/src/commands/logout/index.js +5 -0
- package/src/commands/logout/logout.js +43 -0
- package/src/commands/main.js +206 -0
- package/src/commands/open/index.js +3 -39
- package/src/commands/open/open-admin.js +60 -0
- package/src/commands/open/open-site.js +53 -0
- package/src/commands/open/open.js +40 -0
- package/src/commands/sites/index.js +5 -20
- package/src/commands/sites/sites-create.js +187 -0
- package/src/commands/sites/sites-delete.js +104 -0
- package/src/commands/sites/sites-list.js +90 -0
- package/src/commands/sites/sites.js +32 -0
- package/src/commands/status/index.js +3 -118
- package/src/commands/status/status-hooks.js +69 -0
- package/src/commands/status/status.js +124 -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 +131 -0
- package/src/functions-templates/javascript/stripe-charge/package-lock.json +13 -13
- package/src/functions-templates/javascript/stripe-subscription/package-lock.json +13 -13
- package/src/functions-templates/rust/hello-world/Cargo.toml +1 -1
- package/src/functions-templates/typescript/hello-world/package-lock.json +6 -6
- package/src/lib/build.js +21 -7
- package/src/lib/completion/constants.js +6 -0
- package/src/lib/completion/generate-autocompletion.js +36 -0
- package/src/lib/completion/index.js +5 -0
- package/src/lib/completion/script.js +72 -0
- 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/settings.js +16 -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 +136 -42
- 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 +8 -1
- package/src/utils/gh-auth.js +1 -0
- package/src/utils/gitignore.js +7 -5
- 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/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 +6 -5
- package/src/utils/read-repo-url.js +1 -0
- package/src/utils/redirects.js +2 -2
- package/src/utils/rules-proxy.js +2 -1
- 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/header.js +0 -18
- package/src/utils/logo.js +0 -11
- package/src/utils/show-help.js +0 -5
- package/src/utils/telemetry/tracked-command.js +0 -51
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
const Command = require('../../utils/command')
|
|
2
|
-
const { log, logJson } = require('../../utils/command-helpers')
|
|
3
|
-
|
|
4
|
-
class EnvUnsetCommand extends Command {
|
|
5
|
-
async run() {
|
|
6
|
-
const { args, flags } = this.parse(EnvUnsetCommand)
|
|
7
|
-
const { api, site } = this.netlify
|
|
8
|
-
const siteId = site.id
|
|
9
|
-
const { name } = args
|
|
10
|
-
|
|
11
|
-
if (!siteId) {
|
|
12
|
-
log('No site id found, please run inside a site folder or `netlify link`')
|
|
13
|
-
return false
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const siteData = await api.getSite({ siteId })
|
|
17
|
-
|
|
18
|
-
// Get current environment variables set in the UI
|
|
19
|
-
const {
|
|
20
|
-
build_settings: { env = {} },
|
|
21
|
-
} = siteData
|
|
22
|
-
|
|
23
|
-
const newEnv = env
|
|
24
|
-
|
|
25
|
-
// Delete environment variable from current variables
|
|
26
|
-
delete newEnv[args.name]
|
|
27
|
-
|
|
28
|
-
// Apply environment variable updates
|
|
29
|
-
const siteResult = await api.updateSite({
|
|
30
|
-
siteId,
|
|
31
|
-
body: {
|
|
32
|
-
build_settings: {
|
|
33
|
-
env: newEnv,
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
// Return new environment variables of site if using json flag
|
|
39
|
-
if (flags.json) {
|
|
40
|
-
logJson(siteResult.build_settings.env)
|
|
41
|
-
return false
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
log(`Unset environment variable ${name} for site ${siteData.name}`)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
EnvUnsetCommand.description = `Unset an environment variable which removes it from the UI`
|
|
49
|
-
EnvUnsetCommand.aliases = ['env:delete', 'env:remove']
|
|
50
|
-
EnvUnsetCommand.args = [
|
|
51
|
-
{
|
|
52
|
-
name: 'name',
|
|
53
|
-
required: true,
|
|
54
|
-
description: 'Environment variable name',
|
|
55
|
-
},
|
|
56
|
-
]
|
|
57
|
-
|
|
58
|
-
module.exports = EnvUnsetCommand
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
|
|
3
|
-
const { zipFunctions } = require('@netlify/zip-it-and-ship-it')
|
|
4
|
-
const { flags: flagsLib } = require('@oclif/command')
|
|
5
|
-
|
|
6
|
-
const Command = require('../../utils/command')
|
|
7
|
-
const { exit, log } = require('../../utils/command-helpers')
|
|
8
|
-
const { getFunctionsDir } = require('../../utils/functions')
|
|
9
|
-
const { NETLIFYDEVERR, NETLIFYDEVLOG } = require('../../utils/logo')
|
|
10
|
-
|
|
11
|
-
class FunctionsBuildCommand extends Command {
|
|
12
|
-
run() {
|
|
13
|
-
const { flags } = this.parse(FunctionsBuildCommand)
|
|
14
|
-
|
|
15
|
-
const { config } = this.netlify
|
|
16
|
-
|
|
17
|
-
const src = flags.src || config.build.functionsSource
|
|
18
|
-
const dst = getFunctionsDir({ flags, 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
|
-
fs.mkdirSync(dst, { recursive: true })
|
|
38
|
-
|
|
39
|
-
log(`${NETLIFYDEVLOG} Building functions`)
|
|
40
|
-
zipFunctions(src, dst, { skipGo: true })
|
|
41
|
-
log(`${NETLIFYDEVLOG} Functions built to `, dst)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
FunctionsBuildCommand.description = `Build functions locally
|
|
46
|
-
`
|
|
47
|
-
FunctionsBuildCommand.aliases = ['function:build']
|
|
48
|
-
FunctionsBuildCommand.flags = {
|
|
49
|
-
functions: flagsLib.string({
|
|
50
|
-
char: 'f',
|
|
51
|
-
description: 'Specify a functions directory to build to',
|
|
52
|
-
}),
|
|
53
|
-
src: flagsLib.string({
|
|
54
|
-
char: 's',
|
|
55
|
-
description: 'Specify the source directory for the functions',
|
|
56
|
-
}),
|
|
57
|
-
...FunctionsBuildCommand.flags,
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
module.exports = FunctionsBuildCommand
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const process = require('process')
|
|
4
|
-
|
|
5
|
-
const { flags: flagsLib } = require('@oclif/command')
|
|
6
|
-
const chalk = require('chalk')
|
|
7
|
-
const inquirer = require('inquirer')
|
|
8
|
-
const fetch = require('node-fetch')
|
|
9
|
-
|
|
10
|
-
const Command = require('../../utils/command')
|
|
11
|
-
const { error } = require('../../utils/command-helpers')
|
|
12
|
-
const { BACKGROUND, getFunctions } = require('../../utils/get-functions')
|
|
13
|
-
const { NETLIFYDEVWARN } = require('../../utils/logo')
|
|
14
|
-
|
|
15
|
-
// https://www.netlify.com/docs/functions/#event-triggered-functions
|
|
16
|
-
const events = [
|
|
17
|
-
'deploy-building',
|
|
18
|
-
'deploy-succeeded',
|
|
19
|
-
'deploy-failed',
|
|
20
|
-
'deploy-locked',
|
|
21
|
-
'deploy-unlocked',
|
|
22
|
-
'split-test-activated',
|
|
23
|
-
'split-test-deactivated',
|
|
24
|
-
'split-test-modified',
|
|
25
|
-
'submission-created',
|
|
26
|
-
'identity-validate',
|
|
27
|
-
'identity-signup',
|
|
28
|
-
'identity-login',
|
|
29
|
-
]
|
|
30
|
-
const eventTriggeredFunctions = new Set([...events, ...events.map((name) => `${name}${BACKGROUND}`)])
|
|
31
|
-
|
|
32
|
-
const DEFAULT_PORT = 8888
|
|
33
|
-
|
|
34
|
-
class FunctionsInvokeCommand extends Command {
|
|
35
|
-
async run() {
|
|
36
|
-
const { args, flags } = this.parse(FunctionsInvokeCommand)
|
|
37
|
-
|
|
38
|
-
const { config } = this.netlify
|
|
39
|
-
|
|
40
|
-
const functionsDir = flags.functions || (config.dev && config.dev.functions) || config.functionsDirectory
|
|
41
|
-
if (typeof functionsDir === 'undefined') {
|
|
42
|
-
error('functions directory is undefined, did you forget to set it in netlify.toml?')
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!flags.port)
|
|
46
|
-
console.warn(
|
|
47
|
-
`${NETLIFYDEVWARN} "port" flag was not specified. Attempting to connect to localhost:8888 by default`,
|
|
48
|
-
)
|
|
49
|
-
const port = flags.port || DEFAULT_PORT
|
|
50
|
-
|
|
51
|
-
const functions = await getFunctions(functionsDir)
|
|
52
|
-
const functionToTrigger = await getNameFromArgs(functions, args, flags)
|
|
53
|
-
|
|
54
|
-
let headers = {}
|
|
55
|
-
let body = {}
|
|
56
|
-
|
|
57
|
-
if (eventTriggeredFunctions.has(functionToTrigger)) {
|
|
58
|
-
/** handle event triggered fns */
|
|
59
|
-
// https://www.netlify.com/docs/functions/#event-triggered-functions
|
|
60
|
-
const [name, event] = functionToTrigger.split('-')
|
|
61
|
-
if (name === 'identity') {
|
|
62
|
-
// https://www.netlify.com/docs/functions/#identity-event-functions
|
|
63
|
-
body.event = event
|
|
64
|
-
body.user = {
|
|
65
|
-
id: '1111a1a1-a11a-1111-aa11-aaa11111a11a',
|
|
66
|
-
aud: '',
|
|
67
|
-
role: '',
|
|
68
|
-
email: 'foo@trust-this-company.com',
|
|
69
|
-
app_metadata: {
|
|
70
|
-
provider: 'email',
|
|
71
|
-
},
|
|
72
|
-
user_metadata: {
|
|
73
|
-
full_name: 'Test Person',
|
|
74
|
-
},
|
|
75
|
-
created_at: new Date(Date.now()).toISOString(),
|
|
76
|
-
update_at: new Date(Date.now()).toISOString(),
|
|
77
|
-
}
|
|
78
|
-
} else {
|
|
79
|
-
// non identity functions seem to have a different shape
|
|
80
|
-
// https://www.netlify.com/docs/functions/#event-function-payloads
|
|
81
|
-
body.payload = {
|
|
82
|
-
TODO: 'mock up payload data better',
|
|
83
|
-
}
|
|
84
|
-
body.site = {
|
|
85
|
-
TODO: 'mock up site data better',
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
} else {
|
|
89
|
-
// NOT an event triggered function, but may still want to simulate authentication locally
|
|
90
|
-
let isAuthenticated = false
|
|
91
|
-
if (typeof flags.identity === 'undefined') {
|
|
92
|
-
const { isAuthed } = await inquirer.prompt([
|
|
93
|
-
{
|
|
94
|
-
type: 'confirm',
|
|
95
|
-
name: 'isAuthed',
|
|
96
|
-
message: `Invoke with emulated Netlify Identity authentication headers? (pass --identity/--no-identity to override)`,
|
|
97
|
-
default: true,
|
|
98
|
-
},
|
|
99
|
-
])
|
|
100
|
-
isAuthenticated = isAuthed
|
|
101
|
-
} else {
|
|
102
|
-
isAuthenticated = flags.identity
|
|
103
|
-
}
|
|
104
|
-
if (isAuthenticated) {
|
|
105
|
-
headers = {
|
|
106
|
-
authorization:
|
|
107
|
-
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb3VyY2UiOiJuZXRsaWZ5IGZ1bmN0aW9uczp0cmlnZ2VyIiwidGVzdERhdGEiOiJORVRMSUZZX0RFVl9MT0NBTExZX0VNVUxBVEVEX0pXVCJ9.Xb6vOFrfLUZmyUkXBbCvU4bM7q8tPilF0F03Wupap_c',
|
|
108
|
-
}
|
|
109
|
-
// you can decode this https://jwt.io/
|
|
110
|
-
// {
|
|
111
|
-
// "source": "netlify functions:trigger",
|
|
112
|
-
// "testData": "NETLIFY_DEV_LOCALLY_EMULATED_JWT"
|
|
113
|
-
// }
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const payload = processPayloadFromFlag(flags.payload)
|
|
117
|
-
body = { ...body, ...payload }
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
const response = await fetch(
|
|
121
|
-
`http://localhost:${port}/.netlify/functions/${functionToTrigger}${formatQstring(flags.querystring)}`,
|
|
122
|
-
{
|
|
123
|
-
method: 'post',
|
|
124
|
-
headers,
|
|
125
|
-
body: JSON.stringify(body),
|
|
126
|
-
},
|
|
127
|
-
)
|
|
128
|
-
const data = await response.text()
|
|
129
|
-
console.log(data)
|
|
130
|
-
} catch (error_) {
|
|
131
|
-
error(`Ran into an error invoking your function: ${error_.message}`)
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const formatQstring = function (querystring) {
|
|
137
|
-
if (querystring) {
|
|
138
|
-
return `?${querystring}`
|
|
139
|
-
}
|
|
140
|
-
return ''
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/** process payloads from flag */
|
|
144
|
-
const processPayloadFromFlag = function (payloadString) {
|
|
145
|
-
if (payloadString) {
|
|
146
|
-
// case 1: jsonstring
|
|
147
|
-
let payload = tryParseJSON(payloadString)
|
|
148
|
-
if (payload) return payload
|
|
149
|
-
// case 2: jsonpath
|
|
150
|
-
const payloadpath = path.join(process.cwd(), payloadString)
|
|
151
|
-
const pathexists = fs.existsSync(payloadpath)
|
|
152
|
-
if (pathexists) {
|
|
153
|
-
try {
|
|
154
|
-
// there is code execution potential here
|
|
155
|
-
// eslint-disable-next-line node/global-require, import/no-dynamic-require
|
|
156
|
-
payload = require(payloadpath)
|
|
157
|
-
return payload
|
|
158
|
-
} catch (error_) {
|
|
159
|
-
console.error(error_)
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
// case 3: invalid string, invalid path
|
|
163
|
-
return false
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// prompt for a name if name not supplied
|
|
168
|
-
// also used in functions:create
|
|
169
|
-
const getNameFromArgs = async function (functions, args, flags) {
|
|
170
|
-
const functionToTrigger = getFunctionToTrigger(args, flags)
|
|
171
|
-
const functionNames = functions.map(getFunctionName)
|
|
172
|
-
|
|
173
|
-
if (functionToTrigger) {
|
|
174
|
-
if (functionNames.includes(functionToTrigger)) {
|
|
175
|
-
return functionToTrigger
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
console.warn(
|
|
179
|
-
`Function name ${chalk.yellow(
|
|
180
|
-
functionToTrigger,
|
|
181
|
-
)} supplied but no matching function found in your functions folder, forcing you to pick a valid one...`,
|
|
182
|
-
)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const { trigger } = await inquirer.prompt([
|
|
186
|
-
{
|
|
187
|
-
type: 'list',
|
|
188
|
-
message: 'Pick a function to trigger',
|
|
189
|
-
name: 'trigger',
|
|
190
|
-
choices: functionNames,
|
|
191
|
-
},
|
|
192
|
-
])
|
|
193
|
-
return trigger
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const getFunctionToTrigger = function (args, flags) {
|
|
197
|
-
if (flags.name) {
|
|
198
|
-
if (args.name) {
|
|
199
|
-
console.error('function name specified in both flag and arg format, pick one')
|
|
200
|
-
process.exit(1)
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return flags.name
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return args.name
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const getFunctionName = function ({ name }) {
|
|
210
|
-
return name
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
FunctionsInvokeCommand.description = `Trigger a function while in netlify dev with simulated data, good for testing function calls including Netlify's Event Triggered Functions`
|
|
214
|
-
FunctionsInvokeCommand.aliases = ['function:trigger']
|
|
215
|
-
|
|
216
|
-
FunctionsInvokeCommand.examples = [
|
|
217
|
-
'$ netlify functions:invoke',
|
|
218
|
-
'$ netlify functions:invoke myfunction',
|
|
219
|
-
'$ netlify functions:invoke --name myfunction',
|
|
220
|
-
'$ netlify functions:invoke --name myfunction --identity',
|
|
221
|
-
'$ netlify functions:invoke --name myfunction --no-identity',
|
|
222
|
-
`$ netlify functions:invoke myfunction --payload '{"foo": 1}'`,
|
|
223
|
-
'$ netlify functions:invoke myfunction --querystring "foo=1',
|
|
224
|
-
'$ netlify functions:invoke myfunction --payload "./pathTo.json"',
|
|
225
|
-
]
|
|
226
|
-
FunctionsInvokeCommand.args = [
|
|
227
|
-
{
|
|
228
|
-
name: 'name',
|
|
229
|
-
description: 'function name to invoke',
|
|
230
|
-
},
|
|
231
|
-
]
|
|
232
|
-
|
|
233
|
-
FunctionsInvokeCommand.flags = {
|
|
234
|
-
name: flagsLib.string({
|
|
235
|
-
char: 'n',
|
|
236
|
-
description: 'function name to invoke',
|
|
237
|
-
}),
|
|
238
|
-
functions: flagsLib.string({
|
|
239
|
-
char: 'f',
|
|
240
|
-
description: 'Specify a functions folder to parse, overriding netlify.toml',
|
|
241
|
-
}),
|
|
242
|
-
querystring: flagsLib.string({
|
|
243
|
-
char: 'q',
|
|
244
|
-
description: 'Querystring to add to your function invocation',
|
|
245
|
-
}),
|
|
246
|
-
payload: flagsLib.string({
|
|
247
|
-
char: 'p',
|
|
248
|
-
description: 'Supply POST payload in stringified json, or a path to a json file',
|
|
249
|
-
}),
|
|
250
|
-
identity: flagsLib.boolean({
|
|
251
|
-
description: 'simulate Netlify Identity authentication JWT. pass --no-identity to affirm unauthenticated request',
|
|
252
|
-
allowNo: true,
|
|
253
|
-
}),
|
|
254
|
-
port: flagsLib.integer({
|
|
255
|
-
description: 'Port where netlify dev is accessible. e.g. 8888',
|
|
256
|
-
}),
|
|
257
|
-
...FunctionsInvokeCommand.flags,
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
module.exports = FunctionsInvokeCommand
|
|
261
|
-
|
|
262
|
-
// https://stackoverflow.com/questions/3710204/how-to-check-if-a-string-is-a-valid-json-string-in-javascript-without-using-try
|
|
263
|
-
const tryParseJSON = function (jsonString) {
|
|
264
|
-
try {
|
|
265
|
-
const parsedValue = JSON.parse(jsonString)
|
|
266
|
-
|
|
267
|
-
// Handle non-exception-throwing cases:
|
|
268
|
-
// Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
|
|
269
|
-
// but... JSON.parse(null) returns null, and typeof null === "object",
|
|
270
|
-
// so we must check for that, too. Thankfully, null is falsey, so this suffices:
|
|
271
|
-
if (parsedValue && typeof parsedValue === 'object') {
|
|
272
|
-
return parsedValue
|
|
273
|
-
}
|
|
274
|
-
} catch {}
|
|
275
|
-
|
|
276
|
-
return false
|
|
277
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
const process = require('process')
|
|
2
|
-
|
|
3
|
-
const { flags: flagsLib } = require('@oclif/command')
|
|
4
|
-
const AsciiTable = require('ascii-table')
|
|
5
|
-
|
|
6
|
-
const Command = require('../../utils/command')
|
|
7
|
-
const { error, exit, log, logJson, warn } = require('../../utils/command-helpers')
|
|
8
|
-
const { getFunctionsDir } = require('../../utils/functions')
|
|
9
|
-
const { getFunctions } = require('../../utils/get-functions')
|
|
10
|
-
|
|
11
|
-
class FunctionsListCommand extends Command {
|
|
12
|
-
async run() {
|
|
13
|
-
const { flags } = this.parse(FunctionsListCommand)
|
|
14
|
-
|
|
15
|
-
const { api, config, site } = this.netlify
|
|
16
|
-
|
|
17
|
-
// get deployed site details
|
|
18
|
-
// copied from `netlify status`
|
|
19
|
-
const siteId = site.id
|
|
20
|
-
if (!siteId) {
|
|
21
|
-
warn('Did you run `netlify link` yet?')
|
|
22
|
-
error(`You don't appear to be in a folder that is linked to a site`)
|
|
23
|
-
}
|
|
24
|
-
let siteData
|
|
25
|
-
try {
|
|
26
|
-
siteData = await api.getSite({ siteId })
|
|
27
|
-
} catch (error_) {
|
|
28
|
-
// unauthorized
|
|
29
|
-
if (error_.status === 401) {
|
|
30
|
-
warn(`Log in with a different account or re-link to a site you have permission for`)
|
|
31
|
-
error(`Not authorized to view the currently linked site (${siteId})`)
|
|
32
|
-
}
|
|
33
|
-
// missing
|
|
34
|
-
if (error_.status === 404) {
|
|
35
|
-
error(`The site this folder is linked to can't be found`)
|
|
36
|
-
}
|
|
37
|
-
error(error_)
|
|
38
|
-
}
|
|
39
|
-
const deploy = siteData.published_deploy || {}
|
|
40
|
-
const deployedFunctions = deploy.available_functions || []
|
|
41
|
-
|
|
42
|
-
const functionsDir = getFunctionsDir({ flags, config })
|
|
43
|
-
|
|
44
|
-
if (typeof functionsDir === 'undefined') {
|
|
45
|
-
log('Functions directory is undefined')
|
|
46
|
-
log('Please verify functions.directory is set in your Netlify configuration file (netlify.toml/yml/json)')
|
|
47
|
-
log('See https://docs.netlify.com/configure-builds/file-based-configuration/ for more information')
|
|
48
|
-
process.exit(1)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const functions = await getFunctions(functionsDir)
|
|
52
|
-
const normalizedFunctions = functions.map(normalizeFunction.bind(null, deployedFunctions))
|
|
53
|
-
|
|
54
|
-
if (normalizedFunctions.length === 0) {
|
|
55
|
-
log(`No functions found in ${functionsDir}`)
|
|
56
|
-
exit()
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (flags.json) {
|
|
60
|
-
logJson(normalizedFunctions)
|
|
61
|
-
exit()
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Make table
|
|
65
|
-
log(`Based on local functions folder ${functionsDir}, these are the functions detected`)
|
|
66
|
-
const table = new AsciiTable(`Netlify Functions (in local functions folder)`)
|
|
67
|
-
table.setHeading('Name', 'URL', 'deployed')
|
|
68
|
-
normalizedFunctions.forEach(({ isDeployed, name, url }) => {
|
|
69
|
-
table.addRow(name, url, isDeployed ? 'yes' : 'no')
|
|
70
|
-
})
|
|
71
|
-
log(table.toString())
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const normalizeFunction = function (deployedFunctions, { name, urlPath: url }) {
|
|
76
|
-
const isDeployed = deployedFunctions.some((deployedFunction) => deployedFunction.n === name)
|
|
77
|
-
return { name, url, isDeployed }
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
FunctionsListCommand.description = `List functions that exist locally
|
|
81
|
-
|
|
82
|
-
Helpful for making sure that you have formatted your functions correctly
|
|
83
|
-
|
|
84
|
-
NOT the same as listing the functions that have been deployed. For that info you need to go to your Netlify deploy log.
|
|
85
|
-
`
|
|
86
|
-
FunctionsListCommand.aliases = ['function:list']
|
|
87
|
-
FunctionsListCommand.flags = {
|
|
88
|
-
name: flagsLib.string({
|
|
89
|
-
char: 'n',
|
|
90
|
-
description: 'name to print',
|
|
91
|
-
}),
|
|
92
|
-
functions: flagsLib.string({
|
|
93
|
-
char: 'f',
|
|
94
|
-
description: 'Specify a functions directory to list',
|
|
95
|
-
}),
|
|
96
|
-
json: flagsLib.boolean({
|
|
97
|
-
description: 'Output function data as JSON',
|
|
98
|
-
}),
|
|
99
|
-
...FunctionsListCommand.flags,
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
module.exports = FunctionsListCommand
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
const { join } = require('path')
|
|
2
|
-
|
|
3
|
-
const { flags: flagsLib } = require('@oclif/command')
|
|
4
|
-
|
|
5
|
-
const { startFunctionsServer } = require('../../lib/functions/server')
|
|
6
|
-
const Command = require('../../utils/command')
|
|
7
|
-
const { acquirePort, getSiteInformation, injectEnvVariables } = require('../../utils/dev')
|
|
8
|
-
const { getFunctionsDir } = require('../../utils/functions')
|
|
9
|
-
|
|
10
|
-
const DEFAULT_PORT = 9999
|
|
11
|
-
|
|
12
|
-
class FunctionsServeCommand extends Command {
|
|
13
|
-
async run() {
|
|
14
|
-
const { flags } = this.parse(FunctionsServeCommand)
|
|
15
|
-
|
|
16
|
-
const { netlify } = this
|
|
17
|
-
const { api, config, site, siteInfo } = netlify
|
|
18
|
-
|
|
19
|
-
const functionsDir = getFunctionsDir({ flags, config }, join('netlify', 'functions'))
|
|
20
|
-
|
|
21
|
-
await injectEnvVariables({ env: this.netlify.cachedConfig.env, site })
|
|
22
|
-
|
|
23
|
-
const { capabilities, siteUrl, timeouts } = await getSiteInformation({
|
|
24
|
-
flags,
|
|
25
|
-
api,
|
|
26
|
-
site,
|
|
27
|
-
siteInfo,
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
const functionsPort = await acquirePort({
|
|
31
|
-
configuredPort: flags.port || (config.dev && config.dev.functionsPort),
|
|
32
|
-
defaultPort: DEFAULT_PORT,
|
|
33
|
-
errorMessage: 'Could not acquire configured functions port',
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
await startFunctionsServer({
|
|
37
|
-
config,
|
|
38
|
-
settings: { functions: functionsDir, functionsPort },
|
|
39
|
-
site,
|
|
40
|
-
siteUrl,
|
|
41
|
-
capabilities,
|
|
42
|
-
timeouts,
|
|
43
|
-
functionsPrefix: '/.netlify/functions/',
|
|
44
|
-
buildersPrefix: '/.netlify/builders/',
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
FunctionsServeCommand.description = `(Beta) Serve functions locally
|
|
50
|
-
|
|
51
|
-
Helpful for debugging functions.
|
|
52
|
-
`
|
|
53
|
-
FunctionsServeCommand.aliases = ['function:serve']
|
|
54
|
-
FunctionsServeCommand.flags = {
|
|
55
|
-
functions: flagsLib.string({
|
|
56
|
-
char: 'f',
|
|
57
|
-
description: 'Specify a functions directory to serve',
|
|
58
|
-
}),
|
|
59
|
-
port: flagsLib.integer({
|
|
60
|
-
char: 'p',
|
|
61
|
-
description: 'Specify a port for the functions server',
|
|
62
|
-
}),
|
|
63
|
-
offline: flagsLib.boolean({
|
|
64
|
-
char: 'o',
|
|
65
|
-
description: 'disables any features that require network access',
|
|
66
|
-
}),
|
|
67
|
-
...FunctionsServeCommand.flags,
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
module.exports = FunctionsServeCommand
|
package/src/commands/link.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
|
-
const process = require('process')
|
|
3
|
-
|
|
4
|
-
const { flags: flagsLib } = require('@oclif/command')
|
|
5
|
-
const chalk = require('chalk')
|
|
6
|
-
|
|
7
|
-
const { listSites } = require('../lib/api')
|
|
8
|
-
const Command = require('../utils/command')
|
|
9
|
-
const { error, exit, log } = require('../utils/command-helpers')
|
|
10
|
-
const ensureNetlifyIgnore = require('../utils/gitignore')
|
|
11
|
-
const linkPrompt = require('../utils/link/link-by-prompt')
|
|
12
|
-
const { track } = require('../utils/telemetry')
|
|
13
|
-
|
|
14
|
-
class LinkCommand extends Command {
|
|
15
|
-
async run() {
|
|
16
|
-
await this.authenticate()
|
|
17
|
-
|
|
18
|
-
const { flags } = this.parse(LinkCommand)
|
|
19
|
-
const {
|
|
20
|
-
api,
|
|
21
|
-
repositoryRoot,
|
|
22
|
-
site: { id: siteId },
|
|
23
|
-
state,
|
|
24
|
-
} = this.netlify
|
|
25
|
-
|
|
26
|
-
let siteData
|
|
27
|
-
try {
|
|
28
|
-
siteData = await api.getSite({ siteId })
|
|
29
|
-
} catch {
|
|
30
|
-
// silent api error
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Add .netlify to .gitignore file
|
|
34
|
-
await ensureNetlifyIgnore(repositoryRoot)
|
|
35
|
-
|
|
36
|
-
// Site id is incorrect
|
|
37
|
-
if (siteId && !siteData) {
|
|
38
|
-
console.log(`"${siteId}" was not found in your Netlify account.`)
|
|
39
|
-
console.log(`Please double check your siteID and which account you are logged into via \`netlify status\`.`)
|
|
40
|
-
return exit()
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// If already linked to site. exit and prompt for unlink
|
|
44
|
-
if (siteData) {
|
|
45
|
-
log(`Site already linked to "${siteData.name}"`)
|
|
46
|
-
log(`Admin url: ${siteData.admin_url}`)
|
|
47
|
-
log()
|
|
48
|
-
log(`To unlink this site, run: ${chalk.cyanBright('netlify unlink')}`)
|
|
49
|
-
return exit()
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (flags.id) {
|
|
53
|
-
try {
|
|
54
|
-
siteData = await api.getSite({ site_id: flags.id })
|
|
55
|
-
} catch (error_) {
|
|
56
|
-
if (error_.status === 404) {
|
|
57
|
-
error(new Error(`Site id ${flags.id} not found`))
|
|
58
|
-
} else {
|
|
59
|
-
error(error_)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Save site ID
|
|
64
|
-
state.set('siteId', siteData.id)
|
|
65
|
-
log(`Linked to ${siteData.name} in ${state.path}`)
|
|
66
|
-
|
|
67
|
-
await track('sites_linked', {
|
|
68
|
-
siteId: siteData.id,
|
|
69
|
-
linkType: 'manual',
|
|
70
|
-
kind: 'byId',
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
return exit()
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (flags.name) {
|
|
77
|
-
let results
|
|
78
|
-
try {
|
|
79
|
-
results = await listSites({
|
|
80
|
-
api,
|
|
81
|
-
options: {
|
|
82
|
-
name: flags.name,
|
|
83
|
-
filter: 'all',
|
|
84
|
-
},
|
|
85
|
-
})
|
|
86
|
-
} catch (error_) {
|
|
87
|
-
if (error_.status === 404) {
|
|
88
|
-
error(new Error(`${flags.name} not found`))
|
|
89
|
-
} else {
|
|
90
|
-
error(error_)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (results.length === 0) {
|
|
95
|
-
error(new Error(`No sites found named ${flags.name}`))
|
|
96
|
-
}
|
|
97
|
-
const [firstSiteData] = results
|
|
98
|
-
state.set('siteId', firstSiteData.id)
|
|
99
|
-
|
|
100
|
-
log(`Linked to ${firstSiteData.name} in ${path.relative(path.join(process.cwd(), '..'), state.path)}`)
|
|
101
|
-
|
|
102
|
-
await track('sites_linked', {
|
|
103
|
-
siteId: (firstSiteData && firstSiteData.id) || siteId,
|
|
104
|
-
linkType: 'manual',
|
|
105
|
-
kind: 'byName',
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
return exit()
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
siteData = await linkPrompt(this, flags)
|
|
112
|
-
return siteData
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
LinkCommand.description = `Link a local repo or project folder to an existing site on Netlify`
|
|
117
|
-
|
|
118
|
-
LinkCommand.examples = ['netlify link', 'netlify link --id 123-123-123-123', 'netlify link --name my-site-name']
|
|
119
|
-
|
|
120
|
-
LinkCommand.flags = {
|
|
121
|
-
id: flagsLib.string({
|
|
122
|
-
description: 'ID of site to link to',
|
|
123
|
-
}),
|
|
124
|
-
name: flagsLib.string({
|
|
125
|
-
description: 'Name of site to link to',
|
|
126
|
-
}),
|
|
127
|
-
gitRemoteName: flagsLib.string({
|
|
128
|
-
description: 'Name of Git remote to use. e.g. "origin"',
|
|
129
|
-
}),
|
|
130
|
-
...LinkCommand.flags,
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
module.exports = LinkCommand
|