@netlify/edge-bundler 14.9.18 → 14.10.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 +55 -18
- package/dist/node/formats/tarball.d.ts +7 -1
- package/dist/node/formats/tarball.js +63 -37
- package/dist/node/import_map.d.ts +1 -1
- package/dist/node/import_map.js +1 -2
- package/dist/node/manifest.d.ts +26 -8
- package/dist/node/manifest.js +28 -8
- package/package.json +2 -2
package/dist/node/bundler.js
CHANGED
|
@@ -13,7 +13,7 @@ import { bundle as bundleESZIP } from './formats/eszip.js';
|
|
|
13
13
|
import { bundle as bundleTarball } from './formats/tarball.js';
|
|
14
14
|
import { ImportMap } from './import_map.js';
|
|
15
15
|
import { getLogger } from './logger.js';
|
|
16
|
-
import { writeManifest } from './manifest.js';
|
|
16
|
+
import { generateManifestFunctionConfig, generateManifestRoutes, writeManifest } from './manifest.js';
|
|
17
17
|
import { vendorNPMSpecifiers } from './npm_dependencies.js';
|
|
18
18
|
import { ensureLatestTypes } from './types.js';
|
|
19
19
|
import { nonNullable } from './utils/non_nullable.js';
|
|
@@ -66,8 +66,10 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
66
66
|
}
|
|
67
67
|
const bundles = [];
|
|
68
68
|
let tarballBundleDurationMs;
|
|
69
|
+
let tarballDryRunError;
|
|
70
|
+
let finalizeTarballBundle;
|
|
69
71
|
if (featureFlags.edge_bundler_generate_tarball || featureFlags.edge_bundler_dry_run_generate_tarball) {
|
|
70
|
-
const
|
|
72
|
+
const tarballInitialPromise = (async () => {
|
|
71
73
|
const start = Date.now();
|
|
72
74
|
try {
|
|
73
75
|
return await bundleTarball({
|
|
@@ -89,21 +91,15 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
89
91
|
let tarballPromiseResolved = false;
|
|
90
92
|
if (featureFlags.edge_bundler_dry_run_generate_tarball) {
|
|
91
93
|
try {
|
|
92
|
-
await
|
|
93
|
-
logger.system('Dry run: Tarball bundle generated successfully.');
|
|
94
|
+
await tarballInitialPromise;
|
|
94
95
|
tarballPromiseResolved = true;
|
|
95
96
|
}
|
|
96
97
|
catch (error) {
|
|
97
|
-
|
|
98
|
-
logger.system(`Dry run: Tarball bundle generation failed: ${error.message}`);
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
logger.system(`Dry run: Tarball bundle generation failed: ${String(error)}`);
|
|
102
|
-
}
|
|
98
|
+
tarballDryRunError = error ?? new Error('Unknown error during tarball bundle generation');
|
|
103
99
|
}
|
|
104
100
|
}
|
|
105
101
|
if (featureFlags.edge_bundler_generate_tarball || tarballPromiseResolved) {
|
|
106
|
-
|
|
102
|
+
finalizeTarballBundle = await tarballInitialPromise;
|
|
107
103
|
}
|
|
108
104
|
}
|
|
109
105
|
bundles.push(await bundleESZIP({
|
|
@@ -118,10 +114,6 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
118
114
|
importMap,
|
|
119
115
|
vendorDirectory: vendor?.directory,
|
|
120
116
|
}));
|
|
121
|
-
// The final file name of the bundles contains a SHA256 hash of the contents,
|
|
122
|
-
// which we can only compute now that the files have been generated. So let's
|
|
123
|
-
// rename the bundles to their permanent names.
|
|
124
|
-
await createFinalBundles(bundles, distDirectory, buildID);
|
|
125
117
|
const { internalFunctions: internalFunctionsWithConfig, userFunctions: userFunctionsWithConfig } = await getFunctionConfigs({
|
|
126
118
|
deno,
|
|
127
119
|
importMap,
|
|
@@ -136,14 +128,59 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
136
128
|
internalFunctionsWithConfig,
|
|
137
129
|
declarations,
|
|
138
130
|
});
|
|
131
|
+
const manifestFunctionConfig = generateManifestFunctionConfig({
|
|
132
|
+
functions,
|
|
133
|
+
internalFunctionConfig,
|
|
134
|
+
userFunctionConfig: userFunctionsWithConfig,
|
|
135
|
+
});
|
|
136
|
+
const manifestRoutes = generateManifestRoutes({
|
|
137
|
+
functions,
|
|
138
|
+
declarations,
|
|
139
|
+
});
|
|
140
|
+
if (!tarballDryRunError && finalizeTarballBundle) {
|
|
141
|
+
try {
|
|
142
|
+
bundles.unshift(await finalizeTarballBundle({ manifestFunctionConfig, manifestRoutes }));
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (featureFlags.edge_bundler_dry_run_generate_tarball) {
|
|
146
|
+
tarballDryRunError = error ?? new Error('Unknown error during tarball bundle finalization');
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (featureFlags.edge_bundler_dry_run_generate_tarball) {
|
|
154
|
+
let tarballLogMsg;
|
|
155
|
+
if (tarballDryRunError) {
|
|
156
|
+
if (tarballDryRunError instanceof Error) {
|
|
157
|
+
tarballLogMsg = `Dry run: Eszip successful, tarball bundle generation failed: ${tarballDryRunError.message}`;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
tarballLogMsg = `Dry run: Eszip successful, tarball bundle generation failed: ${String(tarballDryRunError)}`;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
tarballLogMsg = 'Dry run: Eszip and tarball bundle generated successfully.';
|
|
165
|
+
}
|
|
166
|
+
if (tarballLogMsg) {
|
|
167
|
+
// Log tarball generation status after eszip bundling succeeds (only set during dry runs).
|
|
168
|
+
// Reported errors might be multiple lines, so we replace newlines with the literal string '\n' to get a single log line,
|
|
169
|
+
// while still ensuring it could be expanded into the original multi-line message if needed.
|
|
170
|
+
logger.system(tarballLogMsg.replaceAll('\n', '\\n'));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// The final file name of the bundles contains a SHA256 hash of the contents,
|
|
174
|
+
// which we can only compute now that the files have been generated. So let's
|
|
175
|
+
// rename the bundles to their permanent names.
|
|
176
|
+
await createFinalBundles(bundles, distDirectory, buildID);
|
|
139
177
|
const manifest = await writeManifest({
|
|
140
178
|
bundles,
|
|
141
|
-
declarations,
|
|
142
179
|
distDirectory,
|
|
143
180
|
featureFlags,
|
|
144
181
|
functions,
|
|
145
|
-
|
|
146
|
-
|
|
182
|
+
manifestFunctionConfig,
|
|
183
|
+
manifestRoutes,
|
|
147
184
|
importMap: importMapSpecifier,
|
|
148
185
|
layers: deployConfig.layers,
|
|
149
186
|
bundlingTiming: tarballBundleDurationMs === undefined ? undefined : { tarball_ms: tarballBundleDurationMs },
|
|
@@ -3,6 +3,8 @@ import { Bundle } from '../bundle.js';
|
|
|
3
3
|
import { EdgeFunction } from '../edge_function.js';
|
|
4
4
|
import { FeatureFlags } from '../feature_flags.js';
|
|
5
5
|
import { ImportMap } from '../import_map.js';
|
|
6
|
+
import { EdgeFunctionConfig } from '../index.js';
|
|
7
|
+
import { generateManifestRoutes } from '../manifest.js';
|
|
6
8
|
interface BundleTarballOptions {
|
|
7
9
|
basePath: string;
|
|
8
10
|
buildID: string;
|
|
@@ -14,7 +16,11 @@ interface BundleTarballOptions {
|
|
|
14
16
|
importMap: ImportMap;
|
|
15
17
|
vendorDirectory?: string;
|
|
16
18
|
}
|
|
17
|
-
|
|
19
|
+
interface FinalizeTarballBundleOptions {
|
|
20
|
+
manifestFunctionConfig: Record<string, EdgeFunctionConfig>;
|
|
21
|
+
manifestRoutes: ReturnType<typeof generateManifestRoutes>;
|
|
22
|
+
}
|
|
23
|
+
export declare const bundle: ({ buildID, deno, distDirectory, functions, importMap, vendorDirectory, }: BundleTarballOptions) => Promise<(arg: FinalizeTarballBundleOptions) => Promise<Bundle>>;
|
|
18
24
|
/**
|
|
19
25
|
* Rewrites import assert into import with in the bundle directory
|
|
20
26
|
* Defaults to copying the file in its current form
|
|
@@ -13,9 +13,9 @@ const getUnixPath = (input) => input.split(path.sep).join('/');
|
|
|
13
13
|
export const bundle = async ({ buildID, deno, distDirectory, functions, importMap, vendorDirectory, }) => {
|
|
14
14
|
const bundleDir = await tmp.dir({ unsafeCleanup: true });
|
|
15
15
|
const cleanup = [bundleDir.cleanup];
|
|
16
|
-
const
|
|
16
|
+
const initialManifest = {
|
|
17
17
|
functions: {},
|
|
18
|
-
version:
|
|
18
|
+
version: 2,
|
|
19
19
|
};
|
|
20
20
|
const entryPoints = functions.map((func) => func.path);
|
|
21
21
|
// Use deno info to get the module graph and identify which local files are actually needed.
|
|
@@ -24,6 +24,7 @@ export const bundle = async ({ buildID, deno, distDirectory, functions, importMa
|
|
|
24
24
|
// Build prefix mappings to transform file:// URLs to relative paths
|
|
25
25
|
const npmVendorDir = '.netlify-npm-vendor';
|
|
26
26
|
const prefixes = {};
|
|
27
|
+
const additionalImportMapEntries = {};
|
|
27
28
|
// Copy pre-bundled npm modules from vendorDirectory if present.
|
|
28
29
|
// This supports the legacy approach where npm packages are pre-bundled and mapped
|
|
29
30
|
// via import map. Modern code could use npm: specifiers instead, which Deno handles
|
|
@@ -51,10 +52,18 @@ export const bundle = async ({ buildID, deno, distDirectory, functions, importMa
|
|
|
51
52
|
// Build the manifest mapping function names to their relative paths
|
|
52
53
|
for (const func of functions) {
|
|
53
54
|
const relativePath = path.relative(commonPath, func.path);
|
|
54
|
-
|
|
55
|
+
initialManifest.functions[func.name] = getUnixPath(relativePath);
|
|
55
56
|
}
|
|
56
57
|
for (const sourceFile of sourceFilesSet) {
|
|
57
|
-
|
|
58
|
+
let relativePath = path.relative(commonPath, sourceFile);
|
|
59
|
+
if (relativePath.startsWith('vendor' + path.sep)) {
|
|
60
|
+
// root vendor directory is reserved directory and can't be imported directly from with `vendor: true` or `--vendor` flag
|
|
61
|
+
// move from vendor/ to .root-vendor/
|
|
62
|
+
relativePath = relativePath.replace(/vendor[\\/]/, `.root-vendor/`);
|
|
63
|
+
// and import map rewrite so imports remain resolvable
|
|
64
|
+
additionalImportMapEntries['./vendor/'] = `./.root-vendor/`;
|
|
65
|
+
prefixes[pathToFileURL(path.join(commonPath, 'vendor') + path.sep).href] = './.root-vendor/';
|
|
66
|
+
}
|
|
58
67
|
const destPath = path.join(bundleDir.path, relativePath);
|
|
59
68
|
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
60
69
|
// Rewrite import assertions in user files
|
|
@@ -63,7 +72,7 @@ export const bundle = async ({ buildID, deno, distDirectory, functions, importMa
|
|
|
63
72
|
// Map common path to relative paths
|
|
64
73
|
prefixes[pathToFileURL(commonPath + path.sep).href] = './';
|
|
65
74
|
// Get import map contents with file:// URLs transformed to relative paths
|
|
66
|
-
const importMapContents = importMap.getContents(prefixes);
|
|
75
|
+
const importMapContents = importMap.getContents(prefixes, additionalImportMapEntries);
|
|
67
76
|
// Create deno.json with import map contents for runtime resolution
|
|
68
77
|
const denoConfigPath = path.join(bundleDir.path, 'deno.json');
|
|
69
78
|
const denoConfigContents = JSON.stringify(importMapContents, null, 2);
|
|
@@ -78,7 +87,7 @@ export const bundle = async ({ buildID, deno, distDirectory, functions, importMa
|
|
|
78
87
|
'--node-modules-dir=manual',
|
|
79
88
|
'--vendor',
|
|
80
89
|
'--entrypoint',
|
|
81
|
-
...Object.values(
|
|
90
|
+
...Object.values(initialManifest.functions),
|
|
82
91
|
], {
|
|
83
92
|
cwd: bundleDir.path,
|
|
84
93
|
});
|
|
@@ -90,37 +99,49 @@ export const bundle = async ({ buildID, deno, distDirectory, functions, importMa
|
|
|
90
99
|
await rewriteImportAssertions(denoVendorFile, denoVendorFile);
|
|
91
100
|
}
|
|
92
101
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
.
|
|
107
|
-
.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
102
|
+
// First stage of bundling is now done. To finalize bundling we require functionConfig, routes and postCacheRoutes
|
|
103
|
+
// so we could inject those into bundle manifest. Tarball bundling is done in 2-step process process to preserve ordering
|
|
104
|
+
// and potential errors messages that could be thrown to make sure we don't impact behaviors. Otherwise we would throw different
|
|
105
|
+
// kind of errors than we used to and introduce confusion for users.
|
|
106
|
+
return async function finalizeBundle({ manifestFunctionConfig, manifestRoutes }) {
|
|
107
|
+
const manifest = {
|
|
108
|
+
...initialManifest,
|
|
109
|
+
function_config: manifestFunctionConfig,
|
|
110
|
+
routes: manifestRoutes.preCacheRoutes,
|
|
111
|
+
post_cache_routes: manifestRoutes.postCacheRoutes,
|
|
112
|
+
};
|
|
113
|
+
const manifestPath = path.join(bundleDir.path, '___netlify-edge-functions.json');
|
|
114
|
+
const manifestContents = JSON.stringify(manifest);
|
|
115
|
+
await fs.writeFile(manifestPath, manifestContents);
|
|
116
|
+
const tarballPath = path.join(distDirectory, buildID + TARBALL_EXTENSION);
|
|
117
|
+
await fs.mkdir(path.dirname(tarballPath), { recursive: true });
|
|
118
|
+
// List files to include in the tarball as paths relative to the bundle dir.
|
|
119
|
+
// Using absolute paths here leads to platform-specific quirks (notably on Windows),
|
|
120
|
+
// where entries can include drive letters and break extraction/imports.
|
|
121
|
+
// The './' prefix is required to prevent node-tar from interpreting entries
|
|
122
|
+
// starting with '@' as GNU tar archive-include directives, which would cause
|
|
123
|
+
// it to strip the '@' and stat a non-existent path (ENOENT).
|
|
124
|
+
const files = (await listRecursively(bundleDir.path))
|
|
125
|
+
.map((p) => path.relative(bundleDir.path, p))
|
|
126
|
+
.map((p) => './' + getUnixPath(p))
|
|
127
|
+
.sort();
|
|
128
|
+
await tar.create({
|
|
129
|
+
cwd: bundleDir.path,
|
|
130
|
+
file: tarballPath,
|
|
131
|
+
gzip: true,
|
|
132
|
+
noDirRecurse: true,
|
|
133
|
+
// Ensure forward slashes inside the tarball for cross-platform consistency.
|
|
134
|
+
onWriteEntry(entry) {
|
|
135
|
+
entry.path = getUnixPath(entry.path);
|
|
136
|
+
},
|
|
137
|
+
}, files);
|
|
138
|
+
const hash = await getFileHash(tarballPath);
|
|
139
|
+
await Promise.allSettled(cleanup);
|
|
140
|
+
return {
|
|
141
|
+
extension: TARBALL_EXTENSION,
|
|
142
|
+
format: BundleFormat.TARBALL,
|
|
143
|
+
hash,
|
|
144
|
+
};
|
|
124
145
|
};
|
|
125
146
|
};
|
|
126
147
|
// Source file extensions that may contain import statements.
|
|
@@ -147,6 +168,11 @@ async function getRequiredSourceFiles(deno, entryPoints, importMap) {
|
|
|
147
168
|
// Extract all local files from the module graph
|
|
148
169
|
for (const module of graph.modules) {
|
|
149
170
|
if (module.specifier.startsWith('file://')) {
|
|
171
|
+
if (module.error?.startsWith('Module not found')) {
|
|
172
|
+
// Module graph contains all found imported/required modules, even if they don't actually exist
|
|
173
|
+
// This can happen for optional dependencies (dynamic import or require in try/catch).
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
150
176
|
const filePath = fileURLToPath(module.specifier);
|
|
151
177
|
localFiles.add(filePath);
|
|
152
178
|
}
|
|
@@ -20,7 +20,7 @@ export declare class ImportMap {
|
|
|
20
20
|
static applyPrefixesToPath(path: string, prefixes: Record<string, string>): string;
|
|
21
21
|
filterImports(imports?: Record<string, URL | null>): Record<string, string>;
|
|
22
22
|
filterScopes(scopes?: ParsedImportMap['scopes']): Record<string, Imports>;
|
|
23
|
-
getContents(prefixes?: Record<string, string
|
|
23
|
+
getContents(prefixes?: Record<string, string>, imports?: Imports): {
|
|
24
24
|
imports: Imports;
|
|
25
25
|
scopes: {};
|
|
26
26
|
};
|
package/dist/node/import_map.js
CHANGED
|
@@ -116,8 +116,7 @@ export class ImportMap {
|
|
|
116
116
|
// to full URLs. It takes an optional `prefixes` object that specifies a list
|
|
117
117
|
// of prefixes to replace path prefixes (see `applyPrefixesToPath`). Prefixes
|
|
118
118
|
// will be applied on both `imports` and `scopes`.
|
|
119
|
-
getContents(prefixes = {}) {
|
|
120
|
-
let imports = {};
|
|
119
|
+
getContents(prefixes = {}, imports = {}) {
|
|
121
120
|
let scopes = {};
|
|
122
121
|
this.sources.forEach((file) => {
|
|
123
122
|
const importMap = this.resolve(file);
|
package/dist/node/manifest.d.ts
CHANGED
|
@@ -56,24 +56,42 @@ interface Manifest {
|
|
|
56
56
|
post_cache_routes: Route[];
|
|
57
57
|
function_config: Record<string, EdgeFunctionConfig>;
|
|
58
58
|
}
|
|
59
|
-
interface
|
|
60
|
-
|
|
59
|
+
interface GenerateManifestFunctionConfigOptions {
|
|
60
|
+
functions: EdgeFunction[];
|
|
61
|
+
internalFunctionConfig?: Record<string, FunctionConfig>;
|
|
62
|
+
userFunctionConfig?: Record<string, FunctionConfig>;
|
|
63
|
+
}
|
|
64
|
+
interface GenerateManifestRoutesOptions {
|
|
65
|
+
functions: EdgeFunction[];
|
|
61
66
|
declarations?: Declaration[];
|
|
67
|
+
}
|
|
68
|
+
interface GenerateManifestOptionsBase {
|
|
69
|
+
bundles?: Bundle[];
|
|
62
70
|
featureFlags?: FeatureFlags;
|
|
63
|
-
functions: EdgeFunction[];
|
|
64
71
|
importMap?: string;
|
|
65
|
-
internalFunctionConfig?: Record<string, FunctionConfig>;
|
|
66
72
|
layers?: Layer[];
|
|
67
|
-
userFunctionConfig?: Record<string, FunctionConfig>;
|
|
68
73
|
bundlingTiming?: BundlingTiming;
|
|
74
|
+
functions: EdgeFunction[];
|
|
69
75
|
}
|
|
70
|
-
declare const
|
|
76
|
+
export declare const generateManifestFunctionConfig: ({ functions, userFunctionConfig, internalFunctionConfig, }: GenerateManifestFunctionConfigOptions) => Record<string, EdgeFunctionConfig>;
|
|
77
|
+
export declare const generateManifestRoutes: ({ functions, declarations }: GenerateManifestRoutesOptions) => {
|
|
78
|
+
preCacheRoutes: Route[];
|
|
79
|
+
postCacheRoutes: Route[];
|
|
80
|
+
unroutedFunctions: string[];
|
|
81
|
+
declarationsWithoutFunction: Set<string>;
|
|
82
|
+
};
|
|
83
|
+
type GenerateManifestOptions = GenerateManifestOptionsBase & (GenerateManifestFunctionConfigOptions | {
|
|
84
|
+
manifestFunctionConfig: ReturnType<typeof generateManifestFunctionConfig>;
|
|
85
|
+
}) & (GenerateManifestRoutesOptions | {
|
|
86
|
+
manifestRoutes: ReturnType<typeof generateManifestRoutes>;
|
|
87
|
+
});
|
|
88
|
+
declare const generateManifest: ({ bundles, importMap, layers, bundlingTiming, functions, ...rest }: GenerateManifestOptions) => {
|
|
71
89
|
declarationsWithoutFunction: string[];
|
|
72
90
|
manifest: Manifest;
|
|
73
91
|
unroutedFunctions: string[];
|
|
74
92
|
};
|
|
75
|
-
|
|
93
|
+
type WriteManifestOptions = GenerateManifestOptions & {
|
|
76
94
|
distDirectory: string;
|
|
77
|
-
}
|
|
95
|
+
};
|
|
78
96
|
declare const writeManifest: ({ distDirectory, ...rest }: WriteManifestOptions) => Promise<Manifest>;
|
|
79
97
|
export { generateManifest, Manifest, Route, writeManifest };
|
package/dist/node/manifest.js
CHANGED
|
@@ -54,12 +54,8 @@ const normalizeMethods = (method, name) => {
|
|
|
54
54
|
return method.toUpperCase();
|
|
55
55
|
});
|
|
56
56
|
};
|
|
57
|
-
const
|
|
58
|
-
const preCacheRoutes = [];
|
|
59
|
-
const postCacheRoutes = [];
|
|
57
|
+
export const generateManifestFunctionConfig = ({ functions, userFunctionConfig = {}, internalFunctionConfig = {}, }) => {
|
|
60
58
|
const manifestFunctionConfig = Object.fromEntries(functions.map(({ name }) => [name, { excluded_patterns: [] }]));
|
|
61
|
-
const routedFunctions = new Set();
|
|
62
|
-
const declarationsWithoutFunction = new Set();
|
|
63
59
|
for (const [name, singleUserFunctionConfig] of Object.entries(userFunctionConfig)) {
|
|
64
60
|
// If the config block is for a function that is not defined, discard it.
|
|
65
61
|
if (manifestFunctionConfig[name] === undefined) {
|
|
@@ -97,6 +93,13 @@ const generateManifest = ({ bundles = [], declarations = [], functions, userFunc
|
|
|
97
93
|
...rest,
|
|
98
94
|
};
|
|
99
95
|
}
|
|
96
|
+
return sanitizeEdgeFunctionConfig(manifestFunctionConfig);
|
|
97
|
+
};
|
|
98
|
+
export const generateManifestRoutes = ({ functions, declarations = [] }) => {
|
|
99
|
+
const preCacheRoutes = [];
|
|
100
|
+
const postCacheRoutes = [];
|
|
101
|
+
const routedFunctions = new Set();
|
|
102
|
+
const declarationsWithoutFunction = new Set();
|
|
100
103
|
declarations.forEach((declaration) => {
|
|
101
104
|
const func = functions.find(({ name }) => declaration.function === name);
|
|
102
105
|
if (func === undefined) {
|
|
@@ -132,14 +135,32 @@ const generateManifest = ({ bundles = [], declarations = [], functions, userFunc
|
|
|
132
135
|
preCacheRoutes.push(route);
|
|
133
136
|
}
|
|
134
137
|
});
|
|
138
|
+
const unroutedFunctions = functions.filter(({ name }) => !routedFunctions.has(name)).map(({ name }) => name);
|
|
139
|
+
return {
|
|
140
|
+
preCacheRoutes: preCacheRoutes.filter(nonNullable),
|
|
141
|
+
postCacheRoutes: postCacheRoutes.filter(nonNullable),
|
|
142
|
+
unroutedFunctions,
|
|
143
|
+
declarationsWithoutFunction,
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
const generateManifest = ({ bundles = [], importMap, layers = [], bundlingTiming, functions, ...rest }) => {
|
|
147
|
+
const manifestFunctionConfig = 'manifestFunctionConfig' in rest
|
|
148
|
+
? rest.manifestFunctionConfig
|
|
149
|
+
: generateManifestFunctionConfig({ functions, ...rest });
|
|
150
|
+
const { preCacheRoutes, postCacheRoutes, unroutedFunctions, declarationsWithoutFunction } = 'manifestRoutes' in rest
|
|
151
|
+
? rest.manifestRoutes
|
|
152
|
+
: generateManifestRoutes({
|
|
153
|
+
functions,
|
|
154
|
+
...rest,
|
|
155
|
+
});
|
|
135
156
|
const manifestBundles = bundles.map(({ extension, format, hash }) => ({
|
|
136
157
|
asset: hash + extension,
|
|
137
158
|
format,
|
|
138
159
|
}));
|
|
139
160
|
const manifest = {
|
|
140
161
|
bundles: manifestBundles,
|
|
141
|
-
routes: preCacheRoutes
|
|
142
|
-
post_cache_routes: postCacheRoutes
|
|
162
|
+
routes: preCacheRoutes,
|
|
163
|
+
post_cache_routes: postCacheRoutes,
|
|
143
164
|
bundler_version: getPackageVersion(),
|
|
144
165
|
layers,
|
|
145
166
|
import_map: importMap,
|
|
@@ -148,7 +169,6 @@ const generateManifest = ({ bundles = [], declarations = [], functions, userFunc
|
|
|
148
169
|
? { bundling_timing: bundlingTiming }
|
|
149
170
|
: {}),
|
|
150
171
|
};
|
|
151
|
-
const unroutedFunctions = functions.filter(({ name }) => !routedFunctions.has(name)).map(({ name }) => name);
|
|
152
172
|
return { declarationsWithoutFunction: [...declarationsWithoutFunction], manifest, unroutedFunctions };
|
|
153
173
|
};
|
|
154
174
|
const getTrafficRulesConfig = (rl) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/edge-bundler",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.10.0",
|
|
4
4
|
"description": "Intelligently prepare Netlify Edge Functions for deployment",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/node/index.js",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"urlpattern-polyfill": "8.0.2",
|
|
82
82
|
"uuid": "^11.0.0"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "6a547b9ec049b48a1e028e180bc21082cb367643"
|
|
85
85
|
}
|