@netlify/edge-bundler 12.3.3 → 13.0.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.
@@ -42,7 +42,7 @@ const loadWithRetry = (specifier: string, delay = 1000, maxTry = 3) => {
42
42
  maxTry,
43
43
  });
44
44
  } catch (error) {
45
- if (isTooManyTries(error)) {
45
+ if (isTooManyTries(error as Error)) {
46
46
  console.error(`Loading ${specifier} failed after ${maxTry} tries.`);
47
47
  }
48
48
  throw error;
@@ -1,7 +1,7 @@
1
1
  import { type WriteStream } from 'fs';
2
2
  import { ExecaChildProcess } from 'execa';
3
3
  import { Logger } from './logger.js';
4
- declare const DENO_VERSION_RANGE = "1.39.0 - 1.46.3";
4
+ declare const DENO_VERSION_RANGE = "1.39.0 - 2.2.4";
5
5
  type OnBeforeDownloadHook = () => void | Promise<void>;
6
6
  type OnAfterDownloadHook = (error?: Error) => void | Promise<void>;
7
7
  interface DenoOptions {
@@ -37,14 +37,16 @@ declare class DenoBridge {
37
37
  versionRange: string;
38
38
  constructor(options: DenoOptions);
39
39
  private downloadBinary;
40
- private getBinaryVersion;
40
+ getBinaryVersion(binaryPath: string): Promise<string | undefined>;
41
41
  private getCachedBinary;
42
42
  private getGlobalBinary;
43
43
  private getRemoteBinary;
44
44
  private static runWithBinary;
45
45
  private writeVersionFile;
46
46
  ensureCacheDirectory(): Promise<void>;
47
- getBinaryPath(): Promise<{
47
+ getBinaryPath(options?: {
48
+ silent?: boolean;
49
+ }): Promise<{
48
50
  global: boolean;
49
51
  path: string;
50
52
  }>;
@@ -12,7 +12,7 @@ const DENO_VERSION_FILE = 'version.txt';
12
12
  // When updating DENO_VERSION_RANGE, ensure that the deno version
13
13
  // on the netlify/buildbot build image satisfies this range!
14
14
  // https://github.com/netlify/buildbot/blob/f9c03c9dcb091d6570e9d0778381560d469e78ad/build-image/noble/Dockerfile#L410
15
- const DENO_VERSION_RANGE = '1.39.0 - 1.46.3';
15
+ const DENO_VERSION_RANGE = '1.39.0 - 2.2.4';
16
16
  class DenoBridge {
17
17
  constructor(options) {
18
18
  var _a, _b, _c, _d, _e;
@@ -119,15 +119,19 @@ class DenoBridge {
119
119
  async ensureCacheDirectory() {
120
120
  await fs.mkdir(this.cacheDirectory, { recursive: true });
121
121
  }
122
- async getBinaryPath() {
122
+ async getBinaryPath(options) {
123
123
  const globalPath = await this.getGlobalBinary();
124
124
  if (globalPath !== undefined) {
125
- this.logger.system('Using global installation of Deno CLI');
125
+ if (!(options === null || options === void 0 ? void 0 : options.silent)) {
126
+ this.logger.system('Using global installation of Deno CLI');
127
+ }
126
128
  return { global: true, path: globalPath };
127
129
  }
128
130
  const cachedPath = await this.getCachedBinary();
129
131
  if (cachedPath !== undefined) {
130
- this.logger.system('Using cached Deno CLI from', cachedPath);
132
+ if (!(options === null || options === void 0 ? void 0 : options.silent)) {
133
+ this.logger.system('Using cached Deno CLI from', cachedPath);
134
+ }
131
135
  return { global: false, path: cachedPath };
132
136
  }
133
137
  const downloadedPath = await this.getRemoteBinary();
@@ -84,16 +84,11 @@ test('Adds a custom error property to user errors during bundling', async () =>
84
84
  }
85
85
  catch (error) {
86
86
  expect(error).toBeInstanceOf(BundleError);
87
- const [messageBeforeStack] = error.message.split('at <anonymous> (file://');
88
- expect(messageBeforeStack).toMatchInlineSnapshot(`
89
- "error: Uncaught (in promise) Error: The module's source code could not be parsed: Unexpected eof at file:///root/functions/func1.ts:1:27
90
-
91
- export default async () =>
92
- ~
93
- const ret = new Error(getStringFromWasm0(arg0, arg1));
94
- ^
95
- "
96
- `);
87
+ const messageBeforeStack = error.message;
88
+ expect(messageBeforeStack
89
+ .replace(/file:\/\/\/(.*?\/)(build\/packages\/edge-bundler\/deno\/vendor\/deno\.land\/x\/eszip.*)/, 'file://$2')
90
+ // eslint-disable-next-line no-control-regex
91
+ .replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '')).toMatchSnapshot();
97
92
  expect(error.customErrorInfo).toEqual({
98
93
  location: {
99
94
  format: 'eszip',
@@ -407,6 +402,28 @@ test('Loads npm modules from bare specifiers', async () => {
407
402
  await cleanup();
408
403
  await rm(vendorDirectory.path, { force: true, recursive: true });
409
404
  });
405
+ test('Loads npm modules which use package.json.exports', async () => {
406
+ const { basePath, cleanup, distPath } = await useFixture('imports_npm_module_exports');
407
+ const sourceDirectory = join(basePath, 'functions');
408
+ const declarations = [
409
+ {
410
+ function: 'func1',
411
+ path: '/func1',
412
+ },
413
+ ];
414
+ const vendorDirectory = await tmp.dir();
415
+ await bundle([sourceDirectory], distPath, declarations, {
416
+ basePath,
417
+ vendorDirectory: vendorDirectory.path,
418
+ });
419
+ const manifestFile = await readFile(resolve(distPath, 'manifest.json'), 'utf8');
420
+ const manifest = JSON.parse(manifestFile);
421
+ const bundlePath = join(distPath, manifest.bundles[0].asset);
422
+ const { func1 } = await runESZIP(bundlePath, vendorDirectory.path);
423
+ expect(func1).toBe('hello');
424
+ await cleanup();
425
+ await rm(vendorDirectory.path, { force: true, recursive: true });
426
+ });
410
427
  test('Loads npm modules in a monorepo setup', async () => {
411
428
  const systemLogger = vi.fn();
412
429
  const { basePath: rootPath, cleanup, distPath } = await useFixture('monorepo_npm_module');
@@ -1,6 +1,7 @@
1
1
  import { promises as fs } from 'fs';
2
2
  import { join } from 'path';
3
3
  import { pathToFileURL } from 'url';
4
+ import { SemVer } from 'semver';
4
5
  import tmp from 'tmp-promise';
5
6
  import { BundleError } from './bundle_error.js';
6
7
  import { getPackagePath } from './package_json.js';
@@ -39,21 +40,23 @@ export const getFunctionConfig = async ({ func, importMap, deno, log, }) => {
39
40
  // The extractor will use its exit code to signal different error scenarios,
40
41
  // based on the list of exit codes we send as an argument. We then capture
41
42
  // the exit code to know exactly what happened and guide people accordingly.
43
+ const version = new SemVer((await deno.getBinaryVersion((await deno.getBinaryPath({ silent: true })).path)) || '');
42
44
  const { exitCode, stderr, stdout } = await deno.run([
43
45
  'run',
44
46
  '--allow-env',
47
+ version.major >= 2 ? '--allow-import' : '',
45
48
  '--allow-net',
46
49
  '--allow-read',
47
50
  `--allow-write=${collector.path}`,
48
- '--quiet',
49
51
  `--import-map=${importMap.toDataURL()}`,
50
52
  '--no-config',
51
53
  '--node-modules-dir=false',
54
+ '--quiet',
52
55
  extractorPath,
53
56
  pathToFileURL(func.path).href,
54
57
  pathToFileURL(collector.path).href,
55
58
  JSON.stringify(ConfigExitCode),
56
- ], { rejectOnExitCode: false });
59
+ ].filter(Boolean), { rejectOnExitCode: false });
57
60
  if (exitCode !== ConfigExitCode.Success) {
58
61
  handleConfigError(func, exitCode, stderr, log);
59
62
  return {};
@@ -16,7 +16,6 @@ export declare const vendorNPMSpecifiers: ({ basePath, directory, functions, imp
16
16
  baseURL: import("url").URL;
17
17
  imports: Record<string, string>;
18
18
  };
19
- npmSpecifiersWithExtraneousFiles: string[];
20
19
  outputFiles: string[];
21
20
  }>;
22
21
  export {};
@@ -3,13 +3,15 @@ import { builtinModules } from 'module';
3
3
  import path from 'path';
4
4
  import { fileURLToPath, pathToFileURL } from 'url';
5
5
  import { resolve } from '@import-maps/resolve';
6
- import { nodeFileTrace, resolve as nftResolve } from '@vercel/nft';
7
6
  import { build } from 'esbuild';
8
7
  import { findUp } from 'find-up';
9
- import getPackageName from 'get-package-name';
8
+ import { parseImports } from 'parse-imports';
10
9
  import tmp from 'tmp-promise';
11
10
  import { pathsBetween } from './utils/fs.js';
12
11
  const TYPESCRIPT_EXTENSIONS = new Set(['.ts', '.tsx', '.cts', '.ctsx', '.mts', '.mtsx']);
12
+ const slugifyFileName = (specifier) => {
13
+ return specifier.replace(/\//g, '_');
14
+ };
13
15
  const slugifyPackageName = (specifier) => {
14
16
  if (!specifier.startsWith('@'))
15
17
  return specifier;
@@ -55,9 +57,20 @@ const getTypesPath = async (packageJsonPath) => {
55
57
  }
56
58
  return await getTypePathFromTypesPackage(name, packageJsonPath);
57
59
  };
58
- const safelyDetectTypes = async (packageJsonPath) => {
60
+ function packageName(specifier) {
61
+ if (!specifier.startsWith('@'))
62
+ return specifier.split('/')[0];
63
+ const [scope, pkg] = specifier.split('/');
64
+ return `${scope}/${pkg}`;
65
+ }
66
+ const safelyDetectTypes = async (pkg, basePath) => {
59
67
  try {
60
- return await getTypesPath(packageJsonPath);
68
+ const json = await findUp(`node_modules/${packageName(pkg)}/package.json`, {
69
+ cwd: basePath,
70
+ });
71
+ if (json) {
72
+ return await getTypesPath(json);
73
+ }
61
74
  }
62
75
  catch {
63
76
  return undefined;
@@ -81,92 +94,80 @@ const banner = {
81
94
  globalThis.Buffer = __nfyBuffer;
82
95
  `,
83
96
  };
97
+ async function compileTypeScript(file) {
98
+ const compiled = await build({
99
+ bundle: false,
100
+ entryPoints: [file],
101
+ logLevel: 'silent',
102
+ platform: 'node',
103
+ write: false,
104
+ });
105
+ return compiled.outputFiles[0].text;
106
+ }
107
+ async function parseImportsForFile(file, rootPath) {
108
+ const source = TYPESCRIPT_EXTENSIONS.has(path.extname(file))
109
+ ? await compileTypeScript(file)
110
+ : await fs.readFile(file, 'utf-8');
111
+ return await parseImports(source, {
112
+ resolveFrom: rootPath,
113
+ });
114
+ }
84
115
  /**
85
116
  * Parses a set of functions and returns a list of specifiers that correspond
86
117
  * to npm modules.
87
118
  */
88
119
  const getNPMSpecifiers = async ({ basePath, functions, importMap, environment, rootPath }) => {
120
+ var _a;
89
121
  const baseURL = pathToFileURL(basePath);
90
- const { reasons } = await nodeFileTrace(functions, {
91
- base: rootPath,
92
- processCwd: basePath,
93
- readFile: async (filePath) => {
94
- // If this is a TypeScript file, we need to compile in before we can
95
- // parse it.
96
- if (TYPESCRIPT_EXTENSIONS.has(path.extname(filePath))) {
97
- const compiled = await build({
98
- bundle: false,
99
- entryPoints: [filePath],
100
- logLevel: 'silent',
101
- platform: 'node',
102
- write: false,
103
- });
104
- return compiled.outputFiles[0].text;
105
- }
106
- return fs.readFile(filePath, 'utf8');
107
- },
108
- resolve: async (specifier, ...args) => {
109
- // Start by checking whether the specifier matches any import map defined
110
- // by the user.
111
- const { matched, resolvedImport } = resolve(specifier, importMap, baseURL);
112
- // If it does, the resolved import is the specifier we'll evaluate going
113
- // forward.
114
- if (matched && resolvedImport.protocol === 'file:') {
115
- const newSpecifier = fileURLToPath(resolvedImport).replace(/\\/g, '/');
116
- return nftResolve(newSpecifier, ...args);
117
- }
118
- return nftResolve(specifier, ...args);
119
- },
120
- });
121
122
  const npmSpecifiers = [];
122
- const npmSpecifiersWithExtraneousFiles = new Set();
123
- for (const [filePath, reason] of reasons.entries()) {
124
- const parents = [...reason.parents];
125
- const isExtraneousFile = reason.type.every((type) => type === 'asset');
126
- // An extraneous file is a dependency that was traced by NFT and marked
127
- // as not being statically imported. We can't process dynamic importing
128
- // at runtime, so we gather the list of modules that may use these files
129
- // so that we can warn users about this caveat.
130
- if (isExtraneousFile) {
131
- parents.forEach((path) => {
132
- const specifier = getPackageName(path);
133
- if (specifier) {
134
- npmSpecifiersWithExtraneousFiles.add(specifier);
123
+ for (const func of functions) {
124
+ const imports = await parseImportsForFile(func, rootPath);
125
+ for (const i of imports) {
126
+ // The non-null assertion is required because typescript can not infer that `moduleSpecifier.value` can be narrowed to a string.
127
+ // The narrowing is possible because `moduleSpecifier.value` will always be a string when `moduleSpecifier.isConstant` is true.
128
+ const specifier = i.moduleSpecifier.isConstant ? i.moduleSpecifier.value : i.moduleSpecifier.code;
129
+ switch (i.moduleSpecifier.type) {
130
+ case 'absolute': {
131
+ npmSpecifiers.push(...(await getNPMSpecifiers({ basePath, functions: [specifier], importMap, environment, rootPath })));
132
+ break;
135
133
  }
136
- });
137
- }
138
- // every dependency will have its `package.json` in `reasons` exactly once.
139
- // by only looking at this file, we save us from doing duplicate work.
140
- const isPackageJson = filePath.endsWith('package.json');
141
- if (!isPackageJson)
142
- continue;
143
- const packageName = getPackageName(filePath);
144
- if (packageName === undefined)
145
- continue;
146
- const isDirectDependency = parents.some((parentPath) => {
147
- var _a, _b;
148
- if (!parentPath.startsWith(`node_modules${path.sep}`))
149
- return true;
150
- // typically, edge functions have no direct dependency on the `package.json` of a module.
151
- // it's the impl files that depend on `package.json`, so we need to check the parents of
152
- // the `package.json` file as well to see if the module is a direct dependency.
153
- const parents = [...((_b = (_a = reasons.get(parentPath)) === null || _a === void 0 ? void 0 : _a.parents) !== null && _b !== void 0 ? _b : [])];
154
- return parents.some((parentPath) => !parentPath.startsWith(`node_modules${path.sep}`));
155
- });
156
- // We're only interested in capturing the specifiers that are first-level
157
- // dependencies. Because we'll bundle all modules in a subsequent step,
158
- // any transitive dependencies will be handled then.
159
- if (isDirectDependency) {
160
- npmSpecifiers.push({
161
- specifier: packageName,
162
- types: environment === 'development' ? await safelyDetectTypes(path.join(basePath, filePath)) : undefined,
163
- });
134
+ case 'relative': {
135
+ const filePath = path.join(path.dirname(func), specifier);
136
+ npmSpecifiers.push(...(await getNPMSpecifiers({ basePath, functions: [filePath], importMap, environment, rootPath })));
137
+ break;
138
+ }
139
+ case 'package': {
140
+ // node: prefixed imports are detected as packages instead of as builtins
141
+ // we don't want to try and bundle builtins so we ignore node: prefixed imports
142
+ if (specifier.startsWith('node:')) {
143
+ break;
144
+ }
145
+ const { matched, resolvedImport } = resolve(specifier, importMap, baseURL);
146
+ if (matched) {
147
+ if (resolvedImport.protocol === 'file:') {
148
+ const newSpecifier = fileURLToPath(resolvedImport).replace(/\\/g, '/');
149
+ npmSpecifiers.push(...(await getNPMSpecifiers({ basePath, functions: [newSpecifier], importMap, environment, rootPath })));
150
+ }
151
+ }
152
+ else if (!((_a = resolvedImport === null || resolvedImport === void 0 ? void 0 : resolvedImport.protocol) === null || _a === void 0 ? void 0 : _a.startsWith('http'))) {
153
+ const t = await safelyDetectTypes(specifier, basePath);
154
+ npmSpecifiers.push({
155
+ specifier: specifier,
156
+ types: t,
157
+ });
158
+ }
159
+ break;
160
+ }
161
+ case 'builtin':
162
+ case 'invalid':
163
+ case 'unknown': {
164
+ // We don't bundle these types of modules
165
+ break;
166
+ }
167
+ }
164
168
  }
165
169
  }
166
- return {
167
- npmSpecifiers,
168
- npmSpecifiersWithExtraneousFiles: [...npmSpecifiersWithExtraneousFiles],
169
- };
170
+ return npmSpecifiers;
170
171
  };
171
172
  export const vendorNPMSpecifiers = async ({ basePath, directory, functions, importMap, environment, rootPath = basePath, }) => {
172
173
  // The directories that esbuild will use when resolving Node modules. We must
@@ -178,7 +179,7 @@ export const vendorNPMSpecifiers = async ({ basePath, directory, functions, impo
178
179
  // project directory. If a custom directory has been specified, we use it.
179
180
  // Otherwise, create a random temporary directory.
180
181
  const temporaryDirectory = directory ? { path: directory } : await tmp.dir();
181
- const { npmSpecifiers, npmSpecifiersWithExtraneousFiles } = await getNPMSpecifiers({
182
+ const npmSpecifiers = await getNPMSpecifiers({
182
183
  basePath,
183
184
  functions,
184
185
  importMap: importMap.getContentsWithURLObjects(),
@@ -189,8 +190,8 @@ export const vendorNPMSpecifiers = async ({ basePath, directory, functions, impo
189
190
  // where we re-export everything from that specifier. We do this for every
190
191
  // specifier, and each of these files will become entry points to esbuild.
191
192
  const ops = await Promise.all(npmSpecifiers.map(async ({ specifier, types }) => {
192
- const code = `import * as mod from "${specifier}"; export default mod.default; export * from "${specifier}";`;
193
- const filePath = path.join(temporaryDirectory.path, `bundled-${slugifyPackageName(specifier)}.js`);
193
+ const code = `import * as mod from "${specifier}";\nexport default mod.default;\nexport * from "${specifier}";`;
194
+ const filePath = path.join(temporaryDirectory.path, `bundled-${slugifyFileName(specifier)}.js`);
194
195
  await fs.writeFile(filePath, code);
195
196
  return { filePath, specifier, types };
196
197
  }));
@@ -269,7 +270,6 @@ export const vendorNPMSpecifiers = async ({ basePath, directory, functions, impo
269
270
  cleanup,
270
271
  directory: temporaryDirectory.path,
271
272
  importMap: newImportMap,
272
- npmSpecifiersWithExtraneousFiles,
273
273
  outputFiles,
274
274
  };
275
275
  };
@@ -39,7 +39,6 @@ export declare const serve: ({ basePath, bootstrapURL, certificatePath, debug, d
39
39
  features: Record<string, boolean>;
40
40
  functionsConfig: FunctionConfig[];
41
41
  graph: ModuleGraphJson;
42
- npmSpecifiersWithExtraneousFiles: string[];
43
42
  success: boolean;
44
43
  }>>;
45
44
  export {};
@@ -1,5 +1,6 @@
1
1
  import { readdir, unlink } from 'fs/promises';
2
2
  import { join } from 'path';
3
+ import { pathToFileURL } from 'url';
3
4
  import { DenoBridge } from '../bridge.js';
4
5
  import { getFunctionConfig } from '../config.js';
5
6
  import { generateStage2 } from '../formats/javascript.js';
@@ -41,7 +42,6 @@ const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImport
41
42
  const features = {};
42
43
  const importMap = new ImportMap();
43
44
  await importMap.addFiles((_a = options.importMapPaths) !== null && _a !== void 0 ? _a : [], logger);
44
- const npmSpecifiersWithExtraneousFiles = [];
45
45
  // we keep track of the files that are relevant to the user's code, so we can clean up leftovers from past executions later
46
46
  const relevantFiles = [stage2Path];
47
47
  const vendor = await vendorNPMSpecifiers({
@@ -56,7 +56,6 @@ const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImport
56
56
  if (vendor) {
57
57
  features.npmModules = true;
58
58
  importMap.add(vendor.importMap);
59
- npmSpecifiersWithExtraneousFiles.push(...vendor.npmSpecifiersWithExtraneousFiles);
60
59
  relevantFiles.push(...vendor.outputFiles);
61
60
  }
62
61
  await cleanDirectory(distDirectory, relevantFiles);
@@ -65,7 +64,7 @@ const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImport
65
64
  // the `stage2Path` file as well as all of their dependencies.
66
65
  // Consumers such as the CLI can use this information to watch all the
67
66
  // relevant files and issue an isolate restart when one of them changes.
68
- const { stdout } = await deno.run(['info', '--json', stage2Path]);
67
+ const { stdout } = await deno.run(['info', '--json', pathToFileURL(stage2Path).href]);
69
68
  graph = JSON.parse(stdout);
70
69
  }
71
70
  catch {
@@ -95,7 +94,6 @@ const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImport
95
94
  features,
96
95
  functionsConfig,
97
96
  graph,
98
- npmSpecifiersWithExtraneousFiles,
99
97
  success,
100
98
  };
101
99
  };
@@ -42,15 +42,15 @@ test('Starts a server and serves requests for edge functions', async () => {
42
42
  getFunctionsConfig: true,
43
43
  importMapPaths,
44
44
  };
45
- const { features, functionsConfig, graph, success, npmSpecifiersWithExtraneousFiles } = await server(functions, {
45
+ const { features, functionsConfig, graph, success } = await server(functions, {
46
46
  very_secret_secret: 'i love netlify',
47
47
  }, options);
48
48
  expect(features).toEqual({ npmModules: true });
49
49
  expect(success).toBe(true);
50
50
  expect(functionsConfig).toEqual([{ path: '/my-function' }, {}, { path: '/global-netlify' }]);
51
- expect(npmSpecifiersWithExtraneousFiles).toEqual(['dictionary']);
51
+ const modules = graph === null || graph === void 0 ? void 0 : graph.modules.filter(({ kind, mediaType }) => kind === 'esm' && mediaType === 'TypeScript');
52
52
  for (const key in functions) {
53
- const graphEntry = graph === null || graph === void 0 ? void 0 : graph.modules.some(({ kind, mediaType, local }) => kind === 'esm' && mediaType === 'TypeScript' && local === functions[key].path);
53
+ const graphEntry = modules === null || modules === void 0 ? void 0 : modules.some(({ local }) => local === functions[key].path);
54
54
  expect(graphEntry).toBe(true);
55
55
  }
56
56
  const response1 = await fetch(`http://0.0.0.0:${port}/foo`, {
@@ -84,7 +84,7 @@ test('Starts a server and serves requests for edge functions', async () => {
84
84
  });
85
85
  const idBarrelFile = await readFile(join(servePath, 'bundled-id.js'), 'utf-8');
86
86
  expect(idBarrelFile).toContain(`/// <reference types="${join('..', '..', 'node_modules', 'id', 'types.d.ts')}" />`);
87
- const identidadeBarrelFile = await readFile(join(servePath, 'bundled-pt-committee__identidade.js'), 'utf-8');
87
+ const identidadeBarrelFile = await readFile(join(servePath, 'bundled-@pt-committee_identidade.js'), 'utf-8');
88
88
  expect(identidadeBarrelFile).toContain(`/// <reference types="${join('..', '..', 'node_modules', '@types', 'pt-committee__identidade', 'index.d.ts')}" />`);
89
89
  });
90
90
  test('Serves edge functions in a monorepo setup', async () => {
@@ -116,13 +116,12 @@ test('Serves edge functions in a monorepo setup', async () => {
116
116
  getFunctionsConfig: true,
117
117
  importMapPaths,
118
118
  };
119
- const { features, functionsConfig, graph, success, npmSpecifiersWithExtraneousFiles } = await server(functions, {
119
+ const { features, functionsConfig, graph, success } = await server(functions, {
120
120
  very_secret_secret: 'i love netlify',
121
121
  }, options);
122
122
  expect(features).toEqual({ npmModules: true });
123
123
  expect(success).toBe(true);
124
124
  expect(functionsConfig).toEqual([{ path: '/func1' }]);
125
- expect(npmSpecifiersWithExtraneousFiles).toEqual(['child-1']);
126
125
  for (const key in functions) {
127
126
  const graphEntry = graph === null || graph === void 0 ? void 0 : graph.modules.some(({ kind, mediaType, local }) => kind === 'esm' && mediaType === 'TypeScript' && local === functions[key].path);
128
127
  expect(graphEntry).toBe(true);
package/dist/test/util.js CHANGED
@@ -76,7 +76,7 @@ const runESZIP = async (eszipPath, vendorDirectory) => {
76
76
  }
77
77
  await fs.rename(stage2Path, `${stage2Path}.js`);
78
78
  // Run function that imports the extracted stage 2 and invokes each function.
79
- const evalCommand = execa('deno', ['eval', '--no-check', '--import-map', importMapPath, inspectFunction(stage2Path)]);
79
+ const evalCommand = execa('deno', ['eval', '--import-map', importMapPath, inspectFunction(stage2Path)]);
80
80
  (_c = evalCommand.stderr) === null || _c === void 0 ? void 0 : _c.pipe(stderr);
81
81
  const result = await evalCommand;
82
82
  await tmpDir.cleanup();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/edge-bundler",
3
- "version": "12.3.3",
3
+ "version": "13.0.0",
4
4
  "description": "Intelligently prepare Netlify Edge Functions for deployment",
5
5
  "type": "module",
6
6
  "main": "./dist/node/index.js",
@@ -58,7 +58,6 @@
58
58
  },
59
59
  "dependencies": {
60
60
  "@import-maps/resolve": "^1.0.1",
61
- "@vercel/nft": "0.27.7",
62
61
  "ajv": "^8.11.2",
63
62
  "ajv-errors": "^3.0.0",
64
63
  "better-ajv-errors": "^1.2.0",
@@ -74,11 +73,12 @@
74
73
  "node-stream-zip": "^1.15.0",
75
74
  "p-retry": "^5.1.1",
76
75
  "p-wait-for": "^5.0.0",
76
+ "parse-imports": "^2.2.1",
77
77
  "path-key": "^4.0.0",
78
78
  "semver": "^7.3.8",
79
79
  "tmp-promise": "^3.0.3",
80
80
  "urlpattern-polyfill": "8.0.2",
81
81
  "uuid": "^9.0.0"
82
82
  },
83
- "gitHead": "e5ea1c42c57f534be1be05f544b2d7a5dbe57d87"
83
+ "gitHead": "8d10878db3be9cfefe3162fd155c76595aba045e"
84
84
  }