New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@netlify/edge-bundler

Package Overview
Dependencies
Maintainers
18
Versions
137
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@netlify/edge-bundler - npm Package Compare versions

Comparing version 9.4.1 to 9.5.0

deno/vendor/deno.land/x/dir@1.5.1/data_local_dir/mod.ts

4

deno/lib/common.ts

@@ -1,3 +0,3 @@

import { load } from "https://deno.land/x/eszip@v0.40.0/loader.ts";
import { LoadResponse } from "https://deno.land/x/eszip@v0.40.0/mod.ts";
import { load } from "https://deno.land/x/eszip@v0.55.2/loader.ts";
import { LoadResponse } from "https://deno.land/x/eszip@v0.55.2/mod.ts";
import * as path from "https://deno.land/std@0.177.0/path/mod.ts";

@@ -4,0 +4,0 @@ import { retryAsync } from "https://deno.land/x/retry@v2.0.0/mod.ts";

@@ -1,2 +0,2 @@

import { build, LoadResponse } from 'https://deno.land/x/eszip@v0.40.0/mod.ts'
import { build, LoadResponse } from 'https://deno.land/x/eszip@v0.55.2/mod.ts'

@@ -3,0 +3,0 @@ import * as path from 'https://deno.land/std@0.177.0/path/mod.ts'

/// <reference types="node" />
import { ExecaChildProcess } from 'execa';
import { Logger } from './logger.js';
declare const DENO_VERSION_RANGE = "^1.32.5";
declare const DENO_VERSION_RANGE = "^1.37.0";
type OnBeforeDownloadHook = () => void | Promise<void>;

@@ -6,0 +6,0 @@ type OnAfterDownloadHook = (error?: Error) => void | Promise<void>;

@@ -14,3 +14,3 @@ import { promises as fs } from 'fs';

// build-image/buildbot does satisfy this range!
const DENO_VERSION_RANGE = '^1.32.5';
const DENO_VERSION_RANGE = '^1.37.0';
class DenoBridge {

@@ -17,0 +17,0 @@ constructor(options) {

@@ -150,6 +150,3 @@ import { promises as fs } from 'fs';

}, {});
const safelyVendorNPMSpecifiers = async ({ basePath, featureFlags, functions, importMap, logger, vendorDirectory, }) => {
if (!featureFlags.edge_functions_npm_modules) {
return;
}
const safelyVendorNPMSpecifiers = async ({ basePath, functions, importMap, logger, vendorDirectory, }) => {
try {

@@ -156,0 +153,0 @@ return await vendorNPMSpecifiers({

@@ -108,28 +108,4 @@ import { access, readdir, readFile, rm, writeFile } from 'fs/promises';

});
test('Prints a nice error message when user tries importing an npm module and npm support is disabled', async () => {
test('Prints a nice error message when user tries importing an npm module', async () => {
expect.assertions(2);
const { basePath, cleanup, distPath } = await useFixture('imports_npm_module');
const sourceDirectory = join(basePath, 'functions');
const declarations = [
{
function: 'func1',
path: '/func1',
},
];
try {
await bundle([sourceDirectory], distPath, declarations, {
basePath,
importMapPaths: [join(basePath, 'import_map.json')],
});
}
catch (error) {
expect(error).toBeInstanceOf(BundleError);
expect(error.message).toEqual(`It seems like you're trying to import an npm module. This is only supported via CDNs like esm.sh. Have you tried 'import mod from "https://esm.sh/parent-1"'?`);
}
finally {
await cleanup();
}
});
test('Prints a nice error message when user tries importing an npm module and npm support is enabled', async () => {
expect.assertions(2);
const { basePath, cleanup, distPath } = await useFixture('imports_npm_module_scheme');

@@ -146,3 +122,2 @@ const sourceDirectory = join(basePath, 'functions');

basePath,
featureFlags: { edge_functions_npm_modules: true },
});

@@ -158,23 +133,2 @@ }

});
test('Prints a nice error message when user tries importing NPM module with npm: scheme', async () => {
expect.assertions(2);
const { basePath, cleanup, distPath } = await useFixture('imports_npm_module_scheme');
const sourceDirectory = join(basePath, 'functions');
const declarations = [
{
function: 'func1',
path: '/func1',
},
];
try {
await bundle([sourceDirectory], distPath, declarations, { basePath });
}
catch (error) {
expect(error).toBeInstanceOf(BundleError);
expect(error.message).toEqual(`It seems like you're trying to import an npm module. This is only supported via CDNs like esm.sh. Have you tried 'import mod from "https://esm.sh/p-retry"'?`);
}
finally {
await cleanup();
}
});
test('Does not add a custom error property to system errors during bundling', async () => {

@@ -419,3 +373,2 @@ expect.assertions(1);

basePath,
featureFlags: { edge_functions_npm_modules: true },
importMapPaths: [join(basePath, 'import_map.json')],

@@ -434,1 +387,23 @@ vendorDirectory: vendorDirectory.path,

});
test('Loads JSON modules', async () => {
const { basePath, cleanup, distPath } = await useFixture('imports_json');
const sourceDirectory = join(basePath, 'functions');
const declarations = [
{
function: 'func1',
path: '/func1',
},
];
const vendorDirectory = await tmp.dir();
await bundle([sourceDirectory], distPath, declarations, {
basePath,
vendorDirectory: vendorDirectory.path,
});
const manifestFile = await readFile(resolve(distPath, 'manifest.json'), 'utf8');
const manifest = JSON.parse(manifestFile);
const bundlePath = join(distPath, manifest.bundles[0].asset);
const { func1 } = await runESZIP(bundlePath, vendorDirectory.path);
expect(func1).toBe(`{"foo":"bar"}`);
await cleanup();
await rm(vendorDirectory.path, { force: true, recursive: true });
});

@@ -1,12 +0,6 @@

declare const defaultFlags: {
edge_functions_fail_unsupported_regex: boolean;
edge_functions_npm_modules: boolean;
};
declare const defaultFlags: {};
type FeatureFlag = keyof typeof defaultFlags;
type FeatureFlags = Partial<Record<FeatureFlag, boolean>>;
declare const getFlags: (input?: Record<string, boolean>, flags?: {
edge_functions_fail_unsupported_regex: boolean;
edge_functions_npm_modules: boolean;
}) => FeatureFlags;
declare const getFlags: (input?: Record<string, boolean>, flags?: {}) => FeatureFlags;
export { defaultFlags, getFlags };
export type { FeatureFlag, FeatureFlags };

@@ -1,5 +0,2 @@

const defaultFlags = {
edge_functions_fail_unsupported_regex: false,
edge_functions_npm_modules: false,
};
const defaultFlags = {};
const getFlags = (input = {}, flags = defaultFlags) => Object.entries(flags).reduce((result, [key, defaultValue]) => ({

@@ -6,0 +3,0 @@ ...result,

@@ -18,3 +18,3 @@ import { DenoBridge } from '../bridge.js';

}
declare const bundleESZIP: ({ basePath, buildID, debug, deno, distDirectory, externals, featureFlags, functions, importMap, vendorDirectory, }: BundleESZIPOptions) => Promise<Bundle>;
declare const bundleESZIP: ({ basePath, buildID, debug, deno, distDirectory, externals, functions, importMap, vendorDirectory, }: BundleESZIPOptions) => Promise<Bundle>;
export { bundleESZIP as bundle };

@@ -9,3 +9,3 @@ import { join } from 'path';

import { getFileHash } from '../utils/sha256.js';
const bundleESZIP = async ({ basePath, buildID, debug, deno, distDirectory, externals, featureFlags, functions, importMap, vendorDirectory, }) => {
const bundleESZIP = async ({ basePath, buildID, debug, deno, distDirectory, externals, functions, importMap, vendorDirectory, }) => {
const extension = '.eszip';

@@ -37,3 +37,3 @@ const destPath = join(distDirectory, `${buildID}${extension}`);

catch (error) {
throw wrapBundleError(wrapNpmImportError(error, Boolean(featureFlags.edge_functions_npm_modules)), {
throw wrapBundleError(wrapNpmImportError(error), {
format: 'eszip',

@@ -40,0 +40,0 @@ });

@@ -1,2 +0,2 @@

import { mkdir, rm, writeFile } from 'fs/promises';
import { mkdir, writeFile } from 'fs/promises';
import { join } from 'path';

@@ -7,3 +7,2 @@ import { pathToFileURL } from 'url';

const generateStage2 = async ({ bootstrapURL, distDirectory, fileName, formatExportTypeError, formatImportError, functions, }) => {
await rm(distDirectory, { force: true, recursive: true, maxRetries: 3 });
await mkdir(distDirectory, { recursive: true });

@@ -10,0 +9,0 @@ const entryPoint = getLocalEntryPoint(functions, { bootstrapURL, formatExportTypeError, formatImportError });

@@ -45,3 +45,3 @@ import type { Bundle } from './bundle.js';

}
declare const generateManifest: ({ bundles, declarations, featureFlags, functions, userFunctionConfig, internalFunctionConfig, importMap, layers, }: GenerateManifestOptions) => Manifest;
declare const generateManifest: ({ bundles, declarations, functions, userFunctionConfig, internalFunctionConfig, importMap, layers, }: GenerateManifestOptions) => Manifest;
interface WriteManifestOptions extends GenerateManifestOptions {

@@ -48,0 +48,0 @@ distDirectory: string;

@@ -49,3 +49,3 @@ import { promises as fs } from 'fs';

};
const generateManifest = ({ bundles = [], declarations = [], featureFlags, functions, userFunctionConfig = {}, internalFunctionConfig = {}, importMap, layers = [], }) => {
const generateManifest = ({ bundles = [], declarations = [], functions, userFunctionConfig = {}, internalFunctionConfig = {}, importMap, layers = [], }) => {
const preCacheRoutes = [];

@@ -75,4 +75,4 @@ const postCacheRoutes = [];

}
const pattern = getRegularExpression(declaration, featureFlags);
const excludedPattern = getExcludedRegularExpressions(declaration, featureFlags);
const pattern = getRegularExpression(declaration);
const excludedPattern = getExcludedRegularExpressions(declaration);
const route = {

@@ -127,3 +127,3 @@ function: func.name,

};
const getRegularExpression = (declaration, featureFlags) => {
const getRegularExpression = (declaration) => {
if ('pattern' in declaration) {

@@ -134,8 +134,3 @@ try {

catch (error) {
// eslint-disable-next-line max-depth
if (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.edge_functions_fail_unsupported_regex) {
throw new Error(`Could not parse path declaration of function '${declaration.function}': ${error.message}`);
}
console.warn(`Function '${declaration.function}' uses an unsupported regular expression and will not be invoked: ${error.message}`);
return declaration.pattern;
throw wrapBundleError(new Error(`Could not parse path declaration of function '${declaration.function}': ${error.message}`));
}

@@ -145,3 +140,3 @@ }

};
const getExcludedRegularExpressions = (declaration, featureFlags) => {
const getExcludedRegularExpressions = (declaration) => {
if ('excludedPattern' in declaration && declaration.excludedPattern) {

@@ -156,7 +151,3 @@ const excludedPatterns = Array.isArray(declaration.excludedPattern)

catch (error) {
if (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.edge_functions_fail_unsupported_regex) {
throw new Error(`Could not parse path declaration of function '${declaration.function}': ${error.message}`);
}
console.warn(`Function '${declaration.function}' uses an unsupported regular expression and will therefore not be invoked: ${error.message}`);
return excludedPattern;
throw wrapBundleError(new Error(`Could not parse path declaration of function '${declaration.function}': ${error.message}`));
}

@@ -163,0 +154,0 @@ });

import { env } from 'process';
import { test, expect, vi } from 'vitest';
import { test, expect } from 'vitest';
import { getRouteMatcher } from '../test/util.js';

@@ -389,25 +389,8 @@ import { BundleFormat } from './bundle.js';

});
test('Shows a warning if the regular expression contains a negative lookahead', () => {
const mockConsoleWarn = vi.fn();
const consoleWarn = console.warn;
console.warn = mockConsoleWarn;
test('Throws an error if the regular expression contains a negative lookahead', () => {
const functions = [{ name: 'func-1', path: '/path/to/func-1.ts' }];
const declarations = [{ function: 'func-1', pattern: '^/\\w+(?=\\d)$' }];
const manifest = generateManifest({
bundles: [],
declarations,
functions,
});
console.warn = consoleWarn;
expect(manifest.routes).toEqual([{ function: 'func-1', pattern: '^/\\w+(?=\\d)$', excluded_patterns: [] }]);
expect(mockConsoleWarn).toHaveBeenCalledOnce();
expect(mockConsoleWarn).toHaveBeenCalledWith("Function 'func-1' uses an unsupported regular expression and will not be invoked: Regular expressions with lookaheads are not supported");
});
test('Throws an error if the regular expression contains a negative lookahead and the `edge_functions_fail_unsupported_regex` flag is set', () => {
const functions = [{ name: 'func-1', path: '/path/to/func-1.ts' }];
const declarations = [{ function: 'func-1', pattern: '^/\\w+(?=\\d)$' }];
expect(() => generateManifest({
bundles: [],
declarations,
featureFlags: { edge_functions_fail_unsupported_regex: true },
functions,

@@ -414,0 +397,0 @@ })).toThrowError(/^Could not parse path declaration of function 'func-1': Regular expressions with lookaheads are not supported$/);

@@ -20,3 +20,4 @@ /// <reference types="node" />

npmSpecifiersWithExtraneousFiles: string[];
outputFiles: string[];
} | undefined>;
export {};

@@ -202,2 +202,3 @@ import { promises as fs } from 'fs';

format: 'esm',
mainFields: ['module', 'browser', 'main'],
logLevel: 'error',

@@ -259,3 +260,4 @@ nodePaths,

npmSpecifiersWithExtraneousFiles,
outputFiles: outputFiles.map((file) => file.path),
};
};
declare class NPMImportError extends Error {
constructor(originalError: Error, moduleName: string, supportsNPM: boolean);
constructor(originalError: Error, moduleName: string);
}
declare const wrapNpmImportError: (input: unknown, supportsNPM: boolean) => unknown;
declare const wrapNpmImportError: (input: unknown) => unknown;
export { NPMImportError, wrapNpmImportError };
class NPMImportError extends Error {
constructor(originalError, moduleName, supportsNPM) {
let message = `It seems like you're trying to import an npm module. This is only supported via CDNs like esm.sh. Have you tried 'import mod from "https://esm.sh/${moduleName}"'?`;
if (supportsNPM) {
message = `There was an error when loading the '${moduleName}' npm module. Support for npm modules in edge functions is an experimental feature. Refer to https://ntl.fyi/edge-functions-npm for more information.`;
}
super(message);
constructor(originalError, moduleName) {
super(`There was an error when loading the '${moduleName}' npm module. Support for npm modules in edge functions is an experimental feature. Refer to https://ntl.fyi/edge-functions-npm for more information.`);
this.name = 'NPMImportError';

@@ -14,3 +10,3 @@ this.stack = originalError.stack;

}
const wrapNpmImportError = (input, supportsNPM) => {
const wrapNpmImportError = (input) => {
if (input instanceof Error) {

@@ -20,3 +16,3 @@ const match = input.message.match(/Relative import path "(.*)" not prefixed with/);

const [, moduleName] = match;
return new NPMImportError(input, moduleName, supportsNPM);
return new NPMImportError(input, moduleName);
}

@@ -26,3 +22,3 @@ const schemeMatch = input.message.match(/Error: Module not found "npm:(.*)"/);

const [, moduleName] = schemeMatch;
return new NPMImportError(input, moduleName, supportsNPM);
return new NPMImportError(input, moduleName);
}

@@ -29,0 +25,0 @@ }

@@ -0,1 +1,3 @@

import { readdir, unlink } from 'fs/promises';
import { join } from 'path';
import { DenoBridge } from '../bridge.js';

@@ -9,3 +11,13 @@ import { getFunctionConfig } from '../config.js';

import { killProcess, waitForServer } from './util.js';
const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImportMapPath, featureFlags, flags: denoFlags, formatExportTypeError, formatImportError, importMap: baseImportMap, logger, port, }) => {
/**
* Cleans up a directory, except for the files specified in the `except` array.
* Both should be given as absolute paths.
* Assumes the directory doesn't contain any nested directories.
*/
const cleanDirectory = async (directory, except) => {
const files = await readdir(directory);
const toBeDeleted = files.filter((file) => !except.includes(join(directory, file)));
await Promise.all(toBeDeleted.map((file) => unlink(join(directory, file))));
};
const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImportMapPath, flags: denoFlags, formatExportTypeError, formatImportError, importMap: baseImportMap, logger, port, }) => {
const processRef = {};

@@ -28,17 +40,19 @@ const startServer = async (functions, env = {}, options = {}) => {

const npmSpecifiersWithExtraneousFiles = [];
if (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.edge_functions_npm_modules) {
const vendor = await vendorNPMSpecifiers({
basePath,
directory: distDirectory,
functions: functions.map(({ path }) => path),
importMap,
logger,
referenceTypes: true,
});
if (vendor) {
features.npmModules = true;
importMap.add(vendor.importMap);
npmSpecifiersWithExtraneousFiles.push(...vendor.npmSpecifiersWithExtraneousFiles);
}
// we keep track of the files that are relevant to the user's code, so we can clean up leftovers from past executions later
const relevantFiles = [stage2Path];
const vendor = await vendorNPMSpecifiers({
basePath,
directory: distDirectory,
functions: functions.map(({ path }) => path),
importMap,
logger,
referenceTypes: true,
});
if (vendor) {
features.npmModules = true;
importMap.add(vendor.importMap);
npmSpecifiersWithExtraneousFiles.push(...vendor.npmSpecifiersWithExtraneousFiles);
relevantFiles.push(...vendor.outputFiles);
}
await cleanDirectory(distDirectory, relevantFiles);
try {

@@ -45,0 +59,0 @@ // This command will print a JSON object with all the modules found in

@@ -24,5 +24,2 @@ import { readFile } from 'fs/promises';

servePath,
featureFlags: {
edge_functions_npm_modules: true,
},
});

@@ -29,0 +26,0 @@ const functions = [

@@ -58,3 +58,3 @@ import { promises as fs } from 'fs';

'--allow-all',
'https://deno.land/x/eszip@v0.40.0/eszip.ts',
'https://deno.land/x/eszip@v0.55.2/eszip.ts',
'x',

@@ -61,0 +61,0 @@ eszipPath,

{
"name": "@netlify/edge-bundler",
"version": "9.4.1",
"version": "9.5.0",
"description": "Intelligently prepare Netlify Edge Functions for deployment",

@@ -5,0 +5,0 @@ "type": "module",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc