@vercel/build-utils 2.12.3-canary.22 → 2.12.3-canary.26
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/convert-runtime-to-plugin.d.ts +0 -2
- package/dist/convert-runtime-to-plugin.js +5 -51
- package/dist/detect-builders.d.ts +6 -8
- package/dist/detect-builders.js +60 -23
- package/dist/index.js +68 -77
- package/dist/types.d.ts +1 -0
- package/package.json +3 -3
@@ -8,7 +8,6 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
8
|
const path_1 = require("path");
|
9
9
|
const glob_1 = __importDefault(require("./fs/glob"));
|
10
10
|
const normalize_path_1 = require("./fs/normalize-path");
|
11
|
-
const detect_builders_1 = require("./detect-builders");
|
12
11
|
const lambda_1 = require("./lambda");
|
13
12
|
const minimatch_1 = __importDefault(require("minimatch"));
|
14
13
|
/**
|
@@ -19,13 +18,12 @@ const minimatch_1 = __importDefault(require("minimatch"));
|
|
19
18
|
function convertRuntimeToPlugin(buildRuntime, ext) {
|
20
19
|
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
21
20
|
return async function build({ vercelConfig, workPath, }) {
|
22
|
-
var _a;
|
23
21
|
const opts = { cwd: workPath };
|
24
22
|
const files = await glob_1.default('**', opts);
|
25
23
|
delete files['vercel.json']; // Builders/Runtimes didn't have vercel.json
|
26
24
|
const entrypoints = await glob_1.default(`api/**/*${ext}`, opts);
|
27
25
|
const pages = {};
|
28
|
-
const { functions = {}
|
26
|
+
const { functions = {} } = vercelConfig;
|
29
27
|
const traceDir = path_1.join(workPath, '.output', 'runtime-traced-files');
|
30
28
|
await fs_extra_1.default.ensureDir(traceDir);
|
31
29
|
for (const entrypoint of Object.keys(entrypoints)) {
|
@@ -40,6 +38,9 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
40
38
|
includeFiles: config.includeFiles,
|
41
39
|
excludeFiles: config.excludeFiles,
|
42
40
|
},
|
41
|
+
meta: {
|
42
|
+
avoidTopLevelInstall: true,
|
43
|
+
},
|
43
44
|
});
|
44
45
|
pages[entrypoint] = {
|
45
46
|
handler: output.handler,
|
@@ -48,7 +49,7 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
48
49
|
maxDuration: output.maxDuration,
|
49
50
|
environment: output.environment,
|
50
51
|
allowQuery: output.allowQuery,
|
51
|
-
regions: output.regions,
|
52
|
+
//regions: output.regions,
|
52
53
|
};
|
53
54
|
// @ts-ignore This symbol is a private API
|
54
55
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
@@ -82,53 +83,6 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
82
83
|
await fs_extra_1.default.writeFile(nft, json);
|
83
84
|
}
|
84
85
|
await updateFunctionsManifest({ vercelConfig, workPath, pages });
|
85
|
-
const { warnings, errors,
|
86
|
-
//defaultRoutes,
|
87
|
-
redirectRoutes,
|
88
|
-
//rewriteRoutes,
|
89
|
-
dynamicRoutesWithKeys,
|
90
|
-
// errorRoutes, already handled by pages404
|
91
|
-
} = await detect_builders_1.detectBuilders(Object.keys(files), null, {
|
92
|
-
tag: 'latest',
|
93
|
-
functions: functions,
|
94
|
-
projectSettings: undefined,
|
95
|
-
featHandleMiss: true,
|
96
|
-
cleanUrls,
|
97
|
-
trailingSlash,
|
98
|
-
});
|
99
|
-
if (errors) {
|
100
|
-
throw new Error(errors[0].message);
|
101
|
-
}
|
102
|
-
if (warnings) {
|
103
|
-
warnings.forEach(warning => console.warn(warning.message, warning.link));
|
104
|
-
}
|
105
|
-
const redirects = (_a = redirectRoutes === null || redirectRoutes === void 0 ? void 0 : redirectRoutes.filter(r => r.src && 'headers' in r)) === null || _a === void 0 ? void 0 : _a.map(r => {
|
106
|
-
var _a;
|
107
|
-
return ({
|
108
|
-
source: r.src || '',
|
109
|
-
destination: 'headers' in r && ((_a = r.headers) === null || _a === void 0 ? void 0 : _a.Location) ? r.headers.Location : '',
|
110
|
-
statusCode: 'status' in r && r.status ? r.status : 307,
|
111
|
-
regex: r.src || '',
|
112
|
-
});
|
113
|
-
});
|
114
|
-
const dynamicRoutes = dynamicRoutesWithKeys === null || dynamicRoutesWithKeys === void 0 ? void 0 : dynamicRoutesWithKeys.map(r => {
|
115
|
-
const keys = Object.keys(r.routeKeys);
|
116
|
-
return {
|
117
|
-
page: '/' + r.fileName.slice(0, -ext.length),
|
118
|
-
regex: r.regex,
|
119
|
-
routeKeys: r.routeKeys,
|
120
|
-
namedRegex: r.regex
|
121
|
-
.split('([^/]+)')
|
122
|
-
.map((str, i) => str + (keys[i] ? `(?<${keys[i]}>[^/]+)` : ''))
|
123
|
-
.join(''),
|
124
|
-
};
|
125
|
-
});
|
126
|
-
await updateRoutesManifest({
|
127
|
-
workPath,
|
128
|
-
redirects,
|
129
|
-
rewrites: [],
|
130
|
-
dynamicRoutes,
|
131
|
-
});
|
132
86
|
};
|
133
87
|
}
|
134
88
|
exports.convertRuntimeToPlugin = convertRuntimeToPlugin;
|
@@ -6,13 +6,6 @@ interface ErrorResponse {
|
|
6
6
|
action?: string;
|
7
7
|
link?: string;
|
8
8
|
}
|
9
|
-
interface DynamicRoutesWithKeys {
|
10
|
-
fileName: string;
|
11
|
-
regex: string;
|
12
|
-
routeKeys: {
|
13
|
-
[key: string]: string;
|
14
|
-
};
|
15
|
-
}
|
16
9
|
interface Options {
|
17
10
|
tag?: 'canary' | 'latest' | string;
|
18
11
|
functions?: BuilderFunctions;
|
@@ -41,6 +34,11 @@ export declare function detectBuilders(files: string[], pkg?: PackageJson | unde
|
|
41
34
|
redirectRoutes: Route[] | null;
|
42
35
|
rewriteRoutes: Route[] | null;
|
43
36
|
errorRoutes: Route[] | null;
|
44
|
-
|
37
|
+
limitedRoutes: LimitedRoutes | null;
|
45
38
|
}>;
|
39
|
+
interface LimitedRoutes {
|
40
|
+
defaultRoutes: Route[];
|
41
|
+
redirectRoutes: Route[];
|
42
|
+
rewriteRoutes: Route[];
|
43
|
+
}
|
46
44
|
export {};
|
package/dist/detect-builders.js
CHANGED
@@ -66,7 +66,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
66
66
|
redirectRoutes: null,
|
67
67
|
rewriteRoutes: null,
|
68
68
|
errorRoutes: null,
|
69
|
-
|
69
|
+
limitedRoutes: null,
|
70
70
|
};
|
71
71
|
}
|
72
72
|
const sortedFiles = files.sort(sortFiles);
|
@@ -100,12 +100,11 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
100
100
|
let fallbackEntrypoint = null;
|
101
101
|
const apiRoutes = [];
|
102
102
|
const dynamicRoutes = [];
|
103
|
-
const dynamicRoutesWithKeys = [];
|
104
103
|
// API
|
105
104
|
for (const fileName of sortedFiles) {
|
106
105
|
const apiBuilder = maybeGetApiBuilder(fileName, apiMatches, options);
|
107
106
|
if (apiBuilder) {
|
108
|
-
const { routeError, apiRoute, isDynamic
|
107
|
+
const { routeError, apiRoute, isDynamic } = getApiRoute(fileName, apiSortedFiles, options, absolutePathCache);
|
109
108
|
if (routeError) {
|
110
109
|
return {
|
111
110
|
builders: null,
|
@@ -115,18 +114,13 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
115
114
|
redirectRoutes: null,
|
116
115
|
rewriteRoutes: null,
|
117
116
|
errorRoutes: null,
|
118
|
-
|
117
|
+
limitedRoutes: null,
|
119
118
|
};
|
120
119
|
}
|
121
120
|
if (apiRoute) {
|
122
121
|
apiRoutes.push(apiRoute);
|
123
122
|
if (isDynamic) {
|
124
123
|
dynamicRoutes.push(apiRoute);
|
125
|
-
dynamicRoutesWithKeys.push({
|
126
|
-
fileName,
|
127
|
-
regex: apiRoute.src,
|
128
|
-
routeKeys,
|
129
|
-
});
|
130
124
|
}
|
131
125
|
}
|
132
126
|
addToUsedFunctions(apiBuilder);
|
@@ -175,7 +169,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
175
169
|
defaultRoutes: null,
|
176
170
|
rewriteRoutes: null,
|
177
171
|
errorRoutes: null,
|
178
|
-
|
172
|
+
limitedRoutes: null,
|
179
173
|
};
|
180
174
|
}
|
181
175
|
// If `outputDirectory` is an empty string,
|
@@ -212,7 +206,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
212
206
|
defaultRoutes: null,
|
213
207
|
rewriteRoutes: null,
|
214
208
|
errorRoutes: null,
|
215
|
-
|
209
|
+
limitedRoutes: null,
|
216
210
|
};
|
217
211
|
}
|
218
212
|
const builders = [];
|
@@ -231,7 +225,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
231
225
|
});
|
232
226
|
}
|
233
227
|
}
|
234
|
-
const routesResult = getRouteResult(apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
228
|
+
const routesResult = getRouteResult(pkg, apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
235
229
|
return {
|
236
230
|
warnings,
|
237
231
|
builders: builders.length ? builders : null,
|
@@ -240,7 +234,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
240
234
|
defaultRoutes: routesResult.defaultRoutes,
|
241
235
|
rewriteRoutes: routesResult.rewriteRoutes,
|
242
236
|
errorRoutes: routesResult.errorRoutes,
|
243
|
-
|
237
|
+
limitedRoutes: routesResult.limitedRoutes,
|
244
238
|
};
|
245
239
|
}
|
246
240
|
exports.detectBuilders = detectBuilders;
|
@@ -495,7 +489,6 @@ function getApiRoute(fileName, sortedFiles, options, absolutePathCache) {
|
|
495
489
|
return {
|
496
490
|
apiRoute: null,
|
497
491
|
isDynamic: false,
|
498
|
-
routeKeys: {},
|
499
492
|
routeError: {
|
500
493
|
code: 'conflicting_path_segment',
|
501
494
|
message: `The segment "${conflictingSegment}" occurs more than ` +
|
@@ -510,7 +503,6 @@ function getApiRoute(fileName, sortedFiles, options, absolutePathCache) {
|
|
510
503
|
return {
|
511
504
|
apiRoute: null,
|
512
505
|
isDynamic: false,
|
513
|
-
routeKeys: {},
|
514
506
|
routeError: {
|
515
507
|
code: 'conflicting_file_path',
|
516
508
|
message: `Two or more files have conflicting paths or names. ` +
|
@@ -523,7 +515,6 @@ function getApiRoute(fileName, sortedFiles, options, absolutePathCache) {
|
|
523
515
|
return {
|
524
516
|
apiRoute: out.route,
|
525
517
|
isDynamic: out.isDynamic,
|
526
|
-
routeKeys: out.routeKeys,
|
527
518
|
routeError: null,
|
528
519
|
};
|
529
520
|
}
|
@@ -633,7 +624,6 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
633
624
|
const parts = filePath.split('/');
|
634
625
|
let counter = 1;
|
635
626
|
const query = [];
|
636
|
-
const routeKeys = {};
|
637
627
|
let isDynamic = false;
|
638
628
|
const srcParts = parts.map((segment, i) => {
|
639
629
|
const name = getSegmentName(segment);
|
@@ -641,7 +631,6 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
641
631
|
if (name !== null) {
|
642
632
|
// We can't use `URLSearchParams` because `$` would get escaped
|
643
633
|
query.push(`${name}=$${counter++}`);
|
644
|
-
routeKeys[name] = name;
|
645
634
|
isDynamic = true;
|
646
635
|
return `([^/]+)`;
|
647
636
|
}
|
@@ -684,25 +673,53 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
684
673
|
dest: `/${filePath}${queryString}`,
|
685
674
|
};
|
686
675
|
}
|
687
|
-
return { route, isDynamic
|
676
|
+
return { route, isDynamic };
|
688
677
|
}
|
689
|
-
function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
678
|
+
function getRouteResult(pkg, apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
690
679
|
var _a, _b;
|
680
|
+
const deps = Object.assign({}, pkg === null || pkg === void 0 ? void 0 : pkg.dependencies, pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies);
|
691
681
|
const defaultRoutes = [];
|
692
682
|
const redirectRoutes = [];
|
693
683
|
const rewriteRoutes = [];
|
694
684
|
const errorRoutes = [];
|
685
|
+
const limitedRoutes = {
|
686
|
+
defaultRoutes: [],
|
687
|
+
redirectRoutes: [],
|
688
|
+
rewriteRoutes: [],
|
689
|
+
};
|
695
690
|
const framework = ((_a = frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.config) === null || _a === void 0 ? void 0 : _a.framework) || '';
|
696
691
|
const isNextjs = framework === 'nextjs' || _1.isOfficialRuntime('next', frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.use);
|
697
692
|
const ignoreRuntimes = (_b = slugToFramework.get(framework)) === null || _b === void 0 ? void 0 : _b.ignoreRuntimes;
|
698
693
|
if (apiRoutes && apiRoutes.length > 0) {
|
699
694
|
if (options.featHandleMiss) {
|
695
|
+
// Exclude extension names if the corresponding plugin is not found in package.json
|
696
|
+
// detectBuilders({ignoreRoutesForBuilders: ['@vercel/python']})
|
697
|
+
// return a copy of routes.
|
698
|
+
// We should exclud errorRoutes and
|
700
699
|
const extSet = detectApiExtensions(apiBuilders);
|
700
|
+
const withTag = options.tag ? `@${options.tag}` : '';
|
701
|
+
const extSetLimited = detectApiExtensions(apiBuilders.filter(b => {
|
702
|
+
if (b.use === `@vercel/python${withTag}` &&
|
703
|
+
!('vercel-plugin-python' in deps)) {
|
704
|
+
return false;
|
705
|
+
}
|
706
|
+
if (b.use === `@vercel/go${withTag}` &&
|
707
|
+
!('vercel-plugin-go' in deps)) {
|
708
|
+
return false;
|
709
|
+
}
|
710
|
+
if (b.use === `@vercel/ruby${withTag}` &&
|
711
|
+
!('vercel-plugin-ruby' in deps)) {
|
712
|
+
return false;
|
713
|
+
}
|
714
|
+
return true;
|
715
|
+
}));
|
701
716
|
if (extSet.size > 0) {
|
702
|
-
const
|
717
|
+
const extGroup = `(?:\\.(?:${Array.from(extSet)
|
703
718
|
.map(ext => ext.slice(1))
|
704
|
-
.join('|')
|
705
|
-
const
|
719
|
+
.join('|')}))`;
|
720
|
+
const extGroupLimited = `(?:\\.(?:${Array.from(extSetLimited)
|
721
|
+
.map(ext => ext.slice(1))
|
722
|
+
.join('|')}))`;
|
706
723
|
if (options.cleanUrls) {
|
707
724
|
redirectRoutes.push({
|
708
725
|
src: `^/(api(?:.+)?)/index${extGroup}?/?$`,
|
@@ -716,6 +733,18 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
716
733
|
},
|
717
734
|
status: 308,
|
718
735
|
});
|
736
|
+
limitedRoutes.redirectRoutes.push({
|
737
|
+
src: `^/(api(?:.+)?)/index${extGroupLimited}?/?$`,
|
738
|
+
headers: { Location: options.trailingSlash ? '/$1/' : '/$1' },
|
739
|
+
status: 308,
|
740
|
+
});
|
741
|
+
limitedRoutes.redirectRoutes.push({
|
742
|
+
src: `^/api/(.+)${extGroupLimited}/?$`,
|
743
|
+
headers: {
|
744
|
+
Location: options.trailingSlash ? '/api/$1/' : '/api/$1',
|
745
|
+
},
|
746
|
+
status: 308,
|
747
|
+
});
|
719
748
|
}
|
720
749
|
else {
|
721
750
|
defaultRoutes.push({ handle: 'miss' });
|
@@ -724,9 +753,16 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
724
753
|
dest: '/api/$1',
|
725
754
|
check: true,
|
726
755
|
});
|
756
|
+
limitedRoutes.defaultRoutes.push({ handle: 'miss' });
|
757
|
+
limitedRoutes.defaultRoutes.push({
|
758
|
+
src: `^/api/(.+)${extGroupLimited}$`,
|
759
|
+
dest: '/api/$1',
|
760
|
+
check: true,
|
761
|
+
});
|
727
762
|
}
|
728
763
|
}
|
729
764
|
rewriteRoutes.push(...dynamicRoutes);
|
765
|
+
limitedRoutes.rewriteRoutes.push(...dynamicRoutes);
|
730
766
|
if (typeof ignoreRuntimes === 'undefined') {
|
731
767
|
// This route is only necessary to hide the directory listing
|
732
768
|
// to avoid enumerating serverless function names.
|
@@ -771,6 +807,7 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
771
807
|
redirectRoutes,
|
772
808
|
rewriteRoutes,
|
773
809
|
errorRoutes,
|
810
|
+
limitedRoutes,
|
774
811
|
};
|
775
812
|
}
|
776
813
|
function sortFilesBySegmentCount(fileA, fileB) {
|
package/dist/index.js
CHANGED
@@ -26274,7 +26274,7 @@ exports.frameworks = [
|
|
26274
26274
|
name: 'Remix',
|
26275
26275
|
slug: 'remix',
|
26276
26276
|
demo: 'https://remix.examples.vercel.com',
|
26277
|
-
logo: 'https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/remix.svg',
|
26277
|
+
logo: 'https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/remix-no-shadow.svg',
|
26278
26278
|
tagline: 'Build Better Websites',
|
26279
26279
|
description: 'A new Remix app — the result of running `npx create-remix`.',
|
26280
26280
|
website: 'https://remix.run',
|
@@ -26329,8 +26329,8 @@ exports.frameworks = [
|
|
26329
26329
|
],
|
26330
26330
|
defaultHeaders: [
|
26331
26331
|
{
|
26332
|
-
source: '
|
26333
|
-
regex: '
|
26332
|
+
source: '/build/(.*)',
|
26333
|
+
regex: '/build/(.*)',
|
26334
26334
|
headers: [
|
26335
26335
|
{ key: 'cache-control', value: 'public, max-age=31536000, immutable' },
|
26336
26336
|
],
|
@@ -32285,7 +32285,6 @@ const fs_extra_1 = __importDefault(__webpack_require__(5392));
|
|
32285
32285
|
const path_1 = __webpack_require__(5622);
|
32286
32286
|
const glob_1 = __importDefault(__webpack_require__(4240));
|
32287
32287
|
const normalize_path_1 = __webpack_require__(6261);
|
32288
|
-
const detect_builders_1 = __webpack_require__(4246);
|
32289
32288
|
const lambda_1 = __webpack_require__(6721);
|
32290
32289
|
const minimatch_1 = __importDefault(__webpack_require__(9566));
|
32291
32290
|
/**
|
@@ -32296,13 +32295,12 @@ const minimatch_1 = __importDefault(__webpack_require__(9566));
|
|
32296
32295
|
function convertRuntimeToPlugin(buildRuntime, ext) {
|
32297
32296
|
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
32298
32297
|
return async function build({ vercelConfig, workPath, }) {
|
32299
|
-
var _a;
|
32300
32298
|
const opts = { cwd: workPath };
|
32301
32299
|
const files = await glob_1.default('**', opts);
|
32302
32300
|
delete files['vercel.json']; // Builders/Runtimes didn't have vercel.json
|
32303
32301
|
const entrypoints = await glob_1.default(`api/**/*${ext}`, opts);
|
32304
32302
|
const pages = {};
|
32305
|
-
const { functions = {}
|
32303
|
+
const { functions = {} } = vercelConfig;
|
32306
32304
|
const traceDir = path_1.join(workPath, '.output', 'runtime-traced-files');
|
32307
32305
|
await fs_extra_1.default.ensureDir(traceDir);
|
32308
32306
|
for (const entrypoint of Object.keys(entrypoints)) {
|
@@ -32317,6 +32315,9 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
32317
32315
|
includeFiles: config.includeFiles,
|
32318
32316
|
excludeFiles: config.excludeFiles,
|
32319
32317
|
},
|
32318
|
+
meta: {
|
32319
|
+
avoidTopLevelInstall: true,
|
32320
|
+
},
|
32320
32321
|
});
|
32321
32322
|
pages[entrypoint] = {
|
32322
32323
|
handler: output.handler,
|
@@ -32325,7 +32326,7 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
32325
32326
|
maxDuration: output.maxDuration,
|
32326
32327
|
environment: output.environment,
|
32327
32328
|
allowQuery: output.allowQuery,
|
32328
|
-
regions: output.regions,
|
32329
|
+
//regions: output.regions,
|
32329
32330
|
};
|
32330
32331
|
// @ts-ignore This symbol is a private API
|
32331
32332
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
@@ -32359,53 +32360,6 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
32359
32360
|
await fs_extra_1.default.writeFile(nft, json);
|
32360
32361
|
}
|
32361
32362
|
await updateFunctionsManifest({ vercelConfig, workPath, pages });
|
32362
|
-
const { warnings, errors,
|
32363
|
-
//defaultRoutes,
|
32364
|
-
redirectRoutes,
|
32365
|
-
//rewriteRoutes,
|
32366
|
-
dynamicRoutesWithKeys,
|
32367
|
-
// errorRoutes, already handled by pages404
|
32368
|
-
} = await detect_builders_1.detectBuilders(Object.keys(files), null, {
|
32369
|
-
tag: 'latest',
|
32370
|
-
functions: functions,
|
32371
|
-
projectSettings: undefined,
|
32372
|
-
featHandleMiss: true,
|
32373
|
-
cleanUrls,
|
32374
|
-
trailingSlash,
|
32375
|
-
});
|
32376
|
-
if (errors) {
|
32377
|
-
throw new Error(errors[0].message);
|
32378
|
-
}
|
32379
|
-
if (warnings) {
|
32380
|
-
warnings.forEach(warning => console.warn(warning.message, warning.link));
|
32381
|
-
}
|
32382
|
-
const redirects = (_a = redirectRoutes === null || redirectRoutes === void 0 ? void 0 : redirectRoutes.filter(r => r.src && 'headers' in r)) === null || _a === void 0 ? void 0 : _a.map(r => {
|
32383
|
-
var _a;
|
32384
|
-
return ({
|
32385
|
-
source: r.src || '',
|
32386
|
-
destination: 'headers' in r && ((_a = r.headers) === null || _a === void 0 ? void 0 : _a.Location) ? r.headers.Location : '',
|
32387
|
-
statusCode: 'status' in r && r.status ? r.status : 307,
|
32388
|
-
regex: r.src || '',
|
32389
|
-
});
|
32390
|
-
});
|
32391
|
-
const dynamicRoutes = dynamicRoutesWithKeys === null || dynamicRoutesWithKeys === void 0 ? void 0 : dynamicRoutesWithKeys.map(r => {
|
32392
|
-
const keys = Object.keys(r.routeKeys);
|
32393
|
-
return {
|
32394
|
-
page: '/' + r.fileName.slice(0, -ext.length),
|
32395
|
-
regex: r.regex,
|
32396
|
-
routeKeys: r.routeKeys,
|
32397
|
-
namedRegex: r.regex
|
32398
|
-
.split('([^/]+)')
|
32399
|
-
.map((str, i) => str + (keys[i] ? `(?<${keys[i]}>[^/]+)` : ''))
|
32400
|
-
.join(''),
|
32401
|
-
};
|
32402
|
-
});
|
32403
|
-
await updateRoutesManifest({
|
32404
|
-
workPath,
|
32405
|
-
redirects,
|
32406
|
-
rewrites: [],
|
32407
|
-
dynamicRoutes,
|
32408
|
-
});
|
32409
32363
|
};
|
32410
32364
|
}
|
32411
32365
|
exports.convertRuntimeToPlugin = convertRuntimeToPlugin;
|
@@ -32590,7 +32544,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32590
32544
|
redirectRoutes: null,
|
32591
32545
|
rewriteRoutes: null,
|
32592
32546
|
errorRoutes: null,
|
32593
|
-
|
32547
|
+
limitedRoutes: null,
|
32594
32548
|
};
|
32595
32549
|
}
|
32596
32550
|
const sortedFiles = files.sort(sortFiles);
|
@@ -32624,12 +32578,11 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32624
32578
|
let fallbackEntrypoint = null;
|
32625
32579
|
const apiRoutes = [];
|
32626
32580
|
const dynamicRoutes = [];
|
32627
|
-
const dynamicRoutesWithKeys = [];
|
32628
32581
|
// API
|
32629
32582
|
for (const fileName of sortedFiles) {
|
32630
32583
|
const apiBuilder = maybeGetApiBuilder(fileName, apiMatches, options);
|
32631
32584
|
if (apiBuilder) {
|
32632
|
-
const { routeError, apiRoute, isDynamic
|
32585
|
+
const { routeError, apiRoute, isDynamic } = getApiRoute(fileName, apiSortedFiles, options, absolutePathCache);
|
32633
32586
|
if (routeError) {
|
32634
32587
|
return {
|
32635
32588
|
builders: null,
|
@@ -32639,18 +32592,13 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32639
32592
|
redirectRoutes: null,
|
32640
32593
|
rewriteRoutes: null,
|
32641
32594
|
errorRoutes: null,
|
32642
|
-
|
32595
|
+
limitedRoutes: null,
|
32643
32596
|
};
|
32644
32597
|
}
|
32645
32598
|
if (apiRoute) {
|
32646
32599
|
apiRoutes.push(apiRoute);
|
32647
32600
|
if (isDynamic) {
|
32648
32601
|
dynamicRoutes.push(apiRoute);
|
32649
|
-
dynamicRoutesWithKeys.push({
|
32650
|
-
fileName,
|
32651
|
-
regex: apiRoute.src,
|
32652
|
-
routeKeys,
|
32653
|
-
});
|
32654
32602
|
}
|
32655
32603
|
}
|
32656
32604
|
addToUsedFunctions(apiBuilder);
|
@@ -32699,7 +32647,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32699
32647
|
defaultRoutes: null,
|
32700
32648
|
rewriteRoutes: null,
|
32701
32649
|
errorRoutes: null,
|
32702
|
-
|
32650
|
+
limitedRoutes: null,
|
32703
32651
|
};
|
32704
32652
|
}
|
32705
32653
|
// If `outputDirectory` is an empty string,
|
@@ -32736,7 +32684,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32736
32684
|
defaultRoutes: null,
|
32737
32685
|
rewriteRoutes: null,
|
32738
32686
|
errorRoutes: null,
|
32739
|
-
|
32687
|
+
limitedRoutes: null,
|
32740
32688
|
};
|
32741
32689
|
}
|
32742
32690
|
const builders = [];
|
@@ -32755,7 +32703,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32755
32703
|
});
|
32756
32704
|
}
|
32757
32705
|
}
|
32758
|
-
const routesResult = getRouteResult(apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
32706
|
+
const routesResult = getRouteResult(pkg, apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
32759
32707
|
return {
|
32760
32708
|
warnings,
|
32761
32709
|
builders: builders.length ? builders : null,
|
@@ -32764,7 +32712,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32764
32712
|
defaultRoutes: routesResult.defaultRoutes,
|
32765
32713
|
rewriteRoutes: routesResult.rewriteRoutes,
|
32766
32714
|
errorRoutes: routesResult.errorRoutes,
|
32767
|
-
|
32715
|
+
limitedRoutes: routesResult.limitedRoutes,
|
32768
32716
|
};
|
32769
32717
|
}
|
32770
32718
|
exports.detectBuilders = detectBuilders;
|
@@ -33019,7 +32967,6 @@ function getApiRoute(fileName, sortedFiles, options, absolutePathCache) {
|
|
33019
32967
|
return {
|
33020
32968
|
apiRoute: null,
|
33021
32969
|
isDynamic: false,
|
33022
|
-
routeKeys: {},
|
33023
32970
|
routeError: {
|
33024
32971
|
code: 'conflicting_path_segment',
|
33025
32972
|
message: `The segment "${conflictingSegment}" occurs more than ` +
|
@@ -33034,7 +32981,6 @@ function getApiRoute(fileName, sortedFiles, options, absolutePathCache) {
|
|
33034
32981
|
return {
|
33035
32982
|
apiRoute: null,
|
33036
32983
|
isDynamic: false,
|
33037
|
-
routeKeys: {},
|
33038
32984
|
routeError: {
|
33039
32985
|
code: 'conflicting_file_path',
|
33040
32986
|
message: `Two or more files have conflicting paths or names. ` +
|
@@ -33047,7 +32993,6 @@ function getApiRoute(fileName, sortedFiles, options, absolutePathCache) {
|
|
33047
32993
|
return {
|
33048
32994
|
apiRoute: out.route,
|
33049
32995
|
isDynamic: out.isDynamic,
|
33050
|
-
routeKeys: out.routeKeys,
|
33051
32996
|
routeError: null,
|
33052
32997
|
};
|
33053
32998
|
}
|
@@ -33157,7 +33102,6 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
33157
33102
|
const parts = filePath.split('/');
|
33158
33103
|
let counter = 1;
|
33159
33104
|
const query = [];
|
33160
|
-
const routeKeys = {};
|
33161
33105
|
let isDynamic = false;
|
33162
33106
|
const srcParts = parts.map((segment, i) => {
|
33163
33107
|
const name = getSegmentName(segment);
|
@@ -33165,7 +33109,6 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
33165
33109
|
if (name !== null) {
|
33166
33110
|
// We can't use `URLSearchParams` because `$` would get escaped
|
33167
33111
|
query.push(`${name}=$${counter++}`);
|
33168
|
-
routeKeys[name] = name;
|
33169
33112
|
isDynamic = true;
|
33170
33113
|
return `([^/]+)`;
|
33171
33114
|
}
|
@@ -33208,25 +33151,53 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
33208
33151
|
dest: `/${filePath}${queryString}`,
|
33209
33152
|
};
|
33210
33153
|
}
|
33211
|
-
return { route, isDynamic
|
33154
|
+
return { route, isDynamic };
|
33212
33155
|
}
|
33213
|
-
function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
33156
|
+
function getRouteResult(pkg, apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
33214
33157
|
var _a, _b;
|
33158
|
+
const deps = Object.assign({}, pkg === null || pkg === void 0 ? void 0 : pkg.dependencies, pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies);
|
33215
33159
|
const defaultRoutes = [];
|
33216
33160
|
const redirectRoutes = [];
|
33217
33161
|
const rewriteRoutes = [];
|
33218
33162
|
const errorRoutes = [];
|
33163
|
+
const limitedRoutes = {
|
33164
|
+
defaultRoutes: [],
|
33165
|
+
redirectRoutes: [],
|
33166
|
+
rewriteRoutes: [],
|
33167
|
+
};
|
33219
33168
|
const framework = ((_a = frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.config) === null || _a === void 0 ? void 0 : _a.framework) || '';
|
33220
33169
|
const isNextjs = framework === 'nextjs' || _1.isOfficialRuntime('next', frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.use);
|
33221
33170
|
const ignoreRuntimes = (_b = slugToFramework.get(framework)) === null || _b === void 0 ? void 0 : _b.ignoreRuntimes;
|
33222
33171
|
if (apiRoutes && apiRoutes.length > 0) {
|
33223
33172
|
if (options.featHandleMiss) {
|
33173
|
+
// Exclude extension names if the corresponding plugin is not found in package.json
|
33174
|
+
// detectBuilders({ignoreRoutesForBuilders: ['@vercel/python']})
|
33175
|
+
// return a copy of routes.
|
33176
|
+
// We should exclud errorRoutes and
|
33224
33177
|
const extSet = detectApiExtensions(apiBuilders);
|
33178
|
+
const withTag = options.tag ? `@${options.tag}` : '';
|
33179
|
+
const extSetLimited = detectApiExtensions(apiBuilders.filter(b => {
|
33180
|
+
if (b.use === `@vercel/python${withTag}` &&
|
33181
|
+
!('vercel-plugin-python' in deps)) {
|
33182
|
+
return false;
|
33183
|
+
}
|
33184
|
+
if (b.use === `@vercel/go${withTag}` &&
|
33185
|
+
!('vercel-plugin-go' in deps)) {
|
33186
|
+
return false;
|
33187
|
+
}
|
33188
|
+
if (b.use === `@vercel/ruby${withTag}` &&
|
33189
|
+
!('vercel-plugin-ruby' in deps)) {
|
33190
|
+
return false;
|
33191
|
+
}
|
33192
|
+
return true;
|
33193
|
+
}));
|
33225
33194
|
if (extSet.size > 0) {
|
33226
|
-
const
|
33195
|
+
const extGroup = `(?:\\.(?:${Array.from(extSet)
|
33196
|
+
.map(ext => ext.slice(1))
|
33197
|
+
.join('|')}))`;
|
33198
|
+
const extGroupLimited = `(?:\\.(?:${Array.from(extSetLimited)
|
33227
33199
|
.map(ext => ext.slice(1))
|
33228
|
-
.join('|')
|
33229
|
-
const extGroup = `(?:\\.(?:${exts}))`;
|
33200
|
+
.join('|')}))`;
|
33230
33201
|
if (options.cleanUrls) {
|
33231
33202
|
redirectRoutes.push({
|
33232
33203
|
src: `^/(api(?:.+)?)/index${extGroup}?/?$`,
|
@@ -33240,6 +33211,18 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
33240
33211
|
},
|
33241
33212
|
status: 308,
|
33242
33213
|
});
|
33214
|
+
limitedRoutes.redirectRoutes.push({
|
33215
|
+
src: `^/(api(?:.+)?)/index${extGroupLimited}?/?$`,
|
33216
|
+
headers: { Location: options.trailingSlash ? '/$1/' : '/$1' },
|
33217
|
+
status: 308,
|
33218
|
+
});
|
33219
|
+
limitedRoutes.redirectRoutes.push({
|
33220
|
+
src: `^/api/(.+)${extGroupLimited}/?$`,
|
33221
|
+
headers: {
|
33222
|
+
Location: options.trailingSlash ? '/api/$1/' : '/api/$1',
|
33223
|
+
},
|
33224
|
+
status: 308,
|
33225
|
+
});
|
33243
33226
|
}
|
33244
33227
|
else {
|
33245
33228
|
defaultRoutes.push({ handle: 'miss' });
|
@@ -33248,9 +33231,16 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
33248
33231
|
dest: '/api/$1',
|
33249
33232
|
check: true,
|
33250
33233
|
});
|
33234
|
+
limitedRoutes.defaultRoutes.push({ handle: 'miss' });
|
33235
|
+
limitedRoutes.defaultRoutes.push({
|
33236
|
+
src: `^/api/(.+)${extGroupLimited}$`,
|
33237
|
+
dest: '/api/$1',
|
33238
|
+
check: true,
|
33239
|
+
});
|
33251
33240
|
}
|
33252
33241
|
}
|
33253
33242
|
rewriteRoutes.push(...dynamicRoutes);
|
33243
|
+
limitedRoutes.rewriteRoutes.push(...dynamicRoutes);
|
33254
33244
|
if (typeof ignoreRuntimes === 'undefined') {
|
33255
33245
|
// This route is only necessary to hide the directory listing
|
33256
33246
|
// to avoid enumerating serverless function names.
|
@@ -33295,6 +33285,7 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
33295
33285
|
redirectRoutes,
|
33296
33286
|
rewriteRoutes,
|
33297
33287
|
errorRoutes,
|
33288
|
+
limitedRoutes,
|
33298
33289
|
};
|
33299
33290
|
}
|
33300
33291
|
function sortFilesBySegmentCount(fileA, fileB) {
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vercel/build-utils",
|
3
|
-
"version": "2.12.3-canary.
|
3
|
+
"version": "2.12.3-canary.26",
|
4
4
|
"license": "MIT",
|
5
5
|
"main": "./dist/index.js",
|
6
6
|
"types": "./dist/index.d.js",
|
@@ -30,7 +30,7 @@
|
|
30
30
|
"@types/node-fetch": "^2.1.6",
|
31
31
|
"@types/semver": "6.0.0",
|
32
32
|
"@types/yazl": "^2.4.1",
|
33
|
-
"@vercel/frameworks": "0.5.1-canary.
|
33
|
+
"@vercel/frameworks": "0.5.1-canary.16",
|
34
34
|
"@vercel/ncc": "0.24.0",
|
35
35
|
"aggregate-error": "3.0.1",
|
36
36
|
"async-retry": "1.2.3",
|
@@ -49,5 +49,5 @@
|
|
49
49
|
"typescript": "4.3.4",
|
50
50
|
"yazl": "2.4.3"
|
51
51
|
},
|
52
|
-
"gitHead": "
|
52
|
+
"gitHead": "1202ff7b2b8a821c6404a86baa12996f3078ed36"
|
53
53
|
}
|