@netlify/edge-bundler 14.9.17 → 14.9.19

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.
@@ -66,6 +66,7 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
66
66
  }
67
67
  const bundles = [];
68
68
  let tarballBundleDurationMs;
69
+ let tarballLogMsg;
69
70
  if (featureFlags.edge_bundler_generate_tarball || featureFlags.edge_bundler_dry_run_generate_tarball) {
70
71
  const tarballPromise = (async () => {
71
72
  const start = Date.now();
@@ -90,15 +91,15 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
90
91
  if (featureFlags.edge_bundler_dry_run_generate_tarball) {
91
92
  try {
92
93
  await tarballPromise;
93
- logger.system('Dry run: Tarball bundle generated successfully.');
94
+ tarballLogMsg = 'Dry run: Eszip and tarball bundle generated successfully.';
94
95
  tarballPromiseResolved = true;
95
96
  }
96
97
  catch (error) {
97
98
  if (error instanceof Error) {
98
- logger.system(`Dry run: Tarball bundle generation failed: ${error.message}`);
99
+ tarballLogMsg = `Dry run: Eszip successful, tarball bundle generation failed: ${error.message}`;
99
100
  }
100
101
  else {
101
- logger.system(`Dry run: Tarball bundle generation failed: ${String(error)}`);
102
+ tarballLogMsg = `Dry run: Eszip successful, tarball bundle generation failed: ${String(error)}`;
102
103
  }
103
104
  }
104
105
  }
@@ -118,6 +119,12 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
118
119
  importMap,
119
120
  vendorDirectory: vendor?.directory,
120
121
  }));
122
+ // Log tarball generation status after eszip bundling succeeds (only set during dry runs).
123
+ if (tarballLogMsg) {
124
+ // Reported errors might be multiple lines, so we replace newlines with the literal string '\n' to get a single log line,
125
+ // while still ensuring it could be expanded into the original multi-line message if needed.
126
+ logger.system(tarballLogMsg.replaceAll('\n', '\\n'));
127
+ }
121
128
  // The final file name of the bundles contains a SHA256 hash of the contents,
122
129
  // which we can only compute now that the files have been generated. So let's
123
130
  // rename the bundles to their permanent names.
@@ -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
@@ -54,7 +55,15 @@ export const bundle = async ({ buildID, deno, distDirectory, functions, importMa
54
55
  manifest.functions[func.name] = getUnixPath(relativePath);
55
56
  }
56
57
  for (const sourceFile of sourceFilesSet) {
57
- const relativePath = path.relative(commonPath, sourceFile);
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);
@@ -147,6 +156,11 @@ async function getRequiredSourceFiles(deno, entryPoints, importMap) {
147
156
  // Extract all local files from the module graph
148
157
  for (const module of graph.modules) {
149
158
  if (module.specifier.startsWith('file://')) {
159
+ if (module.error?.startsWith('Module not found')) {
160
+ // Module graph contains all found imported/required modules, even if they don't actually exist
161
+ // This can happen for optional dependencies (dynamic import or require in try/catch).
162
+ continue;
163
+ }
150
164
  const filePath = fileURLToPath(module.specifier);
151
165
  localFiles.add(filePath);
152
166
  }
@@ -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
  };
@@ -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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/edge-bundler",
3
- "version": "14.9.17",
3
+ "version": "14.9.19",
4
4
  "description": "Intelligently prepare Netlify Edge Functions for deployment",
5
5
  "type": "module",
6
6
  "main": "./dist/node/index.js",
@@ -76,10 +76,10 @@
76
76
  "parse-imports": "^2.2.1",
77
77
  "path-key": "^4.0.0",
78
78
  "semver": "^7.3.8",
79
- "tar": "^7.5.3",
79
+ "tar": "^7.5.12",
80
80
  "tmp-promise": "^3.0.3",
81
81
  "urlpattern-polyfill": "8.0.2",
82
82
  "uuid": "^11.0.0"
83
83
  },
84
- "gitHead": "4c1f6b11490fca02a044a8f0e3bed51ef6b7c85a"
84
+ "gitHead": "3694352be4959c56e96a6c15dd04ed4d7aa31344"
85
85
  }