@netlify/edge-bundler 8.17.0 → 8.17.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/config.ts +4 -1
- package/dist/node/bundler.d.ts +2 -1
- package/dist/node/bundler.js +3 -3
- package/dist/node/config.d.ts +7 -1
- package/dist/node/config.js +2 -1
- package/dist/node/config.test.js +37 -12
- package/dist/node/declaration.js +6 -1
- package/dist/node/declaration.test.js +6 -0
- package/dist/node/server/server.js +1 -1
- package/dist/node/server/server.test.js +16 -1
- package/package.json +1 -1
package/deno/config.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
const [functionURL, collectorURL, rawExitCodes] = Deno.args
|
|
1
|
+
const [functionURL, collectorURL, bootstrapURL, rawExitCodes] = Deno.args
|
|
2
2
|
const exitCodes = JSON.parse(rawExitCodes)
|
|
3
3
|
|
|
4
|
+
const { Netlify } = await import(bootstrapURL)
|
|
5
|
+
globalThis.Netlify = Netlify
|
|
6
|
+
|
|
4
7
|
let func
|
|
5
8
|
|
|
6
9
|
try {
|
package/dist/node/bundler.d.ts
CHANGED
|
@@ -14,8 +14,9 @@ interface BundleOptions {
|
|
|
14
14
|
onBeforeDownload?: OnBeforeDownloadHook;
|
|
15
15
|
systemLogger?: LogFunction;
|
|
16
16
|
internalSrcFolder?: string;
|
|
17
|
+
bootstrapURL?: string;
|
|
17
18
|
}
|
|
18
|
-
declare const bundle: (sourceDirectories: string[], distDirectory: string, tomlDeclarations?: Declaration[], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths, onAfterDownload, onBeforeDownload, systemLogger, internalSrcFolder, }?: BundleOptions) => Promise<{
|
|
19
|
+
declare const bundle: (sourceDirectories: string[], distDirectory: string, tomlDeclarations?: Declaration[], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths, onAfterDownload, onBeforeDownload, systemLogger, internalSrcFolder, bootstrapURL, }?: BundleOptions) => Promise<{
|
|
19
20
|
functions: import("./edge_function.js").EdgeFunction[];
|
|
20
21
|
manifest: import("./manifest.js").Manifest;
|
|
21
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, bootstrapURL = 'https://edge.netlify.com/bootstrap/index-combined.ts', } = {}) => {
|
|
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, logger)]);
|
|
67
|
-
const userConfigPromises = userFunctions.map(async (func) => [func.name, await getFunctionConfig(func, importMap, deno, logger)]);
|
|
66
|
+
const internalConfigPromises = internalFunctions.map(async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger, bootstrapURL })]);
|
|
67
|
+
const userConfigPromises = userFunctions.map(async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger, bootstrapURL })]);
|
|
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));
|
package/dist/node/config.d.ts
CHANGED
|
@@ -17,4 +17,10 @@ export interface FunctionConfig {
|
|
|
17
17
|
name?: string;
|
|
18
18
|
generator?: string;
|
|
19
19
|
}
|
|
20
|
-
export declare const getFunctionConfig: (func
|
|
20
|
+
export declare const getFunctionConfig: ({ func, importMap, deno, bootstrapURL, log, }: {
|
|
21
|
+
func: EdgeFunction;
|
|
22
|
+
importMap: ImportMap;
|
|
23
|
+
deno: DenoBridge;
|
|
24
|
+
bootstrapURL: string;
|
|
25
|
+
log: Logger;
|
|
26
|
+
}) => 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, log) => {
|
|
29
|
+
export const getFunctionConfig = async ({ func, importMap, deno, bootstrapURL, 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,6 +50,7 @@ export const getFunctionConfig = async (func, importMap, deno, log) => {
|
|
|
50
50
|
extractorPath,
|
|
51
51
|
pathToFileURL(func.path).href,
|
|
52
52
|
pathToFileURL(collector.path).href,
|
|
53
|
+
bootstrapURL,
|
|
53
54
|
JSON.stringify(ConfigExitCode),
|
|
54
55
|
], { rejectOnExitCode: false });
|
|
55
56
|
if (exitCode !== ConfigExitCode.Success) {
|
package/dist/node/config.test.js
CHANGED
|
@@ -9,6 +9,7 @@ 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';
|
|
12
13
|
const importMapFile = {
|
|
13
14
|
baseURL: new URL('file:///some/path/import-map.json'),
|
|
14
15
|
imports: {
|
|
@@ -114,9 +115,15 @@ describe('`getFunctionConfig` extracts configuration properties from function fi
|
|
|
114
115
|
const path = join(tmpDir, `${func.name}.js`);
|
|
115
116
|
await fs.writeFile(path, func.source);
|
|
116
117
|
const funcCall = () => getFunctionConfig({
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
func: {
|
|
119
|
+
name: func.name,
|
|
120
|
+
path,
|
|
121
|
+
},
|
|
122
|
+
importMap: new ImportMap([importMapFile]),
|
|
123
|
+
deno,
|
|
124
|
+
log: logger,
|
|
125
|
+
bootstrapURL,
|
|
126
|
+
});
|
|
120
127
|
if (func.error) {
|
|
121
128
|
await expect(funcCall()).rejects.toThrowError(func.error);
|
|
122
129
|
}
|
|
@@ -194,9 +201,15 @@ test('Passes validation if default export exists and is a function', async () =>
|
|
|
194
201
|
const path = join(tmpDir, `${func.name}.ts`);
|
|
195
202
|
await fs.writeFile(path, func.source);
|
|
196
203
|
await expect(getFunctionConfig({
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
204
|
+
func: {
|
|
205
|
+
name: func.name,
|
|
206
|
+
path,
|
|
207
|
+
},
|
|
208
|
+
importMap: new ImportMap([importMapFile]),
|
|
209
|
+
deno,
|
|
210
|
+
log: logger,
|
|
211
|
+
bootstrapURL,
|
|
212
|
+
})).resolves.not.toThrow();
|
|
200
213
|
await rm(tmpDir, { force: true, recursive: true, maxRetries: 10 });
|
|
201
214
|
});
|
|
202
215
|
test('Fails validation if default export is not function', async () => {
|
|
@@ -218,9 +231,15 @@ test('Fails validation if default export is not function', async () => {
|
|
|
218
231
|
const path = join(tmpDir, `${func.name}.ts`);
|
|
219
232
|
await fs.writeFile(path, func.source);
|
|
220
233
|
const config = getFunctionConfig({
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
234
|
+
func: {
|
|
235
|
+
name: func.name,
|
|
236
|
+
path,
|
|
237
|
+
},
|
|
238
|
+
importMap: new ImportMap([importMapFile]),
|
|
239
|
+
deno,
|
|
240
|
+
log: logger,
|
|
241
|
+
bootstrapURL,
|
|
242
|
+
});
|
|
224
243
|
await expect(config).rejects.toThrowError(invalidDefaultExportErr(path));
|
|
225
244
|
await rm(tmpDir, { force: true, recursive: true, maxRetries: 10 });
|
|
226
245
|
});
|
|
@@ -242,9 +261,15 @@ test('Fails validation if default export is not present', async () => {
|
|
|
242
261
|
const path = join(tmpDir, `${func.name}.ts`);
|
|
243
262
|
await fs.writeFile(path, func.source);
|
|
244
263
|
const config = getFunctionConfig({
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
264
|
+
func: {
|
|
265
|
+
name: func.name,
|
|
266
|
+
path,
|
|
267
|
+
},
|
|
268
|
+
importMap: new ImportMap([importMapFile]),
|
|
269
|
+
deno,
|
|
270
|
+
log: logger,
|
|
271
|
+
bootstrapURL,
|
|
272
|
+
});
|
|
248
273
|
await expect(config).rejects.toThrowError(invalidDefaultExportErr(path));
|
|
249
274
|
await rm(tmpDir, { force: true, recursive: true, maxRetries: 10 });
|
|
250
275
|
});
|
package/dist/node/declaration.js
CHANGED
|
@@ -66,7 +66,12 @@ const createDeclarationsFromFunctionConfigs = (functionConfigs, functionsVisited
|
|
|
66
66
|
// Validates and normalizes a pattern so that it's a valid regular expression
|
|
67
67
|
// in Go, which is the engine used by our edge nodes.
|
|
68
68
|
export const parsePattern = (pattern) => {
|
|
69
|
-
|
|
69
|
+
let enclosedPattern = pattern;
|
|
70
|
+
if (!pattern.startsWith('^'))
|
|
71
|
+
enclosedPattern = `^${enclosedPattern}`;
|
|
72
|
+
if (!pattern.endsWith('$'))
|
|
73
|
+
enclosedPattern = `${enclosedPattern}$`;
|
|
74
|
+
const regexp = new RegExp(enclosedPattern);
|
|
70
75
|
const newRegexp = regexpAST.transform(regexp, {
|
|
71
76
|
Assertion(path) {
|
|
72
77
|
// Lookaheads are not supported. If we find one, throw an error.
|
|
@@ -126,3 +126,9 @@ test('Escapes front slashes in a regex pattern', () => {
|
|
|
126
126
|
const actual = parsePattern(regexPattern);
|
|
127
127
|
expect(actual).toEqual(expected);
|
|
128
128
|
});
|
|
129
|
+
test('Ensures pattern match on the whole path', () => {
|
|
130
|
+
const regexPattern = '/foo/.*/bar';
|
|
131
|
+
const expected = '^\\/foo\\/.*\\/bar$';
|
|
132
|
+
const actual = parsePattern(regexPattern);
|
|
133
|
+
expect(actual).toEqual(expected);
|
|
134
|
+
});
|
|
@@ -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, logger)));
|
|
46
|
+
functionsConfig = await Promise.all(functions.map((func) => getFunctionConfig({ func, importMap, deno, bootstrapURL, log: logger })));
|
|
47
47
|
}
|
|
48
48
|
const success = await waitForServer(port, processRef.ps);
|
|
49
49
|
return {
|
|
@@ -27,6 +27,10 @@ test('Starts a server and serves requests for edge functions', async () => {
|
|
|
27
27
|
name: 'greet',
|
|
28
28
|
path: join(paths.internal, 'greet.ts'),
|
|
29
29
|
},
|
|
30
|
+
{
|
|
31
|
+
name: 'global_netlify',
|
|
32
|
+
path: join(paths.user, 'global_netlify.ts'),
|
|
33
|
+
},
|
|
30
34
|
];
|
|
31
35
|
const options = {
|
|
32
36
|
getFunctionsConfig: true,
|
|
@@ -35,7 +39,7 @@ test('Starts a server and serves requests for edge functions', async () => {
|
|
|
35
39
|
very_secret_secret: 'i love netlify',
|
|
36
40
|
}, options);
|
|
37
41
|
expect(success).toBe(true);
|
|
38
|
-
expect(functionsConfig).toEqual([{ path: '/my-function' }, {}]);
|
|
42
|
+
expect(functionsConfig).toEqual([{ path: '/my-function' }, {}, { path: '/global-netlify' }]);
|
|
39
43
|
for (const key in functions) {
|
|
40
44
|
const graphEntry = graph === null || graph === void 0 ? void 0 : graph.modules.some(
|
|
41
45
|
// @ts-expect-error TODO: Module graph is currently not typed
|
|
@@ -60,4 +64,15 @@ test('Starts a server and serves requests for edge functions', async () => {
|
|
|
60
64
|
});
|
|
61
65
|
expect(response2.status).toBe(200);
|
|
62
66
|
expect(await response2.text()).toBe('HELLO!');
|
|
67
|
+
const response3 = await fetch(`http://0.0.0.0:${port}/global-netlify`, {
|
|
68
|
+
headers: {
|
|
69
|
+
'x-nf-edge-functions': 'global_netlify',
|
|
70
|
+
'x-ef-passthrough': 'passthrough',
|
|
71
|
+
'X-NF-Request-ID': uuidv4(),
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
expect(await response3.json()).toEqual({
|
|
75
|
+
global: 'i love netlify',
|
|
76
|
+
local: 'i love netlify',
|
|
77
|
+
});
|
|
63
78
|
});
|