@netlify/edge-bundler 11.4.0 → 12.0.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.
- package/deno/lib/stage2.test.ts +58 -0
- package/dist/node/bridge.js +0 -1
- package/dist/node/bundle_error.js +0 -1
- package/dist/node/declaration.js +1 -0
- package/dist/node/downloader.test.js +0 -1
- package/dist/node/finder.js +0 -1
- package/dist/node/manifest.js +1 -0
- package/dist/node/manifest.test.js +8 -7
- package/dist/node/npm_dependencies.js +0 -1
- package/dist/node/server/util.js +0 -1
- package/dist/node/types.js +1 -0
- package/dist/node/utils/error.js +0 -2
- package/dist/node/validation/manifest/index.js +0 -1
- package/dist/node/validation/manifest/index.test.js +0 -1
- package/package.json +13 -26
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { assertEquals, assertStringIncludes } from 'https://deno.land/std@0.177.0/testing/asserts.ts'
|
|
2
|
+
|
|
3
|
+
import { join } from 'https://deno.land/std@0.177.0/path/mod.ts'
|
|
4
|
+
import { pathToFileURL } from 'https://deno.land/std@0.177.0/node/url.ts'
|
|
5
|
+
|
|
6
|
+
import { getStage2Entry } from './stage2.ts'
|
|
7
|
+
import { virtualRoot } from './consts.ts'
|
|
8
|
+
|
|
9
|
+
Deno.test('`getStage2Entry` returns a valid stage 2 file', async () => {
|
|
10
|
+
const directory = await Deno.makeTempDir()
|
|
11
|
+
const functions = [
|
|
12
|
+
{
|
|
13
|
+
name: 'func1',
|
|
14
|
+
path: join(directory, 'func1.ts'),
|
|
15
|
+
response: 'Hello from function 1',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'func2',
|
|
19
|
+
path: join(directory, 'func2.ts'),
|
|
20
|
+
response: 'Hello from function 2',
|
|
21
|
+
},
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
for (const func of functions) {
|
|
25
|
+
const contents = `export default async () => new Response(${JSON.stringify(func.response)})`
|
|
26
|
+
|
|
27
|
+
await Deno.writeTextFile(func.path, contents)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const baseURL = pathToFileURL(directory)
|
|
31
|
+
const stage2 = getStage2Entry(
|
|
32
|
+
directory,
|
|
33
|
+
functions.map(({ name, path }) => ({ name, path })),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
// Ensuring that the stage 2 paths have the virtual root before we strip it.
|
|
37
|
+
assertStringIncludes(stage2, virtualRoot)
|
|
38
|
+
|
|
39
|
+
// Replacing the virtual root with the URL of the temporary directory so that
|
|
40
|
+
// we can actually import the module.
|
|
41
|
+
const normalizedStage2 = stage2.replaceAll(virtualRoot, `${baseURL.href}/`)
|
|
42
|
+
|
|
43
|
+
const stage2Path = join(directory, 'stage2.ts')
|
|
44
|
+
const stage2URL = pathToFileURL(stage2Path)
|
|
45
|
+
|
|
46
|
+
await Deno.writeTextFile(stage2Path, normalizedStage2)
|
|
47
|
+
|
|
48
|
+
const mod = await import(stage2URL.href)
|
|
49
|
+
|
|
50
|
+
await Deno.remove(directory, { recursive: true })
|
|
51
|
+
|
|
52
|
+
for (const func of functions) {
|
|
53
|
+
const result = await mod.functions[func.name]()
|
|
54
|
+
|
|
55
|
+
assertEquals(await result.text(), func.response)
|
|
56
|
+
assertEquals(mod.metadata.functions[func.name].url, pathToFileURL(func.path).toString())
|
|
57
|
+
}
|
|
58
|
+
})
|
package/dist/node/bridge.js
CHANGED
|
@@ -157,7 +157,6 @@ class DenoBridge {
|
|
|
157
157
|
const options = { env, extendEnv };
|
|
158
158
|
const ps = DenoBridge.runWithBinary(binaryPath, args, { options, pipeOutput, stderr, stdout });
|
|
159
159
|
if (ref !== undefined) {
|
|
160
|
-
// eslint-disable-next-line no-param-reassign
|
|
161
160
|
ref.ps = ps;
|
|
162
161
|
}
|
|
163
162
|
}
|
|
@@ -21,7 +21,6 @@ class BundleError extends Error {
|
|
|
21
21
|
const wrapBundleError = (input, options) => {
|
|
22
22
|
if (input instanceof Error) {
|
|
23
23
|
if (input.message.includes("The module's source code could not be parsed")) {
|
|
24
|
-
// eslint-disable-next-line no-param-reassign
|
|
25
24
|
input.message = input.stderr;
|
|
26
25
|
}
|
|
27
26
|
return new BundleError(input, options);
|
package/dist/node/declaration.js
CHANGED
|
@@ -37,6 +37,7 @@ const getDeclarationsFromInput = (inputDeclarations, functionConfigs, functionsV
|
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
39
|
// With an in-source config without a path, add the config to the declaration.
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
40
41
|
const { path, excludedPath, ...rest } = config;
|
|
41
42
|
declarations.push({ ...declaration, ...rest });
|
|
42
43
|
}
|
package/dist/node/finder.js
CHANGED
|
@@ -23,7 +23,6 @@ const findFunctionInDirectory = async (directory) => {
|
|
|
23
23
|
for (const candidatePath of candidatePaths) {
|
|
24
24
|
try {
|
|
25
25
|
const stats = await fs.stat(candidatePath);
|
|
26
|
-
// eslint-disable-next-line max-depth
|
|
27
26
|
if (stats.isFile()) {
|
|
28
27
|
functionPath = candidatePath;
|
|
29
28
|
break;
|
package/dist/node/manifest.js
CHANGED
|
@@ -65,6 +65,7 @@ const generateManifest = ({ bundles = [], declarations = [], functions, userFunc
|
|
|
65
65
|
traffic_rules: getTrafficRulesConfig(rateLimit),
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
68
69
|
for (const [name, { excludedPath, path, onError, rateLimit, ...rest }] of Object.entries(internalFunctionConfig)) {
|
|
69
70
|
// If the config block is for a function that is not defined, discard it.
|
|
70
71
|
if (manifestFunctionConfig[name] === undefined) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { env } from 'process';
|
|
2
1
|
import { test, expect } from 'vitest';
|
|
2
|
+
// @ts-expect-error current tsconfig.json doesn't allow this, but I don't want to change it
|
|
3
|
+
import { version } from '../package.json' assert { type: 'json' };
|
|
3
4
|
import { getRouteMatcher } from '../test/util.js';
|
|
4
5
|
import { BundleFormat } from './bundle.js';
|
|
5
6
|
import { BundleError } from './bundle_error.js';
|
|
@@ -26,7 +27,7 @@ test('Generates a manifest with different bundles', () => {
|
|
|
26
27
|
const expectedRoutes = [{ function: 'func-1', pattern: '^/f1/?$', excluded_patterns: [], path: '/f1' }];
|
|
27
28
|
expect(manifest.bundles).toEqual(expectedBundles);
|
|
28
29
|
expect(manifest.routes).toEqual(expectedRoutes);
|
|
29
|
-
expect(manifest.bundler_version).toBe(
|
|
30
|
+
expect(manifest.bundler_version).toBe(version);
|
|
30
31
|
});
|
|
31
32
|
test('Generates a manifest with display names', () => {
|
|
32
33
|
const functions = [{ name: 'func-1', path: '/path/to/func-1.ts' }];
|
|
@@ -47,7 +48,7 @@ test('Generates a manifest with display names', () => {
|
|
|
47
48
|
'func-1': { name: 'Display Name' },
|
|
48
49
|
});
|
|
49
50
|
expect(manifest.routes).toEqual(expectedRoutes);
|
|
50
|
-
expect(manifest.bundler_version).toBe(
|
|
51
|
+
expect(manifest.bundler_version).toBe(version);
|
|
51
52
|
});
|
|
52
53
|
test('Generates a manifest with a generator field', () => {
|
|
53
54
|
const functions = [{ name: 'func-1', path: '/path/to/func-1.ts' }];
|
|
@@ -101,7 +102,7 @@ test('Generates a manifest with excluded paths and patterns', () => {
|
|
|
101
102
|
];
|
|
102
103
|
expect(manifest.routes).toEqual(expectedRoutes);
|
|
103
104
|
expect(manifest.function_config).toEqual({});
|
|
104
|
-
expect(manifest.bundler_version).toBe(
|
|
105
|
+
expect(manifest.bundler_version).toBe(version);
|
|
105
106
|
const matcher = getRouteMatcher(manifest);
|
|
106
107
|
expect((_a = matcher('/f1/hello')) === null || _a === void 0 ? void 0 : _a.function).toBe('func-1');
|
|
107
108
|
expect((_b = matcher('/grandparent/parent/child/grandchild.html')) === null || _b === void 0 ? void 0 : _b.function).toBeUndefined();
|
|
@@ -123,7 +124,7 @@ test('TOML-defined paths can be combined with ISC-defined excluded paths', () =>
|
|
|
123
124
|
expect(manifest.function_config).toEqual({
|
|
124
125
|
'func-1': { excluded_patterns: ['^/f1/exclude/?$'] },
|
|
125
126
|
});
|
|
126
|
-
expect(manifest.bundler_version).toBe(
|
|
127
|
+
expect(manifest.bundler_version).toBe(version);
|
|
127
128
|
});
|
|
128
129
|
test('Filters out internal in-source configurations in user created functions', () => {
|
|
129
130
|
const functions = [
|
|
@@ -312,7 +313,7 @@ test('Generates a manifest without bundles', () => {
|
|
|
312
313
|
const expectedRoutes = [{ function: 'func-1', pattern: '^/f1/?$', excluded_patterns: [], path: '/f1' }];
|
|
313
314
|
expect(manifest.bundles).toEqual([]);
|
|
314
315
|
expect(manifest.routes).toEqual(expectedRoutes);
|
|
315
|
-
expect(manifest.bundler_version).toBe(
|
|
316
|
+
expect(manifest.bundler_version).toBe(version);
|
|
316
317
|
});
|
|
317
318
|
test('Generates a manifest with pre and post-cache routes', () => {
|
|
318
319
|
const bundle1 = {
|
|
@@ -350,7 +351,7 @@ test('Generates a manifest with pre and post-cache routes', () => {
|
|
|
350
351
|
expect(manifest.bundles).toEqual(expectedBundles);
|
|
351
352
|
expect(manifest.routes).toEqual(expectedPreCacheRoutes);
|
|
352
353
|
expect(manifest.post_cache_routes).toEqual(expectedPostCacheRoutes);
|
|
353
|
-
expect(manifest.bundler_version).toBe(
|
|
354
|
+
expect(manifest.bundler_version).toBe(version);
|
|
354
355
|
});
|
|
355
356
|
test('Generates a manifest with layers', () => {
|
|
356
357
|
const functions = [
|
|
@@ -105,7 +105,6 @@ const getNPMSpecifiers = async ({ basePath, functions, importMap, environment, r
|
|
|
105
105
|
}
|
|
106
106
|
return fs.readFile(filePath, 'utf8');
|
|
107
107
|
},
|
|
108
|
-
// eslint-disable-next-line require-await
|
|
109
108
|
resolve: async (specifier, ...args) => {
|
|
110
109
|
// Start by checking whether the specifier matches any import map defined
|
|
111
110
|
// by the user.
|
package/dist/node/server/util.js
CHANGED
package/dist/node/types.js
CHANGED
|
@@ -4,6 +4,7 @@ import fetch from 'node-fetch';
|
|
|
4
4
|
const TYPES_URL = 'https://edge.netlify.com';
|
|
5
5
|
const ensureLatestTypes = async (deno, logger, customTypesURL) => {
|
|
6
6
|
const typesURL = customTypesURL !== null && customTypesURL !== void 0 ? customTypesURL : TYPES_URL;
|
|
7
|
+
// eslint-disable-next-line prefer-const
|
|
7
8
|
let [localVersion, remoteVersion] = [await getLocalVersion(deno), ''];
|
|
8
9
|
try {
|
|
9
10
|
remoteVersion = await getRemoteVersion(typesURL);
|
package/dist/node/utils/error.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2
1
|
export const isNodeError = (error) => error instanceof Error;
|
|
3
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
2
|
export const isFileNotFoundError = (error) => isNodeError(error) && error.code === 'ENOENT';
|
|
@@ -5,7 +5,6 @@ import { validateManifest, ManifestValidationError } from './index.js';
|
|
|
5
5
|
// This only works if this is the same instance of chalk that better-ajv-errors uses
|
|
6
6
|
chalk.level = 0;
|
|
7
7
|
// Factory so we have a new object per test
|
|
8
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
8
|
const getBaseManifest = () => ({
|
|
10
9
|
bundles: [
|
|
11
10
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/edge-bundler",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.1",
|
|
4
4
|
"description": "Intelligently prepare Netlify Edge Functions for deployment",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/node/index.js",
|
|
@@ -15,20 +15,10 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "tsc",
|
|
17
17
|
"build:dev": "tsc -w",
|
|
18
|
-
"prepare": "husky install node_modules/@netlify/eslint-config-node/.husky/",
|
|
19
|
-
"prepublishOnly": "npm ci && npm test",
|
|
20
18
|
"prepack": "npm run build",
|
|
21
|
-
"test": "run-s build
|
|
22
|
-
"format": "run-s format:check-fix:*",
|
|
23
|
-
"format:ci": "run-s format:check:*",
|
|
24
|
-
"format:check-fix:lint": "run-e format:check:lint format:fix:lint",
|
|
25
|
-
"format:check:lint": "cross-env-shell eslint $npm_package_config_eslint",
|
|
26
|
-
"format:fix:lint": "cross-env-shell eslint --fix $npm_package_config_eslint",
|
|
27
|
-
"format:check-fix:prettier": "run-e format:check:prettier format:fix:prettier",
|
|
28
|
-
"format:check:prettier": "cross-env-shell prettier --check $npm_package_config_prettier",
|
|
29
|
-
"format:fix:prettier": "cross-env-shell prettier --write $npm_package_config_prettier",
|
|
19
|
+
"test": "run-s build test:dev",
|
|
30
20
|
"test:dev": "run-s test:dev:*",
|
|
31
|
-
"test:ci": "run-s test:ci:*",
|
|
21
|
+
"test:ci": "run-s test:integration test:ci:*",
|
|
32
22
|
"test:dev:vitest": "vitest run",
|
|
33
23
|
"test:dev:vitest:watch": "vitest watch",
|
|
34
24
|
"test:dev:deno": "deno test --allow-all deno",
|
|
@@ -37,24 +27,21 @@
|
|
|
37
27
|
"test:integration": "node --experimental-modules test/integration/test.js",
|
|
38
28
|
"vendor": "deno vendor --force --output deno/vendor https://deno.land/x/eszip@v0.55.2/mod.ts https://deno.land/x/retry@v2.0.0/mod.ts https://deno.land/x/std@0.177.0/path/mod.ts"
|
|
39
29
|
},
|
|
40
|
-
"config": {
|
|
41
|
-
"eslint": "--ignore-path .gitignore --cache --format=codeframe --max-warnings=0 \"{node,scripts,.github}/**/*.{js,ts,md,html}\" \"*.{js,ts,md,html}\"",
|
|
42
|
-
"prettier": "--ignore-path .gitignore --loglevel=warn \"{node,scripts,.github}/**/*.{js,ts,md,yml,json,html}\" \"*.{js,ts,yml,json,html}\" \".*.{js,ts,yml,json,html}\" \"!**/package-lock.json\" \"!package-lock.json\" \"!node/vendor/**\""
|
|
43
|
-
},
|
|
44
30
|
"keywords": [],
|
|
45
31
|
"license": "MIT",
|
|
46
|
-
"repository":
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/netlify/build.git",
|
|
35
|
+
"directory": "packages/edge-bundler"
|
|
36
|
+
},
|
|
47
37
|
"bugs": {
|
|
48
|
-
"url": "https://github.com/netlify/
|
|
38
|
+
"url": "https://github.com/netlify/build/issues"
|
|
49
39
|
},
|
|
50
40
|
"author": "Netlify Inc.",
|
|
51
41
|
"directories": {
|
|
52
42
|
"test": "test/node"
|
|
53
43
|
},
|
|
54
44
|
"devDependencies": {
|
|
55
|
-
"@commitlint/cli": "^17.0.0",
|
|
56
|
-
"@commitlint/config-conventional": "^17.0.0",
|
|
57
|
-
"@netlify/eslint-config-node": "^7.0.1",
|
|
58
45
|
"@types/glob-to-regexp": "^0.4.1",
|
|
59
46
|
"@types/node": "^14.18.32",
|
|
60
47
|
"@types/semver": "^7.3.9",
|
|
@@ -64,7 +51,6 @@
|
|
|
64
51
|
"chalk": "^4.1.2",
|
|
65
52
|
"cpy": "^9.0.1",
|
|
66
53
|
"cross-env": "^7.0.3",
|
|
67
|
-
"husky": "^8.0.0",
|
|
68
54
|
"nock": "^13.2.4",
|
|
69
55
|
"tar": "^6.1.11",
|
|
70
56
|
"typescript": "^5.0.0",
|
|
@@ -75,13 +61,13 @@
|
|
|
75
61
|
},
|
|
76
62
|
"dependencies": {
|
|
77
63
|
"@import-maps/resolve": "^1.0.1",
|
|
78
|
-
"@vercel/nft": "^0.
|
|
64
|
+
"@vercel/nft": "^0.27.0",
|
|
79
65
|
"ajv": "^8.11.2",
|
|
80
66
|
"ajv-errors": "^3.0.0",
|
|
81
67
|
"better-ajv-errors": "^1.2.0",
|
|
82
68
|
"common-path-prefix": "^3.0.0",
|
|
83
69
|
"env-paths": "^3.0.0",
|
|
84
|
-
"esbuild": "0.
|
|
70
|
+
"esbuild": "0.21.2",
|
|
85
71
|
"execa": "^6.0.0",
|
|
86
72
|
"find-up": "^6.3.0",
|
|
87
73
|
"get-package-name": "^2.2.0",
|
|
@@ -97,5 +83,6 @@
|
|
|
97
83
|
"tmp-promise": "^3.0.3",
|
|
98
84
|
"urlpattern-polyfill": "8.0.2",
|
|
99
85
|
"uuid": "^9.0.0"
|
|
100
|
-
}
|
|
86
|
+
},
|
|
87
|
+
"gitHead": "95038d0359de8abef07cb3caadd8cea0c3fb539e"
|
|
101
88
|
}
|