@netlify/edge-bundler 9.1.0 → 9.2.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.
@@ -18,7 +18,7 @@ class DenoBridge {
18
18
  this.cacheDirectory = (_a = options.cacheDirectory) !== null && _a !== void 0 ? _a : getPathInHome('deno-cli');
19
19
  this.debug = (_b = options.debug) !== null && _b !== void 0 ? _b : false;
20
20
  this.denoDir = options.denoDir;
21
- this.logger = (_c = options.logger) !== null && _c !== void 0 ? _c : getLogger(undefined, options.debug);
21
+ this.logger = (_c = options.logger) !== null && _c !== void 0 ? _c : getLogger(undefined, undefined, options.debug);
22
22
  this.onAfterDownload = options.onAfterDownload;
23
23
  this.onBeforeDownload = options.onBeforeDownload;
24
24
  this.useGlobal = (_d = options.useGlobal) !== null && _d !== void 0 ? _d : true;
@@ -16,9 +16,10 @@ export interface BundleOptions {
16
16
  onAfterDownload?: OnAfterDownloadHook;
17
17
  onBeforeDownload?: OnBeforeDownloadHook;
18
18
  systemLogger?: LogFunction;
19
+ userLogger?: LogFunction;
19
20
  vendorDirectory?: string;
20
21
  }
21
- export declare const bundle: (sourceDirectories: string[], distDirectory: string, tomlDeclarations?: Declaration[], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths, internalSrcFolder, onAfterDownload, onBeforeDownload, systemLogger, vendorDirectory, }?: BundleOptions) => Promise<{
22
+ export declare const bundle: (sourceDirectories: string[], distDirectory: string, tomlDeclarations?: Declaration[], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths, internalSrcFolder, onAfterDownload, onBeforeDownload, userLogger, systemLogger, vendorDirectory, }?: BundleOptions) => Promise<{
22
23
  functions: EdgeFunction[];
23
24
  manifest: import("./manifest.js").Manifest;
24
25
  }>;
@@ -15,8 +15,8 @@ import { getLogger } from './logger.js';
15
15
  import { writeManifest } from './manifest.js';
16
16
  import { vendorNPMSpecifiers } from './npm_dependencies.js';
17
17
  import { ensureLatestTypes } from './types.js';
18
- export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations = [], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths = [], internalSrcFolder, onAfterDownload, onBeforeDownload, systemLogger, vendorDirectory, } = {}) => {
19
- const logger = getLogger(systemLogger, debug);
18
+ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations = [], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths = [], internalSrcFolder, onAfterDownload, onBeforeDownload, userLogger, systemLogger, vendorDirectory, } = {}) => {
19
+ const logger = getLogger(systemLogger, userLogger, debug);
20
20
  const featureFlags = getFlags(inputFeatureFlags);
21
21
  const options = {
22
22
  debug,
@@ -116,7 +116,10 @@ test('Prints a nice error message when user tries importing an npm module and np
116
116
  },
117
117
  ];
118
118
  try {
119
- await bundle([sourceDirectory], distPath, declarations, { basePath });
119
+ await bundle([sourceDirectory], distPath, declarations, {
120
+ basePath,
121
+ importMapPaths: [join(basePath, 'import_map.json')],
122
+ });
120
123
  }
121
124
  catch (error) {
122
125
  expect(error).toBeInstanceOf(BundleError);
@@ -398,6 +401,7 @@ test('Handles imports with the `node:` prefix', async () => {
398
401
  await cleanup();
399
402
  });
400
403
  test('Loads npm modules from bare specifiers', async () => {
404
+ const systemLogger = vi.fn();
401
405
  const { basePath, cleanup, distPath } = await useFixture('imports_npm_module');
402
406
  const sourceDirectory = join(basePath, 'functions');
403
407
  const declarations = [
@@ -412,7 +416,9 @@ test('Loads npm modules from bare specifiers', async () => {
412
416
  featureFlags: { edge_functions_npm_modules: true },
413
417
  importMapPaths: [join(basePath, 'import_map.json')],
414
418
  vendorDirectory: vendorDirectory.path,
419
+ systemLogger,
415
420
  });
421
+ expect(systemLogger.mock.calls.find((call) => call[0] === 'Could not track dependencies in edge function:')).toBeUndefined();
416
422
  const manifestFile = await readFile(resolve(distPath, 'manifest.json'), 'utf8');
417
423
  const manifest = JSON.parse(manifestFile);
418
424
  const bundlePath = join(distPath, manifest.bundles[0].asset);
@@ -3,7 +3,7 @@ import { basename, extname, join, parse } from 'path';
3
3
  import { nonNullable } from './utils/non_nullable.js';
4
4
  // the order of the allowed extensions is also the order we remove duplicates
5
5
  // with a lower index meaning a higher precedence over the others
6
- const ALLOWED_EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx'];
6
+ const ALLOWED_EXTENSIONS = ['.js', '.jsx', '.mjs', '.mts', '.ts', '.tsx'];
7
7
  export const removeDuplicatesByExtension = (functions) => {
8
8
  const seen = new Map();
9
9
  return Object.values(functions.reduce((acc, path) => {
@@ -3,6 +3,6 @@ interface Logger {
3
3
  system: LogFunction;
4
4
  user: LogFunction;
5
5
  }
6
- declare const getLogger: (systemLogger?: LogFunction, debug?: boolean) => Logger;
6
+ declare const getLogger: (systemLogger?: LogFunction, userLogger?: LogFunction, debug?: boolean) => Logger;
7
7
  export { getLogger };
8
8
  export type { LogFunction, Logger };
@@ -1,14 +1,15 @@
1
1
  const noopLogger = () => {
2
2
  // no-op
3
3
  };
4
- const getLogger = (systemLogger, debug = false) => {
4
+ const getLogger = (systemLogger, userLogger, debug = false) => {
5
5
  // If there is a system logger configured, we'll use that. If there isn't,
6
6
  // we'll pipe system logs to stdout if `debug` is enabled and swallow them
7
7
  // otherwise.
8
8
  const system = systemLogger !== null && systemLogger !== void 0 ? systemLogger : (debug ? console.log : noopLogger);
9
+ const user = userLogger !== null && userLogger !== void 0 ? userLogger : console.log;
9
10
  return {
10
11
  system,
11
- user: console.log,
12
+ user,
12
13
  };
13
14
  };
14
15
  export { getLogger };
@@ -8,23 +8,30 @@ afterEach(() => {
8
8
  // Restoring global `console.log`.
9
9
  console.log = consoleLog;
10
10
  });
11
- test('Prints user logs to stdout', () => {
11
+ test('Prints user logs to stdout if no user logger is provided', () => {
12
12
  const mockConsoleLog = vi.fn();
13
13
  console.log = mockConsoleLog;
14
- const logger1 = getLogger(noopLogger, true);
15
- const logger2 = getLogger(noopLogger, false);
14
+ const logger1 = getLogger(noopLogger, undefined, true);
15
+ const logger2 = getLogger(noopLogger, undefined, false);
16
16
  logger1.user('Hello with `debug: true`');
17
17
  logger2.user('Hello with `debug: false`');
18
18
  expect(mockConsoleLog).toHaveBeenCalledTimes(2);
19
19
  expect(mockConsoleLog).toHaveBeenNthCalledWith(1, 'Hello with `debug: true`');
20
20
  expect(mockConsoleLog).toHaveBeenNthCalledWith(2, 'Hello with `debug: false`');
21
21
  });
22
+ test('Prints user logs to user logger provided', () => {
23
+ const userLogger = vi.fn();
24
+ const logger = getLogger(noopLogger, userLogger, true);
25
+ logger.user('Hello!');
26
+ expect(userLogger).toHaveBeenCalledTimes(1);
27
+ expect(userLogger).toHaveBeenNthCalledWith(1, 'Hello!');
28
+ });
22
29
  test('Prints system logs to the system logger provided', () => {
23
30
  const mockSystemLog = vi.fn();
24
31
  const mockConsoleLog = vi.fn();
25
32
  console.log = mockSystemLog;
26
- const logger1 = getLogger(mockSystemLog, true);
27
- const logger2 = getLogger(mockSystemLog, false);
33
+ const logger1 = getLogger(mockSystemLog, undefined, true);
34
+ const logger2 = getLogger(mockSystemLog, undefined, false);
28
35
  logger1.system('Hello with `debug: true`');
29
36
  logger2.system('Hello with `debug: false`');
30
37
  expect(mockConsoleLog).toHaveBeenCalledTimes(0);
@@ -35,8 +42,8 @@ test('Prints system logs to the system logger provided', () => {
35
42
  test('Prints system logs to stdout if there is no system logger provided and `debug` is enabled', () => {
36
43
  const mockConsoleLog = vi.fn();
37
44
  console.log = mockConsoleLog;
38
- const logger1 = getLogger(undefined, true);
39
- const logger2 = getLogger(undefined, false);
45
+ const logger1 = getLogger(undefined, undefined, true);
46
+ const logger2 = getLogger(undefined, undefined, false);
40
47
  logger1.system('Hello with `debug: true`');
41
48
  logger2.system('Hello with `debug: false`');
42
49
  expect(mockConsoleLog).toHaveBeenCalledTimes(1);
@@ -37,6 +37,9 @@ export const getDependencyTrackerPlugin = (specifiers, importMap, baseURL) => ({
37
37
  // If it does, the resolved import is the specifier we'll evaluate going
38
38
  // forward.
39
39
  if (matched) {
40
+ if (resolvedImport.protocol !== 'file:') {
41
+ return { external: true };
42
+ }
40
43
  specifier = fileURLToPath(resolvedImport).replace(/\\/g, '/');
41
44
  result.path = specifier;
42
45
  }
@@ -95,21 +98,28 @@ export const vendorNPMSpecifiers = async ({ basePath, directory, functions, impo
95
98
  // loaded as npm dependencies, because they either use the `npm:` prefix or
96
99
  // they are bare specifiers. We'll collect them in `specifiers`.
97
100
  try {
98
- await build({
101
+ const { errors, warnings } = await build({
99
102
  banner,
100
103
  bundle: true,
101
104
  entryPoints: functions,
102
- logLevel: 'error',
105
+ logLevel: 'silent',
103
106
  nodePaths,
104
107
  outdir: temporaryDirectory.path,
105
108
  platform: 'node',
106
109
  plugins: [getDependencyTrackerPlugin(specifiers, importMap.getContentsWithURLObjects(), pathToFileURL(basePath))],
107
110
  write: false,
111
+ format: 'esm',
108
112
  });
113
+ if (errors.length !== 0) {
114
+ logger.system('ESBuild errored while tracking dependencies in edge function:', errors);
115
+ }
116
+ if (warnings.length !== 0) {
117
+ logger.system('ESBuild warned while tracking dependencies in edge function:', warnings);
118
+ }
109
119
  }
110
120
  catch (error) {
111
121
  logger.system('Could not track dependencies in edge function:', error);
112
- logger.user('An error occurred when trying to scan your edge functions for npm modules, which is an experimental feature. If you are loading npm modules, please share the errors above in https://ntl.fyi/edge-functions-npm. If you are not loading npm modules, you can ignore this message.');
122
+ logger.user('An error occurred when trying to scan your edge functions for npm modules, which is an experimental feature. If you are loading npm modules, please share the link to this deploy in https://ntl.fyi/edge-functions-npm. If you are not loading npm modules, you can ignore this message.');
113
123
  }
114
124
  // If we found no specifiers, there's nothing left to do here.
115
125
  if (specifiers.size === 0) {
@@ -32,9 +32,10 @@ interface ServeOptions {
32
32
  formatImportError?: FormatFunction;
33
33
  port: number;
34
34
  servePath: string;
35
+ userLogger?: LogFunction;
35
36
  systemLogger?: LogFunction;
36
37
  }
37
- export declare const serve: ({ basePath, bootstrapURL, certificatePath, debug, distImportMapPath, inspectSettings, featureFlags, formatExportTypeError, formatImportError, importMapPaths, onAfterDownload, onBeforeDownload, port, servePath, systemLogger, }: ServeOptions) => Promise<(functions: EdgeFunction[], env?: NodeJS.ProcessEnv, options?: StartServerOptions) => Promise<{
38
+ export declare const serve: ({ basePath, bootstrapURL, certificatePath, debug, distImportMapPath, inspectSettings, featureFlags, formatExportTypeError, formatImportError, importMapPaths, onAfterDownload, onBeforeDownload, port, servePath, userLogger, systemLogger, }: ServeOptions) => Promise<(functions: EdgeFunction[], env?: NodeJS.ProcessEnv, options?: StartServerOptions) => Promise<{
38
39
  features: Record<string, boolean>;
39
40
  functionsConfig: FunctionConfig[];
40
41
  graph: any;
@@ -74,8 +74,8 @@ const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImport
74
74
  };
75
75
  return startServer;
76
76
  };
77
- export const serve = async ({ basePath, bootstrapURL, certificatePath, debug, distImportMapPath, inspectSettings, featureFlags, formatExportTypeError, formatImportError, importMapPaths = [], onAfterDownload, onBeforeDownload, port, servePath, systemLogger, }) => {
78
- const logger = getLogger(systemLogger, debug);
77
+ export const serve = async ({ basePath, bootstrapURL, certificatePath, debug, distImportMapPath, inspectSettings, featureFlags, formatExportTypeError, formatImportError, importMapPaths = [], onAfterDownload, onBeforeDownload, port, servePath, userLogger, systemLogger, }) => {
78
+ const logger = getLogger(systemLogger, userLogger, debug);
79
79
  const deno = new DenoBridge({
80
80
  debug,
81
81
  logger,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/edge-bundler",
3
- "version": "9.1.0",
3
+ "version": "9.2.1",
4
4
  "description": "Intelligently prepare Netlify Edge Functions for deployment",
5
5
  "type": "module",
6
6
  "main": "./dist/node/index.js",
@@ -79,7 +79,7 @@
79
79
  "better-ajv-errors": "^1.2.0",
80
80
  "common-path-prefix": "^3.0.0",
81
81
  "env-paths": "^3.0.0",
82
- "esbuild": "0.19.2",
82
+ "esbuild": "0.19.4",
83
83
  "execa": "^6.0.0",
84
84
  "find-up": "^6.3.0",
85
85
  "get-port": "^6.1.2",