@netlify/edge-bundler 2.2.0 → 2.3.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.
- package/deno/config.ts +38 -0
- package/deno/lib/stage2.test.ts +58 -0
- package/dist/node/bootstrap.test.d.ts +1 -0
- package/dist/node/bootstrap.test.js +26 -0
- package/dist/node/bridge.d.ts +2 -1
- package/dist/node/bridge.js +2 -2
- package/dist/node/bridge.test.d.ts +1 -0
- package/dist/node/bridge.test.js +112 -0
- package/dist/node/bundler.d.ts +2 -2
- package/dist/node/bundler.js +29 -20
- package/dist/node/bundler.test.d.ts +1 -0
- package/dist/node/bundler.test.js +246 -0
- package/dist/node/config.d.ts +7 -0
- package/dist/node/config.js +87 -0
- package/dist/node/config.test.d.ts +1 -0
- package/dist/node/config.test.js +174 -0
- package/dist/node/declaration.d.ts +2 -0
- package/dist/node/declaration.js +27 -1
- package/dist/node/downloader.test.d.ts +1 -0
- package/dist/node/downloader.test.js +115 -0
- package/dist/node/feature_flags.js +1 -0
- package/dist/node/import_map.test.d.ts +1 -0
- package/dist/node/import_map.test.js +33 -0
- package/dist/node/logger.test.d.ts +1 -0
- package/dist/node/logger.test.js +45 -0
- package/dist/node/main.test.d.ts +1 -0
- package/dist/node/main.test.js +48 -0
- package/dist/node/manifest.test.d.ts +1 -0
- package/dist/node/manifest.test.js +65 -0
- package/dist/node/package_json.test.d.ts +1 -0
- package/dist/node/package_json.test.js +7 -0
- package/dist/node/serving.test.d.ts +1 -0
- package/dist/node/serving.test.js +31 -0
- package/dist/node/stage_2.test.d.ts +1 -0
- package/dist/node/stage_2.test.js +48 -0
- package/dist/node/types.test.d.ts +1 -0
- package/dist/node/types.test.js +61 -0
- package/dist/test/util.d.ts +3 -0
- package/dist/test/util.js +9 -0
- package/package.json +17 -28
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import getPort from 'get-port';
|
|
3
|
+
import fetch from 'node-fetch';
|
|
4
|
+
import { test, expect } from 'vitest';
|
|
5
|
+
import { fixturesDir } from '../test/util.js';
|
|
6
|
+
import { serve } from './index.js';
|
|
7
|
+
test('bundler serving functionality', async () => {
|
|
8
|
+
const port = await getPort();
|
|
9
|
+
const server = await serve({
|
|
10
|
+
port,
|
|
11
|
+
});
|
|
12
|
+
const { success } = await server([
|
|
13
|
+
{
|
|
14
|
+
name: 'echo_env',
|
|
15
|
+
path: join(fixturesDir, 'serve_test', 'echo_env.ts'),
|
|
16
|
+
},
|
|
17
|
+
], {
|
|
18
|
+
very_secret_secret: 'i love netlify',
|
|
19
|
+
});
|
|
20
|
+
expect(success).toBe(true);
|
|
21
|
+
const response = await fetch(`http://0.0.0.0:${port}/foo`, {
|
|
22
|
+
headers: {
|
|
23
|
+
'x-deno-functions': 'echo_env',
|
|
24
|
+
'x-deno-pass': 'passthrough',
|
|
25
|
+
'X-NF-Request-ID': 'foo',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
expect(response.status).toBe(200);
|
|
29
|
+
const body = (await response.json());
|
|
30
|
+
expect(body.very_secret_secret).toBe('i love netlify');
|
|
31
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import process from 'process';
|
|
4
|
+
import { pathToFileURL } from 'url';
|
|
5
|
+
import del from 'del';
|
|
6
|
+
import { execa } from 'execa';
|
|
7
|
+
import tmp from 'tmp-promise';
|
|
8
|
+
import { test, expect } from 'vitest';
|
|
9
|
+
import { getLocalEntryPoint } from './formats/javascript.js';
|
|
10
|
+
test('`getLocalEntryPoint` returns a valid stage 2 file for local development', async () => {
|
|
11
|
+
const { path: tmpDir } = await tmp.dir();
|
|
12
|
+
// This is a fake bootstrap that we'll create just for the purpose of logging
|
|
13
|
+
// the functions and the metadata that are sent to the `boot` function.
|
|
14
|
+
const printer = `
|
|
15
|
+
export const boot = async (functions, metadata) => {
|
|
16
|
+
const responses = {}
|
|
17
|
+
|
|
18
|
+
for (const name in functions) {
|
|
19
|
+
responses[name] = await functions[name]()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.log(JSON.stringify({ responses, metadata }))
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
const printerPath = join(tmpDir, 'printer.mjs');
|
|
26
|
+
await fs.writeFile(printerPath, printer);
|
|
27
|
+
process.env.NETLIFY_EDGE_BOOTSTRAP = pathToFileURL(printerPath).toString();
|
|
28
|
+
const functions = [
|
|
29
|
+
{ name: 'func1', path: join(tmpDir, 'func1.mjs'), response: 'Hello from function 1' },
|
|
30
|
+
{ name: 'func2', path: join(tmpDir, 'func2.mjs'), response: 'Hello from function 2' },
|
|
31
|
+
];
|
|
32
|
+
for (const func of functions) {
|
|
33
|
+
const contents = `export default () => ${JSON.stringify(func.response)}`;
|
|
34
|
+
await fs.writeFile(func.path, contents);
|
|
35
|
+
}
|
|
36
|
+
const stage2 = getLocalEntryPoint(functions.map(({ name, path }) => ({ name, path })), {});
|
|
37
|
+
const stage2Path = join(tmpDir, 'stage2.mjs');
|
|
38
|
+
await fs.writeFile(stage2Path, stage2);
|
|
39
|
+
const { stdout, stderr } = await execa('deno', ['run', '--allow-all', stage2Path]);
|
|
40
|
+
expect(stderr).toBe('');
|
|
41
|
+
const { metadata, responses } = JSON.parse(stdout);
|
|
42
|
+
for (const func of functions) {
|
|
43
|
+
expect(responses[func.name]).toBe(func.response);
|
|
44
|
+
expect(metadata.functions[func.name].url).toBe(pathToFileURL(func.path).toString());
|
|
45
|
+
}
|
|
46
|
+
await del(tmpDir, { force: true });
|
|
47
|
+
delete process.env.NETLIFY_EDGE_BOOTSTRAP;
|
|
48
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import nock from 'nock';
|
|
4
|
+
import { stub } from 'sinon';
|
|
5
|
+
import tmp from 'tmp-promise';
|
|
6
|
+
import { test, expect } from 'vitest';
|
|
7
|
+
import { testLogger } from '../test/util.js';
|
|
8
|
+
import { DenoBridge } from './bridge.js';
|
|
9
|
+
import { ensureLatestTypes } from './types.js';
|
|
10
|
+
test('`ensureLatestTypes` updates the Deno CLI cache if the local version of types is outdated', async () => {
|
|
11
|
+
const mockURL = 'https://edge.netlify';
|
|
12
|
+
const mockVersion = '123456789';
|
|
13
|
+
const latestVersionMock = nock(mockURL).get('/version.txt').reply(200, mockVersion);
|
|
14
|
+
const tmpDir = await tmp.dir();
|
|
15
|
+
const deno = new DenoBridge({
|
|
16
|
+
cacheDirectory: tmpDir.path,
|
|
17
|
+
logger: testLogger,
|
|
18
|
+
});
|
|
19
|
+
const mock = stub(deno, 'run').resolves();
|
|
20
|
+
await ensureLatestTypes(deno, testLogger, mockURL);
|
|
21
|
+
const versionFile = await fs.readFile(join(tmpDir.path, 'types-version.txt'), 'utf8');
|
|
22
|
+
expect(latestVersionMock.isDone()).toBe(true);
|
|
23
|
+
expect(mock.callCount).toBe(1);
|
|
24
|
+
expect(mock.firstCall.firstArg).toEqual(['cache', '-r', mockURL]);
|
|
25
|
+
expect(versionFile).toBe(mockVersion);
|
|
26
|
+
mock.restore();
|
|
27
|
+
await fs.rmdir(tmpDir.path, { recursive: true });
|
|
28
|
+
});
|
|
29
|
+
test('`ensureLatestTypes` does not update the Deno CLI cache if the local version of types is up-to-date', async () => {
|
|
30
|
+
const mockURL = 'https://edge.netlify';
|
|
31
|
+
const mockVersion = '987654321';
|
|
32
|
+
const tmpDir = await tmp.dir();
|
|
33
|
+
const versionFilePath = join(tmpDir.path, 'types-version.txt');
|
|
34
|
+
await fs.writeFile(versionFilePath, mockVersion);
|
|
35
|
+
const latestVersionMock = nock(mockURL).get('/version.txt').reply(200, mockVersion);
|
|
36
|
+
const deno = new DenoBridge({
|
|
37
|
+
cacheDirectory: tmpDir.path,
|
|
38
|
+
logger: testLogger,
|
|
39
|
+
});
|
|
40
|
+
const mock = stub(deno, 'run').resolves();
|
|
41
|
+
await ensureLatestTypes(deno, testLogger, mockURL);
|
|
42
|
+
expect(latestVersionMock.isDone()).toBe(true);
|
|
43
|
+
expect(mock.callCount).toBe(0);
|
|
44
|
+
mock.restore();
|
|
45
|
+
await fs.rmdir(tmpDir.path, { recursive: true });
|
|
46
|
+
});
|
|
47
|
+
test('`ensureLatestTypes` does not throw if the types URL is not available', async () => {
|
|
48
|
+
const mockURL = 'https://edge.netlify';
|
|
49
|
+
const latestVersionMock = nock(mockURL).get('/version.txt').reply(500);
|
|
50
|
+
const tmpDir = await tmp.dir();
|
|
51
|
+
const deno = new DenoBridge({
|
|
52
|
+
cacheDirectory: tmpDir.path,
|
|
53
|
+
logger: testLogger,
|
|
54
|
+
});
|
|
55
|
+
const mock = stub(deno, 'run').resolves();
|
|
56
|
+
await ensureLatestTypes(deno, testLogger, mockURL);
|
|
57
|
+
expect(latestVersionMock.isDone()).toBe(true);
|
|
58
|
+
expect(mock.callCount).toBe(0);
|
|
59
|
+
mock.restore();
|
|
60
|
+
await fs.rmdir(tmpDir.path, { recursive: true });
|
|
61
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { getLogger } from '../node/logger.js';
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
5
|
+
const testLogger = getLogger(() => { });
|
|
6
|
+
const url = new URL(import.meta.url);
|
|
7
|
+
const dirname = fileURLToPath(url);
|
|
8
|
+
const fixturesDir = resolve(dirname, '..', 'fixtures');
|
|
9
|
+
export { fixturesDir, testLogger };
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/edge-bundler",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Intelligently prepare Netlify Edge Functions for deployment",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/node/index.js",
|
|
7
7
|
"exports": "./dist/node/index.js",
|
|
8
8
|
"files": [
|
|
9
9
|
"deno/**",
|
|
10
|
+
"!deno/**/*.test.ts",
|
|
10
11
|
"dist/**/*.js",
|
|
11
12
|
"dist/**/*.d.ts",
|
|
12
13
|
"shared/**"
|
|
@@ -17,38 +18,26 @@
|
|
|
17
18
|
"prepublishOnly": "npm ci && npm test",
|
|
18
19
|
"prepack": "npm run build",
|
|
19
20
|
"test": "run-s build format test:dev",
|
|
20
|
-
"format": "run-s
|
|
21
|
-
"format:ci": "run-s
|
|
21
|
+
"format": "run-s format:check-fix:*",
|
|
22
|
+
"format:ci": "run-s format:check:*",
|
|
22
23
|
"format:check-fix:lint": "run-e format:check:lint format:fix:lint",
|
|
23
24
|
"format:check:lint": "cross-env-shell eslint $npm_package_config_eslint",
|
|
24
25
|
"format:fix:lint": "cross-env-shell eslint --fix $npm_package_config_eslint",
|
|
25
26
|
"format:check-fix:prettier": "run-e format:check:prettier format:fix:prettier",
|
|
26
27
|
"format:check:prettier": "cross-env-shell prettier --check $npm_package_config_prettier",
|
|
27
28
|
"format:fix:prettier": "cross-env-shell prettier --write $npm_package_config_prettier",
|
|
28
|
-
"test:dev": "run-s
|
|
29
|
-
"test:ci": "run-s
|
|
30
|
-
"test:dev:
|
|
31
|
-
"test:dev:deno": "deno test --allow-all
|
|
32
|
-
"test:ci:
|
|
33
|
-
"test:ci:deno": "deno test --allow-all
|
|
29
|
+
"test:dev": "run-s test:dev:*",
|
|
30
|
+
"test:ci": "run-s test:ci:*",
|
|
31
|
+
"test:dev:vitest": "vitest run",
|
|
32
|
+
"test:dev:deno": "deno test --allow-all deno",
|
|
33
|
+
"test:ci:vitest": "vitest run",
|
|
34
|
+
"test:ci:deno": "deno test --allow-all deno",
|
|
35
|
+
"test:integration": "node --experimental-modules test/integration/test.js"
|
|
34
36
|
},
|
|
35
37
|
"config": {
|
|
36
38
|
"eslint": "--ignore-path .gitignore --cache --format=codeframe --max-warnings=0 \"{node,scripts,.github}/**/*.{js,ts,md,html}\" \"*.{js,ts,md,html}\"",
|
|
37
39
|
"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\""
|
|
38
40
|
},
|
|
39
|
-
"ava": {
|
|
40
|
-
"files": [
|
|
41
|
-
"test/node/**/*.ts",
|
|
42
|
-
"!test/node/fixtures/**"
|
|
43
|
-
],
|
|
44
|
-
"extensions": {
|
|
45
|
-
"ts": "module"
|
|
46
|
-
},
|
|
47
|
-
"nodeArguments": [
|
|
48
|
-
"--loader=ts-node/esm",
|
|
49
|
-
"--no-warnings"
|
|
50
|
-
]
|
|
51
|
-
},
|
|
52
41
|
"keywords": [],
|
|
53
42
|
"license": "MIT",
|
|
54
43
|
"repository": "netlify/edge-bundler",
|
|
@@ -60,7 +49,6 @@
|
|
|
60
49
|
"test": "test/node"
|
|
61
50
|
},
|
|
62
51
|
"devDependencies": {
|
|
63
|
-
"@ava/typescript": "^3.0.1",
|
|
64
52
|
"@commitlint/cli": "^16.0.0",
|
|
65
53
|
"@commitlint/config-conventional": "^16.0.0",
|
|
66
54
|
"@netlify/eslint-config-node": "^4.1.7",
|
|
@@ -69,14 +57,15 @@
|
|
|
69
57
|
"@types/semver": "^7.3.9",
|
|
70
58
|
"@types/sinon": "^10.0.8",
|
|
71
59
|
"@types/uuid": "^8.3.4",
|
|
60
|
+
"@vitest/coverage-c8": "^0.23.4",
|
|
72
61
|
"archiver": "^5.3.1",
|
|
73
|
-
"ava": "^4.0.1",
|
|
74
62
|
"husky": "^8.0.0",
|
|
75
63
|
"nock": "^13.2.4",
|
|
76
|
-
"nyc": "^15.0.0",
|
|
77
64
|
"sinon": "^14.0.0",
|
|
78
|
-
"
|
|
79
|
-
"typescript": "^4.5.4"
|
|
65
|
+
"tar": "^6.1.11",
|
|
66
|
+
"typescript": "^4.5.4",
|
|
67
|
+
"vite": "^3.1.3",
|
|
68
|
+
"vitest": "^0.23.4"
|
|
80
69
|
},
|
|
81
70
|
"engines": {
|
|
82
71
|
"node": "^12.20.0 || ^14.14.0 || >=16.0.0"
|
|
@@ -87,8 +76,8 @@
|
|
|
87
76
|
"del": "^6.0.0",
|
|
88
77
|
"env-paths": "^3.0.0",
|
|
89
78
|
"execa": "^6.0.0",
|
|
90
|
-
"get-port": "^6.1.2",
|
|
91
79
|
"find-up": "^6.3.0",
|
|
80
|
+
"get-port": "^6.1.2",
|
|
92
81
|
"glob-to-regexp": "^0.4.1",
|
|
93
82
|
"node-fetch": "^3.1.1",
|
|
94
83
|
"node-stream-zip": "^1.15.0",
|