@vercel/build-utils 2.12.3-canary.27 → 2.12.3-canary.30
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.
@@ -3,11 +3,12 @@ import type { BuildOptions } from './types';
|
|
3
3
|
/**
|
4
4
|
* Convert legacy Runtime to a Plugin.
|
5
5
|
* @param buildRuntime - a legacy build() function from a Runtime
|
6
|
+
* @param packageName - the name of the package, for example `vercel-plugin-python`
|
6
7
|
* @param ext - the file extension, for example `.py`
|
7
8
|
*/
|
8
9
|
export declare function convertRuntimeToPlugin(buildRuntime: (options: BuildOptions) => Promise<{
|
9
10
|
output: Lambda;
|
10
|
-
}>, ext: string): ({ workPath }: {
|
11
|
+
}>, packageName: string, ext: string): ({ workPath }: {
|
11
12
|
workPath: string;
|
12
13
|
}) => Promise<void>;
|
13
14
|
/**
|
@@ -9,20 +9,54 @@ 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
11
|
const lambda_1 = require("./lambda");
|
12
|
+
const _1 = require(".");
|
13
|
+
// `.output` was already created by the Build Command, so we have
|
14
|
+
// to ensure its contents don't get bundled into the Lambda. Similarily,
|
15
|
+
// we don't want to bundle anything from `.vercel` either. Lastly,
|
16
|
+
// Builders/Runtimes didn't have `vercel.json` or `now.json`.
|
17
|
+
const ignoredPaths = ['.output', '.vercel', 'vercel.json', 'now.json'];
|
18
|
+
const shouldIgnorePath = (file, ignoreFilter, ignoreFile) => {
|
19
|
+
const isNative = ignoredPaths.some(item => {
|
20
|
+
return file.startsWith(item);
|
21
|
+
});
|
22
|
+
if (!ignoreFile) {
|
23
|
+
return isNative;
|
24
|
+
}
|
25
|
+
return isNative || ignoreFilter(file);
|
26
|
+
};
|
12
27
|
/**
|
13
28
|
* Convert legacy Runtime to a Plugin.
|
14
29
|
* @param buildRuntime - a legacy build() function from a Runtime
|
30
|
+
* @param packageName - the name of the package, for example `vercel-plugin-python`
|
15
31
|
* @param ext - the file extension, for example `.py`
|
16
32
|
*/
|
17
|
-
function convertRuntimeToPlugin(buildRuntime, ext) {
|
33
|
+
function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
18
34
|
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
19
35
|
return async function build({ workPath }) {
|
20
36
|
const opts = { cwd: workPath };
|
21
37
|
const files = await glob_1.default('**', opts);
|
22
|
-
|
23
|
-
|
38
|
+
// We also don't want to provide any files to Runtimes that were ignored
|
39
|
+
// through `.vercelignore` or `.nowignore`, because the Build Step does the same.
|
40
|
+
const ignoreFilter = await _1.getIgnoreFilter(workPath);
|
41
|
+
// We're not passing this as an `ignore` filter to the `glob` function above,
|
42
|
+
// so that we can re-use exactly the same `getIgnoreFilter` method that the
|
43
|
+
// Build Step uses (literally the same code). Note that this exclusion only applies
|
44
|
+
// when deploying. Locally, another exclusion further below is needed.
|
45
|
+
for (const file in files) {
|
46
|
+
if (shouldIgnorePath(file, ignoreFilter, true)) {
|
47
|
+
delete files[file];
|
48
|
+
}
|
49
|
+
}
|
50
|
+
const entrypointPattern = `api/**/*${ext}`;
|
51
|
+
const entrypoints = await glob_1.default(entrypointPattern, opts);
|
24
52
|
const pages = {};
|
25
|
-
const
|
53
|
+
const pluginName = packageName.replace('vercel-plugin-', '');
|
54
|
+
const traceDir = path_1.join(workPath, `.output`, `inputs`,
|
55
|
+
// Legacy Runtimes can only provide API Routes, so that's
|
56
|
+
// why we can use this prefix for all of them. Here, we have to
|
57
|
+
// make sure to not use a cryptic hash name, because people
|
58
|
+
// need to be able to easily inspect the output.
|
59
|
+
`api-routes-${pluginName}`);
|
26
60
|
await fs_extra_1.default.ensureDir(traceDir);
|
27
61
|
for (const entrypoint of Object.keys(entrypoints)) {
|
28
62
|
const { output } = await buildRuntime({
|
@@ -46,6 +80,15 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
46
80
|
};
|
47
81
|
// @ts-ignore This symbol is a private API
|
48
82
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
83
|
+
// When deploying, the `files` that are passed to the Legacy Runtimes already
|
84
|
+
// have certain files that are ignored stripped, but locally, that list of
|
85
|
+
// files isn't used by the Legacy Runtimes, so we need to apply the filters
|
86
|
+
// to the outputs that they are returning instead.
|
87
|
+
for (const file in lambdaFiles) {
|
88
|
+
if (shouldIgnorePath(file, ignoreFilter, false)) {
|
89
|
+
delete lambdaFiles[file];
|
90
|
+
}
|
91
|
+
}
|
49
92
|
const entry = path_1.join(workPath, '.output', 'server', 'pages', entrypoint);
|
50
93
|
await fs_extra_1.default.ensureDir(path_1.dirname(entry));
|
51
94
|
await linkOrCopy(files[entrypoint].fsPath, entry);
|
@@ -0,0 +1 @@
|
|
1
|
+
export default function (downloadPath: string, rootDirectory?: string | undefined): Promise<(p: string) => any>;
|
@@ -0,0 +1,59 @@
|
|
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
|
+
const path_1 = __importDefault(require("path"));
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
8
|
+
const ignore_1 = __importDefault(require("ignore"));
|
9
|
+
function isCodedError(error) {
|
10
|
+
return (error !== null &&
|
11
|
+
error !== undefined &&
|
12
|
+
error.code !== undefined);
|
13
|
+
}
|
14
|
+
function clearRelative(s) {
|
15
|
+
return s.replace(/(\n|^)\.\//g, '$1');
|
16
|
+
}
|
17
|
+
async function default_1(downloadPath, rootDirectory) {
|
18
|
+
const readFile = async (p) => {
|
19
|
+
try {
|
20
|
+
return await fs_extra_1.default.readFile(p, 'utf8');
|
21
|
+
}
|
22
|
+
catch (error) {
|
23
|
+
if (error.code === 'ENOENT' ||
|
24
|
+
(error instanceof Error && error.message.includes('ENOENT'))) {
|
25
|
+
return undefined;
|
26
|
+
}
|
27
|
+
throw error;
|
28
|
+
}
|
29
|
+
};
|
30
|
+
const vercelIgnorePath = path_1.default.join(downloadPath, rootDirectory || '', '.vercelignore');
|
31
|
+
const nowIgnorePath = path_1.default.join(downloadPath, rootDirectory || '', '.nowignore');
|
32
|
+
const ignoreContents = [];
|
33
|
+
try {
|
34
|
+
ignoreContents.push(...(await Promise.all([readFile(vercelIgnorePath), readFile(nowIgnorePath)])).filter(Boolean));
|
35
|
+
}
|
36
|
+
catch (error) {
|
37
|
+
if (isCodedError(error) && error.code === 'ENOTDIR') {
|
38
|
+
console.log(`Warning: Cannot read ignore file from ${vercelIgnorePath}`);
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
throw error;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
if (ignoreContents.length === 2) {
|
45
|
+
throw new Error('Cannot use both a `.vercelignore` and `.nowignore` file. Please delete the `.nowignore` file.');
|
46
|
+
}
|
47
|
+
if (ignoreContents.length === 0) {
|
48
|
+
return () => false;
|
49
|
+
}
|
50
|
+
const ignoreFilter = ignore_1.default().add(clearRelative(ignoreContents[0]));
|
51
|
+
return function (p) {
|
52
|
+
// we should not ignore now.json and vercel.json if it asked to.
|
53
|
+
// we depend on these files for building the app with sourceless
|
54
|
+
if (p === 'now.json' || p === 'vercel.json')
|
55
|
+
return false;
|
56
|
+
return ignoreFilter.test(p).ignored;
|
57
|
+
};
|
58
|
+
}
|
59
|
+
exports.default = default_1;
|
package/dist/index.d.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
/// <reference types="node" />
|
1
2
|
import FileBlob from './file-blob';
|
2
3
|
import FileFsRef from './file-fs-ref';
|
3
4
|
import FileRef from './file-ref';
|
@@ -12,7 +13,8 @@ import { getLatestNodeVersion, getDiscontinuedNodeVersions } from './fs/node-ver
|
|
12
13
|
import streamToBuffer from './fs/stream-to-buffer';
|
13
14
|
import shouldServe from './should-serve';
|
14
15
|
import debug from './debug';
|
15
|
-
|
16
|
+
import getIgnoreFilter from './get-ignore-filter';
|
17
|
+
export { FileBlob, FileFsRef, FileRef, Lambda, createLambda, Prerender, download, DownloadedFiles, getWriteableDirectory, glob, GlobOptions, rename, execAsync, spawnAsync, getScriptName, installDependencies, runPackageJsonScript, execCommand, spawnCommand, walkParentDirs, getNodeBinPath, runNpmInstall, runBundleInstall, runPipInstall, runShellScript, getNodeVersion, getLatestNodeVersion, getDiscontinuedNodeVersions, getSpawnOptions, streamToBuffer, shouldServe, debug, isSymbolicLink, getLambdaOptionsFromFunction, scanParentDirs, getIgnoreFilter, };
|
16
18
|
export { detectBuilders, detectOutputDirectory, detectApiDirectory, detectApiExtensions, } from './detect-builders';
|
17
19
|
export { detectFramework } from './detect-framework';
|
18
20
|
export { DetectorFilesystem } from './detectors/filesystem';
|
@@ -32,3 +34,8 @@ export declare const isStaticRuntime: (name?: string | undefined) => boolean;
|
|
32
34
|
* Throws an error if *both* env vars are defined.
|
33
35
|
*/
|
34
36
|
export declare const getPlatformEnv: (name: string) => string | undefined;
|
37
|
+
/**
|
38
|
+
* Helper function for generating file or directories names in `.output/inputs`
|
39
|
+
* for dependencies of files provided to the File System API.
|
40
|
+
*/
|
41
|
+
export declare const getInputHash: (source: Buffer | string) => string;
|
package/dist/index.js
CHANGED
@@ -7657,6 +7657,476 @@ IconvLiteDecoderStream.prototype.collect = function(cb) {
|
|
7657
7657
|
|
7658
7658
|
|
7659
7659
|
|
7660
|
+
/***/ }),
|
7661
|
+
|
7662
|
+
/***/ 3556:
|
7663
|
+
/***/ ((module) => {
|
7664
|
+
|
7665
|
+
// A simple implementation of make-array
|
7666
|
+
function make_array (subject) {
|
7667
|
+
return Array.isArray(subject)
|
7668
|
+
? subject
|
7669
|
+
: [subject]
|
7670
|
+
}
|
7671
|
+
|
7672
|
+
const REGEX_BLANK_LINE = /^\s+$/
|
7673
|
+
const REGEX_LEADING_EXCAPED_EXCLAMATION = /^\\!/
|
7674
|
+
const REGEX_LEADING_EXCAPED_HASH = /^\\#/
|
7675
|
+
const SLASH = '/'
|
7676
|
+
const KEY_IGNORE = typeof Symbol !== 'undefined'
|
7677
|
+
? Symbol.for('node-ignore')
|
7678
|
+
/* istanbul ignore next */
|
7679
|
+
: 'node-ignore'
|
7680
|
+
|
7681
|
+
const define = (object, key, value) =>
|
7682
|
+
Object.defineProperty(object, key, {value})
|
7683
|
+
|
7684
|
+
const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g
|
7685
|
+
|
7686
|
+
// Sanitize the range of a regular expression
|
7687
|
+
// The cases are complicated, see test cases for details
|
7688
|
+
const sanitizeRange = range => range.replace(
|
7689
|
+
REGEX_REGEXP_RANGE,
|
7690
|
+
(match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0)
|
7691
|
+
? match
|
7692
|
+
// Invalid range (out of order) which is ok for gitignore rules but
|
7693
|
+
// fatal for JavaScript regular expression, so eliminate it.
|
7694
|
+
: ''
|
7695
|
+
)
|
7696
|
+
|
7697
|
+
// > If the pattern ends with a slash,
|
7698
|
+
// > it is removed for the purpose of the following description,
|
7699
|
+
// > but it would only find a match with a directory.
|
7700
|
+
// > In other words, foo/ will match a directory foo and paths underneath it,
|
7701
|
+
// > but will not match a regular file or a symbolic link foo
|
7702
|
+
// > (this is consistent with the way how pathspec works in general in Git).
|
7703
|
+
// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'
|
7704
|
+
// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call
|
7705
|
+
// you could use option `mark: true` with `glob`
|
7706
|
+
|
7707
|
+
// '`foo/`' should not continue with the '`..`'
|
7708
|
+
const DEFAULT_REPLACER_PREFIX = [
|
7709
|
+
|
7710
|
+
// > Trailing spaces are ignored unless they are quoted with backslash ("\")
|
7711
|
+
[
|
7712
|
+
// (a\ ) -> (a )
|
7713
|
+
// (a ) -> (a)
|
7714
|
+
// (a \ ) -> (a )
|
7715
|
+
/\\?\s+$/,
|
7716
|
+
match => match.indexOf('\\') === 0
|
7717
|
+
? ' '
|
7718
|
+
: ''
|
7719
|
+
],
|
7720
|
+
|
7721
|
+
// replace (\ ) with ' '
|
7722
|
+
[
|
7723
|
+
/\\\s/g,
|
7724
|
+
() => ' '
|
7725
|
+
],
|
7726
|
+
|
7727
|
+
// Escape metacharacters
|
7728
|
+
// which is written down by users but means special for regular expressions.
|
7729
|
+
|
7730
|
+
// > There are 12 characters with special meanings:
|
7731
|
+
// > - the backslash \,
|
7732
|
+
// > - the caret ^,
|
7733
|
+
// > - the dollar sign $,
|
7734
|
+
// > - the period or dot .,
|
7735
|
+
// > - the vertical bar or pipe symbol |,
|
7736
|
+
// > - the question mark ?,
|
7737
|
+
// > - the asterisk or star *,
|
7738
|
+
// > - the plus sign +,
|
7739
|
+
// > - the opening parenthesis (,
|
7740
|
+
// > - the closing parenthesis ),
|
7741
|
+
// > - and the opening square bracket [,
|
7742
|
+
// > - the opening curly brace {,
|
7743
|
+
// > These special characters are often called "metacharacters".
|
7744
|
+
[
|
7745
|
+
/[\\^$.|*+(){]/g,
|
7746
|
+
match => `\\${match}`
|
7747
|
+
],
|
7748
|
+
|
7749
|
+
[
|
7750
|
+
// > [abc] matches any character inside the brackets
|
7751
|
+
// > (in this case a, b, or c);
|
7752
|
+
/\[([^\]/]*)($|\])/g,
|
7753
|
+
(match, p1, p2) => p2 === ']'
|
7754
|
+
? `[${sanitizeRange(p1)}]`
|
7755
|
+
: `\\${match}`
|
7756
|
+
],
|
7757
|
+
|
7758
|
+
[
|
7759
|
+
// > a question mark (?) matches a single character
|
7760
|
+
/(?!\\)\?/g,
|
7761
|
+
() => '[^/]'
|
7762
|
+
],
|
7763
|
+
|
7764
|
+
// leading slash
|
7765
|
+
[
|
7766
|
+
|
7767
|
+
// > A leading slash matches the beginning of the pathname.
|
7768
|
+
// > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
|
7769
|
+
// A leading slash matches the beginning of the pathname
|
7770
|
+
/^\//,
|
7771
|
+
() => '^'
|
7772
|
+
],
|
7773
|
+
|
7774
|
+
// replace special metacharacter slash after the leading slash
|
7775
|
+
[
|
7776
|
+
/\//g,
|
7777
|
+
() => '\\/'
|
7778
|
+
],
|
7779
|
+
|
7780
|
+
[
|
7781
|
+
// > A leading "**" followed by a slash means match in all directories.
|
7782
|
+
// > For example, "**/foo" matches file or directory "foo" anywhere,
|
7783
|
+
// > the same as pattern "foo".
|
7784
|
+
// > "**/foo/bar" matches file or directory "bar" anywhere that is directly
|
7785
|
+
// > under directory "foo".
|
7786
|
+
// Notice that the '*'s have been replaced as '\\*'
|
7787
|
+
/^\^*\\\*\\\*\\\//,
|
7788
|
+
|
7789
|
+
// '**/foo' <-> 'foo'
|
7790
|
+
() => '^(?:.*\\/)?'
|
7791
|
+
]
|
7792
|
+
]
|
7793
|
+
|
7794
|
+
const DEFAULT_REPLACER_SUFFIX = [
|
7795
|
+
// starting
|
7796
|
+
[
|
7797
|
+
// there will be no leading '/'
|
7798
|
+
// (which has been replaced by section "leading slash")
|
7799
|
+
// If starts with '**', adding a '^' to the regular expression also works
|
7800
|
+
/^(?=[^^])/,
|
7801
|
+
function startingReplacer () {
|
7802
|
+
return !/\/(?!$)/.test(this)
|
7803
|
+
// > If the pattern does not contain a slash /,
|
7804
|
+
// > Git treats it as a shell glob pattern
|
7805
|
+
// Actually, if there is only a trailing slash,
|
7806
|
+
// git also treats it as a shell glob pattern
|
7807
|
+
? '(?:^|\\/)'
|
7808
|
+
|
7809
|
+
// > Otherwise, Git treats the pattern as a shell glob suitable for
|
7810
|
+
// > consumption by fnmatch(3)
|
7811
|
+
: '^'
|
7812
|
+
}
|
7813
|
+
],
|
7814
|
+
|
7815
|
+
// two globstars
|
7816
|
+
[
|
7817
|
+
// Use lookahead assertions so that we could match more than one `'/**'`
|
7818
|
+
/\\\/\\\*\\\*(?=\\\/|$)/g,
|
7819
|
+
|
7820
|
+
// Zero, one or several directories
|
7821
|
+
// should not use '*', or it will be replaced by the next replacer
|
7822
|
+
|
7823
|
+
// Check if it is not the last `'/**'`
|
7824
|
+
(match, index, str) => index + 6 < str.length
|
7825
|
+
|
7826
|
+
// case: /**/
|
7827
|
+
// > A slash followed by two consecutive asterisks then a slash matches
|
7828
|
+
// > zero or more directories.
|
7829
|
+
// > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
|
7830
|
+
// '/**/'
|
7831
|
+
? '(?:\\/[^\\/]+)*'
|
7832
|
+
|
7833
|
+
// case: /**
|
7834
|
+
// > A trailing `"/**"` matches everything inside.
|
7835
|
+
|
7836
|
+
// #21: everything inside but it should not include the current folder
|
7837
|
+
: '\\/.+'
|
7838
|
+
],
|
7839
|
+
|
7840
|
+
// intermediate wildcards
|
7841
|
+
[
|
7842
|
+
// Never replace escaped '*'
|
7843
|
+
// ignore rule '\*' will match the path '*'
|
7844
|
+
|
7845
|
+
// 'abc.*/' -> go
|
7846
|
+
// 'abc.*' -> skip this rule
|
7847
|
+
/(^|[^\\]+)\\\*(?=.+)/g,
|
7848
|
+
|
7849
|
+
// '*.js' matches '.js'
|
7850
|
+
// '*.js' doesn't match 'abc'
|
7851
|
+
(match, p1) => `${p1}[^\\/]*`
|
7852
|
+
],
|
7853
|
+
|
7854
|
+
// trailing wildcard
|
7855
|
+
[
|
7856
|
+
/(\^|\\\/)?\\\*$/,
|
7857
|
+
(match, p1) => {
|
7858
|
+
const prefix = p1
|
7859
|
+
// '\^':
|
7860
|
+
// '/*' does not match ''
|
7861
|
+
// '/*' does not match everything
|
7862
|
+
|
7863
|
+
// '\\\/':
|
7864
|
+
// 'abc/*' does not match 'abc/'
|
7865
|
+
? `${p1}[^/]+`
|
7866
|
+
|
7867
|
+
// 'a*' matches 'a'
|
7868
|
+
// 'a*' matches 'aa'
|
7869
|
+
: '[^/]*'
|
7870
|
+
|
7871
|
+
return `${prefix}(?=$|\\/$)`
|
7872
|
+
}
|
7873
|
+
],
|
7874
|
+
|
7875
|
+
[
|
7876
|
+
// unescape
|
7877
|
+
/\\\\\\/g,
|
7878
|
+
() => '\\'
|
7879
|
+
]
|
7880
|
+
]
|
7881
|
+
|
7882
|
+
const POSITIVE_REPLACERS = [
|
7883
|
+
...DEFAULT_REPLACER_PREFIX,
|
7884
|
+
|
7885
|
+
// 'f'
|
7886
|
+
// matches
|
7887
|
+
// - /f(end)
|
7888
|
+
// - /f/
|
7889
|
+
// - (start)f(end)
|
7890
|
+
// - (start)f/
|
7891
|
+
// doesn't match
|
7892
|
+
// - oof
|
7893
|
+
// - foo
|
7894
|
+
// pseudo:
|
7895
|
+
// -> (^|/)f(/|$)
|
7896
|
+
|
7897
|
+
// ending
|
7898
|
+
[
|
7899
|
+
// 'js' will not match 'js.'
|
7900
|
+
// 'ab' will not match 'abc'
|
7901
|
+
/(?:[^*/])$/,
|
7902
|
+
|
7903
|
+
// 'js*' will not match 'a.js'
|
7904
|
+
// 'js/' will not match 'a.js'
|
7905
|
+
// 'js' will match 'a.js' and 'a.js/'
|
7906
|
+
match => `${match}(?=$|\\/)`
|
7907
|
+
],
|
7908
|
+
|
7909
|
+
...DEFAULT_REPLACER_SUFFIX
|
7910
|
+
]
|
7911
|
+
|
7912
|
+
const NEGATIVE_REPLACERS = [
|
7913
|
+
...DEFAULT_REPLACER_PREFIX,
|
7914
|
+
|
7915
|
+
// #24, #38
|
7916
|
+
// The MISSING rule of [gitignore docs](https://git-scm.com/docs/gitignore)
|
7917
|
+
// A negative pattern without a trailing wildcard should not
|
7918
|
+
// re-include the things inside that directory.
|
7919
|
+
|
7920
|
+
// eg:
|
7921
|
+
// ['node_modules/*', '!node_modules']
|
7922
|
+
// should ignore `node_modules/a.js`
|
7923
|
+
[
|
7924
|
+
/(?:[^*])$/,
|
7925
|
+
match => `${match}(?=$|\\/$)`
|
7926
|
+
],
|
7927
|
+
|
7928
|
+
...DEFAULT_REPLACER_SUFFIX
|
7929
|
+
]
|
7930
|
+
|
7931
|
+
// A simple cache, because an ignore rule only has only one certain meaning
|
7932
|
+
const cache = Object.create(null)
|
7933
|
+
|
7934
|
+
// @param {pattern}
|
7935
|
+
const make_regex = (pattern, negative, ignorecase) => {
|
7936
|
+
const r = cache[pattern]
|
7937
|
+
if (r) {
|
7938
|
+
return r
|
7939
|
+
}
|
7940
|
+
|
7941
|
+
const replacers = negative
|
7942
|
+
? NEGATIVE_REPLACERS
|
7943
|
+
: POSITIVE_REPLACERS
|
7944
|
+
|
7945
|
+
const source = replacers.reduce(
|
7946
|
+
(prev, current) => prev.replace(current[0], current[1].bind(pattern)),
|
7947
|
+
pattern
|
7948
|
+
)
|
7949
|
+
|
7950
|
+
return cache[pattern] = ignorecase
|
7951
|
+
? new RegExp(source, 'i')
|
7952
|
+
: new RegExp(source)
|
7953
|
+
}
|
7954
|
+
|
7955
|
+
// > A blank line matches no files, so it can serve as a separator for readability.
|
7956
|
+
const checkPattern = pattern => pattern
|
7957
|
+
&& typeof pattern === 'string'
|
7958
|
+
&& !REGEX_BLANK_LINE.test(pattern)
|
7959
|
+
|
7960
|
+
// > A line starting with # serves as a comment.
|
7961
|
+
&& pattern.indexOf('#') !== 0
|
7962
|
+
|
7963
|
+
const createRule = (pattern, ignorecase) => {
|
7964
|
+
const origin = pattern
|
7965
|
+
let negative = false
|
7966
|
+
|
7967
|
+
// > An optional prefix "!" which negates the pattern;
|
7968
|
+
if (pattern.indexOf('!') === 0) {
|
7969
|
+
negative = true
|
7970
|
+
pattern = pattern.substr(1)
|
7971
|
+
}
|
7972
|
+
|
7973
|
+
pattern = pattern
|
7974
|
+
// > Put a backslash ("\") in front of the first "!" for patterns that
|
7975
|
+
// > begin with a literal "!", for example, `"\!important!.txt"`.
|
7976
|
+
.replace(REGEX_LEADING_EXCAPED_EXCLAMATION, '!')
|
7977
|
+
// > Put a backslash ("\") in front of the first hash for patterns that
|
7978
|
+
// > begin with a hash.
|
7979
|
+
.replace(REGEX_LEADING_EXCAPED_HASH, '#')
|
7980
|
+
|
7981
|
+
const regex = make_regex(pattern, negative, ignorecase)
|
7982
|
+
|
7983
|
+
return {
|
7984
|
+
origin,
|
7985
|
+
pattern,
|
7986
|
+
negative,
|
7987
|
+
regex
|
7988
|
+
}
|
7989
|
+
}
|
7990
|
+
|
7991
|
+
class IgnoreBase {
|
7992
|
+
constructor ({
|
7993
|
+
ignorecase = true
|
7994
|
+
} = {}) {
|
7995
|
+
this._rules = []
|
7996
|
+
this._ignorecase = ignorecase
|
7997
|
+
define(this, KEY_IGNORE, true)
|
7998
|
+
this._initCache()
|
7999
|
+
}
|
8000
|
+
|
8001
|
+
_initCache () {
|
8002
|
+
this._cache = Object.create(null)
|
8003
|
+
}
|
8004
|
+
|
8005
|
+
// @param {Array.<string>|string|Ignore} pattern
|
8006
|
+
add (pattern) {
|
8007
|
+
this._added = false
|
8008
|
+
|
8009
|
+
if (typeof pattern === 'string') {
|
8010
|
+
pattern = pattern.split(/\r?\n/g)
|
8011
|
+
}
|
8012
|
+
|
8013
|
+
make_array(pattern).forEach(this._addPattern, this)
|
8014
|
+
|
8015
|
+
// Some rules have just added to the ignore,
|
8016
|
+
// making the behavior changed.
|
8017
|
+
if (this._added) {
|
8018
|
+
this._initCache()
|
8019
|
+
}
|
8020
|
+
|
8021
|
+
return this
|
8022
|
+
}
|
8023
|
+
|
8024
|
+
// legacy
|
8025
|
+
addPattern (pattern) {
|
8026
|
+
return this.add(pattern)
|
8027
|
+
}
|
8028
|
+
|
8029
|
+
_addPattern (pattern) {
|
8030
|
+
// #32
|
8031
|
+
if (pattern && pattern[KEY_IGNORE]) {
|
8032
|
+
this._rules = this._rules.concat(pattern._rules)
|
8033
|
+
this._added = true
|
8034
|
+
return
|
8035
|
+
}
|
8036
|
+
|
8037
|
+
if (checkPattern(pattern)) {
|
8038
|
+
const rule = createRule(pattern, this._ignorecase)
|
8039
|
+
this._added = true
|
8040
|
+
this._rules.push(rule)
|
8041
|
+
}
|
8042
|
+
}
|
8043
|
+
|
8044
|
+
filter (paths) {
|
8045
|
+
return make_array(paths).filter(path => this._filter(path))
|
8046
|
+
}
|
8047
|
+
|
8048
|
+
createFilter () {
|
8049
|
+
return path => this._filter(path)
|
8050
|
+
}
|
8051
|
+
|
8052
|
+
ignores (path) {
|
8053
|
+
return !this._filter(path)
|
8054
|
+
}
|
8055
|
+
|
8056
|
+
// @returns `Boolean` true if the `path` is NOT ignored
|
8057
|
+
_filter (path, slices) {
|
8058
|
+
if (!path) {
|
8059
|
+
return false
|
8060
|
+
}
|
8061
|
+
|
8062
|
+
if (path in this._cache) {
|
8063
|
+
return this._cache[path]
|
8064
|
+
}
|
8065
|
+
|
8066
|
+
if (!slices) {
|
8067
|
+
// path/to/a.js
|
8068
|
+
// ['path', 'to', 'a.js']
|
8069
|
+
slices = path.split(SLASH)
|
8070
|
+
}
|
8071
|
+
|
8072
|
+
slices.pop()
|
8073
|
+
|
8074
|
+
return this._cache[path] = slices.length
|
8075
|
+
// > It is not possible to re-include a file if a parent directory of
|
8076
|
+
// > that file is excluded.
|
8077
|
+
// If the path contains a parent directory, check the parent first
|
8078
|
+
? this._filter(slices.join(SLASH) + SLASH, slices)
|
8079
|
+
&& this._test(path)
|
8080
|
+
|
8081
|
+
// Or only test the path
|
8082
|
+
: this._test(path)
|
8083
|
+
}
|
8084
|
+
|
8085
|
+
// @returns {Boolean} true if a file is NOT ignored
|
8086
|
+
_test (path) {
|
8087
|
+
// Explicitly define variable type by setting matched to `0`
|
8088
|
+
let matched = 0
|
8089
|
+
|
8090
|
+
this._rules.forEach(rule => {
|
8091
|
+
// if matched = true, then we only test negative rules
|
8092
|
+
// if matched = false, then we test non-negative rules
|
8093
|
+
if (!(matched ^ rule.negative)) {
|
8094
|
+
matched = rule.negative ^ rule.regex.test(path)
|
8095
|
+
}
|
8096
|
+
})
|
8097
|
+
|
8098
|
+
return !matched
|
8099
|
+
}
|
8100
|
+
}
|
8101
|
+
|
8102
|
+
// Windows
|
8103
|
+
// --------------------------------------------------------------
|
8104
|
+
/* istanbul ignore if */
|
8105
|
+
if (
|
8106
|
+
// Detect `process` so that it can run in browsers.
|
8107
|
+
typeof process !== 'undefined'
|
8108
|
+
&& (
|
8109
|
+
process.env && process.env.IGNORE_TEST_WIN32
|
8110
|
+
|| process.platform === 'win32'
|
8111
|
+
)
|
8112
|
+
) {
|
8113
|
+
const filter = IgnoreBase.prototype._filter
|
8114
|
+
|
8115
|
+
/* eslint no-control-regex: "off" */
|
8116
|
+
const make_posix = str => /^\\\\\?\\/.test(str)
|
8117
|
+
|| /[^\x00-\x80]+/.test(str)
|
8118
|
+
? str
|
8119
|
+
: str.replace(/\\/g, '/')
|
8120
|
+
|
8121
|
+
IgnoreBase.prototype._filter = function filterWin32 (path, slices) {
|
8122
|
+
path = make_posix(path)
|
8123
|
+
return filter.call(this, path, slices)
|
8124
|
+
}
|
8125
|
+
}
|
8126
|
+
|
8127
|
+
module.exports = options => new IgnoreBase(options)
|
8128
|
+
|
8129
|
+
|
7660
8130
|
/***/ }),
|
7661
8131
|
|
7662
8132
|
/***/ 9442:
|
@@ -32286,20 +32756,54 @@ const path_1 = __webpack_require__(5622);
|
|
32286
32756
|
const glob_1 = __importDefault(__webpack_require__(4240));
|
32287
32757
|
const normalize_path_1 = __webpack_require__(6261);
|
32288
32758
|
const lambda_1 = __webpack_require__(6721);
|
32759
|
+
const _1 = __webpack_require__(2855);
|
32760
|
+
// `.output` was already created by the Build Command, so we have
|
32761
|
+
// to ensure its contents don't get bundled into the Lambda. Similarily,
|
32762
|
+
// we don't want to bundle anything from `.vercel` either. Lastly,
|
32763
|
+
// Builders/Runtimes didn't have `vercel.json` or `now.json`.
|
32764
|
+
const ignoredPaths = ['.output', '.vercel', 'vercel.json', 'now.json'];
|
32765
|
+
const shouldIgnorePath = (file, ignoreFilter, ignoreFile) => {
|
32766
|
+
const isNative = ignoredPaths.some(item => {
|
32767
|
+
return file.startsWith(item);
|
32768
|
+
});
|
32769
|
+
if (!ignoreFile) {
|
32770
|
+
return isNative;
|
32771
|
+
}
|
32772
|
+
return isNative || ignoreFilter(file);
|
32773
|
+
};
|
32289
32774
|
/**
|
32290
32775
|
* Convert legacy Runtime to a Plugin.
|
32291
32776
|
* @param buildRuntime - a legacy build() function from a Runtime
|
32777
|
+
* @param packageName - the name of the package, for example `vercel-plugin-python`
|
32292
32778
|
* @param ext - the file extension, for example `.py`
|
32293
32779
|
*/
|
32294
|
-
function convertRuntimeToPlugin(buildRuntime, ext) {
|
32780
|
+
function convertRuntimeToPlugin(buildRuntime, packageName, ext) {
|
32295
32781
|
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
32296
32782
|
return async function build({ workPath }) {
|
32297
32783
|
const opts = { cwd: workPath };
|
32298
32784
|
const files = await glob_1.default('**', opts);
|
32299
|
-
|
32300
|
-
|
32785
|
+
// We also don't want to provide any files to Runtimes that were ignored
|
32786
|
+
// through `.vercelignore` or `.nowignore`, because the Build Step does the same.
|
32787
|
+
const ignoreFilter = await _1.getIgnoreFilter(workPath);
|
32788
|
+
// We're not passing this as an `ignore` filter to the `glob` function above,
|
32789
|
+
// so that we can re-use exactly the same `getIgnoreFilter` method that the
|
32790
|
+
// Build Step uses (literally the same code). Note that this exclusion only applies
|
32791
|
+
// when deploying. Locally, another exclusion further below is needed.
|
32792
|
+
for (const file in files) {
|
32793
|
+
if (shouldIgnorePath(file, ignoreFilter, true)) {
|
32794
|
+
delete files[file];
|
32795
|
+
}
|
32796
|
+
}
|
32797
|
+
const entrypointPattern = `api/**/*${ext}`;
|
32798
|
+
const entrypoints = await glob_1.default(entrypointPattern, opts);
|
32301
32799
|
const pages = {};
|
32302
|
-
const
|
32800
|
+
const pluginName = packageName.replace('vercel-plugin-', '');
|
32801
|
+
const traceDir = path_1.join(workPath, `.output`, `inputs`,
|
32802
|
+
// Legacy Runtimes can only provide API Routes, so that's
|
32803
|
+
// why we can use this prefix for all of them. Here, we have to
|
32804
|
+
// make sure to not use a cryptic hash name, because people
|
32805
|
+
// need to be able to easily inspect the output.
|
32806
|
+
`api-routes-${pluginName}`);
|
32303
32807
|
await fs_extra_1.default.ensureDir(traceDir);
|
32304
32808
|
for (const entrypoint of Object.keys(entrypoints)) {
|
32305
32809
|
const { output } = await buildRuntime({
|
@@ -32323,6 +32827,15 @@ function convertRuntimeToPlugin(buildRuntime, ext) {
|
|
32323
32827
|
};
|
32324
32828
|
// @ts-ignore This symbol is a private API
|
32325
32829
|
const lambdaFiles = output[lambda_1.FILES_SYMBOL];
|
32830
|
+
// When deploying, the `files` that are passed to the Legacy Runtimes already
|
32831
|
+
// have certain files that are ignored stripped, but locally, that list of
|
32832
|
+
// files isn't used by the Legacy Runtimes, so we need to apply the filters
|
32833
|
+
// to the outputs that they are returning instead.
|
32834
|
+
for (const file in lambdaFiles) {
|
32835
|
+
if (shouldIgnorePath(file, ignoreFilter, false)) {
|
32836
|
+
delete lambdaFiles[file];
|
32837
|
+
}
|
32838
|
+
}
|
32326
32839
|
const entry = path_1.join(workPath, '.output', 'server', 'pages', entrypoint);
|
32327
32840
|
await fs_extra_1.default.ensureDir(path_1.dirname(entry));
|
32328
32841
|
await linkOrCopy(files[entrypoint].fsPath, entry);
|
@@ -34426,6 +34939,73 @@ function streamToBuffer(stream) {
|
|
34426
34939
|
exports.default = streamToBuffer;
|
34427
34940
|
|
34428
34941
|
|
34942
|
+
/***/ }),
|
34943
|
+
|
34944
|
+
/***/ 1148:
|
34945
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
34946
|
+
|
34947
|
+
"use strict";
|
34948
|
+
|
34949
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
34950
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
34951
|
+
};
|
34952
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
34953
|
+
const path_1 = __importDefault(__webpack_require__(5622));
|
34954
|
+
const fs_extra_1 = __importDefault(__webpack_require__(5392));
|
34955
|
+
const ignore_1 = __importDefault(__webpack_require__(3556));
|
34956
|
+
function isCodedError(error) {
|
34957
|
+
return (error !== null &&
|
34958
|
+
error !== undefined &&
|
34959
|
+
error.code !== undefined);
|
34960
|
+
}
|
34961
|
+
function clearRelative(s) {
|
34962
|
+
return s.replace(/(\n|^)\.\//g, '$1');
|
34963
|
+
}
|
34964
|
+
async function default_1(downloadPath, rootDirectory) {
|
34965
|
+
const readFile = async (p) => {
|
34966
|
+
try {
|
34967
|
+
return await fs_extra_1.default.readFile(p, 'utf8');
|
34968
|
+
}
|
34969
|
+
catch (error) {
|
34970
|
+
if (error.code === 'ENOENT' ||
|
34971
|
+
(error instanceof Error && error.message.includes('ENOENT'))) {
|
34972
|
+
return undefined;
|
34973
|
+
}
|
34974
|
+
throw error;
|
34975
|
+
}
|
34976
|
+
};
|
34977
|
+
const vercelIgnorePath = path_1.default.join(downloadPath, rootDirectory || '', '.vercelignore');
|
34978
|
+
const nowIgnorePath = path_1.default.join(downloadPath, rootDirectory || '', '.nowignore');
|
34979
|
+
const ignoreContents = [];
|
34980
|
+
try {
|
34981
|
+
ignoreContents.push(...(await Promise.all([readFile(vercelIgnorePath), readFile(nowIgnorePath)])).filter(Boolean));
|
34982
|
+
}
|
34983
|
+
catch (error) {
|
34984
|
+
if (isCodedError(error) && error.code === 'ENOTDIR') {
|
34985
|
+
console.log(`Warning: Cannot read ignore file from ${vercelIgnorePath}`);
|
34986
|
+
}
|
34987
|
+
else {
|
34988
|
+
throw error;
|
34989
|
+
}
|
34990
|
+
}
|
34991
|
+
if (ignoreContents.length === 2) {
|
34992
|
+
throw new Error('Cannot use both a `.vercelignore` and `.nowignore` file. Please delete the `.nowignore` file.');
|
34993
|
+
}
|
34994
|
+
if (ignoreContents.length === 0) {
|
34995
|
+
return () => false;
|
34996
|
+
}
|
34997
|
+
const ignoreFilter = ignore_1.default().add(clearRelative(ignoreContents[0]));
|
34998
|
+
return function (p) {
|
34999
|
+
// we should not ignore now.json and vercel.json if it asked to.
|
35000
|
+
// we depend on these files for building the app with sourceless
|
35001
|
+
if (p === 'now.json' || p === 'vercel.json')
|
35002
|
+
return false;
|
35003
|
+
return ignoreFilter.test(p).ignored;
|
35004
|
+
};
|
35005
|
+
}
|
35006
|
+
exports.default = default_1;
|
35007
|
+
|
35008
|
+
|
34429
35009
|
/***/ }),
|
34430
35010
|
|
34431
35011
|
/***/ 2855:
|
@@ -34459,7 +35039,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
34459
35039
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
34460
35040
|
};
|
34461
35041
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
34462
|
-
exports.getPlatformEnv = exports.isStaticRuntime = exports.isOfficialRuntime = exports.updateRoutesManifest = exports.updateFunctionsManifest = exports.convertRuntimeToPlugin = exports.normalizePath = exports.readConfigFile = exports.DetectorFilesystem = exports.detectFramework = exports.detectApiExtensions = exports.detectApiDirectory = exports.detectOutputDirectory = exports.detectBuilders = exports.scanParentDirs = exports.getLambdaOptionsFromFunction = exports.isSymbolicLink = exports.debug = exports.shouldServe = exports.streamToBuffer = exports.getSpawnOptions = exports.getDiscontinuedNodeVersions = exports.getLatestNodeVersion = exports.getNodeVersion = exports.runShellScript = exports.runPipInstall = exports.runBundleInstall = exports.runNpmInstall = exports.getNodeBinPath = exports.walkParentDirs = exports.spawnCommand = exports.execCommand = exports.runPackageJsonScript = exports.installDependencies = exports.getScriptName = exports.spawnAsync = exports.execAsync = exports.rename = exports.glob = exports.getWriteableDirectory = exports.download = exports.Prerender = exports.createLambda = exports.Lambda = exports.FileRef = exports.FileFsRef = exports.FileBlob = void 0;
|
35042
|
+
exports.getInputHash = exports.getPlatformEnv = exports.isStaticRuntime = exports.isOfficialRuntime = exports.updateRoutesManifest = exports.updateFunctionsManifest = exports.convertRuntimeToPlugin = exports.normalizePath = exports.readConfigFile = exports.DetectorFilesystem = exports.detectFramework = exports.detectApiExtensions = exports.detectApiDirectory = exports.detectOutputDirectory = exports.detectBuilders = exports.getIgnoreFilter = exports.scanParentDirs = exports.getLambdaOptionsFromFunction = exports.isSymbolicLink = exports.debug = exports.shouldServe = exports.streamToBuffer = exports.getSpawnOptions = exports.getDiscontinuedNodeVersions = exports.getLatestNodeVersion = exports.getNodeVersion = exports.runShellScript = exports.runPipInstall = exports.runBundleInstall = exports.runNpmInstall = exports.getNodeBinPath = exports.walkParentDirs = exports.spawnCommand = exports.execCommand = exports.runPackageJsonScript = exports.installDependencies = exports.getScriptName = exports.spawnAsync = exports.execAsync = exports.rename = exports.glob = exports.getWriteableDirectory = exports.download = exports.Prerender = exports.createLambda = exports.Lambda = exports.FileRef = exports.FileFsRef = exports.FileBlob = void 0;
|
35043
|
+
const crypto_1 = __webpack_require__(6417);
|
34463
35044
|
const file_blob_1 = __importDefault(__webpack_require__(2397));
|
34464
35045
|
exports.FileBlob = file_blob_1.default;
|
34465
35046
|
const file_fs_ref_1 = __importDefault(__webpack_require__(9331));
|
@@ -34508,6 +35089,8 @@ const should_serve_1 = __importDefault(__webpack_require__(2564));
|
|
34508
35089
|
exports.shouldServe = should_serve_1.default;
|
34509
35090
|
const debug_1 = __importDefault(__webpack_require__(1868));
|
34510
35091
|
exports.debug = debug_1.default;
|
35092
|
+
const get_ignore_filter_1 = __importDefault(__webpack_require__(1148));
|
35093
|
+
exports.getIgnoreFilter = get_ignore_filter_1.default;
|
34511
35094
|
var detect_builders_1 = __webpack_require__(4246);
|
34512
35095
|
Object.defineProperty(exports, "detectBuilders", ({ enumerable: true, get: function () { return detect_builders_1.detectBuilders; } }));
|
34513
35096
|
Object.defineProperty(exports, "detectOutputDirectory", ({ enumerable: true, get: function () { return detect_builders_1.detectOutputDirectory; } }));
|
@@ -34567,6 +35150,14 @@ const getPlatformEnv = (name) => {
|
|
34567
35150
|
return n;
|
34568
35151
|
};
|
34569
35152
|
exports.getPlatformEnv = getPlatformEnv;
|
35153
|
+
/**
|
35154
|
+
* Helper function for generating file or directories names in `.output/inputs`
|
35155
|
+
* for dependencies of files provided to the File System API.
|
35156
|
+
*/
|
35157
|
+
const getInputHash = (source) => {
|
35158
|
+
return crypto_1.createHash('sha1').update(source).digest('hex');
|
35159
|
+
};
|
35160
|
+
exports.getInputHash = getInputHash;
|
34570
35161
|
|
34571
35162
|
|
34572
35163
|
/***/ }),
|
@@ -34956,6 +35547,14 @@ module.exports = require("constants");
|
|
34956
35547
|
|
34957
35548
|
/***/ }),
|
34958
35549
|
|
35550
|
+
/***/ 6417:
|
35551
|
+
/***/ ((module) => {
|
35552
|
+
|
35553
|
+
"use strict";
|
35554
|
+
module.exports = require("crypto");
|
35555
|
+
|
35556
|
+
/***/ }),
|
35557
|
+
|
34959
35558
|
/***/ 8614:
|
34960
35559
|
/***/ ((module) => {
|
34961
35560
|
|
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.30",
|
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": "9227471acaa7102c0e37b338c6ebcc05cbc95486"
|
53
53
|
}
|