netlify-cli 17.3.2 → 17.4.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.
Files changed (210) hide show
  1. package/README.md +2 -138
  2. package/npm-shrinkwrap.json +76 -76
  3. package/package.json +16 -15
  4. package/src/commands/addons/addons-auth.mjs +27 -30
  5. package/src/commands/addons/addons-config.mjs +145 -154
  6. package/src/commands/addons/addons-create.mjs +94 -108
  7. package/src/commands/addons/addons-delete.mjs +36 -41
  8. package/src/commands/addons/addons-list.mjs +38 -42
  9. package/src/commands/addons/addons.mjs +26 -28
  10. package/src/commands/addons/index.mjs +1 -1
  11. package/src/commands/api/api.mjs +45 -53
  12. package/src/commands/api/index.mjs +1 -1
  13. package/src/commands/base-command.mjs +597 -684
  14. package/src/commands/blobs/blobs-delete.mjs +35 -0
  15. package/src/commands/blobs/blobs-get.mjs +44 -0
  16. package/src/commands/blobs/blobs-list.mjs +48 -0
  17. package/src/commands/blobs/blobs-set.mjs +54 -0
  18. package/src/commands/blobs/blobs.mjs +32 -0
  19. package/src/commands/blobs/index.mjs +1 -0
  20. package/src/commands/build/build.mjs +55 -67
  21. package/src/commands/build/index.mjs +1 -1
  22. package/src/commands/completion/completion.mjs +41 -46
  23. package/src/commands/completion/index.mjs +1 -1
  24. package/src/commands/deploy/deploy.mjs +675 -710
  25. package/src/commands/deploy/index.mjs +1 -1
  26. package/src/commands/dev/dev-exec.mjs +20 -32
  27. package/src/commands/dev/dev.mjs +217 -302
  28. package/src/commands/dev/index.mjs +1 -1
  29. package/src/commands/dev/types.d.ts +30 -0
  30. package/src/commands/env/env-clone.mjs +157 -184
  31. package/src/commands/env/env-get.mjs +49 -68
  32. package/src/commands/env/env-import.mjs +100 -119
  33. package/src/commands/env/env-list.mjs +104 -129
  34. package/src/commands/env/env-set.mjs +160 -185
  35. package/src/commands/env/env-unset.mjs +104 -122
  36. package/src/commands/env/env.mjs +28 -30
  37. package/src/commands/env/index.mjs +1 -1
  38. package/src/commands/functions/functions-build.mjs +29 -41
  39. package/src/commands/functions/functions-create.mjs +533 -601
  40. package/src/commands/functions/functions-invoke.mjs +193 -216
  41. package/src/commands/functions/functions-list.mjs +45 -55
  42. package/src/commands/functions/functions-serve.mjs +51 -61
  43. package/src/commands/functions/functions.mjs +26 -32
  44. package/src/commands/functions/index.mjs +1 -1
  45. package/src/commands/index.mjs +2 -2
  46. package/src/commands/init/index.mjs +1 -1
  47. package/src/commands/init/init.mjs +138 -167
  48. package/src/commands/integration/deploy.mjs +337 -399
  49. package/src/commands/integration/index.mjs +12 -13
  50. package/src/commands/link/index.mjs +1 -1
  51. package/src/commands/link/link.mjs +298 -317
  52. package/src/commands/lm/index.mjs +1 -1
  53. package/src/commands/lm/lm-info.mjs +23 -31
  54. package/src/commands/lm/lm-install.mjs +13 -17
  55. package/src/commands/lm/lm-setup.mjs +80 -84
  56. package/src/commands/lm/lm-uninstall.mjs +7 -12
  57. package/src/commands/lm/lm.mjs +18 -22
  58. package/src/commands/login/index.mjs +1 -1
  59. package/src/commands/login/login.mjs +35 -41
  60. package/src/commands/logout/index.mjs +1 -1
  61. package/src/commands/logout/logout.mjs +25 -31
  62. package/src/commands/main.mjs +166 -201
  63. package/src/commands/open/index.mjs +1 -1
  64. package/src/commands/open/open-admin.mjs +15 -18
  65. package/src/commands/open/open-site.mjs +16 -19
  66. package/src/commands/open/open.mjs +24 -27
  67. package/src/commands/recipes/common.mjs +23 -34
  68. package/src/commands/recipes/index.mjs +1 -1
  69. package/src/commands/recipes/recipes-list.mjs +13 -20
  70. package/src/commands/recipes/recipes.mjs +59 -72
  71. package/src/commands/serve/index.mjs +1 -1
  72. package/src/commands/serve/serve.mjs +142 -189
  73. package/src/commands/sites/index.mjs +2 -2
  74. package/src/commands/sites/sites-create-template.mjs +214 -236
  75. package/src/commands/sites/sites-create.mjs +145 -157
  76. package/src/commands/sites/sites-delete.mjs +75 -81
  77. package/src/commands/sites/sites-list.mjs +63 -66
  78. package/src/commands/sites/sites.mjs +18 -20
  79. package/src/commands/status/index.mjs +1 -1
  80. package/src/commands/status/status-hooks.mjs +32 -34
  81. package/src/commands/status/status.mjs +99 -106
  82. package/src/commands/switch/index.mjs +1 -1
  83. package/src/commands/switch/switch.mjs +32 -37
  84. package/src/commands/types.d.ts +31 -0
  85. package/src/commands/unlink/index.mjs +1 -1
  86. package/src/commands/unlink/unlink.mjs +23 -29
  87. package/src/commands/watch/index.mjs +1 -1
  88. package/src/commands/watch/watch.mjs +91 -105
  89. package/src/functions-templates/javascript/hello/{{name}}.js +2 -3
  90. package/src/lib/account.mjs +4 -5
  91. package/src/lib/api.mjs +22 -20
  92. package/src/lib/blobs/blobs.mjs +36 -45
  93. package/src/lib/build.mjs +82 -85
  94. package/src/lib/completion/constants.mjs +2 -4
  95. package/src/lib/completion/generate-autocompletion.mjs +33 -36
  96. package/src/lib/completion/get-autocompletion.mjs +31 -35
  97. package/src/lib/completion/index.mjs +1 -1
  98. package/src/lib/completion/script.mjs +12 -19
  99. package/src/lib/edge-functions/bootstrap.mjs +3 -5
  100. package/src/lib/edge-functions/consts.mjs +9 -10
  101. package/src/lib/edge-functions/deploy.mjs +28 -34
  102. package/src/lib/edge-functions/editor-helper.mjs +29 -42
  103. package/src/lib/edge-functions/headers.mjs +24 -26
  104. package/src/lib/edge-functions/internal.mjs +38 -44
  105. package/src/lib/edge-functions/proxy.mjs +229 -228
  106. package/src/lib/edge-functions/registry.mjs +473 -574
  107. package/src/lib/exec-fetcher.mjs +115 -122
  108. package/src/lib/fs.mjs +28 -27
  109. package/src/lib/functions/background.mjs +16 -20
  110. package/src/lib/functions/config.mjs +12 -9
  111. package/src/lib/functions/form-submissions-handler.mjs +143 -149
  112. package/src/lib/functions/local-proxy.mjs +40 -44
  113. package/src/lib/functions/memoized-build.mjs +19 -21
  114. package/src/lib/functions/netlify-function.mjs +269 -249
  115. package/src/lib/functions/registry.mjs +509 -568
  116. package/src/lib/functions/runtimes/go/index.mjs +62 -71
  117. package/src/lib/functions/runtimes/index.mjs +8 -15
  118. package/src/lib/functions/runtimes/js/builders/netlify-lambda.mjs +55 -64
  119. package/src/lib/functions/runtimes/js/builders/zisi.mjs +135 -154
  120. package/src/lib/functions/runtimes/js/constants.mjs +1 -1
  121. package/src/lib/functions/runtimes/js/index.mjs +92 -109
  122. package/src/lib/functions/runtimes/js/worker.mjs +43 -45
  123. package/src/lib/functions/runtimes/rust/index.mjs +64 -73
  124. package/src/lib/functions/scheduled.mjs +70 -88
  125. package/src/lib/functions/server.mjs +269 -327
  126. package/src/lib/functions/synchronous.mjs +118 -147
  127. package/src/lib/functions/utils.mjs +38 -46
  128. package/src/lib/geo-location.mjs +69 -81
  129. package/src/lib/http-agent.mjs +87 -90
  130. package/src/lib/images/proxy.mjs +97 -99
  131. package/src/lib/log.mjs +6 -9
  132. package/src/lib/path.mjs +2 -1
  133. package/src/lib/render-error-template.mjs +19 -20
  134. package/src/lib/settings.mjs +17 -19
  135. package/src/lib/spinner.mjs +21 -23
  136. package/src/lib/string.mjs +4 -2
  137. package/src/recipes/vscode/index.mjs +69 -85
  138. package/src/recipes/vscode/settings.mjs +53 -58
  139. package/src/utils/addons/compare.mjs +31 -32
  140. package/src/utils/addons/diffs/index.mjs +16 -17
  141. package/src/utils/addons/diffs/options.mjs +99 -101
  142. package/src/utils/addons/prepare.mjs +100 -97
  143. package/src/utils/addons/prompts.mjs +73 -76
  144. package/src/utils/addons/render.mjs +33 -36
  145. package/src/utils/addons/validation.mjs +19 -15
  146. package/src/utils/banner.mjs +11 -16
  147. package/src/utils/build-info.mjs +65 -66
  148. package/src/utils/command-helpers.mjs +185 -199
  149. package/src/utils/create-deferred.mjs +9 -12
  150. package/src/utils/create-stream-promise.mjs +54 -47
  151. package/src/utils/deploy/constants.mjs +9 -11
  152. package/src/utils/deploy/deploy-site.mjs +162 -182
  153. package/src/utils/deploy/hash-config.mjs +21 -21
  154. package/src/utils/deploy/hash-files.mjs +34 -38
  155. package/src/utils/deploy/hash-fns.mjs +149 -154
  156. package/src/utils/deploy/hasher-segments.mjs +58 -52
  157. package/src/utils/deploy/upload-files.mjs +99 -113
  158. package/src/utils/deploy/util.mjs +85 -91
  159. package/src/utils/detect-server-settings.mjs +236 -268
  160. package/src/utils/dev.mjs +163 -178
  161. package/src/utils/dot-env.mjs +37 -42
  162. package/src/utils/env/index.mjs +148 -148
  163. package/src/utils/execa.mjs +9 -13
  164. package/src/utils/feature-flags.mjs +6 -5
  165. package/src/utils/framework-server.mjs +43 -52
  166. package/src/utils/functions/constants.mjs +1 -1
  167. package/src/utils/functions/functions.mjs +30 -40
  168. package/src/utils/functions/get-functions.mjs +28 -29
  169. package/src/utils/functions/index.mjs +3 -3
  170. package/src/utils/get-global-config.mjs +33 -36
  171. package/src/utils/get-package-json.mjs +14 -15
  172. package/src/utils/get-repo-data.mjs +54 -64
  173. package/src/utils/get-site.mjs +14 -14
  174. package/src/utils/gh-auth.mjs +79 -100
  175. package/src/utils/gitignore.mjs +37 -40
  176. package/src/utils/headers.mjs +33 -35
  177. package/src/utils/hooks/requires-site-info.mjs +26 -22
  178. package/src/utils/init/config-github.mjs +207 -219
  179. package/src/utils/init/config-manual.mjs +83 -100
  180. package/src/utils/init/config.mjs +25 -26
  181. package/src/utils/init/node-version.mjs +23 -30
  182. package/src/utils/init/plugins.mjs +12 -8
  183. package/src/utils/init/utils.mjs +152 -172
  184. package/src/utils/live-tunnel.mjs +118 -141
  185. package/src/utils/lm/install.mjs +220 -259
  186. package/src/utils/lm/requirements.mjs +54 -63
  187. package/src/utils/lm/steps.mjs +31 -31
  188. package/src/utils/lm/ui.mjs +13 -20
  189. package/src/utils/open-browser.mjs +31 -32
  190. package/src/utils/parse-raw-flags.mjs +39 -35
  191. package/src/utils/proxy-server.mjs +84 -71
  192. package/src/utils/proxy.mjs +696 -750
  193. package/src/utils/read-repo-url.mjs +48 -47
  194. package/src/utils/redirects.mjs +49 -49
  195. package/src/utils/request-id.mjs +2 -4
  196. package/src/utils/rules-proxy.mjs +96 -100
  197. package/src/utils/run-build.mjs +109 -132
  198. package/src/utils/shell.mjs +99 -106
  199. package/src/utils/sign-redirect.mjs +14 -14
  200. package/src/utils/sites/utils.mjs +48 -55
  201. package/src/utils/state-config.mjs +101 -101
  202. package/src/utils/static-server.mjs +28 -34
  203. package/src/utils/telemetry/index.mjs +2 -2
  204. package/src/utils/telemetry/report-error.mjs +45 -49
  205. package/src/utils/telemetry/request.mjs +36 -43
  206. package/src/utils/telemetry/telemetry.mjs +90 -105
  207. package/src/utils/telemetry/utils.mjs +5 -6
  208. package/src/utils/telemetry/validation.mjs +55 -53
  209. package/src/utils/types.d.ts +46 -0
  210. package/src/utils/validation.mjs +10 -13
@@ -1,88 +1,81 @@
1
- // @ts-check
2
- import fs from 'fs'
3
- import { createRequire } from 'module'
4
- import path from 'path'
5
-
6
- import inquirer from 'inquirer'
7
- import fetch from 'node-fetch'
8
-
9
- import { NETLIFYDEVWARN, chalk, error, exit } from '../../utils/command-helpers.mjs'
10
- import { BACKGROUND, CLOCKWORK_USERAGENT, getFunctions } from '../../utils/functions/index.mjs'
11
-
12
- const require = createRequire(import.meta.url)
13
-
1
+ import fs from 'fs';
2
+ import { createRequire } from 'module';
3
+ import path from 'path';
4
+ import inquirer from 'inquirer';
5
+ // @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'node... Remove this comment to see the full error message
6
+ import fetch from 'node-fetch';
7
+ import { NETLIFYDEVWARN, chalk, error, exit } from '../../utils/command-helpers.mjs';
8
+ import { BACKGROUND, CLOCKWORK_USERAGENT, getFunctions } from '../../utils/functions/index.mjs';
9
+ const require = createRequire(import.meta.url);
14
10
  // https://docs.netlify.com/functions/trigger-on-events/
15
11
  const events = [
16
- 'deploy-building',
17
- 'deploy-succeeded',
18
- 'deploy-failed',
19
- 'deploy-locked',
20
- 'deploy-unlocked',
21
- 'split-test-activated',
22
- 'split-test-deactivated',
23
- 'split-test-modified',
24
- 'submission-created',
25
- 'identity-validate',
26
- 'identity-signup',
27
- 'identity-login',
28
- ]
29
-
30
- const eventTriggeredFunctions = new Set([...events, ...events.map((name) => `${name}${BACKGROUND}`)])
31
-
32
- const DEFAULT_PORT = 8888
33
-
12
+ 'deploy-building',
13
+ 'deploy-succeeded',
14
+ 'deploy-failed',
15
+ 'deploy-locked',
16
+ 'deploy-unlocked',
17
+ 'split-test-activated',
18
+ 'split-test-deactivated',
19
+ 'split-test-modified',
20
+ 'submission-created',
21
+ 'identity-validate',
22
+ 'identity-signup',
23
+ 'identity-login',
24
+ ];
25
+ const eventTriggeredFunctions = new Set([...events, ...events.map((name) => `${name}${BACKGROUND}`)]);
26
+ const DEFAULT_PORT = 8888;
34
27
  // https://stackoverflow.com/questions/3710204/how-to-check-if-a-string-is-a-valid-json-string-in-javascript-without-using-try
28
+ // @ts-expect-error TS(7006) FIXME: Parameter 'jsonString' implicitly has an 'any' typ... Remove this comment to see the full error message
35
29
  const tryParseJSON = function (jsonString) {
36
- try {
37
- const parsedValue = JSON.parse(jsonString)
38
-
39
- // Handle non-exception-throwing cases:
40
- // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
41
- // but... JSON.parse(null) returns null, and typeof null === "object",
42
- // so we must check for that, too. Thankfully, null is falsey, so this suffices:
43
- if (parsedValue && typeof parsedValue === 'object') {
44
- return parsedValue
30
+ try {
31
+ const parsedValue = JSON.parse(jsonString);
32
+ // Handle non-exception-throwing cases:
33
+ // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
34
+ // but... JSON.parse(null) returns null, and typeof null === "object",
35
+ // so we must check for that, too. Thankfully, null is falsey, so this suffices:
36
+ if (parsedValue && typeof parsedValue === 'object') {
37
+ return parsedValue;
38
+ }
45
39
  }
46
- } catch {}
47
-
48
- return false
49
- }
50
-
40
+ catch { }
41
+ return false;
42
+ };
43
+ // @ts-expect-error TS(7006) FIXME: Parameter 'querystring' implicitly has an 'any' ty... Remove this comment to see the full error message
51
44
  const formatQstring = function (querystring) {
52
- if (querystring) {
53
- return `?${querystring}`
54
- }
55
- return ''
56
- }
57
-
45
+ if (querystring) {
46
+ return `?${querystring}`;
47
+ }
48
+ return '';
49
+ };
58
50
  /**
59
51
  * process payloads from flag
60
52
  * @param {string} payloadString
61
53
  * @param {string} workingDir
62
54
  */
55
+ // @ts-expect-error TS(7006) FIXME: Parameter 'payloadString' implicitly has an 'any' ... Remove this comment to see the full error message
63
56
  const processPayloadFromFlag = function (payloadString, workingDir) {
64
- if (payloadString) {
65
- // case 1: jsonstring
66
- let payload = tryParseJSON(payloadString)
67
- if (payload) return payload
68
- // case 2: jsonpath
69
- const payloadpath = path.join(workingDir, payloadString)
70
- const pathexists = fs.existsSync(payloadpath)
71
- if (pathexists) {
72
- try {
73
- // there is code execution potential here
74
-
75
- payload = require(payloadpath)
76
- return payload
77
- } catch (error_) {
78
- console.error(error_)
79
- }
57
+ if (payloadString) {
58
+ // case 1: jsonstring
59
+ let payload = tryParseJSON(payloadString);
60
+ if (payload)
61
+ return payload;
62
+ // case 2: jsonpath
63
+ const payloadpath = path.join(workingDir, payloadString);
64
+ const pathexists = fs.existsSync(payloadpath);
65
+ if (pathexists) {
66
+ try {
67
+ // there is code execution potential here
68
+ payload = require(payloadpath);
69
+ return payload;
70
+ }
71
+ catch (error_) {
72
+ console.error(error_);
73
+ }
74
+ }
75
+ // case 3: invalid string, invalid path
76
+ return false;
80
77
  }
81
- // case 3: invalid string, invalid path
82
- return false
83
- }
84
- }
85
-
78
+ };
86
79
  /**
87
80
  * prompt for a name if name not supplied
88
81
  * also used in functions:create
@@ -91,182 +84,166 @@ const processPayloadFromFlag = function (payloadString, workingDir) {
91
84
  * @param {string} [argumentName] The name that might be provided as argument (optional argument)
92
85
  * @returns {Promise<string>}
93
86
  */
87
+ // @ts-expect-error TS(7006) FIXME: Parameter 'functions' implicitly has an 'any' type... Remove this comment to see the full error message
94
88
  const getNameFromArgs = async function (functions, options, argumentName) {
95
- const functionToTrigger = getFunctionToTrigger(options, argumentName)
96
- const functionNames = functions.map(({ name }) => name)
97
-
98
- if (functionToTrigger) {
99
- if (functionNames.includes(functionToTrigger)) {
100
- return functionToTrigger
89
+ const functionToTrigger = getFunctionToTrigger(options, argumentName);
90
+ // @ts-expect-error TS(7031) FIXME: Binding element 'name' implicitly has an 'any' typ... Remove this comment to see the full error message
91
+ const functionNames = functions.map(({ name }) => name);
92
+ if (functionToTrigger) {
93
+ if (functionNames.includes(functionToTrigger)) {
94
+ return functionToTrigger;
95
+ }
96
+ console.warn(`Function name ${chalk.yellow(functionToTrigger)} supplied but no matching function found in your functions folder, forcing you to pick a valid one...`);
101
97
  }
102
-
103
- console.warn(
104
- `Function name ${chalk.yellow(
105
- functionToTrigger,
106
- )} supplied but no matching function found in your functions folder, forcing you to pick a valid one...`,
107
- )
108
- }
109
-
110
- const { trigger } = await inquirer.prompt([
111
- {
112
- type: 'list',
113
- message: 'Pick a function to trigger',
114
- name: 'trigger',
115
- choices: functionNames,
116
- },
117
- ])
118
- return trigger
119
- }
120
-
98
+ const { trigger } = await inquirer.prompt([
99
+ {
100
+ type: 'list',
101
+ message: 'Pick a function to trigger',
102
+ name: 'trigger',
103
+ choices: functionNames,
104
+ },
105
+ ]);
106
+ return trigger;
107
+ };
121
108
  /**
122
109
  * get the function name out of the argument or options
123
110
  * @param {import('commander').OptionValues} options
124
111
  * @param {string} [argumentName] The name that might be provided as argument (optional argument)
125
112
  * @returns {string}
126
113
  */
114
+ // @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
127
115
  const getFunctionToTrigger = function (options, argumentName) {
128
- if (options.name) {
129
- if (argumentName) {
130
- console.error('function name specified in both flag and arg format, pick one')
131
- exit(1)
116
+ if (options.name) {
117
+ if (argumentName) {
118
+ console.error('function name specified in both flag and arg format, pick one');
119
+ exit(1);
120
+ }
121
+ return options.name;
132
122
  }
133
-
134
- return options.name
135
- }
136
-
137
- return argumentName
138
- }
139
-
123
+ return argumentName;
124
+ };
140
125
  /**
141
126
  * The functions:invoke command
142
127
  * @param {string} nameArgument
143
128
  * @param {import('commander').OptionValues} options
144
129
  * @param {import('../base-command.mjs').default} command
145
130
  */
131
+ // @ts-expect-error TS(7006) FIXME: Parameter 'nameArgument' implicitly has an 'any' t... Remove this comment to see the full error message
146
132
  const functionsInvoke = async (nameArgument, options, command) => {
147
- const { config, relConfigFilePath } = command.netlify
148
-
149
- const functionsDir = options.functions || (config.dev && config.dev.functions) || config.functionsDirectory
150
- if (typeof functionsDir === 'undefined') {
151
- error(`Functions directory is undefined, did you forget to set it in ${relConfigFilePath}?`)
152
- }
153
-
154
- if (!options.port)
155
- console.warn(`${NETLIFYDEVWARN} "port" flag was not specified. Attempting to connect to localhost:8888 by default`)
156
- const port = options.port || DEFAULT_PORT
157
-
158
- const functions = await getFunctions(functionsDir, config)
159
- const functionToTrigger = await getNameFromArgs(functions, options, nameArgument)
160
- const functionObj = functions.find((func) => func.name === functionToTrigger)
161
-
162
- let headers = {}
163
- let body = {}
164
-
165
- if (functionObj.schedule) {
166
- headers = {
167
- 'user-agent': CLOCKWORK_USERAGENT,
133
+ const { config, relConfigFilePath } = command.netlify;
134
+ const functionsDir = options.functions || (config.dev && config.dev.functions) || config.functionsDirectory;
135
+ if (typeof functionsDir === 'undefined') {
136
+ error(`Functions directory is undefined, did you forget to set it in ${relConfigFilePath}?`);
168
137
  }
169
- } else if (eventTriggeredFunctions.has(functionToTrigger)) {
170
- /** handle event triggered fns */
171
- // https://docs.netlify.com/functions/trigger-on-events/
172
- const [name, event] = functionToTrigger.split('-')
173
- if (name === 'identity') {
174
- // https://docs.netlify.com/functions/functions-and-identity/#trigger-functions-on-identity-events
175
- body.event = event
176
- body.user = {
177
- id: '1111a1a1-a11a-1111-aa11-aaa11111a11a',
178
- aud: '',
179
- role: '',
180
- email: 'foo@trust-this-company.com',
181
- app_metadata: {
182
- provider: 'email',
183
- },
184
- user_metadata: {
185
- full_name: 'Test Person',
186
- },
187
- created_at: new Date(Date.now()).toISOString(),
188
- update_at: new Date(Date.now()).toISOString(),
189
- }
190
- } else {
191
- // non identity functions seem to have a different shape
192
- // https://docs.netlify.com/functions/trigger-on-events/#payload
193
- body.payload = {
194
- TODO: 'mock up payload data better',
195
- }
196
- body.site = {
197
- TODO: 'mock up site data better',
198
- }
138
+ if (!options.port)
139
+ console.warn(`${NETLIFYDEVWARN} "port" flag was not specified. Attempting to connect to localhost:8888 by default`);
140
+ const port = options.port || DEFAULT_PORT;
141
+ const functions = await getFunctions(functionsDir, config);
142
+ const functionToTrigger = await getNameFromArgs(functions, options, nameArgument);
143
+ const functionObj = functions.find((func) => func.name === functionToTrigger);
144
+ let headers = {};
145
+ let body = {};
146
+ // @ts-expect-error TS(2532) FIXME: Object is possibly 'undefined'.
147
+ if (functionObj.schedule) {
148
+ headers = {
149
+ 'user-agent': CLOCKWORK_USERAGENT,
150
+ };
151
+ }
152
+ else if (eventTriggeredFunctions.has(functionToTrigger)) {
153
+ /** handle event triggered fns */
154
+ // https://docs.netlify.com/functions/trigger-on-events/
155
+ const [name, event] = functionToTrigger.split('-');
156
+ if (name === 'identity') {
157
+ // https://docs.netlify.com/functions/functions-and-identity/#trigger-functions-on-identity-events
158
+ // @ts-expect-error TS(2339) FIXME: Property 'event' does not exist on type '{}'.
159
+ body.event = event;
160
+ // @ts-expect-error TS(2339) FIXME: Property 'user' does not exist on type '{}'.
161
+ body.user = {
162
+ id: '1111a1a1-a11a-1111-aa11-aaa11111a11a',
163
+ aud: '',
164
+ role: '',
165
+ email: 'foo@trust-this-company.com',
166
+ app_metadata: {
167
+ provider: 'email',
168
+ },
169
+ user_metadata: {
170
+ full_name: 'Test Person',
171
+ },
172
+ created_at: new Date(Date.now()).toISOString(),
173
+ update_at: new Date(Date.now()).toISOString(),
174
+ };
175
+ }
176
+ else {
177
+ // non identity functions seem to have a different shape
178
+ // https://docs.netlify.com/functions/trigger-on-events/#payload
179
+ // @ts-expect-error TS(2339) FIXME: Property 'payload' does not exist on type '{}'.
180
+ body.payload = {
181
+ TODO: 'mock up payload data better',
182
+ };
183
+ // @ts-expect-error TS(2339) FIXME: Property 'site' does not exist on type '{}'.
184
+ body.site = {
185
+ TODO: 'mock up site data better',
186
+ };
187
+ }
188
+ }
189
+ else {
190
+ // NOT an event triggered function, but may still want to simulate authentication locally
191
+ const isAuthenticated = Boolean(options.identity);
192
+ if (isAuthenticated) {
193
+ headers = {
194
+ authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb3VyY2UiOiJuZXRsaWZ5IGZ1bmN0aW9uczp0cmlnZ2VyIiwidGVzdERhdGEiOiJORVRMSUZZX0RFVl9MT0NBTExZX0VNVUxBVEVEX0pXVCJ9.Xb6vOFrfLUZmyUkXBbCvU4bM7q8tPilF0F03Wupap_c',
195
+ };
196
+ // you can decode this https://jwt.io/
197
+ // {
198
+ // "source": "netlify functions:trigger",
199
+ // "testData": "NETLIFY_DEV_LOCALLY_EMULATED_JWT"
200
+ // }
201
+ }
202
+ }
203
+ const payload = processPayloadFromFlag(options.payload, command.workingDir);
204
+ body = { ...body, ...payload };
205
+ try {
206
+ const response = await fetch(`http://localhost:${port}/.netlify/functions/${functionToTrigger}${formatQstring(options.querystring)}`, {
207
+ method: 'post',
208
+ headers,
209
+ body: JSON.stringify(body),
210
+ });
211
+ const data = await response.text();
212
+ console.log(data);
199
213
  }
200
- } else {
201
- // NOT an event triggered function, but may still want to simulate authentication locally
202
- const isAuthenticated = Boolean(options.identity)
203
-
204
- if (isAuthenticated) {
205
- headers = {
206
- authorization:
207
- 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb3VyY2UiOiJuZXRsaWZ5IGZ1bmN0aW9uczp0cmlnZ2VyIiwidGVzdERhdGEiOiJORVRMSUZZX0RFVl9MT0NBTExZX0VNVUxBVEVEX0pXVCJ9.Xb6vOFrfLUZmyUkXBbCvU4bM7q8tPilF0F03Wupap_c',
208
- }
209
- // you can decode this https://jwt.io/
210
- // {
211
- // "source": "netlify functions:trigger",
212
- // "testData": "NETLIFY_DEV_LOCALLY_EMULATED_JWT"
213
- // }
214
+ catch (error_) {
215
+ // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'.
216
+ error(`Ran into an error invoking your function: ${error_.message}`);
214
217
  }
215
- }
216
- const payload = processPayloadFromFlag(options.payload, command.workingDir)
217
- body = { ...body, ...payload }
218
-
219
- try {
220
- const response = await fetch(
221
- `http://localhost:${port}/.netlify/functions/${functionToTrigger}${formatQstring(options.querystring)}`,
222
- {
223
- method: 'post',
224
- headers,
225
- body: JSON.stringify(body),
226
- },
227
- )
228
- const data = await response.text()
229
- console.log(data)
230
- } catch (error_) {
231
- error(`Ran into an error invoking your function: ${error_.message}`)
232
- }
233
- }
234
-
218
+ };
235
219
  /**
236
220
  * Creates the `netlify functions:invoke` command
237
221
  * @param {import('../base-command.mjs').default} program
238
222
  * @returns
239
223
  */
240
- export const createFunctionsInvokeCommand = (program) =>
241
- program
224
+ // @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
225
+ export const createFunctionsInvokeCommand = (program) => program
242
226
  .command('functions:invoke')
243
227
  .alias('function:trigger')
244
228
  .argument('[name]', 'function name to invoke')
245
- .description(
246
- `Trigger a function while in netlify dev with simulated data, good for testing function calls including Netlify's Event Triggered Functions`,
247
- )
229
+ .description(`Trigger a function while in netlify dev with simulated data, good for testing function calls including Netlify's Event Triggered Functions`)
248
230
  .option('-n, --name <name>', 'function name to invoke')
249
231
  .option('-f, --functions <dir>', 'Specify a functions folder to parse, overriding netlify.toml')
250
232
  .option('-q, --querystring <query>', 'Querystring to add to your function invocation')
251
233
  .option('-p, --payload <data>', 'Supply POST payload in stringified json, or a path to a json file')
252
234
  // TODO: refactor to not need the `undefined` state by removing the --identity flag (value `identity` will be then always defined to true or false)
253
- .option(
254
- '--identity',
255
- 'simulate Netlify Identity authentication JWT. pass --identity to affirm unauthenticated request',
256
- )
257
- .option(
258
- '--no-identity',
259
- 'simulate Netlify Identity authentication JWT. pass --no-identity to affirm unauthenticated request',
260
- )
235
+ .option('--identity', 'simulate Netlify Identity authentication JWT. pass --identity to affirm unauthenticated request')
236
+ .option('--no-identity', 'simulate Netlify Identity authentication JWT. pass --no-identity to affirm unauthenticated request')
237
+ // @ts-expect-error TS(7006) FIXME: Parameter 'value' implicitly has an 'any' type.
261
238
  .option('--port <port>', 'Port where netlify dev is accessible. e.g. 8888', (value) => Number.parseInt(value))
262
239
  .addExamples([
263
- 'netlify functions:invoke',
264
- 'netlify functions:invoke myfunction',
265
- 'netlify functions:invoke --name myfunction',
266
- 'netlify functions:invoke --name myfunction --identity',
267
- 'netlify functions:invoke --name myfunction --no-identity',
268
- `netlify functions:invoke myfunction --payload '{"foo": 1}'`,
269
- 'netlify functions:invoke myfunction --querystring "foo=1',
270
- 'netlify functions:invoke myfunction --payload "./pathTo.json"',
271
- ])
272
- .action(functionsInvoke)
240
+ 'netlify functions:invoke',
241
+ 'netlify functions:invoke myfunction',
242
+ 'netlify functions:invoke --name myfunction',
243
+ 'netlify functions:invoke --name myfunction --identity',
244
+ 'netlify functions:invoke --name myfunction --no-identity',
245
+ `netlify functions:invoke myfunction --payload '{"foo": 1}'`,
246
+ 'netlify functions:invoke myfunction --querystring "foo=1',
247
+ 'netlify functions:invoke myfunction --payload "./pathTo.json"',
248
+ ])
249
+ .action(functionsInvoke);
@@ -1,74 +1,64 @@
1
- // @ts-check
2
- import AsciiTable from 'ascii-table'
3
-
4
- import { exit, log, logJson } from '../../utils/command-helpers.mjs'
5
- import { getFunctions, getFunctionsDir } from '../../utils/functions/index.mjs'
6
- import requiresSiteInfo from '../../utils/hooks/requires-site-info.mjs'
7
-
1
+ import AsciiTable from 'ascii-table';
2
+ import { exit, log, logJson } from '../../utils/command-helpers.mjs';
3
+ import { getFunctions, getFunctionsDir } from '../../utils/functions/index.mjs';
4
+ import requiresSiteInfo from '../../utils/hooks/requires-site-info.mjs';
5
+ // @ts-expect-error TS(7006) FIXME: Parameter 'deployedFunctions' implicitly has an 'a... Remove this comment to see the full error message
8
6
  const normalizeFunction = function (deployedFunctions, { name, urlPath: url }) {
9
- const isDeployed = deployedFunctions.some((deployedFunction) => deployedFunction.n === name)
10
- return { name, url, isDeployed }
11
- }
12
-
7
+ // @ts-expect-error TS(7006) FIXME: Parameter 'deployedFunction' implicitly has an 'an... Remove this comment to see the full error message
8
+ const isDeployed = deployedFunctions.some((deployedFunction) => deployedFunction.n === name);
9
+ return { name, url, isDeployed };
10
+ };
13
11
  /**
14
12
  * The functions:list command
15
13
  * @param {import('commander').OptionValues} options
16
14
  * @param {import('../base-command.mjs').default} command
17
15
  */
16
+ // @ts-expect-error TS(7006) FIXME: Parameter 'options' implicitly has an 'any' type.
18
17
  const functionsList = async (options, command) => {
19
- const { config, relConfigFilePath, siteInfo } = command.netlify
20
-
21
- const deploy = siteInfo.published_deploy || {}
22
- const deployedFunctions = deploy.available_functions || []
23
-
24
- const functionsDir = getFunctionsDir({ options, config })
25
-
26
- if (typeof functionsDir === 'undefined') {
27
- log('Functions directory is undefined')
28
- log(`Please verify that 'functions.directory' is set in your Netlify configuration file ${relConfigFilePath}`)
29
- log('Refer to https://docs.netlify.com/configure-builds/file-based-configuration/ for more information')
30
- exit(1)
31
- }
32
-
33
- const functions = await getFunctions(functionsDir)
34
- const normalizedFunctions = functions.map(normalizeFunction.bind(null, deployedFunctions))
35
-
36
- if (normalizedFunctions.length === 0) {
37
- log(`No functions found in ${functionsDir}`)
38
- exit()
39
- }
40
-
41
- if (options.json) {
42
- logJson(normalizedFunctions)
43
- exit()
44
- }
45
-
46
- // Make table
47
- log(`Based on local functions folder ${functionsDir}, these are the functions detected`)
48
- const table = new AsciiTable(`Netlify Functions (in local functions folder)`)
49
- table.setHeading('Name', 'URL', 'deployed')
50
- normalizedFunctions.forEach(({ isDeployed, name, url }) => {
51
- table.addRow(name, url, isDeployed ? 'yes' : 'no')
52
- })
53
- log(table.toString())
54
- }
55
-
18
+ const { config, relConfigFilePath, siteInfo } = command.netlify;
19
+ const deploy = siteInfo.published_deploy || {};
20
+ const deployedFunctions = deploy.available_functions || [];
21
+ // @ts-expect-error TS(2554) FIXME: Expected 2 arguments, but got 1.
22
+ const functionsDir = getFunctionsDir({ options, config });
23
+ if (typeof functionsDir === 'undefined') {
24
+ log('Functions directory is undefined');
25
+ log(`Please verify that 'functions.directory' is set in your Netlify configuration file ${relConfigFilePath}`);
26
+ log('Refer to https://ntl.fyi/file-based-build-config for more information');
27
+ exit(1);
28
+ }
29
+ const functions = await getFunctions(functionsDir);
30
+ const normalizedFunctions = functions.map(normalizeFunction.bind(null, deployedFunctions));
31
+ if (normalizedFunctions.length === 0) {
32
+ log(`No functions found in ${functionsDir}`);
33
+ exit();
34
+ }
35
+ if (options.json) {
36
+ logJson(normalizedFunctions);
37
+ exit();
38
+ }
39
+ // Make table
40
+ log(`Based on local functions folder ${functionsDir}, these are the functions detected`);
41
+ const table = new AsciiTable(`Netlify Functions (in local functions folder)`);
42
+ table.setHeading('Name', 'URL', 'deployed');
43
+ normalizedFunctions.forEach(({ isDeployed, name, url }) => {
44
+ table.addRow(name, url, isDeployed ? 'yes' : 'no');
45
+ });
46
+ log(table.toString());
47
+ };
56
48
  /**
57
49
  * Creates the `netlify functions:list` command
58
50
  * @param {import('../base-command.mjs').default} program
59
51
  * @returns
60
52
  */
61
- export const createFunctionsListCommand = (program) =>
62
- program
53
+ // @ts-expect-error TS(7006) FIXME: Parameter 'program' implicitly has an 'any' type.
54
+ export const createFunctionsListCommand = (program) => program
63
55
  .command('functions:list')
64
56
  .alias('function:list')
65
- .description(
66
- `List functions that exist locally
57
+ .description(`List functions that exist locally
67
58
  Helpful for making sure that you have formatted your functions correctly
68
59
 
69
- NOT the same as listing the functions that have been deployed. For that info you need to go to your Netlify deploy log.`,
70
- )
60
+ NOT the same as listing the functions that have been deployed. For that info you need to go to your Netlify deploy log.`)
71
61
  .option('-f, --functions <dir>', 'Specify a functions directory to list')
72
62
  .option('--json', 'Output function data as JSON')
73
63
  .hook('preAction', requiresSiteInfo)
74
- .action(functionsList)
64
+ .action(functionsList);