@netlify/edge-bundler 2.8.0 → 2.9.0
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/dist/node/bundler.js +1 -1
- package/dist/node/config.d.ts +7 -1
- package/dist/node/config.js +2 -1
- package/dist/node/config.test.js +18 -5
- package/dist/node/declaration.d.ts +1 -0
- package/dist/node/declaration.js +3 -3
- package/dist/node/manifest.d.ts +5 -0
- package/dist/node/manifest.js +12 -3
- package/dist/node/manifest.test.js +36 -0
- package/package.json +1 -1
package/dist/node/bundler.js
CHANGED
|
@@ -78,7 +78,7 @@ const bundle = async (sourceDirectories, distDirectory, tomlDeclarations = [], {
|
|
|
78
78
|
if (!featureFlags.edge_functions_config_export) {
|
|
79
79
|
return {};
|
|
80
80
|
}
|
|
81
|
-
return getFunctionConfig(func, deno, logger);
|
|
81
|
+
return getFunctionConfig(func, importMap, deno, logger);
|
|
82
82
|
}));
|
|
83
83
|
// Creating a hash of function names to configuration objects.
|
|
84
84
|
const functionsWithConfig = functions.reduce((acc, func, index) => ({ ...acc, [func.name]: functionsConfig[index] }), {});
|
package/dist/node/config.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { DenoBridge } from './bridge.js';
|
|
2
2
|
import { EdgeFunction } from './edge_function.js';
|
|
3
|
+
import { ImportMap } from './import_map.js';
|
|
3
4
|
import { Logger } from './logger.js';
|
|
5
|
+
export declare const enum Mode {
|
|
6
|
+
BeforeCache = "before-cache",
|
|
7
|
+
AfterCache = "after-cache"
|
|
8
|
+
}
|
|
4
9
|
export interface FunctionConfig {
|
|
10
|
+
mode?: Mode;
|
|
5
11
|
path?: string;
|
|
6
12
|
}
|
|
7
|
-
export declare const getFunctionConfig: (func: EdgeFunction, deno: DenoBridge, log: Logger) => Promise<FunctionConfig>;
|
|
13
|
+
export declare const getFunctionConfig: (func: EdgeFunction, importMap: ImportMap, deno: DenoBridge, log: Logger) => Promise<FunctionConfig>;
|
package/dist/node/config.js
CHANGED
|
@@ -19,7 +19,7 @@ const getConfigExtractor = () => {
|
|
|
19
19
|
const configExtractorPath = join(packagePath, 'deno', 'config.ts');
|
|
20
20
|
return configExtractorPath;
|
|
21
21
|
};
|
|
22
|
-
export const getFunctionConfig = async (func, deno, log) => {
|
|
22
|
+
export const getFunctionConfig = async (func, importMap, deno, log) => {
|
|
23
23
|
// The extractor is a Deno script that will import the function and run its
|
|
24
24
|
// `config` export, if one exists.
|
|
25
25
|
const extractorPath = getConfigExtractor();
|
|
@@ -38,6 +38,7 @@ export const getFunctionConfig = async (func, deno, log) => {
|
|
|
38
38
|
'--allow-read',
|
|
39
39
|
`--allow-write=${collector.path}`,
|
|
40
40
|
'--quiet',
|
|
41
|
+
`--import-map=${importMap.toDataURL()}`,
|
|
41
42
|
extractorPath,
|
|
42
43
|
pathToFileURL(func.path).href,
|
|
43
44
|
pathToFileURL(collector.path).href,
|
package/dist/node/config.test.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
2
|
import { join, resolve } from 'path';
|
|
3
|
+
import { pathToFileURL } from 'url';
|
|
3
4
|
import del from 'del';
|
|
4
5
|
import { stub } from 'sinon';
|
|
5
6
|
import tmp from 'tmp-promise';
|
|
@@ -8,6 +9,13 @@ import { fixturesDir } from '../test/util.js';
|
|
|
8
9
|
import { DenoBridge } from './bridge.js';
|
|
9
10
|
import { bundle } from './bundler.js';
|
|
10
11
|
import { getFunctionConfig } from './config.js';
|
|
12
|
+
import { ImportMap } from './import_map.js';
|
|
13
|
+
const importMapFile = {
|
|
14
|
+
baseURL: new URL('file:///some/path/import-map.json'),
|
|
15
|
+
imports: {
|
|
16
|
+
'alias:helper': pathToFileURL(join(fixturesDir, 'helper.ts')).toString(),
|
|
17
|
+
},
|
|
18
|
+
};
|
|
11
19
|
test('`getFunctionConfig` extracts configuration properties from function file', async () => {
|
|
12
20
|
const { path: tmpDir } = await tmp.dir();
|
|
13
21
|
const deno = new DenoBridge({
|
|
@@ -101,7 +109,7 @@ test('`getFunctionConfig` extracts configuration properties from function file',
|
|
|
101
109
|
const config = await getFunctionConfig({
|
|
102
110
|
name: func.name,
|
|
103
111
|
path,
|
|
104
|
-
}, deno, logger);
|
|
112
|
+
}, new ImportMap([importMapFile]), deno, logger);
|
|
105
113
|
expect(config).toEqual(func.expectedConfig);
|
|
106
114
|
if (func.userLog) {
|
|
107
115
|
expect(logger.user.firstCall.firstArg).toMatch(func.userLog);
|
|
@@ -122,9 +130,10 @@ test('Ignores function paths from the in-source `config` function if the feature
|
|
|
122
130
|
featureFlags: {
|
|
123
131
|
edge_functions_produce_eszip: true,
|
|
124
132
|
},
|
|
133
|
+
importMaps: [importMapFile],
|
|
125
134
|
});
|
|
126
135
|
const generatedFiles = await fs.readdir(tmpDir.path);
|
|
127
|
-
expect(result.functions.length).toBe(
|
|
136
|
+
expect(result.functions.length).toBe(6);
|
|
128
137
|
expect(generatedFiles.length).toBe(2);
|
|
129
138
|
const manifestFile = await fs.readFile(resolve(tmpDir.path, 'manifest.json'), 'utf8');
|
|
130
139
|
const manifest = JSON.parse(manifestFile);
|
|
@@ -155,20 +164,24 @@ test('Loads function paths from the in-source `config` function', async () => {
|
|
|
155
164
|
edge_functions_config_export: true,
|
|
156
165
|
edge_functions_produce_eszip: true,
|
|
157
166
|
},
|
|
167
|
+
importMaps: [importMapFile],
|
|
158
168
|
});
|
|
159
169
|
const generatedFiles = await fs.readdir(tmpDir.path);
|
|
160
|
-
expect(result.functions.length).toBe(
|
|
170
|
+
expect(result.functions.length).toBe(6);
|
|
161
171
|
expect(generatedFiles.length).toBe(2);
|
|
162
172
|
const manifestFile = await fs.readFile(resolve(tmpDir.path, 'manifest.json'), 'utf8');
|
|
163
173
|
const manifest = JSON.parse(manifestFile);
|
|
164
|
-
const { bundles, routes } = manifest;
|
|
174
|
+
const { bundles, routes, post_cache_routes: postCacheRoutes } = manifest;
|
|
165
175
|
expect(bundles.length).toBe(1);
|
|
166
176
|
expect(bundles[0].format).toBe('eszip2');
|
|
167
177
|
expect(generatedFiles.includes(bundles[0].asset)).toBe(true);
|
|
168
|
-
expect(routes.length).toBe(
|
|
178
|
+
expect(routes.length).toBe(5);
|
|
169
179
|
expect(routes[0]).toEqual({ function: 'framework-func2', pattern: '^/framework-func2/?$' });
|
|
170
180
|
expect(routes[1]).toEqual({ function: 'user-func2', pattern: '^/user-func2/?$' });
|
|
171
181
|
expect(routes[2]).toEqual({ function: 'framework-func1', pattern: '^/framework-func1/?$' });
|
|
172
182
|
expect(routes[3]).toEqual({ function: 'user-func1', pattern: '^/user-func1/?$' });
|
|
183
|
+
expect(routes[4]).toEqual({ function: 'user-func3', pattern: '^/user-func3/?$' });
|
|
184
|
+
expect(postCacheRoutes.length).toBe(1);
|
|
185
|
+
expect(postCacheRoutes[0]).toEqual({ function: 'user-func4', pattern: '^/user-func4/?$' });
|
|
173
186
|
await fs.rmdir(tmpDir.path, { recursive: true });
|
|
174
187
|
});
|
package/dist/node/declaration.js
CHANGED
|
@@ -9,7 +9,7 @@ export const getDeclarationsFromConfig = (tomlDeclarations, functionsConfig) =>
|
|
|
9
9
|
const { path } = (_a = functionsConfig[declaration.function]) !== null && _a !== void 0 ? _a : {};
|
|
10
10
|
if (path) {
|
|
11
11
|
functionsVisited.add(declaration.function);
|
|
12
|
-
declarations.push({
|
|
12
|
+
declarations.push({ ...declaration, path });
|
|
13
13
|
}
|
|
14
14
|
else {
|
|
15
15
|
declarations.push(declaration);
|
|
@@ -18,9 +18,9 @@ export const getDeclarationsFromConfig = (tomlDeclarations, functionsConfig) =>
|
|
|
18
18
|
// Finally, we must create declarations for functions that are not declared
|
|
19
19
|
// in the TOML at all.
|
|
20
20
|
for (const name in functionsConfig) {
|
|
21
|
-
const { path } = functionsConfig[name];
|
|
21
|
+
const { path, ...config } = functionsConfig[name];
|
|
22
22
|
if (!functionsVisited.has(name) && path) {
|
|
23
|
-
declarations.push({ function: name, path });
|
|
23
|
+
declarations.push({ ...config, function: name, path });
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
return declarations;
|
package/dist/node/manifest.d.ts
CHANGED
|
@@ -17,6 +17,11 @@ interface Manifest {
|
|
|
17
17
|
name?: string;
|
|
18
18
|
pattern: string;
|
|
19
19
|
}[];
|
|
20
|
+
post_cache_routes: {
|
|
21
|
+
function: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
pattern: string;
|
|
24
|
+
}[];
|
|
20
25
|
}
|
|
21
26
|
declare const generateManifest: ({ bundles, declarations, functions }: GenerateManifestOptions) => Manifest;
|
|
22
27
|
interface WriteManifestOptions {
|
package/dist/node/manifest.js
CHANGED
|
@@ -4,18 +4,26 @@ import globToRegExp from 'glob-to-regexp';
|
|
|
4
4
|
import { getPackageVersion } from './package_json.js';
|
|
5
5
|
import { nonNullable } from './utils/non_nullable.js';
|
|
6
6
|
const generateManifest = ({ bundles = [], declarations = [], functions }) => {
|
|
7
|
-
const
|
|
7
|
+
const preCacheRoutes = [];
|
|
8
|
+
const postCacheRoutes = [];
|
|
9
|
+
declarations.forEach((declaration) => {
|
|
8
10
|
const func = functions.find(({ name }) => declaration.function === name);
|
|
9
11
|
if (func === undefined) {
|
|
10
12
|
return;
|
|
11
13
|
}
|
|
12
14
|
const pattern = getRegularExpression(declaration);
|
|
13
15
|
const serializablePattern = pattern.source.replace(/\\\//g, '/');
|
|
14
|
-
|
|
16
|
+
const route = {
|
|
15
17
|
function: func.name,
|
|
16
18
|
name: declaration.name,
|
|
17
19
|
pattern: serializablePattern,
|
|
18
20
|
};
|
|
21
|
+
if (declaration.mode === "after-cache" /* Mode.AfterCache */) {
|
|
22
|
+
postCacheRoutes.push(route);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
preCacheRoutes.push(route);
|
|
26
|
+
}
|
|
19
27
|
});
|
|
20
28
|
const manifestBundles = bundles.map(({ extension, format, hash }) => ({
|
|
21
29
|
asset: hash + extension,
|
|
@@ -23,7 +31,8 @@ const generateManifest = ({ bundles = [], declarations = [], functions }) => {
|
|
|
23
31
|
}));
|
|
24
32
|
const manifest = {
|
|
25
33
|
bundles: manifestBundles,
|
|
26
|
-
routes:
|
|
34
|
+
routes: preCacheRoutes.filter(nonNullable),
|
|
35
|
+
post_cache_routes: postCacheRoutes.filter(nonNullable),
|
|
27
36
|
bundler_version: getPackageVersion(),
|
|
28
37
|
};
|
|
29
38
|
return manifest;
|
|
@@ -80,3 +80,39 @@ test('Generates a manifest without bundles', () => {
|
|
|
80
80
|
expect(manifest.routes).toEqual(expectedRoutes);
|
|
81
81
|
expect(manifest.bundler_version).toBe(env.npm_package_version);
|
|
82
82
|
});
|
|
83
|
+
test('Generates a manifest with pre and post-cache routes', () => {
|
|
84
|
+
const bundle1 = {
|
|
85
|
+
extension: '.ext1',
|
|
86
|
+
format: 'format1',
|
|
87
|
+
hash: '123456',
|
|
88
|
+
};
|
|
89
|
+
const bundle2 = {
|
|
90
|
+
extension: '.ext2',
|
|
91
|
+
format: 'format2',
|
|
92
|
+
hash: '654321',
|
|
93
|
+
};
|
|
94
|
+
const functions = [
|
|
95
|
+
{ name: 'func-1', path: '/path/to/func-1.ts' },
|
|
96
|
+
{ name: 'func-2', path: '/path/to/func-2.ts' },
|
|
97
|
+
{ name: 'func-3', path: '/path/to/func-3.ts' },
|
|
98
|
+
];
|
|
99
|
+
const declarations = [
|
|
100
|
+
{ function: 'func-1', path: '/f1' },
|
|
101
|
+
{ function: 'func-2', mode: 'not_a_supported_mode', path: '/f2' },
|
|
102
|
+
{ function: 'func-3', mode: 'after-cache', path: '/f3' },
|
|
103
|
+
];
|
|
104
|
+
const manifest = generateManifest({ bundles: [bundle1, bundle2], declarations, functions });
|
|
105
|
+
const expectedBundles = [
|
|
106
|
+
{ asset: bundle1.hash + bundle1.extension, format: bundle1.format },
|
|
107
|
+
{ asset: bundle2.hash + bundle2.extension, format: bundle2.format },
|
|
108
|
+
];
|
|
109
|
+
const expectedPreCacheRoutes = [
|
|
110
|
+
{ function: 'func-1', name: undefined, pattern: '^/f1/?$' },
|
|
111
|
+
{ function: 'func-2', name: undefined, pattern: '^/f2/?$' },
|
|
112
|
+
];
|
|
113
|
+
const expectedPostCacheRoutes = [{ function: 'func-3', name: undefined, pattern: '^/f3/?$' }];
|
|
114
|
+
expect(manifest.bundles).toEqual(expectedBundles);
|
|
115
|
+
expect(manifest.routes).toEqual(expectedPreCacheRoutes);
|
|
116
|
+
expect(manifest.post_cache_routes).toEqual(expectedPostCacheRoutes);
|
|
117
|
+
expect(manifest.bundler_version).toBe(env.npm_package_version);
|
|
118
|
+
});
|