@netlify/edge-bundler 8.19.0 → 8.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno/bundle.ts +9 -1
- package/deno/config.ts +4 -2
- package/dist/node/bundle_error.js +4 -0
- package/dist/node/bundler.d.ts +1 -1
- package/dist/node/bundler.js +3 -3
- package/dist/node/bundler.test.js +12 -1
- package/dist/node/config.d.ts +1 -2
- package/dist/node/config.js +1 -2
- package/dist/node/config.test.js +0 -5
- package/dist/node/import_map.js +1 -1
- package/dist/node/import_map.test.js +8 -5
- package/dist/node/server/server.js +1 -1
- package/package.json +1 -1
package/deno/bundle.ts
CHANGED
|
@@ -3,4 +3,12 @@ import { writeStage2 } from './lib/stage2.ts'
|
|
|
3
3
|
const [payload] = Deno.args
|
|
4
4
|
const { basePath, destPath, externals, functions, importMapData } = JSON.parse(payload)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
try {
|
|
7
|
+
await writeStage2({ basePath, destPath, externals, functions, importMapData })
|
|
8
|
+
} catch (error) {
|
|
9
|
+
if (error instanceof Error && error.message.includes("The module's source code could not be parsed")) {
|
|
10
|
+
delete error.stack
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
throw error
|
|
14
|
+
}
|
package/deno/config.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// this needs to be updated whenever there's a change to globalThis.Netlify in bootstrap
|
|
2
|
+
import { Netlify } from "https://64e8753eae24930008fac6d9--edge.netlify.app/bootstrap/index-combined.ts"
|
|
3
|
+
|
|
4
|
+
const [functionURL, collectorURL, rawExitCodes] = Deno.args
|
|
2
5
|
const exitCodes = JSON.parse(rawExitCodes)
|
|
3
6
|
|
|
4
|
-
const { Netlify } = await import(bootstrapURL)
|
|
5
7
|
globalThis.Netlify = Netlify
|
|
6
8
|
|
|
7
9
|
let func
|
|
@@ -20,6 +20,10 @@ class BundleError extends Error {
|
|
|
20
20
|
*/
|
|
21
21
|
const wrapBundleError = (input, options) => {
|
|
22
22
|
if (input instanceof Error) {
|
|
23
|
+
if (input.message.includes("The module's source code could not be parsed")) {
|
|
24
|
+
// eslint-disable-next-line no-param-reassign
|
|
25
|
+
input.message = input.stderr;
|
|
26
|
+
}
|
|
23
27
|
return new BundleError(input, options);
|
|
24
28
|
}
|
|
25
29
|
return input;
|
package/dist/node/bundler.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ interface BundleOptions {
|
|
|
16
16
|
internalSrcFolder?: string;
|
|
17
17
|
bootstrapURL?: string;
|
|
18
18
|
}
|
|
19
|
-
declare const bundle: (sourceDirectories: string[], distDirectory: string, tomlDeclarations?: Declaration[], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths, onAfterDownload, onBeforeDownload, systemLogger, internalSrcFolder,
|
|
19
|
+
declare const bundle: (sourceDirectories: string[], distDirectory: string, tomlDeclarations?: Declaration[], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths, onAfterDownload, onBeforeDownload, systemLogger, internalSrcFolder, }?: BundleOptions) => Promise<{
|
|
20
20
|
functions: import("./edge_function.js").EdgeFunction[];
|
|
21
21
|
manifest: import("./manifest.js").Manifest;
|
|
22
22
|
}>;
|
package/dist/node/bundler.js
CHANGED
|
@@ -14,7 +14,7 @@ import { ImportMap } from './import_map.js';
|
|
|
14
14
|
import { getLogger } from './logger.js';
|
|
15
15
|
import { writeManifest } from './manifest.js';
|
|
16
16
|
import { ensureLatestTypes } from './types.js';
|
|
17
|
-
const bundle = async (sourceDirectories, distDirectory, tomlDeclarations = [], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths = [], onAfterDownload, onBeforeDownload, systemLogger, internalSrcFolder,
|
|
17
|
+
const bundle = async (sourceDirectories, distDirectory, tomlDeclarations = [], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths = [], onAfterDownload, onBeforeDownload, systemLogger, internalSrcFolder, } = {}) => {
|
|
18
18
|
const logger = getLogger(systemLogger, debug);
|
|
19
19
|
const featureFlags = getFlags(inputFeatureFlags);
|
|
20
20
|
const options = {
|
|
@@ -63,8 +63,8 @@ const bundle = async (sourceDirectories, distDirectory, tomlDeclarations = [], {
|
|
|
63
63
|
await createFinalBundles([functionBundle], distDirectory, buildID);
|
|
64
64
|
// Retrieving a configuration object for each function.
|
|
65
65
|
// Run `getFunctionConfig` in parallel as it is a non-trivial operation and spins up deno
|
|
66
|
-
const internalConfigPromises = internalFunctions.map(async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger
|
|
67
|
-
const userConfigPromises = userFunctions.map(async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger
|
|
66
|
+
const internalConfigPromises = internalFunctions.map(async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger })]);
|
|
67
|
+
const userConfigPromises = userFunctions.map(async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger })]);
|
|
68
68
|
// Creating a hash of function names to configuration objects.
|
|
69
69
|
const internalFunctionsWithConfig = Object.fromEntries(await Promise.all(internalConfigPromises));
|
|
70
70
|
const userFunctionsWithConfig = Object.fromEntries(await Promise.all(userConfigPromises));
|
|
@@ -68,7 +68,8 @@ test('Uses the vendored eszip module instead of fetching it from deno.land', asy
|
|
|
68
68
|
await cleanup();
|
|
69
69
|
});
|
|
70
70
|
test('Adds a custom error property to user errors during bundling', async () => {
|
|
71
|
-
|
|
71
|
+
process.env.NO_COLOR = 'true';
|
|
72
|
+
expect.assertions(3);
|
|
72
73
|
const { basePath, cleanup, distPath } = await useFixture('invalid_functions');
|
|
73
74
|
const sourceDirectory = join(basePath, 'functions');
|
|
74
75
|
const declarations = [
|
|
@@ -82,6 +83,16 @@ test('Adds a custom error property to user errors during bundling', async () =>
|
|
|
82
83
|
}
|
|
83
84
|
catch (error) {
|
|
84
85
|
expect(error).toBeInstanceOf(BundleError);
|
|
86
|
+
const [messageBeforeStack] = error.message.split('at <anonymous> (file://');
|
|
87
|
+
expect(messageBeforeStack).toMatchInlineSnapshot(`
|
|
88
|
+
"error: Uncaught (in promise) Error: The module's source code could not be parsed: Unexpected eof at file:///root/functions/func1.ts:1:27
|
|
89
|
+
|
|
90
|
+
export default async () =>
|
|
91
|
+
~
|
|
92
|
+
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
|
93
|
+
^
|
|
94
|
+
"
|
|
95
|
+
`);
|
|
85
96
|
expect(error.customErrorInfo).toEqual({
|
|
86
97
|
location: {
|
|
87
98
|
format: 'eszip',
|
package/dist/node/config.d.ts
CHANGED
|
@@ -19,10 +19,9 @@ export interface FunctionConfig {
|
|
|
19
19
|
generator?: string;
|
|
20
20
|
method?: HTTPMethod | HTTPMethod[];
|
|
21
21
|
}
|
|
22
|
-
export declare const getFunctionConfig: ({ func, importMap, deno,
|
|
22
|
+
export declare const getFunctionConfig: ({ func, importMap, deno, log, }: {
|
|
23
23
|
func: EdgeFunction;
|
|
24
24
|
importMap: ImportMap;
|
|
25
25
|
deno: DenoBridge;
|
|
26
|
-
bootstrapURL: string;
|
|
27
26
|
log: Logger;
|
|
28
27
|
}) => Promise<FunctionConfig>;
|
package/dist/node/config.js
CHANGED
|
@@ -26,7 +26,7 @@ const getConfigExtractor = () => {
|
|
|
26
26
|
const configExtractorPath = join(packagePath, 'deno', 'config.ts');
|
|
27
27
|
return configExtractorPath;
|
|
28
28
|
};
|
|
29
|
-
export const getFunctionConfig = async ({ func, importMap, deno,
|
|
29
|
+
export const getFunctionConfig = async ({ func, importMap, deno, log, }) => {
|
|
30
30
|
// The extractor is a Deno script that will import the function and run its
|
|
31
31
|
// `config` export, if one exists.
|
|
32
32
|
const extractorPath = getConfigExtractor();
|
|
@@ -50,7 +50,6 @@ export const getFunctionConfig = async ({ func, importMap, deno, bootstrapURL, l
|
|
|
50
50
|
extractorPath,
|
|
51
51
|
pathToFileURL(func.path).href,
|
|
52
52
|
pathToFileURL(collector.path).href,
|
|
53
|
-
bootstrapURL,
|
|
54
53
|
JSON.stringify(ConfigExitCode),
|
|
55
54
|
], { rejectOnExitCode: false });
|
|
56
55
|
if (exitCode !== ConfigExitCode.Success) {
|
package/dist/node/config.test.js
CHANGED
|
@@ -9,7 +9,6 @@ import { DenoBridge } from './bridge.js';
|
|
|
9
9
|
import { bundle } from './bundler.js';
|
|
10
10
|
import { getFunctionConfig } from './config.js';
|
|
11
11
|
import { ImportMap } from './import_map.js';
|
|
12
|
-
const bootstrapURL = 'https://edge.netlify.com/bootstrap/index-combined.ts';
|
|
13
12
|
const importMapFile = {
|
|
14
13
|
baseURL: new URL('file:///some/path/import-map.json'),
|
|
15
14
|
imports: {
|
|
@@ -122,7 +121,6 @@ describe('`getFunctionConfig` extracts configuration properties from function fi
|
|
|
122
121
|
importMap: new ImportMap([importMapFile]),
|
|
123
122
|
deno,
|
|
124
123
|
log: logger,
|
|
125
|
-
bootstrapURL,
|
|
126
124
|
});
|
|
127
125
|
if (func.error) {
|
|
128
126
|
await expect(funcCall()).rejects.toThrowError(func.error);
|
|
@@ -246,7 +244,6 @@ test('Passes validation if default export exists and is a function', async () =>
|
|
|
246
244
|
importMap: new ImportMap([importMapFile]),
|
|
247
245
|
deno,
|
|
248
246
|
log: logger,
|
|
249
|
-
bootstrapURL,
|
|
250
247
|
})).resolves.not.toThrow();
|
|
251
248
|
await rm(tmpDir, { force: true, recursive: true, maxRetries: 10 });
|
|
252
249
|
});
|
|
@@ -276,7 +273,6 @@ test('Fails validation if default export is not function', async () => {
|
|
|
276
273
|
importMap: new ImportMap([importMapFile]),
|
|
277
274
|
deno,
|
|
278
275
|
log: logger,
|
|
279
|
-
bootstrapURL,
|
|
280
276
|
});
|
|
281
277
|
await expect(config).rejects.toThrowError(invalidDefaultExportErr(path));
|
|
282
278
|
await rm(tmpDir, { force: true, recursive: true, maxRetries: 10 });
|
|
@@ -306,7 +302,6 @@ test('Fails validation if default export is not present', async () => {
|
|
|
306
302
|
importMap: new ImportMap([importMapFile]),
|
|
307
303
|
deno,
|
|
308
304
|
log: logger,
|
|
309
|
-
bootstrapURL,
|
|
310
305
|
});
|
|
311
306
|
await expect(config).rejects.toThrowError(invalidDefaultExportErr(path));
|
|
312
307
|
await rm(tmpDir, { force: true, recursive: true, maxRetries: 10 });
|
package/dist/node/import_map.js
CHANGED
|
@@ -6,7 +6,7 @@ import { parse } from '@import-maps/resolve';
|
|
|
6
6
|
import { isFileNotFoundError } from './utils/error.js';
|
|
7
7
|
const INTERNAL_IMPORTS = {
|
|
8
8
|
'@netlify/edge-functions': 'https://edge.netlify.com/v1/index.ts',
|
|
9
|
-
'netlify:edge': 'https://edge.netlify.com/v1/index.ts',
|
|
9
|
+
'netlify:edge': 'https://edge.netlify.com/v1/index.ts?v=legacy',
|
|
10
10
|
};
|
|
11
11
|
// ImportMap can take several import map files and merge them into a final
|
|
12
12
|
// import map object, also adding the internal imports in the right order.
|
|
@@ -21,7 +21,8 @@ test('Handles import maps with full URLs without specifying a base URL', () => {
|
|
|
21
21
|
};
|
|
22
22
|
const map = new ImportMap([inputFile1, inputFile2]);
|
|
23
23
|
const { imports } = map.getContents();
|
|
24
|
-
expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts');
|
|
24
|
+
expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts?v=legacy');
|
|
25
|
+
expect(imports['@netlify/edge-functions']).toBe('https://edge.netlify.com/v1/index.ts');
|
|
25
26
|
expect(imports['alias:jamstack']).toBe('https://jamstack.org/');
|
|
26
27
|
expect(imports['alias:pets']).toBe('https://petsofnetlify.com/');
|
|
27
28
|
});
|
|
@@ -36,7 +37,8 @@ test('Resolves relative paths to absolute paths if a base path is not provided',
|
|
|
36
37
|
const map = new ImportMap([inputFile1]);
|
|
37
38
|
const { imports } = map.getContents();
|
|
38
39
|
const expectedPath = join(cwd(), 'my-cool-site', 'heart', 'pets');
|
|
39
|
-
expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts');
|
|
40
|
+
expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts?v=legacy');
|
|
41
|
+
expect(imports['@netlify/edge-functions']).toBe('https://edge.netlify.com/v1/index.ts');
|
|
40
42
|
expect(imports['alias:pets']).toBe(`${pathToFileURL(expectedPath).toString()}/`);
|
|
41
43
|
});
|
|
42
44
|
describe('Returns the fully resolved import map', () => {
|
|
@@ -70,7 +72,7 @@ describe('Returns the fully resolved import map', () => {
|
|
|
70
72
|
specifier2: 'file:///some/full/path/file2.js',
|
|
71
73
|
specifier1: 'file:///some/full/path/file.js',
|
|
72
74
|
'@netlify/edge-functions': 'https://edge.netlify.com/v1/index.ts',
|
|
73
|
-
'netlify:edge': 'https://edge.netlify.com/v1/index.ts',
|
|
75
|
+
'netlify:edge': 'https://edge.netlify.com/v1/index.ts?v=legacy',
|
|
74
76
|
});
|
|
75
77
|
expect(scopes).toStrictEqual({
|
|
76
78
|
'file:///some/cool/path/with/scopes/': {
|
|
@@ -92,7 +94,7 @@ describe('Returns the fully resolved import map', () => {
|
|
|
92
94
|
specifier2: 'file:///root/full/path/file2.js',
|
|
93
95
|
specifier1: 'file:///root/full/path/file.js',
|
|
94
96
|
'@netlify/edge-functions': 'https://edge.netlify.com/v1/index.ts',
|
|
95
|
-
'netlify:edge': 'https://edge.netlify.com/v1/index.ts',
|
|
97
|
+
'netlify:edge': 'https://edge.netlify.com/v1/index.ts?v=legacy',
|
|
96
98
|
});
|
|
97
99
|
expect(scopes).toStrictEqual({
|
|
98
100
|
'file:///root/cool/path/with/scopes/': {
|
|
@@ -128,6 +130,7 @@ test('Writes import map file to disk', async () => {
|
|
|
128
130
|
const { imports } = JSON.parse(createdFile);
|
|
129
131
|
const expectedPath = join(cwd(), 'my-cool-site', 'heart', 'pets', 'file.ts');
|
|
130
132
|
await file.cleanup();
|
|
131
|
-
expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts');
|
|
133
|
+
expect(imports['netlify:edge']).toBe('https://edge.netlify.com/v1/index.ts?v=legacy');
|
|
134
|
+
expect(imports['@netlify/edge-functions']).toBe('https://edge.netlify.com/v1/index.ts');
|
|
132
135
|
expect(imports['alias:pets']).toBe(pathToFileURL(expectedPath).toString());
|
|
133
136
|
});
|
|
@@ -43,7 +43,7 @@ const prepareServer = ({ bootstrapURL, deno, distDirectory, flags: denoFlags, fo
|
|
|
43
43
|
});
|
|
44
44
|
let functionsConfig = [];
|
|
45
45
|
if (options.getFunctionsConfig) {
|
|
46
|
-
functionsConfig = await Promise.all(functions.map((func) => getFunctionConfig({ func, importMap, deno,
|
|
46
|
+
functionsConfig = await Promise.all(functions.map((func) => getFunctionConfig({ func, importMap, deno, log: logger })));
|
|
47
47
|
}
|
|
48
48
|
const success = await waitForServer(port, processRef.ps);
|
|
49
49
|
return {
|