diff --git a/src/runtimes/node/in_source_config/index.ts b/src/runtimes/node/in_source_config/index.ts index 6def38757..ebb2c1d23 100644 --- a/src/runtimes/node/in_source_config/index.ts +++ b/src/runtimes/node/in_source_config/index.ts @@ -23,6 +23,8 @@ export type ISCValues = { schedule?: string methods?: string[] trafficRules?: TrafficRules + name?: string + generator?: string } export interface StaticAnalysisResult extends ISCValues { @@ -177,6 +179,14 @@ export const parseSource = (source: string, { functionName }: FindISCDeclaration result.schedule = configExport.schedule } + if (typeof configExport.name === 'string') { + result.name = configExport.name + } + + if (typeof configExport.generator === 'string') { + result.generator = configExport.generator + } + if (configExport.method !== undefined) { result.methods = normalizeMethods(configExport.method, functionName) } diff --git a/src/runtimes/node/index.ts b/src/runtimes/node/index.ts index f6008640d..286ba3fa4 100644 --- a/src/runtimes/node/index.ts +++ b/src/runtimes/node/index.ts @@ -141,7 +141,7 @@ const zipFunction: ZipFunction = async function ({ invocationMode = INVOCATION_MODE.Background } - const { trafficRules } = staticAnalysisResult + const { trafficRules, generator: staticAnalysisGenerator, name: staticAnalysisName } = staticAnalysisResult const outputModuleFormat = extname(finalMainFile) === MODULE_FILE_EXTENSION.MJS ? MODULE_FORMAT.ESM : MODULE_FORMAT.COMMONJS @@ -151,9 +151,9 @@ const zipFunction: ZipFunction = async function ({ bundler: bundlerName, bundlerWarnings, config, - displayName: config?.name, + displayName: staticAnalysisName || config?.name, entryFilename: zipPath.entryFilename, - generator: config?.generator || getInternalValue(isInternal), + generator: staticAnalysisGenerator || config?.generator || getInternalValue(isInternal), inputs, includedFiles, staticAnalysisResult, diff --git a/tests/fixtures-esm/v2-api-name-generator/.netlify/functions-internal/server.json b/tests/fixtures-esm/v2-api-name-generator/.netlify/functions-internal/server.json new file mode 100644 index 000000000..27f7bfdc7 --- /dev/null +++ b/tests/fixtures-esm/v2-api-name-generator/.netlify/functions-internal/server.json @@ -0,0 +1,7 @@ +{ + "config": { + "name": "should not be respected, ISC takes precedence", + "generator": "should not be respected, ISC takes precedence" + }, + "version": 1 +} diff --git a/tests/fixtures-esm/v2-api-name-generator/.netlify/functions-internal/server.mjs b/tests/fixtures-esm/v2-api-name-generator/.netlify/functions-internal/server.mjs new file mode 100644 index 000000000..fd82de5f8 --- /dev/null +++ b/tests/fixtures-esm/v2-api-name-generator/.netlify/functions-internal/server.mjs @@ -0,0 +1,6 @@ +export default () => new Response('hello world') + +export const config = { + name: 'SSR Function', + generator: 'next-runtime@1.2.3', +} diff --git a/tests/unit/runtimes/node/in_source_config.test.ts b/tests/unit/runtimes/node/in_source_config.test.ts index 09edc4fb6..5f7a3d188 100644 --- a/tests/unit/runtimes/node/in_source_config.test.ts +++ b/tests/unit/runtimes/node/in_source_config.test.ts @@ -703,4 +703,19 @@ describe('V2 API', () => { expect(routes).toEqual([{ pattern: '/products', literal: '/products', methods: [], prefer_static: true }]) }) }) + + test('Understands name and generator', () => { + const source = ` + export default async () => new Response("Hello!") + export const config = { name: "foo", generator: "bar@1.2.3" }` + + const isc = parseSource(source, options) + expect(isc).toEqual({ + inputModuleFormat: 'esm', + routes: [], + runtimeAPIVersion: 2, + name: 'foo', + generator: 'bar@1.2.3', + }) + }) }) diff --git a/tests/v2api.test.ts b/tests/v2api.test.ts index 4454b8521..66910e41b 100644 --- a/tests/v2api.test.ts +++ b/tests/v2api.test.ts @@ -528,4 +528,26 @@ describe.runIf(semver.gte(nodeVersion, '18.13.0'))('V2 functions API', () => { expect(body).toBe('foo!bar') }) }) + + test('Name and Generator are taken from ISC and take precedence over deploy config', async () => { + const { path: tmpDir } = await getTmpDir({ prefix: 'zip-it-test' }) + const manifestPath = join(tmpDir, 'manifest.json') + + const fixtureName = 'v2-api-name-generator' + const pathInternal = join(fixtureName, '.netlify', 'functions-internal') + + const { + files: [func], + } = await zipFixture(pathInternal, { + fixtureDir: FIXTURES_ESM_DIR, + length: 1, + opts: { + manifest: manifestPath, + configFileDirectories: [join(FIXTURES_ESM_DIR, fixtureName)], + }, + }) + + expect(func.displayName).toBe('SSR Function') + expect(func.generator).toBe('next-runtime@1.2.3') + }) })