@vercel/build-utils 2.12.3-canary.22 → 2.12.3-canary.23
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.
@@ -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)) {
|
@@ -48,7 +46,7 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
48
46
|
maxDuration: output.maxDuration,
|
49
47
|
environment: output.environment,
|
50
48
|
allowQuery: output.allowQuery,
|
51
|
-
regions: output.regions,
|
49
|
+
//regions: output.regions,
|
52
50
|
};
|
53
51
|
// @ts-ignore This symbol is a private API
|
54
52
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
@@ -82,53 +80,6 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
82
80
|
await fs_extra_1.default.writeFile(nft, json);
|
83
81
|
}
|
84
82
|
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
83
|
};
|
133
84
|
}
|
134
85
|
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
@@ -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)) {
|
@@ -32325,7 +32323,7 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
32325
32323
|
maxDuration: output.maxDuration,
|
32326
32324
|
environment: output.environment,
|
32327
32325
|
allowQuery: output.allowQuery,
|
32328
|
-
regions: output.regions,
|
32326
|
+
//regions: output.regions,
|
32329
32327
|
};
|
32330
32328
|
// @ts-ignore This symbol is a private API
|
32331
32329
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
@@ -32359,53 +32357,6 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
32359
32357
|
await fs_extra_1.default.writeFile(nft, json);
|
32360
32358
|
}
|
32361
32359
|
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
32360
|
};
|
32410
32361
|
}
|
32411
32362
|
exports.convertRuntimeToPlugin = convertRuntimeToPlugin;
|
@@ -32590,7 +32541,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32590
32541
|
redirectRoutes: null,
|
32591
32542
|
rewriteRoutes: null,
|
32592
32543
|
errorRoutes: null,
|
32593
|
-
|
32544
|
+
limitedRoutes: null,
|
32594
32545
|
};
|
32595
32546
|
}
|
32596
32547
|
const sortedFiles = files.sort(sortFiles);
|
@@ -32624,12 +32575,11 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32624
32575
|
let fallbackEntrypoint = null;
|
32625
32576
|
const apiRoutes = [];
|
32626
32577
|
const dynamicRoutes = [];
|
32627
|
-
const dynamicRoutesWithKeys = [];
|
32628
32578
|
// API
|
32629
32579
|
for (const fileName of sortedFiles) {
|
32630
32580
|
const apiBuilder = maybeGetApiBuilder(fileName, apiMatches, options);
|
32631
32581
|
if (apiBuilder) {
|
32632
|
-
const { routeError, apiRoute, isDynamic
|
32582
|
+
const { routeError, apiRoute, isDynamic } = getApiRoute(fileName, apiSortedFiles, options, absolutePathCache);
|
32633
32583
|
if (routeError) {
|
32634
32584
|
return {
|
32635
32585
|
builders: null,
|
@@ -32639,18 +32589,13 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32639
32589
|
redirectRoutes: null,
|
32640
32590
|
rewriteRoutes: null,
|
32641
32591
|
errorRoutes: null,
|
32642
|
-
|
32592
|
+
limitedRoutes: null,
|
32643
32593
|
};
|
32644
32594
|
}
|
32645
32595
|
if (apiRoute) {
|
32646
32596
|
apiRoutes.push(apiRoute);
|
32647
32597
|
if (isDynamic) {
|
32648
32598
|
dynamicRoutes.push(apiRoute);
|
32649
|
-
dynamicRoutesWithKeys.push({
|
32650
|
-
fileName,
|
32651
|
-
regex: apiRoute.src,
|
32652
|
-
routeKeys,
|
32653
|
-
});
|
32654
32599
|
}
|
32655
32600
|
}
|
32656
32601
|
addToUsedFunctions(apiBuilder);
|
@@ -32699,7 +32644,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32699
32644
|
defaultRoutes: null,
|
32700
32645
|
rewriteRoutes: null,
|
32701
32646
|
errorRoutes: null,
|
32702
|
-
|
32647
|
+
limitedRoutes: null,
|
32703
32648
|
};
|
32704
32649
|
}
|
32705
32650
|
// If `outputDirectory` is an empty string,
|
@@ -32736,7 +32681,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32736
32681
|
defaultRoutes: null,
|
32737
32682
|
rewriteRoutes: null,
|
32738
32683
|
errorRoutes: null,
|
32739
|
-
|
32684
|
+
limitedRoutes: null,
|
32740
32685
|
};
|
32741
32686
|
}
|
32742
32687
|
const builders = [];
|
@@ -32755,7 +32700,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32755
32700
|
});
|
32756
32701
|
}
|
32757
32702
|
}
|
32758
|
-
const routesResult = getRouteResult(apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
32703
|
+
const routesResult = getRouteResult(pkg, apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
32759
32704
|
return {
|
32760
32705
|
warnings,
|
32761
32706
|
builders: builders.length ? builders : null,
|
@@ -32764,7 +32709,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32764
32709
|
defaultRoutes: routesResult.defaultRoutes,
|
32765
32710
|
rewriteRoutes: routesResult.rewriteRoutes,
|
32766
32711
|
errorRoutes: routesResult.errorRoutes,
|
32767
|
-
|
32712
|
+
limitedRoutes: routesResult.limitedRoutes,
|
32768
32713
|
};
|
32769
32714
|
}
|
32770
32715
|
exports.detectBuilders = detectBuilders;
|
@@ -33019,7 +32964,6 @@ function getApiRoute(fileName, sortedFiles, options, absolutePathCache) {
|
|
33019
32964
|
return {
|
33020
32965
|
apiRoute: null,
|
33021
32966
|
isDynamic: false,
|
33022
|
-
routeKeys: {},
|
33023
32967
|
routeError: {
|
33024
32968
|
code: 'conflicting_path_segment',
|
33025
32969
|
message: `The segment "${conflictingSegment}" occurs more than ` +
|
@@ -33034,7 +32978,6 @@ function getApiRoute(fileName, sortedFiles, options, absolutePathCache) {
|
|
33034
32978
|
return {
|
33035
32979
|
apiRoute: null,
|
33036
32980
|
isDynamic: false,
|
33037
|
-
routeKeys: {},
|
33038
32981
|
routeError: {
|
33039
32982
|
code: 'conflicting_file_path',
|
33040
32983
|
message: `Two or more files have conflicting paths or names. ` +
|
@@ -33047,7 +32990,6 @@ function getApiRoute(fileName, sortedFiles, options, absolutePathCache) {
|
|
33047
32990
|
return {
|
33048
32991
|
apiRoute: out.route,
|
33049
32992
|
isDynamic: out.isDynamic,
|
33050
|
-
routeKeys: out.routeKeys,
|
33051
32993
|
routeError: null,
|
33052
32994
|
};
|
33053
32995
|
}
|
@@ -33157,7 +33099,6 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
33157
33099
|
const parts = filePath.split('/');
|
33158
33100
|
let counter = 1;
|
33159
33101
|
const query = [];
|
33160
|
-
const routeKeys = {};
|
33161
33102
|
let isDynamic = false;
|
33162
33103
|
const srcParts = parts.map((segment, i) => {
|
33163
33104
|
const name = getSegmentName(segment);
|
@@ -33165,7 +33106,6 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
33165
33106
|
if (name !== null) {
|
33166
33107
|
// We can't use `URLSearchParams` because `$` would get escaped
|
33167
33108
|
query.push(`${name}=$${counter++}`);
|
33168
|
-
routeKeys[name] = name;
|
33169
33109
|
isDynamic = true;
|
33170
33110
|
return `([^/]+)`;
|
33171
33111
|
}
|
@@ -33208,25 +33148,53 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
33208
33148
|
dest: `/${filePath}${queryString}`,
|
33209
33149
|
};
|
33210
33150
|
}
|
33211
|
-
return { route, isDynamic
|
33151
|
+
return { route, isDynamic };
|
33212
33152
|
}
|
33213
|
-
function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
33153
|
+
function getRouteResult(pkg, apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
33214
33154
|
var _a, _b;
|
33155
|
+
const deps = Object.assign({}, pkg === null || pkg === void 0 ? void 0 : pkg.dependencies, pkg === null || pkg === void 0 ? void 0 : pkg.devDependencies);
|
33215
33156
|
const defaultRoutes = [];
|
33216
33157
|
const redirectRoutes = [];
|
33217
33158
|
const rewriteRoutes = [];
|
33218
33159
|
const errorRoutes = [];
|
33160
|
+
const limitedRoutes = {
|
33161
|
+
defaultRoutes: [],
|
33162
|
+
redirectRoutes: [],
|
33163
|
+
rewriteRoutes: [],
|
33164
|
+
};
|
33219
33165
|
const framework = ((_a = frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.config) === null || _a === void 0 ? void 0 : _a.framework) || '';
|
33220
33166
|
const isNextjs = framework === 'nextjs' || _1.isOfficialRuntime('next', frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.use);
|
33221
33167
|
const ignoreRuntimes = (_b = slugToFramework.get(framework)) === null || _b === void 0 ? void 0 : _b.ignoreRuntimes;
|
33222
33168
|
if (apiRoutes && apiRoutes.length > 0) {
|
33223
33169
|
if (options.featHandleMiss) {
|
33170
|
+
// Exclude extension names if the corresponding plugin is not found in package.json
|
33171
|
+
// detectBuilders({ignoreRoutesForBuilders: ['@vercel/python']})
|
33172
|
+
// return a copy of routes.
|
33173
|
+
// We should exclud errorRoutes and
|
33224
33174
|
const extSet = detectApiExtensions(apiBuilders);
|
33175
|
+
const withTag = options.tag ? `@${options.tag}` : '';
|
33176
|
+
const extSetLimited = detectApiExtensions(apiBuilders.filter(b => {
|
33177
|
+
if (b.use === `@vercel/python${withTag}` &&
|
33178
|
+
!('vercel-plugin-python' in deps)) {
|
33179
|
+
return false;
|
33180
|
+
}
|
33181
|
+
if (b.use === `@vercel/go${withTag}` &&
|
33182
|
+
!('vercel-plugin-go' in deps)) {
|
33183
|
+
return false;
|
33184
|
+
}
|
33185
|
+
if (b.use === `@vercel/ruby${withTag}` &&
|
33186
|
+
!('vercel-plugin-ruby' in deps)) {
|
33187
|
+
return false;
|
33188
|
+
}
|
33189
|
+
return true;
|
33190
|
+
}));
|
33225
33191
|
if (extSet.size > 0) {
|
33226
|
-
const
|
33192
|
+
const extGroup = `(?:\\.(?:${Array.from(extSet)
|
33227
33193
|
.map(ext => ext.slice(1))
|
33228
|
-
.join('|')
|
33229
|
-
const
|
33194
|
+
.join('|')}))`;
|
33195
|
+
const extGroupLimited = `(?:\\.(?:${Array.from(extSetLimited)
|
33196
|
+
.map(ext => ext.slice(1))
|
33197
|
+
.join('|')}))`;
|
33230
33198
|
if (options.cleanUrls) {
|
33231
33199
|
redirectRoutes.push({
|
33232
33200
|
src: `^/(api(?:.+)?)/index${extGroup}?/?$`,
|
@@ -33240,6 +33208,18 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
33240
33208
|
},
|
33241
33209
|
status: 308,
|
33242
33210
|
});
|
33211
|
+
limitedRoutes.redirectRoutes.push({
|
33212
|
+
src: `^/(api(?:.+)?)/index${extGroupLimited}?/?$`,
|
33213
|
+
headers: { Location: options.trailingSlash ? '/$1/' : '/$1' },
|
33214
|
+
status: 308,
|
33215
|
+
});
|
33216
|
+
limitedRoutes.redirectRoutes.push({
|
33217
|
+
src: `^/api/(.+)${extGroupLimited}/?$`,
|
33218
|
+
headers: {
|
33219
|
+
Location: options.trailingSlash ? '/api/$1/' : '/api/$1',
|
33220
|
+
},
|
33221
|
+
status: 308,
|
33222
|
+
});
|
33243
33223
|
}
|
33244
33224
|
else {
|
33245
33225
|
defaultRoutes.push({ handle: 'miss' });
|
@@ -33248,9 +33228,16 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
33248
33228
|
dest: '/api/$1',
|
33249
33229
|
check: true,
|
33250
33230
|
});
|
33231
|
+
limitedRoutes.defaultRoutes.push({ handle: 'miss' });
|
33232
|
+
limitedRoutes.defaultRoutes.push({
|
33233
|
+
src: `^/api/(.+)${extGroupLimited}$`,
|
33234
|
+
dest: '/api/$1',
|
33235
|
+
check: true,
|
33236
|
+
});
|
33251
33237
|
}
|
33252
33238
|
}
|
33253
33239
|
rewriteRoutes.push(...dynamicRoutes);
|
33240
|
+
limitedRoutes.rewriteRoutes.push(...dynamicRoutes);
|
33254
33241
|
if (typeof ignoreRuntimes === 'undefined') {
|
33255
33242
|
// This route is only necessary to hide the directory listing
|
33256
33243
|
// to avoid enumerating serverless function names.
|
@@ -33295,6 +33282,7 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
33295
33282
|
redirectRoutes,
|
33296
33283
|
rewriteRoutes,
|
33297
33284
|
errorRoutes,
|
33285
|
+
limitedRoutes,
|
33298
33286
|
};
|
33299
33287
|
}
|
33300
33288
|
function sortFilesBySegmentCount(fileA, fileB) {
|
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.23",
|
4
4
|
"license": "MIT",
|
5
5
|
"main": "./dist/index.js",
|
6
6
|
"types": "./dist/index.d.js",
|
@@ -49,5 +49,5 @@
|
|
49
49
|
"typescript": "4.3.4",
|
50
50
|
"yazl": "2.4.3"
|
51
51
|
},
|
52
|
-
"gitHead": "
|
52
|
+
"gitHead": "7bd338618c80681a09cd8d4c482f1038f8676f7f"
|
53
53
|
}
|