@netlify/edge-bundler 11.1.0 → 11.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.
- package/dist/node/bridge.d.ts +7 -3
- package/dist/node/bridge.js +16 -8
- package/dist/node/declaration.d.ts +6 -1
- package/dist/node/declaration.js +20 -7
- package/dist/node/declaration.test.js +6 -6
- package/dist/node/manifest.js +2 -8
- package/dist/node/server/server.d.ts +5 -1
- package/dist/node/server/server.js +16 -2
- package/dist/node/server/server.test.js +7 -0
- package/package.json +1 -1
package/dist/node/bridge.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { type WriteStream } from 'fs';
|
|
2
4
|
import { ExecaChildProcess } from 'execa';
|
|
3
5
|
import { Logger } from './logger.js';
|
|
4
6
|
declare const DENO_VERSION_RANGE = "^1.37.0";
|
|
@@ -18,9 +20,11 @@ interface ProcessRef {
|
|
|
18
20
|
ps?: ExecaChildProcess<string>;
|
|
19
21
|
}
|
|
20
22
|
interface RunOptions {
|
|
21
|
-
pipeOutput?: boolean;
|
|
22
23
|
env?: NodeJS.ProcessEnv;
|
|
23
24
|
extendEnv?: boolean;
|
|
25
|
+
pipeOutput?: boolean;
|
|
26
|
+
stderr?: WriteStream;
|
|
27
|
+
stdout?: WriteStream;
|
|
24
28
|
rejectOnExitCode?: boolean;
|
|
25
29
|
}
|
|
26
30
|
declare class DenoBridge {
|
|
@@ -47,8 +51,8 @@ declare class DenoBridge {
|
|
|
47
51
|
path: string;
|
|
48
52
|
}>;
|
|
49
53
|
getEnvironmentVariables(inputEnv?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
50
|
-
run(args: string[], {
|
|
51
|
-
runInBackground(args: string[], ref?: ProcessRef, {
|
|
54
|
+
run(args: string[], { env: inputEnv, extendEnv, rejectOnExitCode, stderr, stdout }?: RunOptions): Promise<import("execa").ExecaReturnValue<string>>;
|
|
55
|
+
runInBackground(args: string[], ref?: ProcessRef, { env: inputEnv, extendEnv, stderr, stdout }?: RunOptions): Promise<void>;
|
|
52
56
|
}
|
|
53
57
|
export { DENO_VERSION_RANGE, DenoBridge };
|
|
54
58
|
export type { DenoOptions, OnAfterDownloadHook, OnBeforeDownloadHook, ProcessRef };
|
package/dist/node/bridge.js
CHANGED
|
@@ -93,13 +93,21 @@ class DenoBridge {
|
|
|
93
93
|
}
|
|
94
94
|
return this.currentDownload;
|
|
95
95
|
}
|
|
96
|
-
static runWithBinary(binaryPath, args, options, pipeOutput) {
|
|
97
|
-
var _a, _b;
|
|
96
|
+
static runWithBinary(binaryPath, args, { options, pipeOutput, stderr, stdout, }) {
|
|
97
|
+
var _a, _b, _c, _d;
|
|
98
98
|
const runDeno = execa(binaryPath, args, options);
|
|
99
|
-
if (
|
|
100
|
-
(_a = runDeno.
|
|
99
|
+
if (stderr) {
|
|
100
|
+
(_a = runDeno.stderr) === null || _a === void 0 ? void 0 : _a.pipe(stderr);
|
|
101
|
+
}
|
|
102
|
+
else if (pipeOutput) {
|
|
101
103
|
(_b = runDeno.stderr) === null || _b === void 0 ? void 0 : _b.pipe(process.stderr);
|
|
102
104
|
}
|
|
105
|
+
if (stdout) {
|
|
106
|
+
(_c = runDeno.stdout) === null || _c === void 0 ? void 0 : _c.pipe(stdout);
|
|
107
|
+
}
|
|
108
|
+
else if (pipeOutput) {
|
|
109
|
+
(_d = runDeno.stdout) === null || _d === void 0 ? void 0 : _d.pipe(process.stdout);
|
|
110
|
+
}
|
|
103
111
|
return runDeno;
|
|
104
112
|
}
|
|
105
113
|
async writeVersionFile(version) {
|
|
@@ -135,19 +143,19 @@ class DenoBridge {
|
|
|
135
143
|
}
|
|
136
144
|
// Runs the Deno CLI in the background and returns a reference to the child
|
|
137
145
|
// process, awaiting its execution.
|
|
138
|
-
async run(args, {
|
|
146
|
+
async run(args, { env: inputEnv, extendEnv = true, rejectOnExitCode = true, stderr, stdout } = {}) {
|
|
139
147
|
const { path: binaryPath } = await this.getBinaryPath();
|
|
140
148
|
const env = this.getEnvironmentVariables(inputEnv);
|
|
141
149
|
const options = { env, extendEnv, reject: rejectOnExitCode };
|
|
142
|
-
return DenoBridge.runWithBinary(binaryPath, args, options,
|
|
150
|
+
return DenoBridge.runWithBinary(binaryPath, args, { options, stderr, stdout });
|
|
143
151
|
}
|
|
144
152
|
// Runs the Deno CLI in the background, assigning a reference of the child
|
|
145
153
|
// process to a `ps` property in the `ref` argument, if one is supplied.
|
|
146
|
-
async runInBackground(args, ref, {
|
|
154
|
+
async runInBackground(args, ref, { env: inputEnv, extendEnv = true, stderr, stdout } = {}) {
|
|
147
155
|
const { path: binaryPath } = await this.getBinaryPath();
|
|
148
156
|
const env = this.getEnvironmentVariables(inputEnv);
|
|
149
157
|
const options = { env, extendEnv };
|
|
150
|
-
const ps = DenoBridge.runWithBinary(binaryPath, args, options,
|
|
158
|
+
const ps = DenoBridge.runWithBinary(binaryPath, args, { options, stderr, stdout });
|
|
151
159
|
if (ref !== undefined) {
|
|
152
160
|
// eslint-disable-next-line no-param-reassign
|
|
153
161
|
ref.ps = ps;
|
|
@@ -17,5 +17,10 @@ type DeclarationWithPattern = BaseDeclaration & {
|
|
|
17
17
|
};
|
|
18
18
|
export type Declaration = DeclarationWithPath | DeclarationWithPattern;
|
|
19
19
|
export declare const mergeDeclarations: (tomlDeclarations: Declaration[], userFunctionsConfig: Record<string, FunctionConfig>, internalFunctionsConfig: Record<string, FunctionConfig>, deployConfigDeclarations: Declaration[], _featureFlags?: FeatureFlags) => Declaration[];
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Normalizes a regular expression, ensuring it has a leading `^` and trailing
|
|
22
|
+
* `$` characters. It also converts the regular expression from PCRE to RE2 if
|
|
23
|
+
* needed.
|
|
24
|
+
*/
|
|
25
|
+
export declare const parsePattern: (pattern: string, pcreRegexpEngine: boolean) => string;
|
|
21
26
|
export {};
|
package/dist/node/declaration.js
CHANGED
|
@@ -66,15 +66,29 @@ const createDeclarationsFromFunctionConfigs = (functionConfigs, functionsVisited
|
|
|
66
66
|
}
|
|
67
67
|
return declarations;
|
|
68
68
|
};
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Normalizes a regular expression, ensuring it has a leading `^` and trailing
|
|
71
|
+
* `$` characters. It also converts the regular expression from PCRE to RE2 if
|
|
72
|
+
* needed.
|
|
73
|
+
*/
|
|
74
|
+
export const parsePattern = (pattern, pcreRegexpEngine) => {
|
|
72
75
|
let enclosedPattern = pattern;
|
|
73
|
-
if (!pattern.startsWith('^'))
|
|
76
|
+
if (!pattern.startsWith('^')) {
|
|
74
77
|
enclosedPattern = `^${enclosedPattern}`;
|
|
75
|
-
|
|
78
|
+
}
|
|
79
|
+
if (!pattern.endsWith('$')) {
|
|
76
80
|
enclosedPattern = `${enclosedPattern}$`;
|
|
81
|
+
}
|
|
77
82
|
const regexp = new RegExp(enclosedPattern);
|
|
83
|
+
const regexpString = pcreRegexpEngine ? regexp.toString() : transformPCRERegexp(regexp);
|
|
84
|
+
// Strip leading and forward slashes.
|
|
85
|
+
return regexpString.slice(1, -1);
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Transforms a PCRE regular expression into a RE2 expression, compatible
|
|
89
|
+
* with the Go engine used in our edge nodes.
|
|
90
|
+
*/
|
|
91
|
+
const transformPCRERegexp = (regexp) => {
|
|
78
92
|
const newRegexp = regexpAST.transform(regexp, {
|
|
79
93
|
Assertion(path) {
|
|
80
94
|
// Lookaheads are not supported. If we find one, throw an error.
|
|
@@ -95,6 +109,5 @@ export const parsePattern = (pattern) => {
|
|
|
95
109
|
}
|
|
96
110
|
},
|
|
97
111
|
});
|
|
98
|
-
|
|
99
|
-
return newRegexp.toString().slice(1, -1);
|
|
112
|
+
return newRegexp.toString();
|
|
100
113
|
};
|
|
@@ -117,18 +117,18 @@ test('netlify.toml-defined excludedPath are respected', () => {
|
|
|
117
117
|
test('Does not escape front slashes in a regex pattern if they are already escaped', () => {
|
|
118
118
|
const regexPattern = '^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/shows(?:\\/(.*))(.json)?[\\/#\\?]?$';
|
|
119
119
|
const expected = '^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/shows(?:\\/(.*))(.json)?[\\/#\\?]?$';
|
|
120
|
-
|
|
121
|
-
expect(
|
|
120
|
+
expect(parsePattern(regexPattern, false)).toEqual(expected);
|
|
121
|
+
expect(parsePattern(regexPattern, true)).toEqual(expected);
|
|
122
122
|
});
|
|
123
123
|
test('Escapes front slashes in a regex pattern', () => {
|
|
124
124
|
const regexPattern = '^(?:/(_next/data/[^/]{1,}))?(?:/([^/.]{1,}))/shows(?:/(.*))(.json)?[/#\\?]?$';
|
|
125
125
|
const expected = '^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/shows(?:\\/(.*))(.json)?[/#\\?]?$';
|
|
126
|
-
|
|
127
|
-
expect(
|
|
126
|
+
expect(parsePattern(regexPattern, false)).toEqual(expected);
|
|
127
|
+
expect(parsePattern(regexPattern, true)).toEqual(expected);
|
|
128
128
|
});
|
|
129
129
|
test('Ensures pattern match on the whole path', () => {
|
|
130
130
|
const regexPattern = '/foo/.*/bar';
|
|
131
131
|
const expected = '^\\/foo\\/.*\\/bar$';
|
|
132
|
-
|
|
133
|
-
expect(
|
|
132
|
+
expect(parsePattern(regexPattern, false)).toEqual(expected);
|
|
133
|
+
expect(parsePattern(regexPattern, true)).toEqual(expected);
|
|
134
134
|
});
|
package/dist/node/manifest.js
CHANGED
|
@@ -137,11 +137,8 @@ const pathToRegularExpression = (path) => {
|
|
|
137
137
|
};
|
|
138
138
|
const getRegularExpression = (declaration, pcreRegexpEngine) => {
|
|
139
139
|
if ('pattern' in declaration) {
|
|
140
|
-
if (pcreRegexpEngine) {
|
|
141
|
-
return declaration.pattern;
|
|
142
|
-
}
|
|
143
140
|
try {
|
|
144
|
-
return parsePattern(declaration.pattern);
|
|
141
|
+
return parsePattern(declaration.pattern, pcreRegexpEngine);
|
|
145
142
|
}
|
|
146
143
|
catch (error) {
|
|
147
144
|
throw wrapBundleError(new Error(`Could not parse path declaration of function '${declaration.function}': ${error.message}`));
|
|
@@ -154,12 +151,9 @@ const getExcludedRegularExpressions = (declaration, pcreRegexpEngine) => {
|
|
|
154
151
|
const excludedPatterns = Array.isArray(declaration.excludedPattern)
|
|
155
152
|
? declaration.excludedPattern
|
|
156
153
|
: [declaration.excludedPattern];
|
|
157
|
-
if (pcreRegexpEngine) {
|
|
158
|
-
return excludedPatterns;
|
|
159
|
-
}
|
|
160
154
|
return excludedPatterns.map((excludedPattern) => {
|
|
161
155
|
try {
|
|
162
|
-
return parsePattern(excludedPattern);
|
|
156
|
+
return parsePattern(excludedPattern, pcreRegexpEngine);
|
|
163
157
|
}
|
|
164
158
|
catch (error) {
|
|
165
159
|
throw wrapBundleError(new Error(`Could not parse path declaration of function '${declaration.function}': ${error.message}`));
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
/// <reference types="node" />
|
|
4
4
|
/// <reference types="node" />
|
|
5
5
|
/// <reference types="node" />
|
|
6
|
+
/// <reference types="node" />
|
|
7
|
+
import type { WriteStream } from 'fs';
|
|
6
8
|
import { OnAfterDownloadHook, OnBeforeDownloadHook } from '../bridge.js';
|
|
7
9
|
import { FunctionConfig } from '../config.js';
|
|
8
10
|
import type { EdgeFunction } from '../edge_function.js';
|
|
@@ -34,10 +36,12 @@ interface ServeOptions {
|
|
|
34
36
|
port: number;
|
|
35
37
|
rootPath?: string;
|
|
36
38
|
servePath: string;
|
|
39
|
+
stderr?: WriteStream;
|
|
40
|
+
stdout?: WriteStream;
|
|
37
41
|
userLogger?: LogFunction;
|
|
38
42
|
systemLogger?: LogFunction;
|
|
39
43
|
}
|
|
40
|
-
export declare const serve: ({ basePath, bootstrapURL, certificatePath, debug, distImportMapPath, inspectSettings, featureFlags, formatExportTypeError, formatImportError, onAfterDownload, onBeforeDownload, port, rootPath, servePath, userLogger, systemLogger, }: ServeOptions) => Promise<(functions: EdgeFunction[], env?: NodeJS.ProcessEnv, options?: StartServerOptions) => Promise<{
|
|
44
|
+
export declare const serve: ({ basePath, bootstrapURL, certificatePath, debug, distImportMapPath, inspectSettings, featureFlags, formatExportTypeError, formatImportError, onAfterDownload, onBeforeDownload, port, rootPath, servePath, stderr, stdout, userLogger, systemLogger, }: ServeOptions) => Promise<(functions: EdgeFunction[], env?: NodeJS.ProcessEnv, options?: StartServerOptions) => Promise<{
|
|
41
45
|
features: Record<string, boolean>;
|
|
42
46
|
functionsConfig: FunctionConfig[];
|
|
43
47
|
graph: ModuleGraphJson;
|
|
@@ -18,7 +18,7 @@ const cleanDirectory = async (directory, except) => {
|
|
|
18
18
|
const toBeDeleted = files.filter((file) => !except.includes(join(directory, file)));
|
|
19
19
|
await Promise.all(toBeDeleted.map((file) => unlink(join(directory, file))));
|
|
20
20
|
};
|
|
21
|
-
const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImportMapPath, flags: denoFlags, formatExportTypeError, formatImportError, logger, port, rootPath, }) => {
|
|
21
|
+
const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImportMapPath, flags: denoFlags, formatExportTypeError, formatImportError, logger, port, rootPath, stderr, stdout, }) => {
|
|
22
22
|
const processRef = {};
|
|
23
23
|
const startServer = async (functions, env = {}, options = {}) => {
|
|
24
24
|
var _a;
|
|
@@ -77,9 +77,11 @@ const prepareServer = ({ basePath, bootstrapURL, deno, distDirectory, distImport
|
|
|
77
77
|
// with variables from the user's system, since those will not be available
|
|
78
78
|
// in the production environment.
|
|
79
79
|
await deno.runInBackground(['run', ...denoFlags, ...extraDenoFlags, stage2Path, ...applicationFlags], processRef, {
|
|
80
|
-
pipeOutput: true,
|
|
81
80
|
env,
|
|
82
81
|
extendEnv: false,
|
|
82
|
+
pipeOutput: true,
|
|
83
|
+
stderr,
|
|
84
|
+
stdout,
|
|
83
85
|
});
|
|
84
86
|
let functionsConfig = [];
|
|
85
87
|
if (options.getFunctionsConfig) {
|
|
@@ -165,6 +167,16 @@ rootPath,
|
|
|
165
167
|
* operate.
|
|
166
168
|
*/
|
|
167
169
|
servePath,
|
|
170
|
+
/**
|
|
171
|
+
* Writable stream to receive the stderr of the server process. If not set,
|
|
172
|
+
* the stderr of the parent process will be used.
|
|
173
|
+
*/
|
|
174
|
+
stderr,
|
|
175
|
+
/**
|
|
176
|
+
* Writable stream to receive the stdout of the server process. If not set,
|
|
177
|
+
* the stdout of the parent process will be used.
|
|
178
|
+
*/
|
|
179
|
+
stdout,
|
|
168
180
|
/**
|
|
169
181
|
* Custom logging function to be used for user-facing messages. Defaults to
|
|
170
182
|
* `console.log`.
|
|
@@ -214,6 +226,8 @@ systemLogger, }) => {
|
|
|
214
226
|
formatExportTypeError,
|
|
215
227
|
formatImportError,
|
|
216
228
|
logger,
|
|
229
|
+
stderr,
|
|
230
|
+
stdout,
|
|
217
231
|
port,
|
|
218
232
|
rootPath,
|
|
219
233
|
});
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { createWriteStream } from 'fs';
|
|
1
2
|
import { readFile } from 'fs/promises';
|
|
2
3
|
import { join } from 'path';
|
|
3
4
|
import process from 'process';
|
|
4
5
|
import getPort from 'get-port';
|
|
5
6
|
import fetch from 'node-fetch';
|
|
7
|
+
import tmp from 'tmp-promise';
|
|
6
8
|
import { v4 as uuidv4 } from 'uuid';
|
|
7
9
|
import { test, expect } from 'vitest';
|
|
8
10
|
import { fixturesDir } from '../../test/util.js';
|
|
@@ -86,6 +88,8 @@ test('Starts a server and serves requests for edge functions', async () => {
|
|
|
86
88
|
expect(identidadeBarrelFile).toContain(`/// <reference types="${join('..', '..', 'node_modules', '@types', 'pt-committee__identidade', 'index.d.ts')}" />`);
|
|
87
89
|
});
|
|
88
90
|
test('Serves edge functions in a monorepo setup', async () => {
|
|
91
|
+
const tmpFile = await tmp.file();
|
|
92
|
+
const stderr = createWriteStream(tmpFile.path);
|
|
89
93
|
const rootPath = join(fixturesDir, 'monorepo_npm_module');
|
|
90
94
|
const basePath = join(rootPath, 'packages', 'frontend');
|
|
91
95
|
const paths = {
|
|
@@ -100,6 +104,7 @@ test('Serves edge functions in a monorepo setup', async () => {
|
|
|
100
104
|
port,
|
|
101
105
|
rootPath,
|
|
102
106
|
servePath,
|
|
107
|
+
stderr,
|
|
103
108
|
});
|
|
104
109
|
const functions = [
|
|
105
110
|
{
|
|
@@ -131,4 +136,6 @@ test('Serves edge functions in a monorepo setup', async () => {
|
|
|
131
136
|
});
|
|
132
137
|
expect(response1.status).toBe(200);
|
|
133
138
|
expect(await response1.text()).toBe(`<parent-1><child-1>JavaScript</child-1></parent-1>, <parent-2><child-2><grandchild-1>APIs<cwd>${process.cwd()}</cwd></grandchild-1></child-2></parent-2>, <parent-3><child-2><grandchild-1>Markup<cwd>${process.cwd()}</cwd></grandchild-1></child-2></parent-3>`);
|
|
139
|
+
expect(await readFile(tmpFile.path, 'utf8')).toContain('[func1] Something is on fire');
|
|
140
|
+
await tmpFile.cleanup();
|
|
134
141
|
});
|