netlify-cli 15.9.1-rc.0 → 15.10.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 (36) hide show
  1. package/npm-shrinkwrap.json +236 -738
  2. package/package.json +6 -5
  3. package/src/commands/base-command.mjs +59 -195
  4. package/src/commands/deploy/deploy.mjs +9 -21
  5. package/src/commands/dev/dev.mjs +15 -21
  6. package/src/commands/functions/functions-create.mjs +3 -0
  7. package/src/commands/functions/functions-invoke.mjs +5 -8
  8. package/src/commands/init/init.mjs +1 -1
  9. package/src/commands/link/link.mjs +5 -5
  10. package/src/commands/serve/serve.mjs +5 -11
  11. package/src/commands/sites/sites-create-template.mjs +1 -1
  12. package/src/commands/sites/sites-create.mjs +1 -1
  13. package/src/functions-templates/typescript/hello-world/package-lock.json +6 -6
  14. package/src/lib/edge-functions/bootstrap.mjs +1 -1
  15. package/src/lib/edge-functions/headers.mjs +1 -0
  16. package/src/lib/edge-functions/internal.mjs +3 -5
  17. package/src/lib/edge-functions/proxy.mjs +4 -27
  18. package/src/lib/functions/runtimes/js/index.mjs +1 -1
  19. package/src/lib/functions/runtimes/js/worker.mjs +1 -1
  20. package/src/lib/spinner.mjs +1 -1
  21. package/src/utils/command-helpers.mjs +7 -16
  22. package/src/utils/detect-server-settings.mjs +198 -147
  23. package/src/utils/framework-server.mjs +2 -2
  24. package/src/utils/functions/functions.mjs +0 -7
  25. package/src/utils/get-repo-data.mjs +6 -5
  26. package/src/utils/init/config-github.mjs +2 -2
  27. package/src/utils/init/config-manual.mjs +7 -24
  28. package/src/utils/init/frameworks.mjs +23 -0
  29. package/src/utils/init/utils.mjs +63 -62
  30. package/src/utils/proxy-server.mjs +4 -7
  31. package/src/utils/proxy.mjs +0 -4
  32. package/src/utils/run-build.mjs +7 -58
  33. package/src/utils/shell.mjs +3 -14
  34. package/src/utils/state-config.mjs +1 -5
  35. package/src/utils/static-server.mjs +0 -4
  36. package/src/utils/build-info.mjs +0 -19
@@ -2,6 +2,7 @@
2
2
  import fs from 'fs'
3
3
  import { createRequire } from 'module'
4
4
  import path from 'path'
5
+ import process from 'process'
5
6
 
6
7
  import inquirer from 'inquirer'
7
8
  import fetch from 'node-fetch'
@@ -55,18 +56,14 @@ const formatQstring = function (querystring) {
55
56
  return ''
56
57
  }
57
58
 
58
- /**
59
- * process payloads from flag
60
- * @param {string} payloadString
61
- * @param {string} workingDir
62
- */
63
- const processPayloadFromFlag = function (payloadString, workingDir) {
59
+ /** process payloads from flag */
60
+ const processPayloadFromFlag = function (payloadString) {
64
61
  if (payloadString) {
65
62
  // case 1: jsonstring
66
63
  let payload = tryParseJSON(payloadString)
67
64
  if (payload) return payload
68
65
  // case 2: jsonpath
69
- const payloadpath = path.join(workingDir, payloadString)
66
+ const payloadpath = path.join(process.cwd(), payloadString)
70
67
  const pathexists = fs.existsSync(payloadpath)
71
68
  if (pathexists) {
72
69
  try {
@@ -213,7 +210,7 @@ const functionsInvoke = async (nameArgument, options, command) => {
213
210
  // }
214
211
  }
215
212
  }
216
- const payload = processPayloadFromFlag(options.payload, command.workingDir)
213
+ const payload = processPayloadFromFlag(options.payload)
217
214
  body = { ...body, ...payload }
218
215
 
219
216
  try {
@@ -196,7 +196,7 @@ export const init = async (options, command) => {
196
196
  }
197
197
 
198
198
  // Look for local repo
199
- const repoData = await getRepoData({ workingDir: command.workingDir, remoteName: options.gitRemoteName })
199
+ const repoData = await getRepoData({ remoteName: options.gitRemoteName })
200
200
  if (repoData.error) {
201
201
  await handleNoGitRemoteAndExit({ command, error: repoData.error, state })
202
202
  }
@@ -11,11 +11,11 @@ import { track } from '../../utils/telemetry/index.mjs'
11
11
 
12
12
  /**
13
13
  *
14
- * @param {import('../base-command.mjs').default} command
14
+ * @param {import('../base-command.mjs').NetlifyOptions} netlify
15
15
  * @param {import('commander').OptionValues} options
16
16
  */
17
- const linkPrompt = async (command, options) => {
18
- const { api, state } = command.netlify
17
+ const linkPrompt = async (netlify, options) => {
18
+ const { api, state } = netlify
19
19
 
20
20
  const SITE_NAME_PROMPT = 'Search by full or partial site name'
21
21
  const SITE_LIST_PROMPT = 'Choose from a list of your recently updated sites'
@@ -24,7 +24,7 @@ const linkPrompt = async (command, options) => {
24
24
  let GIT_REMOTE_PROMPT = 'Use the current git remote origin URL'
25
25
  let site
26
26
  // Get git remote data if exists
27
- const repoData = await getRepoData({ workingDir: command.workingDir, remoteName: options.gitRemoteName })
27
+ const repoData = await getRepoData({ remoteName: options.gitRemoteName })
28
28
 
29
29
  let linkChoices = [SITE_NAME_PROMPT, SITE_LIST_PROMPT, SITE_ID_PROMPT]
30
30
 
@@ -326,7 +326,7 @@ export const link = async (options, command) => {
326
326
  kind: 'byName',
327
327
  })
328
328
  } else {
329
- siteData = await linkPrompt(command, options)
329
+ siteData = await linkPrompt(command.netlify, options)
330
330
  }
331
331
  return siteData
332
332
  }
@@ -69,10 +69,10 @@ const serve = async (options, command) => {
69
69
  // Netlify Build are loaded.
70
70
  await getInternalFunctionsDir({ base: site.root, ensureExists: true })
71
71
 
72
- /** @type {Partial<import('../../utils/types.js').ServerSettings>} */
72
+ /** @type {Partial<import('../../utils/types').ServerSettings>} */
73
73
  let settings = {}
74
74
  try {
75
- settings = await detectServerSettings(devConfig, options, command)
75
+ settings = await detectServerSettings(devConfig, options, site.root)
76
76
 
77
77
  cachedConfig.config = getConfigWithPlugins(cachedConfig.config, settings)
78
78
  } catch (error_) {
@@ -87,13 +87,7 @@ const serve = async (options, command) => {
87
87
  `${NETLIFYDEVWARN} Changes will not be hot-reloaded, so if you need to rebuild your site you must exit and run 'netlify serve' again`,
88
88
  )
89
89
 
90
- const { configPath: configPathOverride } = await runBuildTimeline({
91
- cachedConfig,
92
- options,
93
- settings,
94
- projectDir: command.workingDir,
95
- site,
96
- })
90
+ const { configPath: configPathOverride } = await runBuildTimeline({ cachedConfig, options, settings, site })
97
91
 
98
92
  await startFunctionsServer({
99
93
  api,
@@ -123,7 +117,8 @@ const serve = async (options, command) => {
123
117
 
124
118
  // TODO: We should consolidate this with the existing config watcher.
125
119
  const getUpdatedConfig = async () => {
126
- const { config: newConfig } = await command.getConfig({ cwd: command.workingDir, offline: true, state })
120
+ const cwd = options.cwd || process.cwd()
121
+ const { config: newConfig } = await command.getConfig({ cwd, offline: true, state })
127
122
  const normalizedNewConfig = normalizeConfig(newConfig)
128
123
 
129
124
  return normalizedNewConfig
@@ -140,7 +135,6 @@ const serve = async (options, command) => {
140
135
  getUpdatedConfig,
141
136
  inspectSettings,
142
137
  offline: options.offline,
143
- projectDir: command.workingDir,
144
138
  settings,
145
139
  site,
146
140
  siteInfo,
@@ -197,7 +197,7 @@ const sitesCreateTemplate = async (repository, options, command) => {
197
197
 
198
198
  if (options.withCi) {
199
199
  log('Configuring CI')
200
- const repoData = await getRepoData({ workingDir: command.workingDir })
200
+ const repoData = await getRepoData()
201
201
  await configureRepo({ command, siteId: site.id, repoData, manual: options.manual })
202
202
  }
203
203
 
@@ -102,7 +102,7 @@ export const sitesCreate = async (options, command) => {
102
102
 
103
103
  if (options.withCi) {
104
104
  log('Configuring CI')
105
- const repoData = await getRepoData({ workingDir: command.workingDir })
105
+ const repoData = await getRepoData()
106
106
  await configureRepo({ command, siteId: site.id, repoData, manual: options.manual })
107
107
  }
108
108
 
@@ -26,9 +26,9 @@
26
26
  }
27
27
  },
28
28
  "node_modules/@types/node": {
29
- "version": "14.18.53",
30
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz",
31
- "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A=="
29
+ "version": "14.18.54",
30
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.54.tgz",
31
+ "integrity": "sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw=="
32
32
  },
33
33
  "node_modules/is-promise": {
34
34
  "version": "4.0.0",
@@ -58,9 +58,9 @@
58
58
  }
59
59
  },
60
60
  "@types/node": {
61
- "version": "14.18.53",
62
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz",
63
- "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A=="
61
+ "version": "14.18.54",
62
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.54.tgz",
63
+ "integrity": "sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw=="
64
64
  },
65
65
  "is-promise": {
66
66
  "version": "4.0.0",
@@ -1,5 +1,5 @@
1
1
  import { env } from 'process'
2
2
 
3
- const latestBootstrapURL = 'https://64ae60d920fd0f000865bcfc--edge.netlify.com/bootstrap/index-combined.ts'
3
+ const latestBootstrapURL = 'https://64c264287e9cbb0008621df3--edge.netlify.com/bootstrap/index-combined.ts'
4
4
 
5
5
  export const getBootstrapURL = () => env.NETLIFY_EDGE_BOOTSTRAP || latestBootstrapURL
@@ -2,6 +2,7 @@
2
2
  import { Buffer } from 'buffer'
3
3
 
4
4
  export const headers = {
5
+ DeployID: 'x-nf-deploy-id',
5
6
  FeatureFlags: 'x-nf-feature-flags',
6
7
  ForwardedHost: 'x-forwarded-host',
7
8
  Functions: 'x-nf-edge-functions',
@@ -1,16 +1,14 @@
1
1
  // @ts-check
2
2
  import { readFile, stat } from 'fs/promises'
3
3
  import { dirname, join, resolve } from 'path'
4
+ import { cwd } from 'process'
4
5
 
5
6
  import { getPathInProject } from '../settings.mjs'
6
7
 
7
8
  import { INTERNAL_EDGE_FUNCTIONS_FOLDER } from './consts.mjs'
8
9
 
9
- /**
10
- * @param {string} workingDir
11
- */
12
- export const getInternalFunctions = async (workingDir) => {
13
- const path = join(workingDir, getPathInProject([INTERNAL_EDGE_FUNCTIONS_FOLDER]))
10
+ export const getInternalFunctions = async () => {
11
+ const path = join(cwd(), getPathInProject([INTERNAL_EDGE_FUNCTIONS_FOLDER]))
14
12
 
15
13
  try {
16
14
  const stats = await stat(path)
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
  import { Buffer } from 'buffer'
3
3
  import { relative } from 'path'
4
- import { env } from 'process'
4
+ import { cwd, env } from 'process'
5
5
 
6
6
  // eslint-disable-next-line import/no-namespace
7
7
  import * as bundler from '@netlify/edge-bundler'
@@ -62,26 +62,6 @@ export const createAccountInfoHeader = (accountInfo = {}) => {
62
62
  return Buffer.from(accountString).toString('base64')
63
63
  }
64
64
 
65
- /**
66
- *
67
- * @param {object} config
68
- * @param {*} config.accountId
69
- * @param {*} config.config
70
- * @param {*} config.configPath
71
- * @param {*} config.debug
72
- * @param {*} config.env
73
- * @param {*} config.geoCountry
74
- * @param {*} config.geolocationMode
75
- * @param {*} config.getUpdatedConfig
76
- * @param {*} config.inspectSettings
77
- * @param {*} config.mainPort
78
- * @param {boolean=} config.offline
79
- * @param {*} config.passthroughPort
80
- * @param {*} config.projectDir
81
- * @param {*} config.siteInfo
82
- * @param {*} config.state
83
- * @returns
84
- */
85
65
  export const initializeProxy = async ({
86
66
  accountId,
87
67
  config,
@@ -99,11 +79,7 @@ export const initializeProxy = async ({
99
79
  siteInfo,
100
80
  state,
101
81
  }) => {
102
- const {
103
- functions: internalFunctions,
104
- importMap,
105
- path: internalFunctionsPath,
106
- } = await getInternalFunctions(projectDir)
82
+ const { functions: internalFunctions, importMap, path: internalFunctionsPath } = await getInternalFunctions()
107
83
  const userFunctionsPath = config.build.edge_functions
108
84
  const isolatePort = await getAvailablePort()
109
85
 
@@ -139,6 +115,7 @@ export const initializeProxy = async ({
139
115
 
140
116
  // Setting header with geolocation and site info.
141
117
  req.headers[headers.Geo] = Buffer.from(JSON.stringify(geoLocation)).toString('base64')
118
+ req.headers[headers.DeployID] = '0'
142
119
  req.headers[headers.Site] = createSiteInfoHeader(siteInfo)
143
120
  req.headers[headers.Account] = createAccountInfoHeader({ id: accountId })
144
121
 
@@ -156,7 +133,7 @@ export const initializeProxy = async ({
156
133
  )} matches declaration for edge function ${chalk.yellow(
157
134
  functionName,
158
135
  )}, but there's no matching function file in ${chalk.yellow(
159
- relative(projectDir, userFunctionsPath),
136
+ relative(cwd(), userFunctionsPath),
160
137
  )}. Please visit ${chalk.blue('https://ntl.fyi/edge-create')} for more information.`,
161
138
  )
162
139
  })
@@ -3,7 +3,7 @@ import { dirname } from 'path'
3
3
  import { pathToFileURL } from 'url'
4
4
  import { Worker } from 'worker_threads'
5
5
 
6
- import lambdaLocal from '@skn0tt/lambda-local'
6
+ import lambdaLocal from 'lambda-local'
7
7
  import winston from 'winston'
8
8
 
9
9
  import detectNetlifyLambdaBuilder from './builders/netlify-lambda.mjs'
@@ -1,8 +1,8 @@
1
1
  import { createServer } from 'net'
2
2
  import { isMainThread, workerData, parentPort } from 'worker_threads'
3
3
 
4
- import lambdaLocal from '@skn0tt/lambda-local'
5
4
  import { isStream } from 'is-stream'
5
+ import lambdaLocal from 'lambda-local'
6
6
  import sourceMapSupport from 'source-map-support'
7
7
 
8
8
  if (isMainThread) {
@@ -17,7 +17,7 @@ export const startSpinner = ({ text }) =>
17
17
  * Stops the spinner with the following text
18
18
  * @param {object} config
19
19
  * @param {ora.Ora} config.spinner
20
- * @param {boolean} [config.error]
20
+ * @param {object} [config.error]
21
21
  * @param {string} [config.text]
22
22
  * @returns {void}
23
23
  */
@@ -24,7 +24,7 @@ const argv = process.argv.slice(2)
24
24
  * Chalk instance for CLI that can be initialized with no colors mode
25
25
  * needed for json outputs where we don't want to have colors
26
26
  * @param {boolean} noColors - disable chalk colors
27
- * @return {import('chalk').ChalkInstance} - default or custom chalk instance
27
+ * @return {object} - default or custom chalk instance
28
28
  */
29
29
  const safeChalk = function (noColors) {
30
30
  if (noColors) {
@@ -174,18 +174,12 @@ export const warn = (message = '') => {
174
174
 
175
175
  /**
176
176
  * throws an error or log it
177
- * @param {unknown} message
177
+ * @param {string|Error} message
178
178
  * @param {object} [options]
179
179
  * @param {boolean} [options.exit]
180
180
  */
181
181
  export const error = (message = '', options = {}) => {
182
- const err =
183
- message instanceof Error
184
- ? message
185
- : // eslint-disable-next-line unicorn/no-nested-ternary
186
- typeof message === 'string'
187
- ? new Error(message)
188
- : /** @type {Error} */ ({ message, stack: undefined, name: 'Error' })
182
+ const err = message instanceof Error ? message : new Error(message)
189
183
 
190
184
  if (options.exit === false) {
191
185
  const bang = chalk.red(BANG)
@@ -204,13 +198,10 @@ export const exit = (code = 0) => {
204
198
  process.exit(code)
205
199
  }
206
200
 
207
- /**
208
- * When `build.publish` is not set by the user, the CLI behavior differs in
209
- * several ways. It detects it by checking if `build.publish` is `undefined`.
210
- * However, `@netlify/config` adds a default value to `build.publish`.
211
- * This removes 'publish' and 'publishOrigin' in this case.
212
- * @param {*} config
213
- */
201
+ // When `build.publish` is not set by the user, the CLI behavior differs in
202
+ // several ways. It detects it by checking if `build.publish` is `undefined`.
203
+ // However, `@netlify/config` adds a default value to `build.publish`.
204
+ // This removes 'publish' and 'publishOrigin' in this case.
214
205
  export const normalizeConfig = (config) => {
215
206
  // Unused var here is in order to omit 'publish' from build config
216
207
  // eslint-disable-next-line no-unused-vars