Skip to content

Commit 52f5d9f

Browse files
fix: handle pre-built V2 functions (#6076)
1 parent e9e1503 commit 52f5d9f

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

src/lib/functions/registry.mjs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// @ts-check
2-
import { mkdir } from 'fs/promises'
2+
import { mkdir, stat } from 'fs/promises'
33
import { createRequire } from 'module'
44
import { basename, extname, isAbsolute, join, resolve } from 'path'
55
import { env } from 'process'
@@ -39,6 +39,7 @@ export class FunctionsRegistry {
3939
debug = false,
4040
isConnected = false,
4141
logLambdaCompat,
42+
manifest,
4243
projectRoot,
4344
settings,
4445
timeouts,
@@ -96,6 +97,14 @@ export class FunctionsRegistry {
9697
* @type {boolean}
9798
*/
9899
this.logLambdaCompat = Boolean(logLambdaCompat)
100+
101+
/**
102+
* Contents of a `manifest.json` file that can be looked up when dealing
103+
* with built functions.
104+
*
105+
* @type {object}
106+
*/
107+
this.manifest = manifest
99108
}
100109

101110
checkTypesPackage() {
@@ -390,12 +399,30 @@ export class FunctionsRegistry {
390399
FunctionsRegistry.logEvent('extracted', { func })
391400
}
392401

393-
func.mainFile = join(unzippedDirectory, `${func.name}.js`)
402+
// If there's a manifest file, look up the function in order to extract
403+
// the build data.
404+
const manifestEntry = (this.manifest?.functions || []).find((manifestFunc) => manifestFunc.name === func.name)
405+
406+
func.buildData = manifestEntry?.buildData || {}
407+
408+
// When we look at an unzipped function, we don't know whether it uses
409+
// the legacy entry file format (i.e. `[function name].js`) or the new
410+
// one (i.e. `___netlify-entry-point.mjs`). Let's look for the new one
411+
// and use it if it exists, otherwise use the old one.
412+
try {
413+
const v2EntryPointPath = join(unzippedDirectory, '___netlify-entry-point.mjs')
414+
415+
await stat(v2EntryPointPath)
416+
417+
func.mainFile = v2EntryPointPath
418+
} catch {
419+
func.mainFile = join(unzippedDirectory, `${func.name}.js`)
420+
}
421+
} else {
422+
this.buildFunctionAndWatchFiles(func, !isReload)
394423
}
395424

396425
this.functions.set(name, func)
397-
398-
this.buildFunctionAndWatchFiles(func, !isReload)
399426
}
400427

401428
/**

src/lib/functions/server.mjs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// @ts-check
22
import { Buffer } from 'buffer'
33
import { promises as fs } from 'fs'
4+
import path from 'path'
45

56
import express from 'express'
67
import expressLogging from 'express-logging'
@@ -261,6 +262,7 @@ export const startFunctionsServer = async (options) => {
261262
options
262263
const internalFunctionsDir = await getInternalFunctionsDir({ base: site.root })
263264
const functionsDirectories = []
265+
let manifest
264266

265267
// If the `loadDistFunctions` parameter is sent, the functions server will
266268
// use the built functions created by zip-it-and-ship-it rather than building
@@ -270,6 +272,18 @@ export const startFunctionsServer = async (options) => {
270272

271273
if (distPath) {
272274
functionsDirectories.push(distPath)
275+
276+
// When using built functions, read the manifest file so that we can
277+
// extract metadata such as routes and API version.
278+
try {
279+
const manifestPath = path.join(distPath, 'manifest.json')
280+
// eslint-disable-next-line unicorn/prefer-json-parse-buffer
281+
const data = await fs.readFile(manifestPath, 'utf8')
282+
283+
manifest = JSON.parse(data)
284+
} catch {
285+
// no-op
286+
}
273287
}
274288
} else {
275289
// The order of the function directories matters. Rightmost directories take
@@ -297,6 +311,7 @@ export const startFunctionsServer = async (options) => {
297311
debug,
298312
isConnected: Boolean(siteUrl),
299313
logLambdaCompat: isFeatureFlagEnabled('cli_log_lambda_compat', siteInfo),
314+
manifest,
300315
// functions always need to be inside the packagePath if set inside a monorepo
301316
projectRoot: command.workingDir,
302317
settings,

0 commit comments

Comments
 (0)