diff --git a/packages/edge-bundler/node/bundler.test.ts b/packages/edge-bundler/node/bundler.test.ts index 15fc9c6659..a1bfd32ec6 100644 --- a/packages/edge-bundler/node/bundler.test.ts +++ b/packages/edge-bundler/node/bundler.test.ts @@ -1,16 +1,15 @@ import { Buffer } from 'buffer' -import { execSync } from 'node:child_process' import { access, readdir, readFile, rm, writeFile } from 'fs/promises' import { join, resolve } from 'path' import process from 'process' import { pathToFileURL } from 'url' -import { lt } from 'semver' +import { gte, lt } from 'semver' import tmp from 'tmp-promise' import { test, expect, vi, describe } from 'vitest' import { importMapSpecifier } from '../shared/consts.js' -import { runESZIP, runTarball, useFixture } from '../test/util.js' +import { denoVersion, runESZIP, runTarball, useFixture } from '../test/util.js' import { BundleError } from './bundle_error.js' import { bundle, BundleOptions } from './bundler.js' @@ -599,7 +598,7 @@ test('Loads npm modules in a monorepo setup', async () => { await rm(vendorDirectory.path, { force: true, recursive: true }) }) -test('Loads JSON modules', async () => { +test('Loads JSON modules with `with` attribute', async () => { const { basePath, cleanup, distPath } = await useFixture('imports_json') const sourceDirectory = join(basePath, 'functions') const declarations: Declaration[] = [ @@ -626,6 +625,45 @@ test('Loads JSON modules', async () => { await rm(vendorDirectory.path, { force: true, recursive: true }) }) +// We can't run this on versions above 2.0.0 because the bundling will fail +// entirely, and what we're asserting here is that we emit a system log when +// import assertions are detected on successful builds. Also, running it on +// earlier versions won't work either, since those won't even show a warning. +test.skipIf(lt(denoVersion, '1.46.3') || gte(denoVersion, '2.0.0'))( + 'Emits a system log when import assertions are used', + async () => { + const { basePath, cleanup, distPath } = await useFixture('with_import_assert') + const sourceDirectory = join(basePath, 'functions') + const declarations: Declaration[] = [ + { + function: 'func1', + path: '/func1', + }, + ] + const vendorDirectory = await tmp.dir() + const systemLogger = vi.fn() + + await bundle([sourceDirectory], distPath, declarations, { + basePath, + systemLogger, + vendorDirectory: vendorDirectory.path, + }) + + const manifestFile = await readFile(resolve(distPath, 'manifest.json'), 'utf8') + const manifest = JSON.parse(manifestFile) + const bundlePath = join(distPath, manifest.bundles[0].asset) + const { func1 } = await runESZIP(bundlePath, vendorDirectory.path) + + expect(func1).toBe(`{"foo":"bar"}`) + expect(systemLogger).toHaveBeenCalledWith( + `Edge function uses import assertions: ${join(sourceDirectory, 'func1.ts')}`, + ) + + await cleanup() + await rm(vendorDirectory.path, { force: true, recursive: true }) + }, +) + test('Supports TSX and process.env', async () => { const { basePath, cleanup, distPath } = await useFixture('tsx') const sourceDirectory = join(basePath, 'functions') @@ -694,8 +732,6 @@ test('Loads edge functions from the Frameworks API', async () => { await cleanup() }) -const denoVersion = execSync('deno eval --no-lock "console.log(Deno.version.deno)"').toString() - describe.skipIf(lt(denoVersion, '2.4.2'))( 'Produces a tarball bundle', () => { diff --git a/packages/edge-bundler/node/config.ts b/packages/edge-bundler/node/config.ts index cc64c1df12..df76405915 100644 --- a/packages/edge-bundler/node/config.ts +++ b/packages/edge-bundler/node/config.ts @@ -96,11 +96,12 @@ export const getFunctionConfig = async ({ // with the extractor. const collector = await tmp.file() + // Retrieving the version of Deno. + const version = new SemVer((await deno.getBinaryVersion((await deno.getBinaryPath({ silent: true })).path)) || '') + // The extractor will use its exit code to signal different error scenarios, // based on the list of exit codes we send as an argument. We then capture // the exit code to know exactly what happened and guide people accordingly. - const version = new SemVer((await deno.getBinaryVersion((await deno.getBinaryPath({ silent: true })).path)) || '') - const { exitCode, stderr, stdout } = await deno.run( [ 'run', @@ -121,6 +122,10 @@ export const getFunctionConfig = async ({ { rejectOnExitCode: false }, ) + if (stderr.includes('Import assertions are deprecated')) { + log.system(`Edge function uses import assertions: ${func.path}`) + } + if (exitCode !== ConfigExitCode.Success) { handleConfigError(func, exitCode, stderr, log) diff --git a/packages/edge-bundler/test/fixtures/with_import_assert/functions/dict.json b/packages/edge-bundler/test/fixtures/with_import_assert/functions/dict.json new file mode 100644 index 0000000000..b42f309e7a --- /dev/null +++ b/packages/edge-bundler/test/fixtures/with_import_assert/functions/dict.json @@ -0,0 +1,3 @@ +{ + "foo": "bar" +} \ No newline at end of file diff --git a/packages/edge-bundler/test/fixtures/with_import_assert/functions/func1.ts b/packages/edge-bundler/test/fixtures/with_import_assert/functions/func1.ts new file mode 100644 index 0000000000..1471989aaf --- /dev/null +++ b/packages/edge-bundler/test/fixtures/with_import_assert/functions/func1.ts @@ -0,0 +1,4 @@ +import dict from './dict.json' assert { type: "json" } + + +export default async () => Response.json(dict) diff --git a/packages/edge-bundler/test/util.ts b/packages/edge-bundler/test/util.ts index 0b54dc55d1..e0e56c643d 100644 --- a/packages/edge-bundler/test/util.ts +++ b/packages/edge-bundler/test/util.ts @@ -1,7 +1,8 @@ -import { promises as fs } from 'fs' -import { join, resolve } from 'path' -import { stderr, stdout } from 'process' -import { fileURLToPath, pathToFileURL } from 'url' +import { execSync } from 'node:child_process' +import { promises as fs } from 'node:fs' +import { join, resolve } from 'node:path' +import { stderr, stdout } from 'node:process' +import { fileURLToPath, pathToFileURL } from 'node:url' import cpy from 'cpy' import { execa } from 'execa' @@ -169,3 +170,5 @@ export const runTarball = async (tarballPath: string) => { return JSON.parse(result.stdout) } + +export const denoVersion = execSync('deno eval --no-lock "console.log(Deno.version.deno)"').toString()