@vercel/build-utils 2.12.3-canary.2 → 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.
- package/dist/convert-runtime-to-plugin.d.ts +73 -0
- package/dist/convert-runtime-to-plugin.js +173 -0
- package/dist/detect-builders.d.ts +6 -0
- package/dist/detect-builders.js +58 -5
- package/dist/fs/glob.js +2 -1
- package/dist/fs/normalize-path.d.ts +4 -0
- package/dist/fs/normalize-path.js +11 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4300 -3523
- package/dist/lambda.d.ts +7 -3
- package/dist/lambda.js +14 -4
- package/dist/prerender.d.ts +3 -1
- package/dist/prerender.js +10 -1
- package/dist/types.d.ts +1 -0
- package/package.json +6 -6
@@ -0,0 +1,73 @@
|
|
1
|
+
import { Lambda } from './lambda';
|
2
|
+
import type { BuilderFunctions, BuildOptions } from './types';
|
3
|
+
/**
|
4
|
+
* Convert legacy Runtime to a Plugin.
|
5
|
+
* @param buildRuntime - a legacy build() function from a Runtime
|
6
|
+
* @param ext - the file extension, for example `.py`
|
7
|
+
*/
|
8
|
+
export declare function convertRuntimeToPlugin(buildRuntime: (options: BuildOptions) => Promise<{
|
9
|
+
output: Lambda;
|
10
|
+
}>, ext: string): ({ vercelConfig, workPath, }: {
|
11
|
+
vercelConfig: {
|
12
|
+
functions?: BuilderFunctions;
|
13
|
+
regions?: string[];
|
14
|
+
};
|
15
|
+
workPath: string;
|
16
|
+
}) => Promise<void>;
|
17
|
+
/**
|
18
|
+
* If `.output/functions-manifest.json` exists, append to the pages
|
19
|
+
* property. Otherwise write a new file. This will also read `vercel.json`
|
20
|
+
* and apply relevant `functions` property config.
|
21
|
+
*/
|
22
|
+
export declare function updateFunctionsManifest({ vercelConfig, workPath, pages, }: {
|
23
|
+
vercelConfig: {
|
24
|
+
functions?: BuilderFunctions;
|
25
|
+
regions?: string[];
|
26
|
+
};
|
27
|
+
workPath: string;
|
28
|
+
pages: {
|
29
|
+
[key: string]: any;
|
30
|
+
};
|
31
|
+
}): Promise<void>;
|
32
|
+
/**
|
33
|
+
* Append routes to the `routes-manifest.json` file.
|
34
|
+
* If the file does not exist, it will be created.
|
35
|
+
*/
|
36
|
+
export declare function updateRoutesManifest({ workPath, redirects, rewrites, headers, dynamicRoutes, staticRoutes, }: {
|
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
|
+
}[];
|
57
|
+
dynamicRoutes?: {
|
58
|
+
page: string;
|
59
|
+
regex: string;
|
60
|
+
namedRegex?: string;
|
61
|
+
routeKeys?: {
|
62
|
+
[named: string]: string;
|
63
|
+
};
|
64
|
+
}[];
|
65
|
+
staticRoutes?: {
|
66
|
+
page: string;
|
67
|
+
regex: string;
|
68
|
+
namedRegex?: string;
|
69
|
+
routeKeys?: {
|
70
|
+
[named: string]: string;
|
71
|
+
};
|
72
|
+
}[];
|
73
|
+
}): Promise<void>;
|
@@ -0,0 +1,173 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.updateRoutesManifest = exports.updateFunctionsManifest = exports.convertRuntimeToPlugin = void 0;
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
8
|
+
const path_1 = require("path");
|
9
|
+
const glob_1 = __importDefault(require("./fs/glob"));
|
10
|
+
const normalize_path_1 = require("./fs/normalize-path");
|
11
|
+
const lambda_1 = require("./lambda");
|
12
|
+
const minimatch_1 = __importDefault(require("minimatch"));
|
13
|
+
/**
|
14
|
+
* Convert legacy Runtime to a Plugin.
|
15
|
+
* @param buildRuntime - a legacy build() function from a Runtime
|
16
|
+
* @param ext - the file extension, for example `.py`
|
17
|
+
*/
|
18
|
+
function convertRuntimeToPlugin(buildRuntime, ext) {
|
19
|
+
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
20
|
+
return async function build({ vercelConfig, workPath, }) {
|
21
|
+
const opts = { cwd: workPath };
|
22
|
+
const files = await glob_1.default('**', opts);
|
23
|
+
delete files['vercel.json']; // Builders/Runtimes didn't have vercel.json
|
24
|
+
const entrypoints = await glob_1.default(`api/**/*${ext}`, opts);
|
25
|
+
const pages = {};
|
26
|
+
const { functions = {} } = vercelConfig;
|
27
|
+
const traceDir = path_1.join(workPath, '.output', 'runtime-traced-files');
|
28
|
+
await fs_extra_1.default.ensureDir(traceDir);
|
29
|
+
for (const entrypoint of Object.keys(entrypoints)) {
|
30
|
+
const key = Object.keys(functions).find(src => src === entrypoint || minimatch_1.default(entrypoint, src)) || '';
|
31
|
+
const config = functions[key] || {};
|
32
|
+
const { output } = await buildRuntime({
|
33
|
+
files,
|
34
|
+
entrypoint,
|
35
|
+
workPath,
|
36
|
+
config: {
|
37
|
+
zeroConfig: true,
|
38
|
+
includeFiles: config.includeFiles,
|
39
|
+
excludeFiles: config.excludeFiles,
|
40
|
+
},
|
41
|
+
});
|
42
|
+
pages[entrypoint] = {
|
43
|
+
handler: output.handler,
|
44
|
+
runtime: output.runtime,
|
45
|
+
memory: output.memory,
|
46
|
+
maxDuration: output.maxDuration,
|
47
|
+
environment: output.environment,
|
48
|
+
allowQuery: output.allowQuery,
|
49
|
+
//regions: output.regions,
|
50
|
+
};
|
51
|
+
// @ts-ignore This symbol is a private API
|
52
|
+
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
53
|
+
const entry = path_1.join(workPath, '.output', 'server', 'pages', entrypoint);
|
54
|
+
await fs_extra_1.default.ensureDir(path_1.dirname(entry));
|
55
|
+
await linkOrCopy(files[entrypoint].fsPath, entry);
|
56
|
+
const tracedFiles = [];
|
57
|
+
Object.entries(lambdaFiles).forEach(async ([relPath, file]) => {
|
58
|
+
const newPath = path_1.join(traceDir, relPath);
|
59
|
+
tracedFiles.push({ absolutePath: newPath, relativePath: relPath });
|
60
|
+
if (file.fsPath) {
|
61
|
+
await linkOrCopy(file.fsPath, newPath);
|
62
|
+
}
|
63
|
+
else if (file.type === 'FileBlob') {
|
64
|
+
const { data, mode } = file;
|
65
|
+
await fs_extra_1.default.writeFile(newPath, data, { mode });
|
66
|
+
}
|
67
|
+
else {
|
68
|
+
throw new Error(`Unknown file type: ${file.type}`);
|
69
|
+
}
|
70
|
+
});
|
71
|
+
const nft = path_1.join(workPath, '.output', 'server', 'pages', `${entrypoint}.nft.json`);
|
72
|
+
const json = JSON.stringify({
|
73
|
+
version: 1,
|
74
|
+
files: tracedFiles.map(f => ({
|
75
|
+
input: normalize_path_1.normalizePath(path_1.relative(nft, f.absolutePath)),
|
76
|
+
output: normalize_path_1.normalizePath(f.relativePath),
|
77
|
+
})),
|
78
|
+
});
|
79
|
+
await fs_extra_1.default.ensureDir(path_1.dirname(nft));
|
80
|
+
await fs_extra_1.default.writeFile(nft, json);
|
81
|
+
}
|
82
|
+
await updateFunctionsManifest({ vercelConfig, workPath, pages });
|
83
|
+
};
|
84
|
+
}
|
85
|
+
exports.convertRuntimeToPlugin = convertRuntimeToPlugin;
|
86
|
+
async function linkOrCopy(existingPath, newPath) {
|
87
|
+
try {
|
88
|
+
await fs_extra_1.default.createLink(existingPath, newPath);
|
89
|
+
}
|
90
|
+
catch (err) {
|
91
|
+
if (err.code !== 'EEXIST') {
|
92
|
+
await fs_extra_1.default.copyFile(existingPath, newPath);
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
async function readJson(filePath) {
|
97
|
+
try {
|
98
|
+
const str = await fs_extra_1.default.readFile(filePath, 'utf8');
|
99
|
+
return JSON.parse(str);
|
100
|
+
}
|
101
|
+
catch (err) {
|
102
|
+
if (err.code === 'ENOENT') {
|
103
|
+
return {};
|
104
|
+
}
|
105
|
+
throw err;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
/**
|
109
|
+
* If `.output/functions-manifest.json` exists, append to the pages
|
110
|
+
* property. Otherwise write a new file. This will also read `vercel.json`
|
111
|
+
* and apply relevant `functions` property config.
|
112
|
+
*/
|
113
|
+
async function updateFunctionsManifest({ vercelConfig, workPath, pages, }) {
|
114
|
+
const functionsManifestPath = path_1.join(workPath, '.output', 'functions-manifest.json');
|
115
|
+
const functionsManifest = await readJson(functionsManifestPath);
|
116
|
+
if (!functionsManifest.version)
|
117
|
+
functionsManifest.version = 1;
|
118
|
+
if (!functionsManifest.pages)
|
119
|
+
functionsManifest.pages = {};
|
120
|
+
for (const [pageKey, pageConfig] of Object.entries(pages)) {
|
121
|
+
const fnConfig = await lambda_1.getLambdaOptionsFromFunction({
|
122
|
+
sourceFile: pageKey,
|
123
|
+
config: vercelConfig,
|
124
|
+
});
|
125
|
+
functionsManifest.pages[pageKey] = {
|
126
|
+
...pageConfig,
|
127
|
+
memory: fnConfig.memory || pageConfig.memory,
|
128
|
+
maxDuration: fnConfig.maxDuration || pageConfig.maxDuration,
|
129
|
+
regions: vercelConfig.regions || pageConfig.regions,
|
130
|
+
};
|
131
|
+
}
|
132
|
+
await fs_extra_1.default.writeFile(functionsManifestPath, JSON.stringify(functionsManifest));
|
133
|
+
}
|
134
|
+
exports.updateFunctionsManifest = updateFunctionsManifest;
|
135
|
+
/**
|
136
|
+
* Append routes to the `routes-manifest.json` file.
|
137
|
+
* If the file does not exist, it will be created.
|
138
|
+
*/
|
139
|
+
async function updateRoutesManifest({ workPath, redirects, rewrites, headers, dynamicRoutes, staticRoutes, }) {
|
140
|
+
const routesManifestPath = path_1.join(workPath, '.output', 'routes-manifest.json');
|
141
|
+
const routesManifest = await readJson(routesManifestPath);
|
142
|
+
if (!routesManifest.version)
|
143
|
+
routesManifest.version = 3;
|
144
|
+
if (routesManifest.pages404 === undefined)
|
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
|
+
}
|
161
|
+
if (dynamicRoutes) {
|
162
|
+
if (!routesManifest.dynamicRoutes)
|
163
|
+
routesManifest.dynamicRoutes = [];
|
164
|
+
routesManifest.dynamicRoutes.push(...dynamicRoutes);
|
165
|
+
}
|
166
|
+
if (staticRoutes) {
|
167
|
+
if (!routesManifest.staticRoutes)
|
168
|
+
routesManifest.staticRoutes = [];
|
169
|
+
routesManifest.staticRoutes.push(...staticRoutes);
|
170
|
+
}
|
171
|
+
await fs_extra_1.default.writeFile(routesManifestPath, JSON.stringify(routesManifest));
|
172
|
+
}
|
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/fs/glob.js
CHANGED
@@ -8,6 +8,7 @@ const assert_1 = __importDefault(require("assert"));
|
|
8
8
|
const glob_1 = __importDefault(require("glob"));
|
9
9
|
const util_1 = require("util");
|
10
10
|
const fs_extra_1 = require("fs-extra");
|
11
|
+
const normalize_path_1 = require("./normalize-path");
|
11
12
|
const file_fs_ref_1 = __importDefault(require("../file-fs-ref"));
|
12
13
|
const vanillaGlob = util_1.promisify(glob_1.default);
|
13
14
|
async function glob(pattern, opts, mountpoint) {
|
@@ -31,7 +32,7 @@ async function glob(pattern, opts, mountpoint) {
|
|
31
32
|
options.dot = true;
|
32
33
|
const files = await vanillaGlob(pattern, options);
|
33
34
|
for (const relativePath of files) {
|
34
|
-
const fsPath = path_1.default.join(options.cwd, relativePath)
|
35
|
+
const fsPath = normalize_path_1.normalizePath(path_1.default.join(options.cwd, relativePath));
|
35
36
|
let stat = options.statCache[fsPath];
|
36
37
|
assert_1.default(stat, `statCache does not contain value for ${relativePath} (resolved to ${fsPath})`);
|
37
38
|
const isSymlink = options.symlinks[fsPath];
|
@@ -0,0 +1,11 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.normalizePath = void 0;
|
4
|
+
const isWin = process.platform === 'win32';
|
5
|
+
/**
|
6
|
+
* Convert Windows separators to Unix separators.
|
7
|
+
*/
|
8
|
+
function normalizePath(p) {
|
9
|
+
return isWin ? p.replace(/\\/g, '/') : p;
|
10
|
+
}
|
11
|
+
exports.normalizePath = normalizePath;
|
package/dist/index.d.ts
CHANGED
@@ -17,6 +17,8 @@ export { detectBuilders, detectOutputDirectory, detectApiDirectory, detectApiExt
|
|
17
17
|
export { detectFramework } from './detect-framework';
|
18
18
|
export { DetectorFilesystem } from './detectors/filesystem';
|
19
19
|
export { readConfigFile } from './fs/read-config-file';
|
20
|
+
export { normalizePath } from './fs/normalize-path';
|
21
|
+
export { convertRuntimeToPlugin, updateFunctionsManifest, updateRoutesManifest, } from './convert-runtime-to-plugin';
|
20
22
|
export * from './schemas';
|
21
23
|
export * from './types';
|
22
24
|
export * from './errors';
|