Skip to content

Commit

Permalink
Merge branch 'main' into feat/npm-modules
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardoboucas committed Sep 6, 2023
2 parents aee247b + 3d4ea09 commit 9b4389b
Show file tree
Hide file tree
Showing 13 changed files with 56 additions and 26 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## [8.19.1](https://github.com/netlify/edge-bundler/compare/v8.19.0...v8.19.1) (2023-09-06)


### Bug Fixes

* hide stack trace on syntax errors ([#464](https://github.com/netlify/edge-bundler/issues/464)) ([9261b8c](https://github.com/netlify/edge-bundler/commit/9261b8c13a07970be0e177aa6f1c4358ac862110))
* pin bootstrap version used in config extraction ([#469](https://github.com/netlify/edge-bundler/issues/469)) ([19d142d](https://github.com/netlify/edge-bundler/commit/19d142dcb17953e4c598626709662a2ddb6cf506))
* remap `netlify:edge` specifier ([#467](https://github.com/netlify/edge-bundler/issues/467)) ([9728d1a](https://github.com/netlify/edge-bundler/commit/9728d1a067cd791226eae2110e03897d2e0ac97b))

## [8.19.0](https://github.com/netlify/edge-bundler/compare/v8.18.0...v8.19.0) (2023-08-28)


Expand Down
10 changes: 9 additions & 1 deletion deno/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@ import { writeStage2 } from './lib/stage2.ts'
const [payload] = Deno.args
const { basePath, destPath, externals, functions, importMapData, vendorDirectory } = JSON.parse(payload)

await writeStage2({ basePath, destPath, externals, functions, importMapData, vendorDirectory })
try {
await writeStage2({ basePath, destPath, externals, functions, importMapData, vendorDirectory })
} catch (error) {
if (error instanceof Error && error.message.includes("The module's source code could not be parsed")) {
delete error.stack
}

throw error
}
6 changes: 4 additions & 2 deletions deno/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const [functionURL, collectorURL, bootstrapURL, rawExitCodes] = Deno.args
// this needs to be updated whenever there's a change to globalThis.Netlify in bootstrap
import { Netlify } from "https://64e8753eae24930008fac6d9--edge.netlify.app/bootstrap/index-combined.ts"

const [functionURL, collectorURL, rawExitCodes] = Deno.args
const exitCodes = JSON.parse(rawExitCodes)

const { Netlify } = await import(bootstrapURL)
globalThis.Netlify = Netlify

let func
Expand Down
7 changes: 7 additions & 0 deletions node/bundle_error.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { ExecaError } from 'execa'

interface BundleErrorOptions {
format: string
}
Expand Down Expand Up @@ -30,6 +32,11 @@ class BundleError extends Error {
*/
const wrapBundleError = (input: unknown, options?: BundleErrorOptions) => {
if (input instanceof Error) {
if (input.message.includes("The module's source code could not be parsed")) {
// eslint-disable-next-line no-param-reassign
input.message = (input as ExecaError).stderr
}

return new BundleError(input, options)
}

Expand Down
13 changes: 12 additions & 1 deletion node/bundler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ test('Uses the vendored eszip module instead of fetching it from deno.land', asy
})

test('Adds a custom error property to user errors during bundling', async () => {
expect.assertions(2)
process.env.NO_COLOR = 'true'
expect.assertions(3)

const { basePath, cleanup, distPath } = await useFixture('invalid_functions')
const sourceDirectory = join(basePath, 'functions')
Expand All @@ -102,6 +103,16 @@ test('Adds a custom error property to user errors during bundling', async () =>
await bundle([sourceDirectory], distPath, declarations, { basePath })
} catch (error) {
expect(error).toBeInstanceOf(BundleError)
const [messageBeforeStack] = (error as BundleError).message.split('at <anonymous> (file://')
expect(messageBeforeStack).toMatchInlineSnapshot(`
"error: Uncaught (in promise) Error: The module's source code could not be parsed: Unexpected eof at file:///root/functions/func1.ts:1:27
export default async () =>
~
const ret = new Error(getStringFromWasm0(arg0, arg1));
^
"
`)
expect((error as BundleError).customErrorInfo).toEqual({
location: {
format: 'eszip',
Expand Down
5 changes: 2 additions & 3 deletions node/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export const bundle = async (
tomlDeclarations: Declaration[] = [],
{
basePath: inputBasePath,
bootstrapURL = 'https://edge.netlify.com/bootstrap/index-combined.ts',
cacheDirectory,
configPath,
debug,
Expand Down Expand Up @@ -125,10 +124,10 @@ export const bundle = async (
// Retrieving a configuration object for each function.
// Run `getFunctionConfig` in parallel as it is a non-trivial operation and spins up deno
const internalConfigPromises = internalFunctions.map(
async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger, bootstrapURL })] as const,
async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger })] as const,
)
const userConfigPromises = userFunctions.map(
async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger, bootstrapURL })] as const,
async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger })] as const,
)

// Creating a hash of function names to configuration objects.
Expand Down
6 changes: 0 additions & 6 deletions node/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import { FunctionConfig, getFunctionConfig } from './config.js'
import type { Declaration } from './declaration.js'
import { ImportMap } from './import_map.js'

const bootstrapURL = 'https://edge.netlify.com/bootstrap/index-combined.ts'

const importMapFile = {
baseURL: new URL('file:///some/path/import-map.json'),
imports: {
Expand Down Expand Up @@ -146,7 +144,6 @@ describe('`getFunctionConfig` extracts configuration properties from function fi
importMap: new ImportMap([importMapFile]),
deno,
log: logger,
bootstrapURL,
})

if (func.error) {
Expand Down Expand Up @@ -284,7 +281,6 @@ test('Passes validation if default export exists and is a function', async () =>
importMap: new ImportMap([importMapFile]),
deno,
log: logger,
bootstrapURL,
}),
).resolves.not.toThrow()

Expand Down Expand Up @@ -321,7 +317,6 @@ test('Fails validation if default export is not function', async () => {
importMap: new ImportMap([importMapFile]),
deno,
log: logger,
bootstrapURL,
})

await expect(config).rejects.toThrowError(invalidDefaultExportErr(path))
Expand Down Expand Up @@ -358,7 +353,6 @@ test('Fails validation if default export is not present', async () => {
importMap: new ImportMap([importMapFile]),
deno,
log: logger,
bootstrapURL,
})

await expect(config).rejects.toThrowError(invalidDefaultExportErr(path))
Expand Down
3 changes: 0 additions & 3 deletions node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,11 @@ export const getFunctionConfig = async ({
func,
importMap,
deno,
bootstrapURL,
log,
}: {
func: EdgeFunction
importMap: ImportMap
deno: DenoBridge
bootstrapURL: string
log: Logger
}) => {
// The extractor is a Deno script that will import the function and run its
Expand Down Expand Up @@ -94,7 +92,6 @@ export const getFunctionConfig = async ({
extractorPath,
pathToFileURL(func.path).href,
pathToFileURL(collector.path).href,
bootstrapURL,
JSON.stringify(ConfigExitCode),
],
{ rejectOnExitCode: false },
Expand Down
13 changes: 8 additions & 5 deletions node/import_map.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ test('Handles import maps with full URLs without specifying a base URL', () => {
const map = new ImportMap([inputFile1, inputFile2])
const { imports } = map.getContents()

expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts')
expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts?v=legacy')
expect(imports['@netlify/edge-functions']).toBe('https://edge.netlify.com/v1/index.ts')
expect(imports['alias:jamstack']).toBe('https://jamstack.org/')
expect(imports['alias:pets']).toBe('https://petsofnetlify.com/')
})
Expand All @@ -44,7 +45,8 @@ test('Resolves relative paths to absolute paths if a base path is not provided',
const { imports } = map.getContents()
const expectedPath = join(cwd(), 'my-cool-site', 'heart', 'pets')

expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts')
expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts?v=legacy')
expect(imports['@netlify/edge-functions']).toBe('https://edge.netlify.com/v1/index.ts')
expect(imports['alias:pets']).toBe(`${pathToFileURL(expectedPath).toString()}/`)
})

Expand Down Expand Up @@ -81,7 +83,7 @@ describe('Returns the fully resolved import map', () => {
specifier2: 'file:///some/full/path/file2.js',
specifier1: 'file:///some/full/path/file.js',
'@netlify/edge-functions': 'https://edge.netlify.com/v1/index.ts',
'netlify:edge': 'https://edge.netlify.com/v1/index.ts',
'netlify:edge': 'https://edge.netlify.com/v1/index.ts?v=legacy',
})

expect(scopes).toStrictEqual({
Expand All @@ -106,7 +108,7 @@ describe('Returns the fully resolved import map', () => {
specifier2: 'file:///root/full/path/file2.js',
specifier1: 'file:///root/full/path/file.js',
'@netlify/edge-functions': 'https://edge.netlify.com/v1/index.ts',
'netlify:edge': 'https://edge.netlify.com/v1/index.ts',
'netlify:edge': 'https://edge.netlify.com/v1/index.ts?v=legacy',
})

expect(scopes).toStrictEqual({
Expand Down Expand Up @@ -154,6 +156,7 @@ test('Writes import map file to disk', async () => {

await file.cleanup()

expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts')
expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts?v=legacy')
expect(imports['@netlify/edge-functions']).toBe('https://edge.netlify.com/v1/index.ts')
expect(imports['alias:pets']).toBe(pathToFileURL(expectedPath).toString())
})
2 changes: 1 addition & 1 deletion node/import_map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { isFileNotFoundError } from './utils/error.js'

const INTERNAL_IMPORTS = {
'@netlify/edge-functions': 'https://edge.netlify.com/v1/index.ts',
'netlify:edge': 'https://edge.netlify.com/v1/index.ts',
'netlify:edge': 'https://edge.netlify.com/v1/index.ts?v=legacy',
}

type Imports = Record<string, string>
Expand Down
2 changes: 1 addition & 1 deletion node/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ const prepareServer = ({

if (options.getFunctionsConfig) {
functionsConfig = await Promise.all(
functions.map((func) => getFunctionConfig({ func, importMap, deno, bootstrapURL, log: logger })),
functions.map((func) => getFunctionConfig({ func, importMap, deno, log: logger })),
)
}

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@netlify/edge-bundler",
"version": "8.19.0",
"version": "8.19.1",
"description": "Intelligently prepare Netlify Edge Functions for deployment",
"type": "module",
"main": "./dist/node/index.js",
Expand Down

0 comments on commit 9b4389b

Please sign in to comment.