@vercel/build-utils 2.12.3-canary.20 → 2.12.3-canary.24
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 +41 -6
- package/dist/convert-runtime-to-plugin.js +30 -14
- package/dist/detect-builders.d.ts +6 -0
- package/dist/detect-builders.js +58 -5
- package/dist/index.js +159 -23
- package/package.json +3 -3
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Lambda } from './lambda';
|
2
|
-
import type { BuildOptions } from './types';
|
2
|
+
import type { BuilderFunctions, BuildOptions } from './types';
|
3
3
|
/**
|
4
4
|
* Convert legacy Runtime to a Plugin.
|
5
5
|
* @param buildRuntime - a legacy build() function from a Runtime
|
@@ -7,7 +7,11 @@ import type { BuildOptions } from './types';
|
|
7
7
|
*/
|
8
8
|
export declare function convertRuntimeToPlugin(buildRuntime: (options: BuildOptions) => Promise<{
|
9
9
|
output: Lambda;
|
10
|
-
}>, ext: string): ({ workPath }: {
|
10
|
+
}>, ext: string): ({ vercelConfig, workPath, }: {
|
11
|
+
vercelConfig: {
|
12
|
+
functions?: BuilderFunctions;
|
13
|
+
regions?: string[];
|
14
|
+
};
|
11
15
|
workPath: string;
|
12
16
|
}) => Promise<void>;
|
13
17
|
/**
|
@@ -15,18 +19,41 @@ export declare function convertRuntimeToPlugin(buildRuntime: (options: BuildOpti
|
|
15
19
|
* property. Otherwise write a new file. This will also read `vercel.json`
|
16
20
|
* and apply relevant `functions` property config.
|
17
21
|
*/
|
18
|
-
export declare function updateFunctionsManifest({ workPath, pages, }: {
|
22
|
+
export declare function updateFunctionsManifest({ vercelConfig, workPath, pages, }: {
|
23
|
+
vercelConfig: {
|
24
|
+
functions?: BuilderFunctions;
|
25
|
+
regions?: string[];
|
26
|
+
};
|
19
27
|
workPath: string;
|
20
28
|
pages: {
|
21
29
|
[key: string]: any;
|
22
30
|
};
|
23
31
|
}): Promise<void>;
|
24
32
|
/**
|
25
|
-
*
|
26
|
-
* If the file does not exist, it
|
33
|
+
* Append routes to the `routes-manifest.json` file.
|
34
|
+
* If the file does not exist, it will be created.
|
27
35
|
*/
|
28
|
-
export declare function updateRoutesManifest({ workPath, dynamicRoutes, }: {
|
36
|
+
export declare function updateRoutesManifest({ workPath, redirects, rewrites, headers, dynamicRoutes, staticRoutes, }: {
|
29
37
|
workPath: string;
|
38
|
+
redirects?: {
|
39
|
+
source: string;
|
40
|
+
destination: string;
|
41
|
+
statusCode: number;
|
42
|
+
regex: string;
|
43
|
+
}[];
|
44
|
+
rewrites?: {
|
45
|
+
source: string;
|
46
|
+
destination: string;
|
47
|
+
regex: string;
|
48
|
+
}[];
|
49
|
+
headers?: {
|
50
|
+
source: string;
|
51
|
+
headers: {
|
52
|
+
key: string;
|
53
|
+
value: string;
|
54
|
+
}[];
|
55
|
+
regex: string;
|
56
|
+
}[];
|
30
57
|
dynamicRoutes?: {
|
31
58
|
page: string;
|
32
59
|
regex: string;
|
@@ -35,4 +62,12 @@ export declare function updateRoutesManifest({ workPath, dynamicRoutes, }: {
|
|
35
62
|
[named: string]: string;
|
36
63
|
};
|
37
64
|
}[];
|
65
|
+
staticRoutes?: {
|
66
|
+
page: string;
|
67
|
+
regex: string;
|
68
|
+
namedRegex?: string;
|
69
|
+
routeKeys?: {
|
70
|
+
[named: string]: string;
|
71
|
+
};
|
72
|
+
}[];
|
38
73
|
}): Promise<void>;
|
@@ -16,13 +16,14 @@ const minimatch_1 = __importDefault(require("minimatch"));
|
|
16
16
|
* @param ext - the file extension, for example `.py`
|
17
17
|
*/
|
18
18
|
function convertRuntimeToPlugin(buildRuntime, ext) {
|
19
|
-
|
19
|
+
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
20
|
+
return async function build({ vercelConfig, workPath, }) {
|
20
21
|
const opts = { cwd: workPath };
|
21
22
|
const files = await glob_1.default('**', opts);
|
22
23
|
delete files['vercel.json']; // Builders/Runtimes didn't have vercel.json
|
23
24
|
const entrypoints = await glob_1.default(`api/**/*${ext}`, opts);
|
24
25
|
const pages = {};
|
25
|
-
const { functions = {} } =
|
26
|
+
const { functions = {} } = vercelConfig;
|
26
27
|
const traceDir = path_1.join(workPath, '.output', 'runtime-traced-files');
|
27
28
|
await fs_extra_1.default.ensureDir(traceDir);
|
28
29
|
for (const entrypoint of Object.keys(entrypoints)) {
|
@@ -45,7 +46,7 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
45
46
|
maxDuration: output.maxDuration,
|
46
47
|
environment: output.environment,
|
47
48
|
allowQuery: output.allowQuery,
|
48
|
-
regions: output.regions,
|
49
|
+
//regions: output.regions,
|
49
50
|
};
|
50
51
|
// @ts-ignore This symbol is a private API
|
51
52
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
@@ -78,7 +79,7 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
78
79
|
await fs_extra_1.default.ensureDir(path_1.dirname(nft));
|
79
80
|
await fs_extra_1.default.writeFile(nft, json);
|
80
81
|
}
|
81
|
-
await updateFunctionsManifest({ workPath, pages });
|
82
|
+
await updateFunctionsManifest({ vercelConfig, workPath, pages });
|
82
83
|
};
|
83
84
|
}
|
84
85
|
exports.convertRuntimeToPlugin = convertRuntimeToPlugin;
|
@@ -104,18 +105,13 @@ async function readJson(filePath) {
|
|
104
105
|
throw err;
|
105
106
|
}
|
106
107
|
}
|
107
|
-
async function readVercelConfig(workPath) {
|
108
|
-
const vercelJsonPath = path_1.join(workPath, 'vercel.json');
|
109
|
-
return readJson(vercelJsonPath);
|
110
|
-
}
|
111
108
|
/**
|
112
109
|
* If `.output/functions-manifest.json` exists, append to the pages
|
113
110
|
* property. Otherwise write a new file. This will also read `vercel.json`
|
114
111
|
* and apply relevant `functions` property config.
|
115
112
|
*/
|
116
|
-
async function updateFunctionsManifest({ workPath, pages, }) {
|
113
|
+
async function updateFunctionsManifest({ vercelConfig, workPath, pages, }) {
|
117
114
|
const functionsManifestPath = path_1.join(workPath, '.output', 'functions-manifest.json');
|
118
|
-
const vercelConfig = await readVercelConfig(workPath);
|
119
115
|
const functionsManifest = await readJson(functionsManifestPath);
|
120
116
|
if (!functionsManifest.version)
|
121
117
|
functionsManifest.version = 1;
|
@@ -137,21 +133,41 @@ async function updateFunctionsManifest({ workPath, pages, }) {
|
|
137
133
|
}
|
138
134
|
exports.updateFunctionsManifest = updateFunctionsManifest;
|
139
135
|
/**
|
140
|
-
*
|
141
|
-
* If the file does not exist, it
|
136
|
+
* Append routes to the `routes-manifest.json` file.
|
137
|
+
* If the file does not exist, it will be created.
|
142
138
|
*/
|
143
|
-
async function updateRoutesManifest({ workPath, dynamicRoutes, }) {
|
139
|
+
async function updateRoutesManifest({ workPath, redirects, rewrites, headers, dynamicRoutes, staticRoutes, }) {
|
144
140
|
const routesManifestPath = path_1.join(workPath, '.output', 'routes-manifest.json');
|
145
141
|
const routesManifest = await readJson(routesManifestPath);
|
146
142
|
if (!routesManifest.version)
|
147
|
-
routesManifest.version =
|
143
|
+
routesManifest.version = 3;
|
148
144
|
if (routesManifest.pages404 === undefined)
|
149
145
|
routesManifest.pages404 = true;
|
146
|
+
if (redirects) {
|
147
|
+
if (!routesManifest.redirects)
|
148
|
+
routesManifest.redirects = [];
|
149
|
+
routesManifest.redirects.push(...redirects);
|
150
|
+
}
|
151
|
+
if (rewrites) {
|
152
|
+
if (!routesManifest.rewrites)
|
153
|
+
routesManifest.rewrites = [];
|
154
|
+
routesManifest.rewrites.push(...rewrites);
|
155
|
+
}
|
156
|
+
if (headers) {
|
157
|
+
if (!routesManifest.headers)
|
158
|
+
routesManifest.headers = [];
|
159
|
+
routesManifest.headers.push(...headers);
|
160
|
+
}
|
150
161
|
if (dynamicRoutes) {
|
151
162
|
if (!routesManifest.dynamicRoutes)
|
152
163
|
routesManifest.dynamicRoutes = [];
|
153
164
|
routesManifest.dynamicRoutes.push(...dynamicRoutes);
|
154
165
|
}
|
166
|
+
if (staticRoutes) {
|
167
|
+
if (!routesManifest.staticRoutes)
|
168
|
+
routesManifest.staticRoutes = [];
|
169
|
+
routesManifest.staticRoutes.push(...staticRoutes);
|
170
|
+
}
|
155
171
|
await fs_extra_1.default.writeFile(routesManifestPath, JSON.stringify(routesManifest));
|
156
172
|
}
|
157
173
|
exports.updateRoutesManifest = updateRoutesManifest;
|
@@ -34,5 +34,11 @@ export declare function detectBuilders(files: string[], pkg?: PackageJson | unde
|
|
34
34
|
redirectRoutes: Route[] | null;
|
35
35
|
rewriteRoutes: Route[] | null;
|
36
36
|
errorRoutes: Route[] | null;
|
37
|
+
limitedRoutes: LimitedRoutes | null;
|
37
38
|
}>;
|
39
|
+
interface LimitedRoutes {
|
40
|
+
defaultRoutes: Route[];
|
41
|
+
redirectRoutes: Route[];
|
42
|
+
rewriteRoutes: Route[];
|
43
|
+
}
|
38
44
|
export {};
|
package/dist/detect-builders.js
CHANGED
@@ -66,6 +66,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
66
66
|
redirectRoutes: null,
|
67
67
|
rewriteRoutes: null,
|
68
68
|
errorRoutes: null,
|
69
|
+
limitedRoutes: null,
|
69
70
|
};
|
70
71
|
}
|
71
72
|
const sortedFiles = files.sort(sortFiles);
|
@@ -113,6 +114,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
113
114
|
redirectRoutes: null,
|
114
115
|
rewriteRoutes: null,
|
115
116
|
errorRoutes: null,
|
117
|
+
limitedRoutes: null,
|
116
118
|
};
|
117
119
|
}
|
118
120
|
if (apiRoute) {
|
@@ -167,6 +169,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
167
169
|
defaultRoutes: null,
|
168
170
|
rewriteRoutes: null,
|
169
171
|
errorRoutes: null,
|
172
|
+
limitedRoutes: null,
|
170
173
|
};
|
171
174
|
}
|
172
175
|
// If `outputDirectory` is an empty string,
|
@@ -203,6 +206,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
203
206
|
defaultRoutes: null,
|
204
207
|
rewriteRoutes: null,
|
205
208
|
errorRoutes: null,
|
209
|
+
limitedRoutes: null,
|
206
210
|
};
|
207
211
|
}
|
208
212
|
const builders = [];
|
@@ -221,7 +225,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
221
225
|
});
|
222
226
|
}
|
223
227
|
}
|
224
|
-
const routesResult = getRouteResult(apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
228
|
+
const routesResult = getRouteResult(pkg, apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
225
229
|
return {
|
226
230
|
warnings,
|
227
231
|
builders: builders.length ? builders : null,
|
@@ -230,6 +234,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
230
234
|
defaultRoutes: routesResult.defaultRoutes,
|
231
235
|
rewriteRoutes: routesResult.rewriteRoutes,
|
232
236
|
errorRoutes: routesResult.errorRoutes,
|
237
|
+
limitedRoutes: routesResult.limitedRoutes,
|
233
238
|
};
|
234
239
|
}
|
235
240
|
exports.detectBuilders = detectBuilders;
|
@@ -670,23 +675,51 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
670
675
|
}
|
671
676
|
return { route, isDynamic };
|
672
677
|
}
|
673
|
-
function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
678
|
+
function getRouteResult(pkg, apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
674
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);
|
675
681
|
const defaultRoutes = [];
|
676
682
|
const redirectRoutes = [];
|
677
683
|
const rewriteRoutes = [];
|
678
684
|
const errorRoutes = [];
|
685
|
+
const limitedRoutes = {
|
686
|
+
defaultRoutes: [],
|
687
|
+
redirectRoutes: [],
|
688
|
+
rewriteRoutes: [],
|
689
|
+
};
|
679
690
|
const framework = ((_a = frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.config) === null || _a === void 0 ? void 0 : _a.framework) || '';
|
680
691
|
const isNextjs = framework === 'nextjs' || _1.isOfficialRuntime('next', frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.use);
|
681
692
|
const ignoreRuntimes = (_b = slugToFramework.get(framework)) === null || _b === void 0 ? void 0 : _b.ignoreRuntimes;
|
682
693
|
if (apiRoutes && apiRoutes.length > 0) {
|
683
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
|
684
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
|
+
}));
|
685
716
|
if (extSet.size > 0) {
|
686
|
-
const
|
717
|
+
const extGroup = `(?:\\.(?:${Array.from(extSet)
|
687
718
|
.map(ext => ext.slice(1))
|
688
|
-
.join('|')
|
689
|
-
const
|
719
|
+
.join('|')}))`;
|
720
|
+
const extGroupLimited = `(?:\\.(?:${Array.from(extSetLimited)
|
721
|
+
.map(ext => ext.slice(1))
|
722
|
+
.join('|')}))`;
|
690
723
|
if (options.cleanUrls) {
|
691
724
|
redirectRoutes.push({
|
692
725
|
src: `^/(api(?:.+)?)/index${extGroup}?/?$`,
|
@@ -700,6 +733,18 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
700
733
|
},
|
701
734
|
status: 308,
|
702
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
|
+
});
|
703
748
|
}
|
704
749
|
else {
|
705
750
|
defaultRoutes.push({ handle: 'miss' });
|
@@ -708,9 +753,16 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
708
753
|
dest: '/api/$1',
|
709
754
|
check: true,
|
710
755
|
});
|
756
|
+
limitedRoutes.defaultRoutes.push({ handle: 'miss' });
|
757
|
+
limitedRoutes.defaultRoutes.push({
|
758
|
+
src: `^/api/(.+)${extGroupLimited}$`,
|
759
|
+
dest: '/api/$1',
|
760
|
+
check: true,
|
761
|
+
});
|
711
762
|
}
|
712
763
|
}
|
713
764
|
rewriteRoutes.push(...dynamicRoutes);
|
765
|
+
limitedRoutes.rewriteRoutes.push(...dynamicRoutes);
|
714
766
|
if (typeof ignoreRuntimes === 'undefined') {
|
715
767
|
// This route is only necessary to hide the directory listing
|
716
768
|
// to avoid enumerating serverless function names.
|
@@ -755,6 +807,7 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
755
807
|
redirectRoutes,
|
756
808
|
rewriteRoutes,
|
757
809
|
errorRoutes,
|
810
|
+
limitedRoutes,
|
758
811
|
};
|
759
812
|
}
|
760
813
|
function sortFilesBySegmentCount(fileA, fileB) {
|
package/dist/index.js
CHANGED
@@ -26195,7 +26195,7 @@ exports.frameworks = [
|
|
26195
26195
|
tagline: 'Gatsby helps developers build blazing fast websites and apps with React.',
|
26196
26196
|
description: 'A Gatsby app, using the default starter theme and a Serverless Function API.',
|
26197
26197
|
website: 'https://gatsbyjs.org',
|
26198
|
-
sort:
|
26198
|
+
sort: 5,
|
26199
26199
|
envPrefix: 'GATSBY_',
|
26200
26200
|
detectors: {
|
26201
26201
|
every: [
|
@@ -26270,6 +26270,73 @@ exports.frameworks = [
|
|
26270
26270
|
},
|
26271
26271
|
cachePattern: '{.cache,public}/**',
|
26272
26272
|
},
|
26273
|
+
{
|
26274
|
+
name: 'Remix',
|
26275
|
+
slug: 'remix',
|
26276
|
+
demo: 'https://remix.examples.vercel.com',
|
26277
|
+
logo: 'https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/remix.svg',
|
26278
|
+
tagline: 'Build Better Websites',
|
26279
|
+
description: 'A new Remix app — the result of running `npx create-remix`.',
|
26280
|
+
website: 'https://remix.run',
|
26281
|
+
sort: 6,
|
26282
|
+
detectors: {
|
26283
|
+
every: [
|
26284
|
+
{
|
26285
|
+
path: 'package.json',
|
26286
|
+
matchContent: '"(dev)?(d|D)ependencies":\\s*{[^}]*"remix":\\s*".+?"[^}]*}',
|
26287
|
+
},
|
26288
|
+
],
|
26289
|
+
},
|
26290
|
+
settings: {
|
26291
|
+
installCommand: {
|
26292
|
+
placeholder: '`yarn install` or `npm install`',
|
26293
|
+
},
|
26294
|
+
buildCommand: {
|
26295
|
+
value: 'remix build',
|
26296
|
+
placeholder: '`npm run build` or `remix build`',
|
26297
|
+
},
|
26298
|
+
devCommand: {
|
26299
|
+
value: 'remix dev',
|
26300
|
+
placeholder: 'remix dev',
|
26301
|
+
},
|
26302
|
+
outputDirectory: {
|
26303
|
+
value: 'public',
|
26304
|
+
},
|
26305
|
+
},
|
26306
|
+
dependency: 'remix',
|
26307
|
+
getFsOutputDir: async () => 'public',
|
26308
|
+
getOutputDirName: async () => 'public',
|
26309
|
+
defaultRoutes: [
|
26310
|
+
{
|
26311
|
+
src: '^/build/(.*)$',
|
26312
|
+
headers: { 'cache-control': 'public, max-age=31536000, immutable' },
|
26313
|
+
continue: true,
|
26314
|
+
},
|
26315
|
+
{
|
26316
|
+
handle: 'filesystem',
|
26317
|
+
},
|
26318
|
+
{
|
26319
|
+
src: '/(.*)',
|
26320
|
+
dest: '/api',
|
26321
|
+
},
|
26322
|
+
],
|
26323
|
+
defaultRewrites: [
|
26324
|
+
{
|
26325
|
+
source: '/(.*)',
|
26326
|
+
regex: '/(.*)',
|
26327
|
+
destination: '/api',
|
26328
|
+
},
|
26329
|
+
],
|
26330
|
+
defaultHeaders: [
|
26331
|
+
{
|
26332
|
+
source: '/build/(.*)',
|
26333
|
+
regex: '/build/(.*)',
|
26334
|
+
headers: [
|
26335
|
+
{ key: 'cache-control', value: 'public, max-age=31536000, immutable' },
|
26336
|
+
],
|
26337
|
+
},
|
26338
|
+
]
|
26339
|
+
},
|
26273
26340
|
{
|
26274
26341
|
name: 'Hexo',
|
26275
26342
|
slug: 'hexo',
|
@@ -26278,7 +26345,6 @@ exports.frameworks = [
|
|
26278
26345
|
tagline: 'Hexo is a fast, simple & powerful blog framework powered by Node.js.',
|
26279
26346
|
description: 'A Hexo site, created with the Hexo CLI.',
|
26280
26347
|
website: 'https://hexo.io',
|
26281
|
-
sort: 3,
|
26282
26348
|
detectors: {
|
26283
26349
|
every: [
|
26284
26350
|
{
|
@@ -26315,7 +26381,6 @@ exports.frameworks = [
|
|
26315
26381
|
tagline: '11ty is a simpler static site generator written in JavaScript, created to be an alternative to Jekyll.',
|
26316
26382
|
description: 'An Eleventy site, created with npm init.',
|
26317
26383
|
website: 'https://www.11ty.dev',
|
26318
|
-
sort: 4,
|
26319
26384
|
detectors: {
|
26320
26385
|
every: [
|
26321
26386
|
{
|
@@ -27027,6 +27092,7 @@ exports.frameworks = [
|
|
27027
27092
|
tagline: 'Svelte lets you write high performance reactive apps with significantly less boilerplate.',
|
27028
27093
|
description: 'A basic Svelte app using the default template.',
|
27029
27094
|
website: 'https://svelte.dev',
|
27095
|
+
sort: 3,
|
27030
27096
|
detectors: {
|
27031
27097
|
every: [
|
27032
27098
|
{
|
@@ -27216,6 +27282,7 @@ exports.frameworks = [
|
|
27216
27282
|
tagline: 'Create React App allows you to get going with React in no time.',
|
27217
27283
|
description: 'A React app, bootstrapped with create-react-app, and a Serverless Function API.',
|
27218
27284
|
website: 'https://create-react-app.dev',
|
27285
|
+
sort: 4,
|
27219
27286
|
envPrefix: 'REACT_APP_',
|
27220
27287
|
detectors: {
|
27221
27288
|
some: [
|
@@ -27597,6 +27664,7 @@ exports.frameworks = [
|
|
27597
27664
|
tagline: 'Nuxt.js is the web comprehensive framework that lets you dream big with Vue.js.',
|
27598
27665
|
description: 'A Nuxt.js app, bootstrapped with create-nuxt-app.',
|
27599
27666
|
website: 'https://nuxtjs.org',
|
27667
|
+
sort: 2,
|
27600
27668
|
envPrefix: 'NUXT_ENV_',
|
27601
27669
|
detectors: {
|
27602
27670
|
every: [
|
@@ -27690,7 +27758,6 @@ exports.frameworks = [
|
|
27690
27758
|
tagline: 'Hugo is the world’s fastest framework for building websites, written in Go.',
|
27691
27759
|
description: 'A Hugo site, created with the Hugo CLI.',
|
27692
27760
|
website: 'https://gohugo.io',
|
27693
|
-
sort: 5,
|
27694
27761
|
detectors: {
|
27695
27762
|
some: [
|
27696
27763
|
{
|
@@ -32226,13 +32293,14 @@ const minimatch_1 = __importDefault(__webpack_require__(9566));
|
|
32226
32293
|
* @param ext - the file extension, for example `.py`
|
32227
32294
|
*/
|
32228
32295
|
function convertRuntimeToPlugin(buildRuntime, ext) {
|
32229
|
-
|
32296
|
+
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
32297
|
+
return async function build({ vercelConfig, workPath, }) {
|
32230
32298
|
const opts = { cwd: workPath };
|
32231
32299
|
const files = await glob_1.default('**', opts);
|
32232
32300
|
delete files['vercel.json']; // Builders/Runtimes didn't have vercel.json
|
32233
32301
|
const entrypoints = await glob_1.default(`api/**/*${ext}`, opts);
|
32234
32302
|
const pages = {};
|
32235
|
-
const { functions = {} } =
|
32303
|
+
const { functions = {} } = vercelConfig;
|
32236
32304
|
const traceDir = path_1.join(workPath, '.output', 'runtime-traced-files');
|
32237
32305
|
await fs_extra_1.default.ensureDir(traceDir);
|
32238
32306
|
for (const entrypoint of Object.keys(entrypoints)) {
|
@@ -32255,7 +32323,7 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
32255
32323
|
maxDuration: output.maxDuration,
|
32256
32324
|
environment: output.environment,
|
32257
32325
|
allowQuery: output.allowQuery,
|
32258
|
-
regions: output.regions,
|
32326
|
+
//regions: output.regions,
|
32259
32327
|
};
|
32260
32328
|
// @ts-ignore This symbol is a private API
|
32261
32329
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
@@ -32288,7 +32356,7 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
32288
32356
|
await fs_extra_1.default.ensureDir(path_1.dirname(nft));
|
32289
32357
|
await fs_extra_1.default.writeFile(nft, json);
|
32290
32358
|
}
|
32291
|
-
await updateFunctionsManifest({ workPath, pages });
|
32359
|
+
await updateFunctionsManifest({ vercelConfig, workPath, pages });
|
32292
32360
|
};
|
32293
32361
|
}
|
32294
32362
|
exports.convertRuntimeToPlugin = convertRuntimeToPlugin;
|
@@ -32314,18 +32382,13 @@ async function readJson(filePath) {
|
|
32314
32382
|
throw err;
|
32315
32383
|
}
|
32316
32384
|
}
|
32317
|
-
async function readVercelConfig(workPath) {
|
32318
|
-
const vercelJsonPath = path_1.join(workPath, 'vercel.json');
|
32319
|
-
return readJson(vercelJsonPath);
|
32320
|
-
}
|
32321
32385
|
/**
|
32322
32386
|
* If `.output/functions-manifest.json` exists, append to the pages
|
32323
32387
|
* property. Otherwise write a new file. This will also read `vercel.json`
|
32324
32388
|
* and apply relevant `functions` property config.
|
32325
32389
|
*/
|
32326
|
-
async function updateFunctionsManifest({ workPath, pages, }) {
|
32390
|
+
async function updateFunctionsManifest({ vercelConfig, workPath, pages, }) {
|
32327
32391
|
const functionsManifestPath = path_1.join(workPath, '.output', 'functions-manifest.json');
|
32328
|
-
const vercelConfig = await readVercelConfig(workPath);
|
32329
32392
|
const functionsManifest = await readJson(functionsManifestPath);
|
32330
32393
|
if (!functionsManifest.version)
|
32331
32394
|
functionsManifest.version = 1;
|
@@ -32347,21 +32410,41 @@ async function updateFunctionsManifest({ workPath, pages, }) {
|
|
32347
32410
|
}
|
32348
32411
|
exports.updateFunctionsManifest = updateFunctionsManifest;
|
32349
32412
|
/**
|
32350
|
-
*
|
32351
|
-
* If the file does not exist, it
|
32413
|
+
* Append routes to the `routes-manifest.json` file.
|
32414
|
+
* If the file does not exist, it will be created.
|
32352
32415
|
*/
|
32353
|
-
async function updateRoutesManifest({ workPath, dynamicRoutes, }) {
|
32416
|
+
async function updateRoutesManifest({ workPath, redirects, rewrites, headers, dynamicRoutes, staticRoutes, }) {
|
32354
32417
|
const routesManifestPath = path_1.join(workPath, '.output', 'routes-manifest.json');
|
32355
32418
|
const routesManifest = await readJson(routesManifestPath);
|
32356
32419
|
if (!routesManifest.version)
|
32357
|
-
routesManifest.version =
|
32420
|
+
routesManifest.version = 3;
|
32358
32421
|
if (routesManifest.pages404 === undefined)
|
32359
32422
|
routesManifest.pages404 = true;
|
32423
|
+
if (redirects) {
|
32424
|
+
if (!routesManifest.redirects)
|
32425
|
+
routesManifest.redirects = [];
|
32426
|
+
routesManifest.redirects.push(...redirects);
|
32427
|
+
}
|
32428
|
+
if (rewrites) {
|
32429
|
+
if (!routesManifest.rewrites)
|
32430
|
+
routesManifest.rewrites = [];
|
32431
|
+
routesManifest.rewrites.push(...rewrites);
|
32432
|
+
}
|
32433
|
+
if (headers) {
|
32434
|
+
if (!routesManifest.headers)
|
32435
|
+
routesManifest.headers = [];
|
32436
|
+
routesManifest.headers.push(...headers);
|
32437
|
+
}
|
32360
32438
|
if (dynamicRoutes) {
|
32361
32439
|
if (!routesManifest.dynamicRoutes)
|
32362
32440
|
routesManifest.dynamicRoutes = [];
|
32363
32441
|
routesManifest.dynamicRoutes.push(...dynamicRoutes);
|
32364
32442
|
}
|
32443
|
+
if (staticRoutes) {
|
32444
|
+
if (!routesManifest.staticRoutes)
|
32445
|
+
routesManifest.staticRoutes = [];
|
32446
|
+
routesManifest.staticRoutes.push(...staticRoutes);
|
32447
|
+
}
|
32365
32448
|
await fs_extra_1.default.writeFile(routesManifestPath, JSON.stringify(routesManifest));
|
32366
32449
|
}
|
32367
32450
|
exports.updateRoutesManifest = updateRoutesManifest;
|
@@ -32458,6 +32541,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32458
32541
|
redirectRoutes: null,
|
32459
32542
|
rewriteRoutes: null,
|
32460
32543
|
errorRoutes: null,
|
32544
|
+
limitedRoutes: null,
|
32461
32545
|
};
|
32462
32546
|
}
|
32463
32547
|
const sortedFiles = files.sort(sortFiles);
|
@@ -32505,6 +32589,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32505
32589
|
redirectRoutes: null,
|
32506
32590
|
rewriteRoutes: null,
|
32507
32591
|
errorRoutes: null,
|
32592
|
+
limitedRoutes: null,
|
32508
32593
|
};
|
32509
32594
|
}
|
32510
32595
|
if (apiRoute) {
|
@@ -32559,6 +32644,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32559
32644
|
defaultRoutes: null,
|
32560
32645
|
rewriteRoutes: null,
|
32561
32646
|
errorRoutes: null,
|
32647
|
+
limitedRoutes: null,
|
32562
32648
|
};
|
32563
32649
|
}
|
32564
32650
|
// If `outputDirectory` is an empty string,
|
@@ -32595,6 +32681,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32595
32681
|
defaultRoutes: null,
|
32596
32682
|
rewriteRoutes: null,
|
32597
32683
|
errorRoutes: null,
|
32684
|
+
limitedRoutes: null,
|
32598
32685
|
};
|
32599
32686
|
}
|
32600
32687
|
const builders = [];
|
@@ -32613,7 +32700,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32613
32700
|
});
|
32614
32701
|
}
|
32615
32702
|
}
|
32616
|
-
const routesResult = getRouteResult(apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
32703
|
+
const routesResult = getRouteResult(pkg, apiRoutes, dynamicRoutes, usedOutputDirectory, apiBuilders, frontendBuilder, options);
|
32617
32704
|
return {
|
32618
32705
|
warnings,
|
32619
32706
|
builders: builders.length ? builders : null,
|
@@ -32622,6 +32709,7 @@ async function detectBuilders(files, pkg, options = {}) {
|
|
32622
32709
|
defaultRoutes: routesResult.defaultRoutes,
|
32623
32710
|
rewriteRoutes: routesResult.rewriteRoutes,
|
32624
32711
|
errorRoutes: routesResult.errorRoutes,
|
32712
|
+
limitedRoutes: routesResult.limitedRoutes,
|
32625
32713
|
};
|
32626
32714
|
}
|
32627
32715
|
exports.detectBuilders = detectBuilders;
|
@@ -33062,23 +33150,51 @@ function createRouteFromPath(filePath, featHandleMiss, cleanUrls) {
|
|
33062
33150
|
}
|
33063
33151
|
return { route, isDynamic };
|
33064
33152
|
}
|
33065
|
-
function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
33153
|
+
function getRouteResult(pkg, apiRoutes, dynamicRoutes, outputDirectory, apiBuilders, frontendBuilder, options) {
|
33066
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);
|
33067
33156
|
const defaultRoutes = [];
|
33068
33157
|
const redirectRoutes = [];
|
33069
33158
|
const rewriteRoutes = [];
|
33070
33159
|
const errorRoutes = [];
|
33160
|
+
const limitedRoutes = {
|
33161
|
+
defaultRoutes: [],
|
33162
|
+
redirectRoutes: [],
|
33163
|
+
rewriteRoutes: [],
|
33164
|
+
};
|
33071
33165
|
const framework = ((_a = frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.config) === null || _a === void 0 ? void 0 : _a.framework) || '';
|
33072
33166
|
const isNextjs = framework === 'nextjs' || _1.isOfficialRuntime('next', frontendBuilder === null || frontendBuilder === void 0 ? void 0 : frontendBuilder.use);
|
33073
33167
|
const ignoreRuntimes = (_b = slugToFramework.get(framework)) === null || _b === void 0 ? void 0 : _b.ignoreRuntimes;
|
33074
33168
|
if (apiRoutes && apiRoutes.length > 0) {
|
33075
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
|
33076
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
|
+
}));
|
33077
33191
|
if (extSet.size > 0) {
|
33078
|
-
const
|
33192
|
+
const extGroup = `(?:\\.(?:${Array.from(extSet)
|
33193
|
+
.map(ext => ext.slice(1))
|
33194
|
+
.join('|')}))`;
|
33195
|
+
const extGroupLimited = `(?:\\.(?:${Array.from(extSetLimited)
|
33079
33196
|
.map(ext => ext.slice(1))
|
33080
|
-
.join('|')
|
33081
|
-
const extGroup = `(?:\\.(?:${exts}))`;
|
33197
|
+
.join('|')}))`;
|
33082
33198
|
if (options.cleanUrls) {
|
33083
33199
|
redirectRoutes.push({
|
33084
33200
|
src: `^/(api(?:.+)?)/index${extGroup}?/?$`,
|
@@ -33092,6 +33208,18 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
33092
33208
|
},
|
33093
33209
|
status: 308,
|
33094
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
|
+
});
|
33095
33223
|
}
|
33096
33224
|
else {
|
33097
33225
|
defaultRoutes.push({ handle: 'miss' });
|
@@ -33100,9 +33228,16 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
33100
33228
|
dest: '/api/$1',
|
33101
33229
|
check: true,
|
33102
33230
|
});
|
33231
|
+
limitedRoutes.defaultRoutes.push({ handle: 'miss' });
|
33232
|
+
limitedRoutes.defaultRoutes.push({
|
33233
|
+
src: `^/api/(.+)${extGroupLimited}$`,
|
33234
|
+
dest: '/api/$1',
|
33235
|
+
check: true,
|
33236
|
+
});
|
33103
33237
|
}
|
33104
33238
|
}
|
33105
33239
|
rewriteRoutes.push(...dynamicRoutes);
|
33240
|
+
limitedRoutes.rewriteRoutes.push(...dynamicRoutes);
|
33106
33241
|
if (typeof ignoreRuntimes === 'undefined') {
|
33107
33242
|
// This route is only necessary to hide the directory listing
|
33108
33243
|
// to avoid enumerating serverless function names.
|
@@ -33147,6 +33282,7 @@ function getRouteResult(apiRoutes, dynamicRoutes, outputDirectory, apiBuilders,
|
|
33147
33282
|
redirectRoutes,
|
33148
33283
|
rewriteRoutes,
|
33149
33284
|
errorRoutes,
|
33285
|
+
limitedRoutes,
|
33150
33286
|
};
|
33151
33287
|
}
|
33152
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.24",
|
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.14",
|
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": "3559531e4c14875a275059e3f43aeba38deda275"
|
53
53
|
}
|