@netlify/edge-bundler 8.16.3 → 8.17.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/dist/node/bridge.d.ts +1 -1
- package/dist/node/bridge.js +1 -1
- package/dist/node/config.test.js +2 -1
- package/dist/node/feature_flags.d.ts +2 -0
- package/dist/node/feature_flags.js +1 -0
- package/dist/node/manifest.js +25 -13
- package/dist/node/manifest.test.js +60 -21
- package/dist/node/utils/urlpattern.d.ts +4 -0
- package/dist/node/utils/urlpattern.js +3 -0
- package/package.json +4 -3
package/dist/node/bridge.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { ExecaChildProcess } from 'execa';
|
|
3
3
|
import { Logger } from './logger.js';
|
|
4
|
-
declare const DENO_VERSION_RANGE = "^1.
|
|
4
|
+
declare const DENO_VERSION_RANGE = "^1.32.5";
|
|
5
5
|
type OnBeforeDownloadHook = () => void | Promise<void>;
|
|
6
6
|
type OnAfterDownloadHook = (error?: Error) => void | Promise<void>;
|
|
7
7
|
interface DenoOptions {
|
package/dist/node/bridge.js
CHANGED
|
@@ -11,7 +11,7 @@ import { getBinaryExtension } from './platform.js';
|
|
|
11
11
|
const DENO_VERSION_FILE = 'version.txt';
|
|
12
12
|
// When updating DENO_VERSION_RANGE, ensure that the deno version installed in the
|
|
13
13
|
// build-image/buildbot does satisfy this range!
|
|
14
|
-
const DENO_VERSION_RANGE = '^1.
|
|
14
|
+
const DENO_VERSION_RANGE = '^1.32.5';
|
|
15
15
|
class DenoBridge {
|
|
16
16
|
constructor(options) {
|
|
17
17
|
var _a, _b, _c, _d, _e;
|
package/dist/node/config.test.js
CHANGED
|
@@ -149,6 +149,7 @@ test('Loads function paths from the in-source `config` function', async () => {
|
|
|
149
149
|
const result = await bundle([internalDirectory, userDirectory], distPath, declarations, {
|
|
150
150
|
basePath,
|
|
151
151
|
configPath: join(internalDirectory, 'config.json'),
|
|
152
|
+
featureFlags: { edge_functions_path_urlpattern: true },
|
|
152
153
|
});
|
|
153
154
|
const generatedFiles = await fs.readdir(distPath);
|
|
154
155
|
expect(result.functions.length).toBe(7);
|
|
@@ -165,7 +166,7 @@ test('Loads function paths from the in-source `config` function', async () => {
|
|
|
165
166
|
expect(routes[2]).toEqual({ function: 'framework-func1', pattern: '^/framework-func1/?$', excluded_patterns: [] });
|
|
166
167
|
expect(routes[3]).toEqual({ function: 'user-func1', pattern: '^/user-func1/?$', excluded_patterns: [] });
|
|
167
168
|
expect(routes[4]).toEqual({ function: 'user-func3', pattern: '^/user-func3/?$', excluded_patterns: [] });
|
|
168
|
-
expect(routes[5]).toEqual({ function: 'user-func5', pattern: '^/user-func5
|
|
169
|
+
expect(routes[5]).toEqual({ function: 'user-func5', pattern: '^/user-func5(?:/(.*))/?$', excluded_patterns: [] });
|
|
169
170
|
expect(postCacheRoutes.length).toBe(1);
|
|
170
171
|
expect(postCacheRoutes[0]).toEqual({ function: 'user-func4', pattern: '^/user-func4/?$', excluded_patterns: [] });
|
|
171
172
|
expect(Object.keys(functionConfig)).toHaveLength(1);
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
declare const defaultFlags: {
|
|
2
2
|
edge_functions_fail_unsupported_regex: boolean;
|
|
3
|
+
edge_functions_path_urlpattern: boolean;
|
|
3
4
|
};
|
|
4
5
|
type FeatureFlag = keyof typeof defaultFlags;
|
|
5
6
|
type FeatureFlags = Partial<Record<FeatureFlag, boolean>>;
|
|
6
7
|
declare const getFlags: (input?: Record<string, boolean>, flags?: {
|
|
7
8
|
edge_functions_fail_unsupported_regex: boolean;
|
|
9
|
+
edge_functions_path_urlpattern: boolean;
|
|
8
10
|
}) => FeatureFlags;
|
|
9
11
|
export { defaultFlags, getFlags };
|
|
10
12
|
export type { FeatureFlag, FeatureFlags };
|
package/dist/node/manifest.js
CHANGED
|
@@ -4,6 +4,7 @@ import globToRegExp from 'glob-to-regexp';
|
|
|
4
4
|
import { parsePattern } from './declaration.js';
|
|
5
5
|
import { getPackageVersion } from './package_json.js';
|
|
6
6
|
import { nonNullable } from './utils/non_nullable.js';
|
|
7
|
+
import { ExtendedURLPattern } from './utils/urlpattern.js';
|
|
7
8
|
const removeEmptyConfigValues = (functionConfig) => Object.entries(functionConfig).reduce((acc, [key, value]) => {
|
|
8
9
|
if (value && !(Array.isArray(value) && value.length === 0)) {
|
|
9
10
|
return { ...acc, [key]: value };
|
|
@@ -25,10 +26,10 @@ const sanitizeEdgeFunctionConfig = (config) => {
|
|
|
25
26
|
}
|
|
26
27
|
return newConfig;
|
|
27
28
|
};
|
|
28
|
-
const addExcludedPatterns = (name, manifestFunctionConfig, excludedPath) => {
|
|
29
|
+
const addExcludedPatterns = (name, manifestFunctionConfig, excludedPath, featureFlags) => {
|
|
29
30
|
if (excludedPath) {
|
|
30
31
|
const paths = Array.isArray(excludedPath) ? excludedPath : [excludedPath];
|
|
31
|
-
const excludedPatterns = paths.map(pathToRegularExpression).map(serializePattern);
|
|
32
|
+
const excludedPatterns = paths.map((path) => pathToRegularExpression(path, featureFlags)).map(serializePattern);
|
|
32
33
|
manifestFunctionConfig[name].excluded_patterns.push(...excludedPatterns);
|
|
33
34
|
}
|
|
34
35
|
};
|
|
@@ -41,7 +42,7 @@ const generateManifest = ({ bundles = [], declarations = [], featureFlags, funct
|
|
|
41
42
|
if (manifestFunctionConfig[name] === undefined) {
|
|
42
43
|
continue;
|
|
43
44
|
}
|
|
44
|
-
addExcludedPatterns(name, manifestFunctionConfig, excludedPath);
|
|
45
|
+
addExcludedPatterns(name, manifestFunctionConfig, excludedPath, featureFlags);
|
|
45
46
|
manifestFunctionConfig[name] = { ...manifestFunctionConfig[name], on_error: onError };
|
|
46
47
|
}
|
|
47
48
|
for (const [name, { excludedPath, path, onError, ...rest }] of Object.entries(internalFunctionConfig)) {
|
|
@@ -49,7 +50,7 @@ const generateManifest = ({ bundles = [], declarations = [], featureFlags, funct
|
|
|
49
50
|
if (manifestFunctionConfig[name] === undefined) {
|
|
50
51
|
continue;
|
|
51
52
|
}
|
|
52
|
-
addExcludedPatterns(name, manifestFunctionConfig, excludedPath);
|
|
53
|
+
addExcludedPatterns(name, manifestFunctionConfig, excludedPath, featureFlags);
|
|
53
54
|
manifestFunctionConfig[name] = { ...manifestFunctionConfig[name], on_error: onError, ...rest };
|
|
54
55
|
}
|
|
55
56
|
declarations.forEach((declaration) => {
|
|
@@ -57,8 +58,8 @@ const generateManifest = ({ bundles = [], declarations = [], featureFlags, funct
|
|
|
57
58
|
if (func === undefined) {
|
|
58
59
|
return;
|
|
59
60
|
}
|
|
60
|
-
const pattern = getRegularExpression(declaration, featureFlags
|
|
61
|
-
const excludedPattern = getExcludedRegularExpressions(declaration, featureFlags
|
|
61
|
+
const pattern = getRegularExpression(declaration, featureFlags);
|
|
62
|
+
const excludedPattern = getExcludedRegularExpressions(declaration, featureFlags);
|
|
62
63
|
const route = {
|
|
63
64
|
function: func.name,
|
|
64
65
|
pattern: serializePattern(pattern),
|
|
@@ -86,7 +87,18 @@ const generateManifest = ({ bundles = [], declarations = [], featureFlags, funct
|
|
|
86
87
|
};
|
|
87
88
|
return manifest;
|
|
88
89
|
};
|
|
89
|
-
const pathToRegularExpression = (path) => {
|
|
90
|
+
const pathToRegularExpression = (path, featureFlags) => {
|
|
91
|
+
if (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.edge_functions_path_urlpattern) {
|
|
92
|
+
const pattern = new ExtendedURLPattern({ pathname: path });
|
|
93
|
+
// Removing the `^` and `$` delimiters because we'll need to modify what's
|
|
94
|
+
// between them.
|
|
95
|
+
const source = pattern.regexp.pathname.source.slice(1, -1);
|
|
96
|
+
// Wrapping the expression source with `^` and `$`. Also, adding an optional
|
|
97
|
+
// trailing slash, so that a declaration of `path: "/foo"` matches requests
|
|
98
|
+
// for both `/foo` and `/foo/`.
|
|
99
|
+
const normalizedSource = `^${source}\\/?$`;
|
|
100
|
+
return normalizedSource;
|
|
101
|
+
}
|
|
90
102
|
// We use the global flag so that `globToRegExp` will not wrap the expression
|
|
91
103
|
// with `^` and `$`. We'll do that ourselves.
|
|
92
104
|
const regularExpression = globToRegExp(path, { flags: 'g' });
|
|
@@ -96,23 +108,23 @@ const pathToRegularExpression = (path) => {
|
|
|
96
108
|
const normalizedSource = `^${regularExpression.source}\\/?$`;
|
|
97
109
|
return normalizedSource;
|
|
98
110
|
};
|
|
99
|
-
const getRegularExpression = (declaration,
|
|
111
|
+
const getRegularExpression = (declaration, featureFlags) => {
|
|
100
112
|
if ('pattern' in declaration) {
|
|
101
113
|
try {
|
|
102
114
|
return parsePattern(declaration.pattern);
|
|
103
115
|
}
|
|
104
116
|
catch (error) {
|
|
105
117
|
// eslint-disable-next-line max-depth
|
|
106
|
-
if (
|
|
118
|
+
if (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.edge_functions_fail_unsupported_regex) {
|
|
107
119
|
throw new Error(`Could not parse path declaration of function '${declaration.function}': ${error.message}`);
|
|
108
120
|
}
|
|
109
121
|
console.warn(`Function '${declaration.function}' uses an unsupported regular expression and will not be invoked: ${error.message}`);
|
|
110
122
|
return declaration.pattern;
|
|
111
123
|
}
|
|
112
124
|
}
|
|
113
|
-
return pathToRegularExpression(declaration.path);
|
|
125
|
+
return pathToRegularExpression(declaration.path, featureFlags);
|
|
114
126
|
};
|
|
115
|
-
const getExcludedRegularExpressions = (declaration,
|
|
127
|
+
const getExcludedRegularExpressions = (declaration, featureFlags) => {
|
|
116
128
|
if ('excludedPattern' in declaration && declaration.excludedPattern) {
|
|
117
129
|
const excludedPatterns = Array.isArray(declaration.excludedPattern)
|
|
118
130
|
? declaration.excludedPattern
|
|
@@ -122,7 +134,7 @@ const getExcludedRegularExpressions = (declaration, failUnsupportedRegex = false
|
|
|
122
134
|
return parsePattern(excludedPattern);
|
|
123
135
|
}
|
|
124
136
|
catch (error) {
|
|
125
|
-
if (
|
|
137
|
+
if (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.edge_functions_fail_unsupported_regex) {
|
|
126
138
|
throw new Error(`Could not parse path declaration of function '${declaration.function}': ${error.message}`);
|
|
127
139
|
}
|
|
128
140
|
console.warn(`Function '${declaration.function}' uses an unsupported regular expression and will therefore not be invoked: ${error.message}`);
|
|
@@ -132,7 +144,7 @@ const getExcludedRegularExpressions = (declaration, failUnsupportedRegex = false
|
|
|
132
144
|
}
|
|
133
145
|
if ('path' in declaration && declaration.excludedPath) {
|
|
134
146
|
const paths = Array.isArray(declaration.excludedPath) ? declaration.excludedPath : [declaration.excludedPath];
|
|
135
|
-
return paths.map(pathToRegularExpression);
|
|
147
|
+
return paths.map((path) => pathToRegularExpression(path, featureFlags));
|
|
136
148
|
}
|
|
137
149
|
return [];
|
|
138
150
|
};
|
|
@@ -34,8 +34,14 @@ test('Generates a manifest with display names', () => {
|
|
|
34
34
|
name: 'Display Name',
|
|
35
35
|
},
|
|
36
36
|
};
|
|
37
|
-
const manifest = generateManifest({
|
|
38
|
-
|
|
37
|
+
const manifest = generateManifest({
|
|
38
|
+
bundles: [],
|
|
39
|
+
declarations,
|
|
40
|
+
functions,
|
|
41
|
+
internalFunctionConfig,
|
|
42
|
+
featureFlags: { edge_functions_path_urlpattern: true },
|
|
43
|
+
});
|
|
44
|
+
const expectedRoutes = [{ function: 'func-1', pattern: '^/f1(?:/(.*))/?$', excluded_patterns: [] }];
|
|
39
45
|
expect(manifest.function_config).toEqual({
|
|
40
46
|
'func-1': { name: 'Display Name' },
|
|
41
47
|
});
|
|
@@ -50,8 +56,14 @@ test('Generates a manifest with a generator field', () => {
|
|
|
50
56
|
generator: '@netlify/fake-plugin@1.0.0',
|
|
51
57
|
},
|
|
52
58
|
};
|
|
53
|
-
const manifest = generateManifest({
|
|
54
|
-
|
|
59
|
+
const manifest = generateManifest({
|
|
60
|
+
bundles: [],
|
|
61
|
+
declarations,
|
|
62
|
+
functions,
|
|
63
|
+
internalFunctionConfig,
|
|
64
|
+
featureFlags: { edge_functions_path_urlpattern: true },
|
|
65
|
+
});
|
|
66
|
+
const expectedRoutes = [{ function: 'func-1', pattern: '^/f1(?:/(.*))/?$', excluded_patterns: [] }];
|
|
55
67
|
const expectedFunctionConfig = { 'func-1': { generator: '@netlify/fake-plugin@1.0.0' } };
|
|
56
68
|
expect(manifest.routes).toEqual(expectedRoutes);
|
|
57
69
|
expect(manifest.function_config).toEqual(expectedFunctionConfig);
|
|
@@ -65,14 +77,23 @@ test('Generates a manifest with excluded paths and patterns', () => {
|
|
|
65
77
|
];
|
|
66
78
|
const declarations = [
|
|
67
79
|
{ function: 'func-1', path: '/f1/*', excludedPath: '/f1/exclude' },
|
|
68
|
-
{ function: 'func-2', pattern: '^/f2
|
|
80
|
+
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$', excludedPattern: ['^/f2/exclude$', '^/f2/exclude-as-well$'] },
|
|
69
81
|
{ function: 'func-3', path: '/*', excludedPath: '/**/*.html' },
|
|
70
82
|
];
|
|
71
|
-
const manifest = generateManifest({
|
|
83
|
+
const manifest = generateManifest({
|
|
84
|
+
bundles: [],
|
|
85
|
+
declarations,
|
|
86
|
+
functions,
|
|
87
|
+
featureFlags: { edge_functions_path_urlpattern: true },
|
|
88
|
+
});
|
|
72
89
|
const expectedRoutes = [
|
|
73
|
-
{ function: 'func-1', pattern: '^/f1
|
|
74
|
-
{ function: 'func-2', pattern: '^/f2
|
|
75
|
-
{
|
|
90
|
+
{ function: 'func-1', pattern: '^/f1(?:/(.*))/?$', excluded_patterns: ['^/f1/exclude/?$'] },
|
|
91
|
+
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$', excluded_patterns: ['^/f2/exclude$', '^/f2/exclude-as-well$'] },
|
|
92
|
+
{
|
|
93
|
+
function: 'func-3',
|
|
94
|
+
pattern: '^(?:/(.*))/?$',
|
|
95
|
+
excluded_patterns: ['^(?:/((?:.*)(?:/(?:.*))*))?(?:/(.*))\\.html/?$'],
|
|
96
|
+
},
|
|
76
97
|
];
|
|
77
98
|
expect(manifest.routes).toEqual(expectedRoutes);
|
|
78
99
|
expect(manifest.function_config).toEqual({});
|
|
@@ -87,8 +108,14 @@ test('TOML-defined paths can be combined with ISC-defined excluded paths', () =>
|
|
|
87
108
|
const userFunctionConfig = {
|
|
88
109
|
'func-1': { excludedPath: '/f1/exclude' },
|
|
89
110
|
};
|
|
90
|
-
const manifest = generateManifest({
|
|
91
|
-
|
|
111
|
+
const manifest = generateManifest({
|
|
112
|
+
bundles: [],
|
|
113
|
+
declarations,
|
|
114
|
+
functions,
|
|
115
|
+
userFunctionConfig,
|
|
116
|
+
featureFlags: { edge_functions_path_urlpattern: true },
|
|
117
|
+
});
|
|
118
|
+
const expectedRoutes = [{ function: 'func-1', pattern: '^/f1(?:/(.*))/?$', excluded_patterns: [] }];
|
|
92
119
|
expect(manifest.routes).toEqual(expectedRoutes);
|
|
93
120
|
expect(manifest.function_config).toEqual({
|
|
94
121
|
'func-1': { excluded_patterns: ['^/f1/exclude/?$'] },
|
|
@@ -102,7 +129,7 @@ test('Filters out internal in-source configurations in user created functions',
|
|
|
102
129
|
];
|
|
103
130
|
const declarations = [
|
|
104
131
|
{ function: 'func-1', path: '/f1/*' },
|
|
105
|
-
{ function: 'func-2', pattern: '^/f2
|
|
132
|
+
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$' },
|
|
106
133
|
];
|
|
107
134
|
const userFunctionConfig = {
|
|
108
135
|
'func-1': {
|
|
@@ -163,22 +190,23 @@ test('excludedPath from ISC goes into function_config, TOML goes into routes', (
|
|
|
163
190
|
functions,
|
|
164
191
|
userFunctionConfig,
|
|
165
192
|
internalFunctionConfig,
|
|
193
|
+
featureFlags: { edge_functions_path_urlpattern: true },
|
|
166
194
|
});
|
|
167
195
|
expect(manifest.routes).toEqual([
|
|
168
196
|
{
|
|
169
197
|
function: 'customisation',
|
|
170
|
-
pattern: '^/showcases
|
|
198
|
+
pattern: '^/showcases(?:/(.*))/?$',
|
|
171
199
|
excluded_patterns: [],
|
|
172
200
|
},
|
|
173
201
|
{
|
|
174
202
|
function: 'customisation',
|
|
175
|
-
pattern: '^/checkout
|
|
176
|
-
excluded_patterns: ['
|
|
203
|
+
pattern: '^/checkout(?:/(.*))/?$',
|
|
204
|
+
excluded_patterns: ['^(?:/(.*))/terms-and-conditions/?$'],
|
|
177
205
|
},
|
|
178
206
|
]);
|
|
179
207
|
expect(manifest.function_config).toEqual({
|
|
180
208
|
customisation: {
|
|
181
|
-
excluded_patterns: ['
|
|
209
|
+
excluded_patterns: ['^(?:/(.*))\\.css/?$', '^(?:/(.*))\\.jpg/?$'],
|
|
182
210
|
},
|
|
183
211
|
});
|
|
184
212
|
const matcher = getRouteMatcher(manifest);
|
|
@@ -195,7 +223,7 @@ test('Includes failure modes in manifest', () => {
|
|
|
195
223
|
];
|
|
196
224
|
const declarations = [
|
|
197
225
|
{ function: 'func-1', path: '/f1/*' },
|
|
198
|
-
{ function: 'func-2', pattern: '^/f2
|
|
226
|
+
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$' },
|
|
199
227
|
];
|
|
200
228
|
const userFunctionConfig = {
|
|
201
229
|
'func-1': {
|
|
@@ -292,8 +320,8 @@ test('Generates a manifest with layers', () => {
|
|
|
292
320
|
{ function: 'func-2', path: '/f2/*' },
|
|
293
321
|
];
|
|
294
322
|
const expectedRoutes = [
|
|
295
|
-
{ function: 'func-1', pattern: '^/f1
|
|
296
|
-
{ function: 'func-2', pattern: '^/f2
|
|
323
|
+
{ function: 'func-1', pattern: '^/f1(?:/(.*))/?$', excluded_patterns: [] },
|
|
324
|
+
{ function: 'func-2', pattern: '^/f2(?:/(.*))/?$', excluded_patterns: [] },
|
|
297
325
|
];
|
|
298
326
|
const layers = [
|
|
299
327
|
{
|
|
@@ -301,8 +329,19 @@ test('Generates a manifest with layers', () => {
|
|
|
301
329
|
flag: 'edge_functions_onion_layer',
|
|
302
330
|
},
|
|
303
331
|
];
|
|
304
|
-
const manifest1 = generateManifest({
|
|
305
|
-
|
|
332
|
+
const manifest1 = generateManifest({
|
|
333
|
+
bundles: [],
|
|
334
|
+
declarations,
|
|
335
|
+
functions,
|
|
336
|
+
featureFlags: { edge_functions_path_urlpattern: true },
|
|
337
|
+
});
|
|
338
|
+
const manifest2 = generateManifest({
|
|
339
|
+
bundles: [],
|
|
340
|
+
declarations,
|
|
341
|
+
functions,
|
|
342
|
+
layers,
|
|
343
|
+
featureFlags: { edge_functions_path_urlpattern: true },
|
|
344
|
+
});
|
|
306
345
|
expect(manifest1.routes).toEqual(expectedRoutes);
|
|
307
346
|
expect(manifest1.layers).toEqual([]);
|
|
308
347
|
expect(manifest2.routes).toEqual(expectedRoutes);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/edge-bundler",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.17.0",
|
|
4
4
|
"description": "Intelligently prepare Netlify Edge Functions for deployment",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/node/index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"test:dev:vitest": "vitest run",
|
|
33
33
|
"test:dev:vitest:watch": "vitest watch",
|
|
34
34
|
"test:dev:deno": "deno test --allow-all deno",
|
|
35
|
-
"test:ci:vitest": "vitest run",
|
|
35
|
+
"test:ci:vitest": "vitest run --coverage",
|
|
36
36
|
"test:ci:deno": "deno test --allow-all deno",
|
|
37
37
|
"test:integration": "node --experimental-modules test/integration/test.js"
|
|
38
38
|
},
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"@types/node": "^14.18.32",
|
|
59
59
|
"@types/semver": "^7.3.9",
|
|
60
60
|
"@types/uuid": "^9.0.0",
|
|
61
|
-
"@vitest/coverage-
|
|
61
|
+
"@vitest/coverage-v8": "^0.33.0",
|
|
62
62
|
"archiver": "^5.3.1",
|
|
63
63
|
"chalk": "^4.1.2",
|
|
64
64
|
"cpy": "^9.0.1",
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
"regexp-tree": "^0.1.24",
|
|
94
94
|
"semver": "^7.3.8",
|
|
95
95
|
"tmp-promise": "^3.0.3",
|
|
96
|
+
"urlpattern-polyfill": "8.0.2",
|
|
96
97
|
"uuid": "^9.0.0"
|
|
97
98
|
}
|
|
98
99
|
}
|