netlify-cli 17.7.0 → 17.8.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": "17.7.0",
3
+ "version": "17.8.0",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "netlify-cli",
9
- "version": "17.7.0",
9
+ "version": "17.8.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": "17.7.0",
4
+ "version": "17.8.0",
5
5
  "author": "Netlify Inc.",
6
6
  "type": "module",
7
7
  "engines": {
@@ -253,7 +253,9 @@ export class EdgeFunctionsRegistry {
253
253
  */
254
254
  processGraph(graph) {
255
255
  if (!graph) {
256
- warn('Could not process edge functions dependency graph. Live reload will not be available.');
256
+ if (this.functions.length !== 0) {
257
+ warn('Could not process edge functions dependency graph. Live reload will not be available.');
258
+ }
257
259
  return;
258
260
  }
259
261
  // Creating a Map from `this.functions` that maps function paths to function
@@ -8,9 +8,7 @@ import { BACKGROUND } from '../../utils/functions/get-functions.js';
8
8
  const TYPESCRIPT_EXTENSIONS = new Set(['.cts', '.mts', '.ts']);
9
9
  const V2_MIN_NODE_VERSION = '18.14.0';
10
10
  // Returns a new set with all elements of `setA` that don't exist in `setB`.
11
- // @ts-expect-error TS(7006) FIXME: Parameter 'setA' implicitly has an 'any' type.
12
11
  const difference = (setA, setB) => new Set([...setA].filter((item) => !setB.has(item)));
13
- // @ts-expect-error TS(7006) FIXME: Parameter 'schedule' implicitly has an 'any' type.
14
12
  const getNextRun = function (schedule) {
15
13
  const cron = CronParser.parseExpression(schedule, {
16
14
  tz: 'Etc/UTC',
@@ -41,60 +39,40 @@ export default class NetlifyFunction {
41
39
  timeoutBackground,
42
40
  // @ts-expect-error TS(7031) FIXME: Binding element 'timeoutSynchronous' implicitly ha... Remove this comment to see the full error message
43
41
  timeoutSynchronous, }) {
44
- // @ts-expect-error TS(2339) FIXME: Property 'blobsContext' does not exist on type 'Ne... Remove this comment to see the full error message
45
- this.blobsContext = blobsContext;
46
- // @ts-expect-error TS(2339) FIXME: Property 'buildError' does not exist on type 'Netl... Remove this comment to see the full error message
47
42
  this.buildError = null;
43
+ // List of the function's source files. This starts out as an empty set
44
+ // and will get populated on every build.
45
+ this.srcFiles = new Set();
46
+ this.blobsContext = blobsContext;
48
47
  // @ts-expect-error TS(2339) FIXME: Property 'config' does not exist on type 'NetlifyF... Remove this comment to see the full error message
49
48
  this.config = config;
50
- // @ts-expect-error TS(2339) FIXME: Property 'directory' does not exist on type 'Netli... Remove this comment to see the full error message
51
49
  this.directory = directory;
52
- // @ts-expect-error TS(2339) FIXME: Property 'errorExit' does not exist on type 'Netli... Remove this comment to see the full error message
53
- this.errorExit = errorExit;
54
- // @ts-expect-error TS(2339) FIXME: Property 'mainFile' does not exist on type 'Netlif... Remove this comment to see the full error message
55
50
  this.mainFile = mainFile;
56
- // @ts-expect-error TS(2339) FIXME: Property 'name' does not exist on type 'NetlifyFun... Remove this comment to see the full error message
57
51
  this.name = name;
58
- // @ts-expect-error TS(2339) FIXME: Property 'displayName' does not exist on type 'Net... Remove this comment to see the full error message
59
52
  this.displayName = displayName ?? name;
60
- // @ts-expect-error TS(2339) FIXME: Property 'projectRoot' does not exist on type 'Net... Remove this comment to see the full error message
61
53
  this.projectRoot = projectRoot;
62
54
  // @ts-expect-error TS(2339) FIXME: Property 'runtime' does not exist on type 'Netlify... Remove this comment to see the full error message
63
55
  this.runtime = runtime;
64
- // @ts-expect-error TS(2339) FIXME: Property 'timeoutBackground' does not exist on typ... Remove this comment to see the full error message
65
56
  this.timeoutBackground = timeoutBackground;
66
- // @ts-expect-error TS(2339) FIXME: Property 'timeoutSynchronous' does not exist on ty... Remove this comment to see the full error message
67
57
  this.timeoutSynchronous = timeoutSynchronous;
68
58
  // @ts-expect-error TS(2339) FIXME: Property 'settings' does not exist on type 'Netlif... Remove this comment to see the full error message
69
59
  this.settings = settings;
70
- // Determines whether this is a background function based on the function
71
- // name.
72
- // @ts-expect-error TS(2339) FIXME: Property 'isBackground' does not exist on type 'Ne... Remove this comment to see the full error message
73
60
  this.isBackground = name.endsWith(BACKGROUND);
74
61
  const functionConfig = config.functions && config.functions[name];
75
- // @ts-expect-error TS(2339) FIXME: Property 'schedule' does not exist on type 'Netlif... Remove this comment to see the full error message
76
62
  this.schedule = functionConfig && functionConfig.schedule;
77
- // List of the function's source files. This starts out as an empty set
78
- // and will get populated on every build.
79
- // @ts-expect-error TS(2339) FIXME: Property 'srcFiles' does not exist on type 'Netlif... Remove this comment to see the full error message
80
63
  this.srcFiles = new Set();
81
64
  }
82
65
  get filename() {
83
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
84
66
  if (!this.buildData?.mainFile) {
85
67
  return null;
86
68
  }
87
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
88
69
  return basename(this.buildData.mainFile);
89
70
  }
90
71
  getRecommendedExtension() {
91
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
92
72
  if (this.buildData?.runtimeAPIVersion !== 2) {
93
73
  return;
94
74
  }
95
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
96
75
  const extension = this.buildData?.mainFile ? extname(this.buildData.mainFile) : undefined;
97
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
98
76
  const moduleFormat = this.buildData?.outputModuleFormat;
99
77
  if (moduleFormat === 'esm') {
100
78
  return;
@@ -108,18 +86,14 @@ export default class NetlifyFunction {
108
86
  }
109
87
  hasValidName() {
110
88
  // same as https://github.com/netlify/bitballoon/blob/fbd7881e6c8e8c48e7a0145da4ee26090c794108/app/models/deploy.rb#L482
111
- // @ts-expect-error TS(2339) FIXME: Property 'name' does not exist on type 'NetlifyFun... Remove this comment to see the full error message
112
89
  // eslint-disable-next-line unicorn/better-regex
113
90
  return /^[A-Za-z0-9_-]+$/.test(this.name);
114
91
  }
115
92
  async isScheduled() {
116
- // @ts-expect-error TS(2339) FIXME: Property 'buildQueue' does not exist on type 'Netl... Remove this comment to see the full error message
117
93
  await this.buildQueue;
118
- // @ts-expect-error TS(2339) FIXME: Property 'schedule' does not exist on type 'Netlif... Remove this comment to see the full error message
119
94
  return Boolean(this.schedule);
120
95
  }
121
96
  isSupported() {
122
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
123
97
  return !(this.buildData?.runtimeAPIVersion === 2 && semver.lt(nodeVersion, V2_MIN_NODE_VERSION));
124
98
  }
125
99
  isTypeScript() {
@@ -132,7 +106,7 @@ export default class NetlifyFunction {
132
106
  if (!(await this.isScheduled())) {
133
107
  return null;
134
108
  }
135
- // @ts-expect-error TS(2339) FIXME: Property 'schedule' does not exist on type 'Netlif... Remove this comment to see the full error message
109
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
136
110
  return getNextRun(this.schedule);
137
111
  }
138
112
  // The `build` method transforms source files into invocable functions. Its
@@ -146,24 +120,17 @@ export default class NetlifyFunction {
146
120
  const buildFunction = await this.runtime.getBuildFunction({
147
121
  // @ts-expect-error TS(2339) FIXME: Property 'config' does not exist on type 'NetlifyF... Remove this comment to see the full error message
148
122
  config: this.config,
149
- // @ts-expect-error TS(2339) FIXME: Property 'directory' does not exist on type 'Netli... Remove this comment to see the full error message
150
123
  directory: this.directory,
151
- // @ts-expect-error TS(2339) FIXME: Property 'errorExit' does not exist on type 'Netli... Remove this comment to see the full error message
152
- errorExit: this.errorExit,
124
+ errorExit,
153
125
  func: this,
154
- // @ts-expect-error TS(2339) FIXME: Property 'projectRoot' does not exist on type 'Net... Remove this comment to see the full error message
155
126
  projectRoot: this.projectRoot,
156
127
  });
157
- // @ts-expect-error TS(2339) FIXME: Property 'buildQueue' does not exist on type 'Netl... Remove this comment to see the full error message
158
128
  this.buildQueue = buildFunction({ cache });
159
129
  try {
160
- // @ts-expect-error TS(2339) FIXME: Property 'buildQueue' does not exist on type 'Netl... Remove this comment to see the full error message
161
130
  const { includedFiles = [], schedule, srcFiles, ...buildData } = await this.buildQueue;
162
131
  const srcFilesSet = new Set(srcFiles);
163
132
  const srcFilesDiff = this.getSrcFilesDiff(srcFilesSet);
164
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
165
133
  this.buildData = buildData;
166
- // @ts-expect-error TS(2339) FIXME: Property 'buildError' does not exist on type 'Netl... Remove this comment to see the full error message
167
134
  this.buildError = null;
168
135
  // @ts-expect-error TS(2339) FIXME: Property 'srcFiles' does not exist on type 'Netlif... Remove this comment to see the full error message
169
136
  this.srcFiles = srcFilesSet;
@@ -175,24 +142,18 @@ export default class NetlifyFunction {
175
142
  return { includedFiles, srcFilesDiff };
176
143
  }
177
144
  catch (error) {
178
- // @ts-expect-error TS(2339) FIXME: Property 'buildError' does not exist on type 'Netl... Remove this comment to see the full error message
179
145
  this.buildError = error;
180
146
  return { error };
181
147
  }
182
148
  }
183
149
  async getBuildData() {
184
- // @ts-expect-error TS(2339) FIXME: Property 'buildQueue' does not exist on type 'Netl... Remove this comment to see the full error message
185
150
  await this.buildQueue;
186
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
187
151
  return this.buildData;
188
152
  }
189
153
  // Compares a new set of source files against a previous one, returning an
190
154
  // object with two Sets, one with added and the other with deleted files.
191
- // @ts-expect-error TS(7006) FIXME: Parameter 'newSrcFiles' implicitly has an 'any' ty... Remove this comment to see the full error message
192
155
  getSrcFilesDiff(newSrcFiles) {
193
- // @ts-expect-error TS(2339) FIXME: Property 'srcFiles' does not exist on type 'Netlif... Remove this comment to see the full error message
194
156
  const added = difference(newSrcFiles, this.srcFiles);
195
- // @ts-expect-error TS(2339) FIXME: Property 'srcFiles' does not exist on type 'Netlif... Remove this comment to see the full error message
196
157
  const deleted = difference(this.srcFiles, newSrcFiles);
197
158
  return {
198
159
  added,
@@ -201,22 +162,16 @@ export default class NetlifyFunction {
201
162
  }
202
163
  // Invokes the function and returns its response object.
203
164
  async invoke(event = {}, context = {}) {
204
- // @ts-expect-error TS(2339) FIXME: Property 'buildQueue' does not exist on type 'Netl... Remove this comment to see the full error message
205
165
  await this.buildQueue;
206
- // @ts-expect-error TS(2339) FIXME: Property 'buildError' does not exist on type 'Netl... Remove this comment to see the full error message
207
166
  if (this.buildError) {
208
167
  // @ts-expect-error TS(2339) FIXME: Property 'buildError' does not exist on type 'Netl... Remove this comment to see the full error message
209
168
  return { result: null, error: { errorMessage: this.buildError.message } };
210
169
  }
211
- // @ts-expect-error TS(2339) FIXME: Property 'isBackground' does not exist on type 'Ne... Remove this comment to see the full error message
212
170
  const timeout = this.isBackground ? this.timeoutBackground : this.timeoutSynchronous;
213
171
  const environment = {};
214
- // @ts-expect-error TS(2339) FIXME: Property 'blobsContext' does not exist on type 'Ne... Remove this comment to see the full error message
215
172
  if (this.blobsContext) {
216
173
  const payload = JSON.stringify({
217
- // @ts-expect-error TS(2339) FIXME: Property 'blobsContext' does not exist on type 'Ne... Remove this comment to see the full error message
218
174
  url: this.blobsContext.edgeURL,
219
- // @ts-expect-error TS(2339) FIXME: Property 'blobsContext' does not exist on type 'Ne... Remove this comment to see the full error message
220
175
  token: this.blobsContext.token,
221
176
  });
222
177
  // @ts-expect-error TS(2339) FIXME: Property 'blobs' does not exist on type '{}'.
@@ -239,20 +194,15 @@ export default class NetlifyFunction {
239
194
  }
240
195
  /**
241
196
  * Matches all routes agains the incoming request. If a match is found, then the matched route is returned.
242
- * @param {string} rawPath
243
- * @param {string} method
244
197
  * @returns matched route
245
198
  */
246
- // @ts-expect-error TS(7006) FIXME: Parameter 'rawPath' implicitly has an 'any' type.
247
- async matchURLPath(rawPath, method) {
248
- // @ts-expect-error TS(2339) FIXME: Property 'buildQueue' does not exist on type 'Netl... Remove this comment to see the full error message
199
+ async matchURLPath(rawPath, method, hasStaticFile) {
249
200
  await this.buildQueue;
250
201
  let path = rawPath !== '/' && rawPath.endsWith('/') ? rawPath.slice(0, -1) : rawPath;
251
202
  path = path.toLowerCase();
252
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
253
203
  const { routes = [] } = this.buildData;
254
204
  // @ts-expect-error TS(7031) FIXME: Binding element 'expression' implicitly has an 'an... Remove this comment to see the full error message
255
- return routes.find(({ expression, literal, methods }) => {
205
+ const route = routes.find(({ expression, literal, methods }) => {
256
206
  if (methods.length !== 0 && !methods.includes(method)) {
257
207
  return false;
258
208
  }
@@ -265,9 +215,15 @@ export default class NetlifyFunction {
265
215
  }
266
216
  return false;
267
217
  });
218
+ if (!route) {
219
+ return;
220
+ }
221
+ if (route.prefer_static && (await hasStaticFile())) {
222
+ return;
223
+ }
224
+ return route;
268
225
  }
269
226
  get runtimeAPIVersion() {
270
- // @ts-expect-error TS(2339) FIXME: Property 'buildData' does not exist on type 'Netli... Remove this comment to see the full error message
271
227
  return this.buildData?.runtimeAPIVersion ?? 1;
272
228
  }
273
229
  get url() {
@@ -278,7 +234,6 @@ export default class NetlifyFunction {
278
234
  const port = this.settings.port || this.settings.functionsPort;
279
235
  // @ts-expect-error TS(2339) FIXME: Property 'settings' does not exist on type 'Netlif... Remove this comment to see the full error message
280
236
  const protocol = this.settings.https ? 'https' : 'http';
281
- // @ts-expect-error TS(2339) FIXME: Property 'name' does not exist on type 'NetlifyFun... Remove this comment to see the full error message
282
237
  const url = new URL(`/.netlify/functions/${this.name}`, `${protocol}://localhost:${port}`);
283
238
  return url.href;
284
239
  }
@@ -17,9 +17,7 @@ const ZIP_EXTENSION = '.zip';
17
17
  * @typedef {"buildError" | "extracted" | "loaded" | "missing-types-package" | "reloaded" | "reloading" | "removed"} FunctionEvent
18
18
  */
19
19
  export class FunctionsRegistry {
20
- constructor({
21
- // @ts-expect-error TS(7031) FIXME: Binding element 'blobsContext' implicitly has an '... Remove this comment to see the full error message
22
- blobsContext,
20
+ constructor({ blobsContext,
23
21
  // @ts-expect-error TS(7031) FIXME: Binding element 'capabilities' implicitly has an '... Remove this comment to see the full error message
24
22
  capabilities,
25
23
  // @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any' t... Remove this comment to see the full error message
@@ -27,33 +25,36 @@ export class FunctionsRegistry {
27
25
  // @ts-expect-error TS(7031) FIXME: Binding element 'logLambdaCompat' implicitly has a... Remove this comment to see the full error message
28
26
  logLambdaCompat,
29
27
  // @ts-expect-error TS(7031) FIXME: Binding element 'manifest' implicitly has an 'any'... Remove this comment to see the full error message
30
- manifest,
31
- // @ts-expect-error TS(7031) FIXME: Binding element 'projectRoot' implicitly has an 'a... Remove this comment to see the full error message
32
- projectRoot,
28
+ manifest, projectRoot,
33
29
  // @ts-expect-error TS(7031) FIXME: Binding element 'settings' implicitly has an 'any'... Remove this comment to see the full error message
34
30
  settings,
35
31
  // @ts-expect-error TS(7031) FIXME: Binding element 'timeouts' implicitly has an 'any'... Remove this comment to see the full error message
36
32
  timeouts, }) {
33
+ /**
34
+ * The functions held by the registry
35
+ */
36
+ this.functions = new Map();
37
+ /**
38
+ * File watchers for function files. Maps function names to objects built
39
+ * by the `watchDebounced` utility.
40
+ */
41
+ this.functionWatchers = new Map();
42
+ /**
43
+ * Keeps track of whether we've checked whether `TYPES_PACKAGE` is
44
+ * installed.
45
+ */
46
+ this.hasCheckedTypesPackage = false;
37
47
  // @ts-expect-error TS(2339) FIXME: Property 'capabilities' does not exist on type 'Fu... Remove this comment to see the full error message
38
48
  this.capabilities = capabilities;
39
49
  // @ts-expect-error TS(2339) FIXME: Property 'config' does not exist on type 'Function... Remove this comment to see the full error message
40
50
  this.config = config;
41
- // @ts-expect-error TS(2339) FIXME: Property 'debug' does not exist on type 'Functions... Remove this comment to see the full error message
42
51
  this.debug = debug;
43
- // @ts-expect-error TS(2339) FIXME: Property 'isConnected' does not exist on type 'Fun... Remove this comment to see the full error message
44
52
  this.isConnected = isConnected;
45
- // @ts-expect-error TS(2339) FIXME: Property 'projectRoot' does not exist on type 'Fun... Remove this comment to see the full error message
46
53
  this.projectRoot = projectRoot;
47
54
  // @ts-expect-error TS(2339) FIXME: Property 'timeouts' does not exist on type 'Functi... Remove this comment to see the full error message
48
55
  this.timeouts = timeouts;
49
56
  // @ts-expect-error TS(2339) FIXME: Property 'settings' does not exist on type 'Functi... Remove this comment to see the full error message
50
57
  this.settings = settings;
51
- /**
52
- * Context object for Netlify Blobs
53
- *
54
- * @type {import("../blobs/blobs.js").BlobsContext}
55
- */
56
- // @ts-expect-error TS(2339) FIXME: Property 'blobsContext' does not exist on type 'Fu... Remove this comment to see the full error message
57
58
  this.blobsContext = blobsContext;
58
59
  /**
59
60
  * An object to be shared among all functions in the registry. It can be
@@ -73,27 +74,6 @@ export class FunctionsRegistry {
73
74
  */
74
75
  // @ts-expect-error TS(2339) FIXME: Property 'directoryWatchers' does not exist on typ... Remove this comment to see the full error message
75
76
  this.directoryWatchers = new Map();
76
- /**
77
- * The functions held by the registry
78
- *
79
- * @type {Map<string, NetlifyFunction>}
80
- */
81
- // @ts-expect-error TS(2339) FIXME: Property 'functions' does not exist on type 'Funct... Remove this comment to see the full error message
82
- this.functions = new Map();
83
- /**
84
- * File watchers for function files. Maps function names to objects built
85
- * by the `watchDebounced` utility.
86
- *
87
- * @type {Map<string, Awaited<ReturnType<watchDebounced>>>}
88
- */
89
- // @ts-expect-error TS(2339) FIXME: Property 'functionWatchers' does not exist on type... Remove this comment to see the full error message
90
- this.functionWatchers = new Map();
91
- /**
92
- * Keeps track of whether we've checked whether `TYPES_PACKAGE` is
93
- * installed.
94
- */
95
- // @ts-expect-error TS(2339) FIXME: Property 'hasCheckedTypesPackage' does not exist o... Remove this comment to see the full error message
96
- this.hasCheckedTypesPackage = false;
97
77
  /**
98
78
  * Whether to log V1 functions as using the "Lambda compatibility mode"
99
79
  *
@@ -111,16 +91,12 @@ export class FunctionsRegistry {
111
91
  this.manifest = manifest;
112
92
  }
113
93
  checkTypesPackage() {
114
- // @ts-expect-error TS(2339) FIXME: Property 'hasCheckedTypesPackage' does not exist o... Remove this comment to see the full error message
115
94
  if (this.hasCheckedTypesPackage) {
116
95
  return;
117
96
  }
118
- // @ts-expect-error TS(2339) FIXME: Property 'hasCheckedTypesPackage' does not exist o... Remove this comment to see the full error message
119
97
  this.hasCheckedTypesPackage = true;
120
- // @ts-expect-error TS(2339) FIXME: Property 'projectRoot' does not exist on type 'Fun... Remove this comment to see the full error message
121
98
  const require = createRequire(this.projectRoot);
122
99
  try {
123
- // @ts-expect-error TS(2339) FIXME: Property 'projectRoot' does not exist on type 'Fun... Remove this comment to see the full error message
124
100
  require.resolve(TYPES_PACKAGE, { paths: [this.projectRoot] });
125
101
  }
126
102
  catch (error) {
@@ -135,10 +111,7 @@ export class FunctionsRegistry {
135
111
  * Runs before `scan` and calls any `onDirectoryScan` hooks defined by the
136
112
  * runtime before the directory is read. This gives runtime the opportunity
137
113
  * to run additional logic when a directory is scanned.
138
- *
139
- * @param {string} directory
140
114
  */
141
- // @ts-expect-error TS(7006) FIXME: Parameter 'directory' implicitly has an 'any' type... Remove this comment to see the full error message
142
115
  static async prepareDirectoryScan(directory) {
143
116
  await mkdir(directory, { recursive: true });
144
117
  // We give runtimes the opportunity to react to a directory scan and run
@@ -156,12 +129,7 @@ export class FunctionsRegistry {
156
129
  /**
157
130
  * Builds a function and sets up the appropriate file watchers so that any
158
131
  * changes will trigger another build.
159
- *
160
- * @param {NetlifyFunction} func
161
- * @param {boolean} [firstLoad ]
162
- * @returns
163
132
  */
164
- // @ts-expect-error TS(7006) FIXME: Parameter 'func' implicitly has an 'any' type.
165
133
  async buildFunctionAndWatchFiles(func, firstLoad = false) {
166
134
  if (!firstLoad) {
167
135
  FunctionsRegistry.logEvent('reloading', { func });
@@ -196,16 +164,13 @@ export class FunctionsRegistry {
196
164
  if (!srcFilesDiff) {
197
165
  return;
198
166
  }
199
- // @ts-expect-error TS(2339) FIXME: Property 'functionWatchers' does not exist on type... Remove this comment to see the full error message
200
167
  const watcher = this.functionWatchers.get(func.name);
201
168
  // If there is already a watcher for this function, we need to unwatch any
202
169
  // files that have been removed and watch any files that have been added.
203
170
  if (watcher) {
204
- // @ts-expect-error TS(7006) FIXME: Parameter 'path' implicitly has an 'any' type.
205
171
  srcFilesDiff.deleted.forEach((path) => {
206
172
  watcher.unwatch(path);
207
173
  });
208
- // @ts-expect-error TS(7006) FIXME: Parameter 'path' implicitly has an 'any' type.
209
174
  srcFilesDiff.added.forEach((path) => {
210
175
  watcher.add(path);
211
176
  });
@@ -220,18 +185,13 @@ export class FunctionsRegistry {
220
185
  this.buildFunctionAndWatchFiles(func, false);
221
186
  },
222
187
  });
223
- // @ts-expect-error TS(2339) FIXME: Property 'functionWatchers' does not exist on type... Remove this comment to see the full error message
224
188
  this.functionWatchers.set(func.name, newWatcher);
225
189
  }
226
190
  }
227
191
  /**
228
192
  * Returns a function by name.
229
- *
230
- * @param {string} name
231
193
  */
232
- // @ts-expect-error TS(7006) FIXME: Parameter 'name' implicitly has an 'any' type.
233
194
  get(name) {
234
- // @ts-expect-error TS(2339) FIXME: Property 'functions' does not exist on type 'Funct... Remove this comment to see the full error message
235
195
  return this.functions.get(name);
236
196
  }
237
197
  /**
@@ -240,17 +200,13 @@ export class FunctionsRegistry {
240
200
  * matches the default functions URL (i.e. can only be for a function) but no
241
201
  * function with the given name exists, returns an object with the function
242
202
  * and the route set to `null`. Otherwise, `undefined` is returned,
243
- *
244
- * @param {string} url
245
- * @param {string} method
246
203
  */
247
- // @ts-expect-error TS(7006) FIXME: Parameter 'url' implicitly has an 'any' type.
248
- async getFunctionForURLPath(url, method) {
204
+ async getFunctionForURLPath(urlPath, method, hasStaticFile) {
249
205
  // We're constructing a URL object just so that we can extract the path from
250
206
  // the incoming URL. It doesn't really matter that we don't have the actual
251
207
  // local URL with the correct port.
252
- const urlPath = new URL(url, 'http://localhost').pathname;
253
- const defaultURLMatch = urlPath.match(DEFAULT_FUNCTION_URL_EXPRESSION);
208
+ const url = new URL(`http://localhost${urlPath}`);
209
+ const defaultURLMatch = url.pathname.match(DEFAULT_FUNCTION_URL_EXPRESSION);
254
210
  if (defaultURLMatch) {
255
211
  const func = this.get(defaultURLMatch[2]);
256
212
  if (!func) {
@@ -260,14 +216,13 @@ export class FunctionsRegistry {
260
216
  if (routes.length !== 0) {
261
217
  // @ts-expect-error TS(7006) FIXME: Parameter 'route' implicitly has an 'any' type.
262
218
  const paths = routes.map((route) => chalk.underline(route.pattern)).join(', ');
263
- warn(`Function ${chalk.yellow(func.name)} cannot be invoked on ${chalk.underline(urlPath)}, because the function has the following URL paths defined: ${paths}`);
219
+ warn(`Function ${chalk.yellow(func.name)} cannot be invoked on ${chalk.underline(url.pathname)}, because the function has the following URL paths defined: ${paths}`);
264
220
  return;
265
221
  }
266
222
  return { func, route: null };
267
223
  }
268
- // @ts-expect-error TS(2339) FIXME: Property 'functions' does not exist on type 'Funct... Remove this comment to see the full error message
269
224
  for (const func of this.functions.values()) {
270
- const route = await func.matchURLPath(urlPath, method);
225
+ const route = await func.matchURLPath(url.pathname, method, hasStaticFile);
271
226
  if (route) {
272
227
  return { func, route };
273
228
  }
@@ -352,7 +307,6 @@ export class FunctionsRegistry {
352
307
  // the new location.
353
308
  if (extname(func.mainFile) === ZIP_EXTENSION) {
354
309
  const unzippedDirectory = await this.unzipFunction(func);
355
- // @ts-expect-error TS(2339) FIXME: Property 'debug' does not exist on type 'Functions... Remove this comment to see the full error message
356
310
  if (this.debug) {
357
311
  FunctionsRegistry.logEvent('extracted', { func });
358
312
  }
@@ -360,13 +314,16 @@ export class FunctionsRegistry {
360
314
  // the build data.
361
315
  // @ts-expect-error TS(2339) FIXME: Property 'manifest' does not exist on type 'Functi... Remove this comment to see the full error message
362
316
  const manifestEntry = (this.manifest?.functions || []).find((manifestFunc) => manifestFunc.name === func.name);
363
- func.buildData = manifestEntry?.buildData || {};
317
+ func.buildData = {
318
+ ...manifestEntry?.buildData,
319
+ routes: manifestEntry.routes,
320
+ };
364
321
  // When we look at an unzipped function, we don't know whether it uses
365
- // the legacy entry file format (i.e. `[function name].js`) or the new
366
- // one (i.e. `___netlify-entry-point.js`). Let's look for the new one
322
+ // the legacy entry file format (i.e. `[function name].mjs`) or the new
323
+ // one (i.e. `___netlify-entry-point.mjs`). Let's look for the new one
367
324
  // and use it if it exists, otherwise use the old one.
368
325
  try {
369
- const v2EntryPointPath = join(unzippedDirectory, '___netlify-entry-point.js');
326
+ const v2EntryPointPath = join(unzippedDirectory, '___netlify-entry-point.mjs');
370
327
  await stat(v2EntryPointPath);
371
328
  func.mainFile = v2EntryPointPath;
372
329
  }
@@ -377,7 +334,6 @@ export class FunctionsRegistry {
377
334
  else {
378
335
  this.buildFunctionAndWatchFiles(func, !isReload);
379
336
  }
380
- // @ts-expect-error TS(2339) FIXME: Property 'functions' does not exist on type 'Funct... Remove this comment to see the full error message
381
337
  this.functions.set(name, func);
382
338
  }
383
339
  /**
@@ -419,7 +375,6 @@ export class FunctionsRegistry {
419
375
  });
420
376
  // Before registering any functions, we look for any functions that were on
421
377
  // the previous list but are missing from the new one. We unregister them.
422
- // @ts-expect-error TS(2339) FIXME: Property 'functions' does not exist on type 'Funct... Remove this comment to see the full error message
423
378
  const deletedFunctions = [...this.functions.values()].filter((oldFunc) => {
424
379
  const isFound = functions.some((newFunc) => newFunc.name === oldFunc.name && newFunc.mainFile === oldFunc.mainFile);
425
380
  return !isFound;
@@ -438,12 +393,10 @@ export class FunctionsRegistry {
438
393
  return;
439
394
  }
440
395
  // If this function has already been registered, we skip it.
441
- // @ts-expect-error TS(2339) FIXME: Property 'functions' does not exist on type 'Funct... Remove this comment to see the full error message
442
396
  if (this.functions.has(name)) {
443
397
  return;
444
398
  }
445
399
  const func = new NetlifyFunction({
446
- // @ts-expect-error TS(2339) FIXME: Property 'blobsContext' does not exist on type 'Fu... Remove this comment to see the full error message
447
400
  blobsContext: this.blobsContext,
448
401
  // @ts-expect-error TS(2339) FIXME: Property 'config' does not exist on type 'Function... Remove this comment to see the full error message
449
402
  config: this.config,
@@ -452,7 +405,6 @@ export class FunctionsRegistry {
452
405
  mainFile,
453
406
  name,
454
407
  displayName,
455
- // @ts-expect-error TS(2339) FIXME: Property 'projectRoot' does not exist on type 'Fun... Remove this comment to see the full error message
456
408
  projectRoot: this.projectRoot,
457
409
  runtime,
458
410
  // @ts-expect-error TS(2339) FIXME: Property 'timeouts' does not exist on type 'Functi... Remove this comment to see the full error message
@@ -469,7 +421,6 @@ export class FunctionsRegistry {
469
421
  await this.registerFunction(name, func, isReload);
470
422
  return func;
471
423
  }));
472
- // @ts-expect-error TS(2339) FIXME: Property 'name' does not exist on type 'NetlifyFun... Remove this comment to see the full error message
473
424
  const addedFunctionNames = new Set(addedFunctions.filter(Boolean).map((func) => func?.name));
474
425
  deletedFunctions.forEach((func) => {
475
426
  // If a function we've unregistered was also registered in this run, then
@@ -486,10 +437,7 @@ export class FunctionsRegistry {
486
437
  * Creates a watcher that looks at files being added or removed from a
487
438
  * functions directory. It doesn't care about files being changed, because
488
439
  * those will be handled by each functions' watcher.
489
- *
490
- * @param {string} directory
491
440
  */
492
- // @ts-expect-error TS(7006) FIXME: Parameter 'directory' implicitly has an 'any' type... Remove this comment to see the full error message
493
441
  async setupDirectoryWatcher(directory) {
494
442
  // @ts-expect-error TS(2339) FIXME: Property 'directoryWatchers' does not exist on typ... Remove this comment to see the full error message
495
443
  if (this.directoryWatchers.has(directory)) {
@@ -509,32 +457,21 @@ export class FunctionsRegistry {
509
457
  }
510
458
  /**
511
459
  * Removes a function from the registry and closes its file watchers.
512
- *
513
- * @param {NetlifyFunction} func
514
460
  */
515
- // @ts-expect-error TS(7006) FIXME: Parameter 'func' implicitly has an 'any' type.
516
461
  async unregisterFunction(func) {
517
462
  const { name } = func;
518
- // @ts-expect-error TS(2339) FIXME: Property 'functions' does not exist on type 'Funct... Remove this comment to see the full error message
519
463
  this.functions.delete(name);
520
- // @ts-expect-error TS(2339) FIXME: Property 'functionWatchers' does not exist on type... Remove this comment to see the full error message
521
464
  const watcher = this.functionWatchers.get(name);
522
465
  if (watcher) {
523
466
  await watcher.close();
524
467
  }
525
- // @ts-expect-error TS(2339) FIXME: Property 'functionWatchers' does not exist on type... Remove this comment to see the full error message
526
468
  this.functionWatchers.delete(name);
527
469
  }
528
470
  /**
529
471
  * Takes a zipped function and extracts its contents to an internal directory.
530
- *
531
- * @param {NetlifyFunction} func
532
472
  */
533
- // @ts-expect-error TS(7006) FIXME: Parameter 'func' implicitly has an 'any' type.
534
473
  async unzipFunction(func) {
535
- const targetDirectory = resolve(
536
- // @ts-expect-error TS(2339) FIXME: Property 'projectRoot' does not exist on type 'Fun... Remove this comment to see the full error message
537
- this.projectRoot, getPathInProject([SERVE_FUNCTIONS_FOLDER, '.unzipped', func.name]));
474
+ const targetDirectory = resolve(this.projectRoot, getPathInProject([SERVE_FUNCTIONS_FOLDER, '.unzipped', func.name]));
538
475
  await extractZip(func.mainFile, { dir: targetDirectory });
539
476
  return targetDirectory;
540
477
  }
@@ -259,6 +259,7 @@ export const startFunctionsServer = async (options) => {
259
259
  }
260
260
  const functionsRegistry = new FunctionsRegistry({
261
261
  blobsContext,
262
+ // @ts-expect-error TS(7031) FIXME
262
263
  capabilities,
263
264
  config,
264
265
  debug,
@@ -94,7 +94,7 @@ export const initializeProxy = async function ({ config, settings, }) {
94
94
  if (!sourceImagePath.startsWith('http://') && !sourceImagePath.startsWith('https://')) {
95
95
  // Construct the full URL for relative paths to request from development server
96
96
  const sourceImagePathWithLeadingSlash = sourceImagePath.startsWith('/') ? sourceImagePath : `/${sourceImagePath}`;
97
- const fullImageUrl = `${devServerUrl}/${encodeURIComponent(sourceImagePathWithLeadingSlash)}`;
97
+ const fullImageUrl = `${devServerUrl}${encodeURIComponent(sourceImagePathWithLeadingSlash)}`;
98
98
  console.log(`fullImageUrl: ${fullImageUrl}`);
99
99
  req.url = `/${modifiers}/${fullImageUrl}`;
100
100
  }
@@ -312,8 +312,9 @@ siteInfo, }) {
312
312
  (ct.endsWith('/x-www-form-urlencoded') || ct === 'multipart/form-data')) {
313
313
  return proxy.web(req, res, { target: options.functionsServer });
314
314
  }
315
- const matchingFunction = functionsRegistry && (await functionsRegistry.getFunctionForURLPath(destURL, req.method));
316
315
  const destStaticFile = await getStatic(dest.pathname, options.publicFolder);
316
+ const matchingFunction = functionsRegistry &&
317
+ (await functionsRegistry.getFunctionForURLPath(destURL, req.method, () => Boolean(destStaticFile)));
317
318
  let statusValue;
318
319
  if (match.force ||
319
320
  (!staticFile && ((!options.framework && destStaticFile) || isInternal(destURL) || matchingFunction))) {
@@ -573,11 +574,15 @@ res) => {
573
574
  req.originalBody = ['GET', 'OPTIONS', 'HEAD'].includes(req.method)
574
575
  ? null
575
576
  : await createStreamPromise(req, BYTES_LIMIT);
577
+ if (isImageRequest(req)) {
578
+ return imageProxy(req, res);
579
+ }
576
580
  const edgeFunctionsProxyURL = await edgeFunctionsProxy(req, res);
577
581
  if (edgeFunctionsProxyURL !== undefined) {
578
582
  return proxy.web(req, res, { target: edgeFunctionsProxyURL });
579
583
  }
580
- const functionMatch = functionsRegistry && (await functionsRegistry.getFunctionForURLPath(req.url, req.method));
584
+ const functionMatch = functionsRegistry &&
585
+ (await functionsRegistry.getFunctionForURLPath(req.url, req.method, () => getStatic(decodeURIComponent(reqToURL(req, req.url).pathname), settings.dist)));
581
586
  if (functionMatch) {
582
587
  // Setting an internal header with the function name so that we don't
583
588
  // have to match the URL again in the functions server.
@@ -626,9 +631,6 @@ res) => {
626
631
  (ct.endsWith('/x-www-form-urlencoded') || ct === 'multipart/form-data')) {
627
632
  return proxy.web(req, res, { target: functionsServer });
628
633
  }
629
- if (isImageRequest(req)) {
630
- return imageProxy(req, res);
631
- }
632
634
  proxy.web(req, res, options);
633
635
  };
634
636
  /**