From 7996715b662209337deca4b1f662047b7209559c Mon Sep 17 00:00:00 2001 From: Daniel Tschinder <231804+danez@users.noreply.github.com> Date: Tue, 21 Mar 2023 14:45:21 +0100 Subject: [PATCH] feat!: split user and internal ISC function configs - add a new test for the order of internal functions - ensures that the cache property is only added to the manifest if not undefined BREAKING CHANGE: `bundle()` has a new mandatory param `internalSourceDirectory` for the internal function directory --- node/__snapshots__/declaration.test.ts.snap | 38 +++++++++++++++ node/bundler.test.ts | 36 +++++++++----- node/bundler.ts | 49 +++++++++++--------- node/config.test.ts | 6 +-- node/declaration.test.ts | 45 +++++++++++++----- node/declaration.ts | 16 +++++-- node/manifest.test.ts | 4 +- node/manifest.ts | 11 +++-- test/integration/internal-functions/func2.ts | 3 ++ test/integration/test.js | 22 ++++++--- 10 files changed, 166 insertions(+), 64 deletions(-) create mode 100644 node/__snapshots__/declaration.test.ts.snap create mode 100644 test/integration/internal-functions/func2.ts diff --git a/node/__snapshots__/declaration.test.ts.snap b/node/__snapshots__/declaration.test.ts.snap new file mode 100644 index 00000000..aba7462f --- /dev/null +++ b/node/__snapshots__/declaration.test.ts.snap @@ -0,0 +1,38 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Deploy config takes precedence over user config 1`] = ` +[ + { + "function": "user-a", + "path": "/path1", + }, + { + "function": "user-b", + "path": "/path2", + }, + { + "function": "framework-a", + "path": "/path1", + }, + { + "function": "framework-b", + "path": "/path2", + }, + { + "function": "framework-c", + "path": "/path1", + }, + { + "function": "framework-c", + "path": "/path2", + }, + { + "function": "user-c", + "path": "/path1", + }, + { + "function": "user-c", + "path": "/path2", + }, +] +`; diff --git a/node/bundler.test.ts b/node/bundler.test.ts index 749679b4..75401a55 100644 --- a/node/bundler.test.ts +++ b/node/bundler.test.ts @@ -26,7 +26,7 @@ test('Produces an ESZIP bundle', async () => { ] const userDirectory = join(basePath, 'user-functions') const internalDirectory = join(basePath, 'functions') - const result = await bundle([userDirectory, internalDirectory], distPath, declarations, { + const result = await bundle([userDirectory], internalDirectory, distPath, declarations, { basePath, configPath: join(internalDirectory, 'config.json'), importMapPaths: [join(userDirectory, 'import_map.json')], @@ -67,7 +67,8 @@ test('Uses the vendored eszip module instead of fetching it from deno.land', asy }, ] const sourceDirectory = join(basePath, 'functions') - const result = await bundle([sourceDirectory], distPath, declarations, { + const internalDirectory = join(basePath, 'notexist') + const result = await bundle([sourceDirectory], internalDirectory, distPath, declarations, { basePath, configPath: join(sourceDirectory, 'config.json'), }) @@ -92,6 +93,7 @@ test('Adds a custom error property to user errors during bundling', async () => const { basePath, cleanup, distPath } = await useFixture('invalid_functions') const sourceDirectory = join(basePath, 'functions') + const internalDirectory = join(basePath, 'notexist') const declarations: Declaration[] = [ { function: 'func1', @@ -100,7 +102,7 @@ test('Adds a custom error property to user errors during bundling', async () => ] try { - await bundle([sourceDirectory], distPath, declarations, { basePath }) + await bundle([sourceDirectory], internalDirectory, distPath, declarations, { basePath }) } catch (error) { expect(error).toBeInstanceOf(BundleError) expect((error as BundleError).customErrorInfo).toEqual({ @@ -120,6 +122,7 @@ test('Prints a nice error message when user tries importing NPM module', async ( const { basePath, cleanup, distPath } = await useFixture('imports_npm_module') const sourceDirectory = join(basePath, 'functions') + const internalDirectory = join(basePath, 'notexist') const declarations: Declaration[] = [ { function: 'func1', @@ -128,7 +131,7 @@ test('Prints a nice error message when user tries importing NPM module', async ( ] try { - await bundle([sourceDirectory], distPath, declarations, { basePath }) + await bundle([sourceDirectory], internalDirectory, distPath, declarations, { basePath }) } catch (error) { expect(error).toBeInstanceOf(BundleError) expect((error as BundleError).message).toEqual( @@ -144,6 +147,7 @@ test('Prints a nice error message when user tries importing NPM module with npm: const { basePath, cleanup, distPath } = await useFixture('imports_npm_module_scheme') const sourceDirectory = join(basePath, 'functions') + const internalDirectory = join(basePath, 'notexist') const declarations: Declaration[] = [ { function: 'func1', @@ -152,7 +156,7 @@ test('Prints a nice error message when user tries importing NPM module with npm: ] try { - await bundle([sourceDirectory], distPath, declarations, { basePath }) + await bundle([sourceDirectory], internalDirectory, distPath, declarations, { basePath }) } catch (error) { expect(error).toBeInstanceOf(BundleError) expect((error as BundleError).message).toEqual( @@ -179,6 +183,7 @@ test('Uses the cache directory as the `DENO_DIR` value', async () => { const { basePath, cleanup, distPath } = await useFixture('with_import_maps') const sourceDirectory = join(basePath, 'functions') + const internalDirectory = join(basePath, 'notexist') const cacheDir = await tmp.dir() const declarations: Declaration[] = [ { @@ -192,7 +197,7 @@ test('Uses the cache directory as the `DENO_DIR` value', async () => { configPath: join(sourceDirectory, 'config.json'), } - const result = await bundle([sourceDirectory], distPath, declarations, options) + const result = await bundle([sourceDirectory], internalDirectory, distPath, declarations, options) const outFiles = await fs.readdir(distPath) expect(result.functions.length).toBe(1) @@ -208,13 +213,14 @@ test('Uses the cache directory as the `DENO_DIR` value', async () => { test('Supports import maps with relative paths', async () => { const { basePath, cleanup, distPath } = await useFixture('with_import_maps') const sourceDirectory = join(basePath, 'functions') + const internalDirectory = join(basePath, 'notexist') const declarations: Declaration[] = [ { function: 'func1', path: '/func1', }, ] - const result = await bundle([sourceDirectory], distPath, declarations, { + const result = await bundle([sourceDirectory], internalDirectory, distPath, declarations, { basePath, configPath: join(sourceDirectory, 'config.json'), }) @@ -237,6 +243,7 @@ test('Supports import maps with relative paths', async () => { test('Ignores any user-defined `deno.json` files', async () => { const { basePath, cleanup, distPath } = await useFixture('with_import_maps') const sourceDirectory = join(basePath, 'functions') + const internalDirectory = join(basePath, 'notexist') const declarations: Declaration[] = [ { function: 'func1', @@ -279,7 +286,7 @@ test('Ignores any user-defined `deno.json` files', async () => { await fs.writeFile(denoConfigPath, JSON.stringify(denoConfig)) expect(() => - bundle([sourceDirectory], distPath, declarations, { + bundle([sourceDirectory], internalDirectory, distPath, declarations, { basePath, configPath: join(sourceDirectory, 'config.json'), }), @@ -292,6 +299,7 @@ test('Ignores any user-defined `deno.json` files', async () => { test('Processes a function that imports a custom layer', async () => { const { basePath, cleanup, distPath } = await useFixture('with_layers') const sourceDirectory = join(basePath, 'functions') + const internalDirectory = join(basePath, 'notexist') const declarations: Declaration[] = [ { function: 'func1', @@ -299,7 +307,7 @@ test('Processes a function that imports a custom layer', async () => { }, ] const layer = { name: 'https://edge-function-layer-template.netlify.app/mod.ts', flag: 'edge-functions-layer-test' } - const result = await bundle([sourceDirectory], distPath, declarations, { + const result = await bundle([sourceDirectory], internalDirectory, distPath, declarations, { basePath, configPath: join(sourceDirectory, 'config.json'), }) @@ -329,11 +337,13 @@ test('Loads declarations and import maps from the deploy configuration', async ( path: '/func1', }, ] - const directories = [join(basePath, 'netlify', 'edge-functions'), join(basePath, '.netlify', 'edge-functions')] - const result = await bundle(directories, distPath, declarations, { + + const sourceDirectory = join(basePath, 'netlify', 'edge-functions') + const internalDirectory = join(basePath, '.netlify', 'edge-functions') + + const result = await bundle([sourceDirectory], internalDirectory, distPath, declarations, { basePath, configPath: join(basePath, '.netlify', 'edge-functions', 'manifest.json'), - internalSrcFolder: directories[1], }) const generatedFiles = await fs.readdir(distPath) @@ -362,6 +372,7 @@ test("Ignores entries in `importMapPaths` that don't point to an existing import const systemLogger = vi.fn() const { basePath, cleanup, distPath } = await useFixture('with_import_maps') const sourceDirectory = join(basePath, 'user-functions') + const internalDirectory = join(basePath, 'notexist') // Creating import map file const importMap = await tmp.file() @@ -381,6 +392,7 @@ test("Ignores entries in `importMapPaths` that don't point to an existing import const nonExistingImportMapPath = join(distPath, 'some-file-that-does-not-exist.json') const result = await bundle( [sourceDirectory], + internalDirectory, distPath, [ { diff --git a/node/bundler.ts b/node/bundler.ts index fc95fd87..4555b63c 100644 --- a/node/bundler.ts +++ b/node/bundler.ts @@ -1,5 +1,5 @@ import { promises as fs } from 'fs' -import { join, resolve } from 'path' +import { join } from 'path' import commonPathPrefix from 'common-path-prefix' import isPathInside from 'is-path-inside' @@ -32,11 +32,11 @@ interface BundleOptions { onAfterDownload?: OnAfterDownloadHook onBeforeDownload?: OnBeforeDownloadHook systemLogger?: LogFunction - internalSrcFolder?: string } const bundle = async ( sourceDirectories: string[], + internalSourceDirectory: string, distDirectory: string, tomlDeclarations: Declaration[] = [], { @@ -50,8 +50,8 @@ const bundle = async ( onAfterDownload, onBeforeDownload, systemLogger, - internalSrcFolder, }: BundleOptions = {}, + // eslint-disable-next-line max-params ) => { const logger = getLogger(systemLogger, debug) const featureFlags = getFlags(inputFeatureFlags) @@ -62,7 +62,7 @@ const bundle = async ( onAfterDownload, onBeforeDownload, } - const internalFunctionsPath = internalSrcFolder && resolve(internalSrcFolder) + if (cacheDirectory !== undefined) { options.denoDir = join(cacheDirectory, 'deno_dir') } @@ -88,7 +88,10 @@ const bundle = async ( await importMap.addFiles([deployConfig?.importMap, ...importMapPaths], logger) - const functions = await findFunctions(sourceDirectories) + const userFunctions = sourceDirectories.length === 0 ? [] : await findFunctions(sourceDirectories) + const internalFunctions = await findFunctions([internalSourceDirectory]) + const functions = [...internalFunctions, ...userFunctions] + const functionBundle = await bundleESZIP({ basePath, buildID, @@ -106,28 +109,31 @@ const bundle = async ( // rename the bundles to their permanent names. await createFinalBundles([functionBundle], distDirectory, buildID) - // Retrieving a configuration object for each function. - const functionsConfig = await Promise.all( - functions.map((func) => getFunctionConfig(func, importMap, deno, logger, featureFlags)), - ) - // Creating a hash of function names to configuration objects. - const functionsWithConfig = functions.reduce( - (acc, func, index) => ({ ...acc, [func.name]: functionsConfig[index] }), - {} as Record, - ) + const internalFunctionsWithConfig: Record = {} + for (const func of internalFunctions) { + internalFunctionsWithConfig[func.name] = await getFunctionConfig(func, importMap, deno, logger, featureFlags) + } + + const userFunctionsWithConfig: Record = {} + for (const func of userFunctions) { + userFunctionsWithConfig[func.name] = await getFunctionConfig(func, importMap, deno, logger, featureFlags) + } // Creating a final declarations array by combining the TOML file with the // deploy configuration API and the in-source configuration. - const declarationsFromConfig = mergeDeclarations(tomlDeclarations, functionsWithConfig, deployConfig.declarations) + const declarationsFromConfig = mergeDeclarations( + tomlDeclarations, + userFunctionsWithConfig, + internalFunctionsWithConfig, + deployConfig.declarations, + ) // If any declarations are autogenerated and are missing the generator field // add a default string. - const declarations = internalFunctionsPath - ? declarationsFromConfig.map((declaration) => - addGeneratorFieldIfMissing(declaration, functions, internalFunctionsPath), - ) - : declarationsFromConfig + const declarations = declarationsFromConfig.map((declaration) => + addGeneratorFieldIfMissing(declaration, functions, internalSourceDirectory), + ) const manifest = await writeManifest({ bundles: [functionBundle], @@ -135,7 +141,8 @@ const bundle = async ( distDirectory, featureFlags, functions, - functionConfig: functionsWithConfig, + userFunctionConfig: userFunctionsWithConfig, + internalFunctionConfig: internalFunctionsWithConfig, importMap: importMapSpecifier, layers: deployConfig.layers, }) diff --git a/node/config.test.ts b/node/config.test.ts index bbe2945b..84a245af 100644 --- a/node/config.test.ts +++ b/node/config.test.ts @@ -184,7 +184,7 @@ test('Loads function paths from the in-source `config` function', async () => { path: '/user-func2', }, ] - const result = await bundle([internalDirectory, userDirectory], distPath, declarations, { + const result = await bundle([userDirectory], internalDirectory, distPath, declarations, { basePath, configPath: join(internalDirectory, 'config.json'), }) @@ -202,9 +202,9 @@ test('Loads function paths from the in-source `config` function', async () => { expect(generatedFiles.includes(bundles[0].asset)).toBe(true) expect(routes.length).toBe(6) - expect(routes[0]).toEqual({ function: 'framework-func2', pattern: '^/framework-func2/?$' }) + expect(routes[0]).toEqual({ function: 'framework-func2', generator: 'internalFunc', pattern: '^/framework-func2/?$' }) expect(routes[1]).toEqual({ function: 'user-func2', pattern: '^/user-func2/?$' }) - expect(routes[2]).toEqual({ function: 'framework-func1', pattern: '^/framework-func1/?$' }) + expect(routes[2]).toEqual({ function: 'framework-func1', generator: 'internalFunc', pattern: '^/framework-func1/?$' }) expect(routes[3]).toEqual({ function: 'user-func1', pattern: '^/user-func1/?$' }) expect(routes[4]).toEqual({ function: 'user-func3', pattern: '^/user-func3/?$' }) expect(routes[5]).toEqual({ function: 'user-func5', pattern: '^/user-func5/.*/?$' }) diff --git a/node/declaration.test.ts b/node/declaration.test.ts index b04d7f13..2ddb2f21 100644 --- a/node/declaration.test.ts +++ b/node/declaration.test.ts @@ -3,16 +3,37 @@ import { test, expect } from 'vitest' import { FunctionConfig } from './config.js' import { Declaration, mergeDeclarations } from './declaration.js' -// TODO: Add tests with the deploy config. const deployConfigDeclarations: Declaration[] = [] +test('Deploy config takes precedence over user config', () => { + const deployConfigDeclarations: Declaration[] = [ + { function: 'framework-a', path: '/path1' }, + { function: 'framework-b', path: '/path2' }, + ] + + const tomlConfig: Declaration[] = [ + { function: 'user-a', path: '/path1' }, + { function: 'user-b', path: '/path2' }, + ] + + const userFuncConfig = { + 'user-c': { path: ['/path1', '/path2'] }, + } as Record + + const internalFuncConfig = { + 'framework-c': { path: ['/path1', '/path2'] }, + } as Record + + expect(mergeDeclarations(tomlConfig, userFuncConfig, internalFuncConfig, deployConfigDeclarations)).toMatchSnapshot() +}) + test('In-source config takes precedence over netlify.toml config', () => { const tomlConfig: Declaration[] = [ { function: 'geolocation', path: '/geo', cache: 'off' }, { function: 'json', path: '/json', cache: 'manual' }, ] - const funcConfig = { + const userFuncConfig = { geolocation: { path: ['/geo-isc', '/*'], cache: 'manual' }, json: { path: '/json', cache: 'off' }, } as Record @@ -23,7 +44,7 @@ test('In-source config takes precedence over netlify.toml config', () => { { function: 'json', path: '/json', cache: 'off' }, ] - const declarations = mergeDeclarations(tomlConfig, funcConfig, deployConfigDeclarations) + const declarations = mergeDeclarations(tomlConfig, userFuncConfig, {}, deployConfigDeclarations) expect(declarations).toEqual(expectedDeclarations) }) @@ -34,7 +55,7 @@ test("Declarations don't break if no in-source config is provided", () => { { function: 'json', path: '/json', cache: 'manual' }, ] - const funcConfig = { + const userFuncConfig = { geolocation: { path: ['/geo-isc'], cache: 'manual' }, json: {}, } as Record @@ -44,7 +65,7 @@ test("Declarations don't break if no in-source config is provided", () => { { function: 'json', path: '/json', cache: 'manual' }, ] - const declarations = mergeDeclarations(tomlConfig, funcConfig, deployConfigDeclarations) + const declarations = mergeDeclarations(tomlConfig, userFuncConfig, {}, deployConfigDeclarations) expect(declarations).toEqual(expectedDeclarations) }) @@ -68,10 +89,10 @@ test('In-source config works independent of the netlify.toml file if a path is d const expectedDeclarationsWithoutISCPath = [{ function: 'geolocation', path: '/geo', cache: 'off' }] - const declarationsWithISCPath = mergeDeclarations(tomlConfig, funcConfigWithPath, deployConfigDeclarations) + const declarationsWithISCPath = mergeDeclarations(tomlConfig, funcConfigWithPath, {}, deployConfigDeclarations) expect(declarationsWithISCPath).toEqual(expectedDeclarationsWithISCPath) - const declarationsWithoutISCPath = mergeDeclarations(tomlConfig, funcConfigWithoutPath, deployConfigDeclarations) + const declarationsWithoutISCPath = mergeDeclarations(tomlConfig, funcConfigWithoutPath, {}, deployConfigDeclarations) expect(declarationsWithoutISCPath).toEqual(expectedDeclarationsWithoutISCPath) }) @@ -84,7 +105,7 @@ test('In-source config works if only the cache config property is set', () => { const expectedDeclarations = [{ function: 'geolocation', path: '/geo', cache: 'manual' }] - expect(mergeDeclarations(tomlConfig, funcConfig, deployConfigDeclarations)).toEqual(expectedDeclarations) + expect(mergeDeclarations(tomlConfig, funcConfig, {}, deployConfigDeclarations)).toEqual(expectedDeclarations) }) test("In-source config path property works if it's not an array", () => { @@ -96,7 +117,7 @@ test("In-source config path property works if it's not an array", () => { const expectedDeclarations = [{ function: 'json', path: '/json', cache: 'manual' }] - expect(mergeDeclarations(tomlConfig, funcConfig, deployConfigDeclarations)).toEqual(expectedDeclarations) + expect(mergeDeclarations(tomlConfig, funcConfig, {}, deployConfigDeclarations)).toEqual(expectedDeclarations) }) test("In-source config path property works if it's not an array and it's not present in toml or deploy config", () => { @@ -110,7 +131,7 @@ test("In-source config path property works if it's not an array and it's not pre { function: 'json', path: '/json-isc', cache: 'manual' }, ] - expect(mergeDeclarations(tomlConfig, funcConfig, deployConfigDeclarations)).toEqual(expectedDeclarations) + expect(mergeDeclarations(tomlConfig, funcConfig, {}, deployConfigDeclarations)).toEqual(expectedDeclarations) }) test('In-source config works if path property is an empty array with cache value specified', () => { @@ -122,7 +143,7 @@ test('In-source config works if path property is an empty array with cache value const expectedDeclarations = [{ function: 'json', path: '/json-toml', cache: 'manual' }] - expect(mergeDeclarations(tomlConfig, funcConfig, deployConfigDeclarations)).toEqual(expectedDeclarations) + expect(mergeDeclarations(tomlConfig, funcConfig, {}, deployConfigDeclarations)).toEqual(expectedDeclarations) }) test('netlify.toml-defined excludedPath are respected', () => { @@ -132,7 +153,7 @@ test('netlify.toml-defined excludedPath are respected', () => { const expectedDeclarations = [{ function: 'geolocation', path: '/geo/*', excludedPath: '/geo/exclude' }] - const declarations = mergeDeclarations(tomlConfig, funcConfig, deployConfigDeclarations) + const declarations = mergeDeclarations(tomlConfig, funcConfig, {}, deployConfigDeclarations) expect(declarations).toEqual(expectedDeclarations) }) diff --git a/node/declaration.ts b/node/declaration.ts index 3e14d507..bbd58df8 100644 --- a/node/declaration.ts +++ b/node/declaration.ts @@ -23,7 +23,8 @@ export type Declaration = DeclarationWithPath | DeclarationWithPattern export const mergeDeclarations = ( tomlDeclarations: Declaration[], - functionsConfig: Record, + userFunctionsConfig: Record, + internalFunctionsConfig: Record, deployConfigDeclarations: Declaration[], ) => { const declarations: Declaration[] = [] @@ -34,7 +35,7 @@ export const mergeDeclarations = ( // a function configuration object, we replace the path because that object // takes precedence. for (const declaration of [...tomlDeclarations, ...deployConfigDeclarations]) { - const config = functionsConfig[declaration.function] + const config = userFunctionsConfig[declaration.function] || internalFunctionsConfig[declaration.function] if (!config) { // If no config is found, add the declaration as is. @@ -59,15 +60,20 @@ export const mergeDeclarations = ( // Finally, we must create declarations for functions that are not declared // in the TOML at all. - for (const name in functionsConfig) { - const { cache, path } = functionsConfig[name] + for (const name in { ...internalFunctionsConfig, ...userFunctionsConfig }) { + const { cache, path } = internalFunctionsConfig[name] || userFunctionsConfig[name] // If we have a path specified, create a declaration for each path. if (!functionsVisited.has(name) && path) { const paths = Array.isArray(path) ? path : [path] paths.forEach((singlePath) => { - declarations.push({ cache, function: name, path: singlePath }) + const declaration: Declaration = { function: name, path: singlePath } + // only add cache if not null or undefined + if (cache) { + declaration.cache = cache + } + declarations.push(declaration) }) } } diff --git a/node/manifest.test.ts b/node/manifest.test.ts index abbbc14b..cbf2da94 100644 --- a/node/manifest.test.ts +++ b/node/manifest.test.ts @@ -111,12 +111,12 @@ test('Includes failure modes in manifest', () => { { function: 'func-1', name: 'Display Name', path: '/f1/*' }, { function: 'func-2', pattern: '^/f2/.*/?$' }, ] - const functionConfig: Record = { + const userFunctionConfig: Record = { 'func-1': { onError: '/custom-error', }, } - const manifest = generateManifest({ bundles: [], declarations, functions, functionConfig }) + const manifest = generateManifest({ bundles: [], declarations, functions, userFunctionConfig }) expect(manifest.function_config).toEqual({ 'func-1': { excluded_patterns: [], on_error: '/custom-error' }, }) diff --git a/node/manifest.ts b/node/manifest.ts index 4d4ffe91..16b929fb 100644 --- a/node/manifest.ts +++ b/node/manifest.ts @@ -38,9 +38,10 @@ interface GenerateManifestOptions { declarations?: Declaration[] featureFlags?: FeatureFlags functions: EdgeFunction[] - functionConfig?: Record importMap?: string + internalFunctionConfig?: Record layers?: Layer[] + userFunctionConfig?: Record } // JavaScript regular expressions are converted to strings with leading and @@ -66,7 +67,8 @@ const generateManifest = ({ declarations = [], featureFlags, functions, - functionConfig = {}, + userFunctionConfig = {}, + internalFunctionConfig = {}, importMap, layers = [], }: GenerateManifestOptions) => { @@ -76,7 +78,10 @@ const generateManifest = ({ functions.map(({ name }) => [name, { excluded_patterns: [] }]), ) - for (const [name, { excludedPath, onError }] of Object.entries(functionConfig)) { + for (const [name, { excludedPath, onError }] of Object.entries({ + ...internalFunctionConfig, + ...userFunctionConfig, + })) { // If the config block is for a function that is not defined, discard it. if (manifestFunctionConfig[name] === undefined) { continue diff --git a/test/integration/internal-functions/func2.ts b/test/integration/internal-functions/func2.ts new file mode 100644 index 00000000..ac1d48a0 --- /dev/null +++ b/test/integration/internal-functions/func2.ts @@ -0,0 +1,3 @@ +export default async () => new Response('Hello') + +export const config = { path: '/func2' } diff --git a/test/integration/test.js b/test/integration/test.js index 3f7e64d1..f9c365c0 100644 --- a/test/integration/test.js +++ b/test/integration/test.js @@ -14,6 +14,7 @@ import tmp from 'tmp-promise' const exec = promisify(childProcess.exec) const require = createRequire(import.meta.url) const functionsDir = resolve(fileURLToPath(import.meta.url), '..', 'functions') +const internalFunctionsDir = resolve(fileURLToPath(import.meta.url), '..', 'internal-functions') const pathsToCleanup = new Set() @@ -58,6 +59,7 @@ const bundleFunction = async (bundlerDir) => { console.log(`Copying test fixture to '${basePath}'...`) await cpy(`${functionsDir}/**`, join(basePath, 'functions')) + await cpy(`${internalFunctionsDir}/**`, join(basePath, 'internal-functions')) pathsToCleanup.add(basePath) @@ -65,9 +67,15 @@ const bundleFunction = async (bundlerDir) => { console.log(`Bundling functions at '${basePath}'...`) - const bundleOutput = await bundle([join(basePath, 'functions')], destPath, [{ function: 'func1', path: '/func1' }], { - basePath, - }) + const bundleOutput = await bundle( + [join(basePath, 'functions')], + join(basePath, 'internal-functions'), + destPath, + [{ function: 'func1', path: '/func1' }], + { + basePath, + }, + ) return { basePath, @@ -81,9 +89,11 @@ const runAssertions = ({ basePath, bundleOutput }) => { const { functions } = bundleOutput - assert.equal(functions.length, 1) - assert.equal(functions[0].name, 'func1') - assert.equal(functions[0].path, join(basePath, 'functions', 'func1.ts')) + assert.strictEqual(functions.length, 2) + assert.strictEqual(functions[0].name, 'func2') + assert.strictEqual(functions[0].path, join(basePath, 'internal-functions', 'func2.ts')) + assert.strictEqual(functions[1].name, 'func1') + assert.strictEqual(functions[1].path, join(basePath, 'functions', 'func1.ts')) } const cleanup = async () => {