netlify-cli 15.10.0 → 15.11.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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
- "version": "15.10.0",
3
+ "version": "15.11.0",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "netlify-cli",
9
- "version": "15.10.0",
9
+ "version": "15.11.0",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "netlify-cli",
3
3
  "description": "Netlify command line tool",
4
- "version": "15.10.0",
4
+ "version": "15.11.0",
5
5
  "author": "Netlify Inc.",
6
6
  "type": "module",
7
7
  "engines": {
@@ -1,9 +1,14 @@
1
1
  // @ts-check
2
+ import { version as nodeVersion } from 'process'
3
+
2
4
  import CronParser from 'cron-parser'
5
+ import semver from 'semver'
3
6
 
4
7
  import { error as errorExit } from '../../utils/command-helpers.mjs'
5
8
  import { BACKGROUND } from '../../utils/functions/get-functions.mjs'
6
9
 
10
+ const V2_MIN_NODE_VERSION = '18.0.0'
11
+
7
12
  // Returns a new set with all elements of `setA` that don't exist in `setB`.
8
13
  const difference = (setA, setB) => new Set([...setA].filter((item) => !setB.has(item)))
9
14
 
@@ -27,12 +32,13 @@ export default class NetlifyFunction {
27
32
  timeoutBackground,
28
33
  timeoutSynchronous,
29
34
  }) {
35
+ this.buildError = null
30
36
  this.config = config
31
37
  this.directory = directory
32
38
  this.errorExit = errorExit
33
39
  this.mainFile = mainFile
34
40
  this.name = name
35
- this.displayName = displayName
41
+ this.displayName = displayName ?? name
36
42
  this.projectRoot = projectRoot
37
43
  this.runtime = runtime
38
44
  this.timeoutBackground = timeoutBackground
@@ -63,6 +69,10 @@ export default class NetlifyFunction {
63
69
  return Boolean(this.schedule)
64
70
  }
65
71
 
72
+ isSupported() {
73
+ return !(this.buildData?.runtimeAPIVersion === 2 && semver.lt(nodeVersion, V2_MIN_NODE_VERSION))
74
+ }
75
+
66
76
  async getNextRun() {
67
77
  if (!(await this.isScheduled())) {
68
78
  return null
@@ -93,11 +103,22 @@ export default class NetlifyFunction {
93
103
  const srcFilesDiff = this.getSrcFilesDiff(srcFilesSet)
94
104
 
95
105
  this.buildData = buildData
106
+ this.buildError = null
96
107
  this.srcFiles = srcFilesSet
97
108
  this.schedule = schedule || this.schedule
98
109
 
110
+ if (!this.isSupported()) {
111
+ throw new Error(
112
+ `Function requires Node.js version ${V2_MIN_NODE_VERSION} or above, but ${nodeVersion.slice(
113
+ 1,
114
+ )} is installed. Refer to https://ntl.fyi/functions-node18 for information on how to update.`,
115
+ )
116
+ }
117
+
99
118
  return { includedFiles, srcFilesDiff }
100
119
  } catch (error) {
120
+ this.buildError = error
121
+
101
122
  return { error }
102
123
  }
103
124
  }
@@ -118,6 +139,10 @@ export default class NetlifyFunction {
118
139
  async invoke(event, context) {
119
140
  await this.buildQueue
120
141
 
142
+ if (this.buildError) {
143
+ return { result: null, error: { errorMessage: this.buildError.message } }
144
+ }
145
+
121
146
  const timeout = this.isBackground ? this.timeoutBackground : this.timeoutSynchronous
122
147
 
123
148
  try {
@@ -6,15 +6,7 @@ import { env } from 'process'
6
6
  import { listFunctions } from '@netlify/zip-it-and-ship-it'
7
7
  import extractZip from 'extract-zip'
8
8
 
9
- import {
10
- chalk,
11
- getTerminalLink,
12
- log,
13
- NETLIFYDEVERR,
14
- NETLIFYDEVLOG,
15
- warn,
16
- watchDebounced,
17
- } from '../../utils/command-helpers.mjs'
9
+ import { chalk, log, NETLIFYDEVERR, NETLIFYDEVLOG, warn, watchDebounced } from '../../utils/command-helpers.mjs'
18
10
  import { INTERNAL_FUNCTIONS_FOLDER, SERVE_FUNCTIONS_FOLDER } from '../../utils/functions/functions.mjs'
19
11
  import { BACKGROUND_FUNCTIONS_WARNING } from '../log.mjs'
20
12
  import { getPathInProject } from '../settings.mjs'
@@ -70,21 +62,23 @@ export class FunctionsRegistry {
70
62
  )
71
63
  }
72
64
 
73
- async buildFunctionAndWatchFiles(func, { verbose = false } = {}) {
74
- if (verbose) {
75
- log(`${NETLIFYDEVLOG} ${chalk.magenta('Reloading')} function ${chalk.yellow(func.name)}...`)
65
+ async buildFunctionAndWatchFiles(func, firstLoad = false) {
66
+ if (!firstLoad) {
67
+ log(`${NETLIFYDEVLOG} ${chalk.magenta('Reloading')} function ${chalk.yellow(func.displayName)}...`)
76
68
  }
77
69
 
78
- const { error_, includedFiles, srcFilesDiff } = await func.build({ cache: this.buildCache })
70
+ const { error: buildError, includedFiles, srcFilesDiff } = await func.build({ cache: this.buildCache })
79
71
 
80
- if (error_) {
72
+ if (buildError) {
81
73
  log(
82
- `${NETLIFYDEVERR} ${chalk.red('Failed')} reloading function ${chalk.yellow(func.name)} with error:\n${
83
- error_.message
74
+ `${NETLIFYDEVERR} ${chalk.red('Failed to load')} function ${chalk.yellow(func.displayName)}: ${
75
+ buildError.message
84
76
  }`,
85
77
  )
86
- } else if (verbose) {
87
- log(`${NETLIFYDEVLOG} ${chalk.green('Reloaded')} function ${chalk.yellow(func.name)}`)
78
+ } else {
79
+ const verb = firstLoad ? 'Loaded' : 'Reloaded'
80
+
81
+ log(`${NETLIFYDEVLOG} ${chalk.green(verb)} function ${chalk.yellow(func.displayName)}`)
88
82
  }
89
83
 
90
84
  // If the build hasn't resulted in any files being added or removed, there
@@ -116,7 +110,7 @@ export class FunctionsRegistry {
116
110
 
117
111
  const newWatcher = await watchDebounced(filesToWatch, {
118
112
  onChange: () => {
119
- this.buildFunctionAndWatchFiles(func, { verbose: true })
113
+ this.buildFunctionAndWatchFiles(func, false)
120
114
  },
121
115
  })
122
116
 
@@ -163,14 +157,8 @@ export class FunctionsRegistry {
163
157
  }
164
158
 
165
159
  this.functions.set(name, func)
166
- this.buildFunctionAndWatchFiles(func)
167
160
 
168
- log(
169
- `${NETLIFYDEVLOG} ${chalk.green('Loaded')} function ${getTerminalLink(
170
- chalk.yellow(func.displayName || name),
171
- func.url,
172
- )}.`,
173
- )
161
+ this.buildFunctionAndWatchFiles(func, true)
174
162
  }
175
163
 
176
164
  // This function is here so we can mock it in tests
@@ -11,7 +11,7 @@ if (isMainThread) {
11
11
 
12
12
  sourceMapSupport.install()
13
13
 
14
- lambdaLocal.getLogger().level = 'warn'
14
+ lambdaLocal.getLogger().level = 'alert'
15
15
 
16
16
  const { clientContext, entryFilePath, event, timeoutMs } = workerData
17
17