@vercel/build-utils 2.15.2-canary.2 → 2.15.2-canary.5

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.
@@ -136,6 +136,10 @@ async function getNodeVersion(destPath, _nodeVersion, config = {}, meta = {}) {
136
136
  const latest = node_version_1.getLatestNodeVersion();
137
137
  return { ...latest, runtime: 'nodejs' };
138
138
  }
139
+ if (process.env.ENABLE_EXPERIMENTAL_NODE16 === '1') {
140
+ console.warn('Warning: Using experimental Node.js 16.x due to ENABLE_EXPERIMENTAL_NODE16=1');
141
+ return { major: 16, range: '16.x', runtime: 'nodejs16.x' };
142
+ }
139
143
  const { packageJson } = await scanParentDirs(destPath, true);
140
144
  let { nodeVersion } = config;
141
145
  let isAuto = true;
package/dist/index.js CHANGED
@@ -7663,15 +7663,26 @@ IconvLiteDecoderStream.prototype.collect = function(cb) {
7663
7663
  /***/ ((module) => {
7664
7664
 
7665
7665
  // A simple implementation of make-array
7666
- function make_array (subject) {
7666
+ function makeArray (subject) {
7667
7667
  return Array.isArray(subject)
7668
7668
  ? subject
7669
7669
  : [subject]
7670
7670
  }
7671
7671
 
7672
- const REGEX_BLANK_LINE = /^\s+$/
7673
- const REGEX_LEADING_EXCAPED_EXCLAMATION = /^\\!/
7674
- const REGEX_LEADING_EXCAPED_HASH = /^\\#/
7672
+ const EMPTY = ''
7673
+ const SPACE = ' '
7674
+ const ESCAPE = '\\'
7675
+ const REGEX_TEST_BLANK_LINE = /^\s+$/
7676
+ const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/
7677
+ const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/
7678
+ const REGEX_SPLITALL_CRLF = /\r?\n/g
7679
+ // /foo,
7680
+ // ./foo,
7681
+ // ../foo,
7682
+ // .
7683
+ // ..
7684
+ const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/
7685
+
7675
7686
  const SLASH = '/'
7676
7687
  const KEY_IGNORE = typeof Symbol !== 'undefined'
7677
7688
  ? Symbol.for('node-ignore')
@@ -7683,6 +7694,8 @@ const define = (object, key, value) =>
7683
7694
 
7684
7695
  const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g
7685
7696
 
7697
+ const RETURN_FALSE = () => false
7698
+
7686
7699
  // Sanitize the range of a regular expression
7687
7700
  // The cases are complicated, see test cases for details
7688
7701
  const sanitizeRange = range => range.replace(
@@ -7691,9 +7704,15 @@ const sanitizeRange = range => range.replace(
7691
7704
  ? match
7692
7705
  // Invalid range (out of order) which is ok for gitignore rules but
7693
7706
  // fatal for JavaScript regular expression, so eliminate it.
7694
- : ''
7707
+ : EMPTY
7695
7708
  )
7696
7709
 
7710
+ // See fixtures #59
7711
+ const cleanRangeBackSlash = slashes => {
7712
+ const {length} = slashes
7713
+ return slashes.slice(0, length - length % 2)
7714
+ }
7715
+
7697
7716
  // > If the pattern ends with a slash,
7698
7717
  // > it is removed for the purpose of the following description,
7699
7718
  // > but it would only find a match with a directory.
@@ -7705,7 +7724,7 @@ const sanitizeRange = range => range.replace(
7705
7724
  // you could use option `mark: true` with `glob`
7706
7725
 
7707
7726
  // '`foo/`' should not continue with the '`..`'
7708
- const DEFAULT_REPLACER_PREFIX = [
7727
+ const REPLACERS = [
7709
7728
 
7710
7729
  // > Trailing spaces are ignored unless they are quoted with backslash ("\")
7711
7730
  [
@@ -7714,14 +7733,14 @@ const DEFAULT_REPLACER_PREFIX = [
7714
7733
  // (a \ ) -> (a )
7715
7734
  /\\?\s+$/,
7716
7735
  match => match.indexOf('\\') === 0
7717
- ? ' '
7718
- : ''
7736
+ ? SPACE
7737
+ : EMPTY
7719
7738
  ],
7720
7739
 
7721
7740
  // replace (\ ) with ' '
7722
7741
  [
7723
7742
  /\\\s/g,
7724
- () => ' '
7743
+ () => SPACE
7725
7744
  ],
7726
7745
 
7727
7746
  // Escape metacharacters
@@ -7742,19 +7761,10 @@ const DEFAULT_REPLACER_PREFIX = [
7742
7761
  // > - the opening curly brace {,
7743
7762
  // > These special characters are often called "metacharacters".
7744
7763
  [
7745
- /[\\^$.|*+(){]/g,
7764
+ /[\\$.|*+(){^]/g,
7746
7765
  match => `\\${match}`
7747
7766
  ],
7748
7767
 
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
7768
  [
7759
7769
  // > a question mark (?) matches a single character
7760
7770
  /(?!\\)\?/g,
@@ -7788,10 +7798,8 @@ const DEFAULT_REPLACER_PREFIX = [
7788
7798
 
7789
7799
  // '**/foo' <-> 'foo'
7790
7800
  () => '^(?:.*\\/)?'
7791
- ]
7792
- ]
7801
+ ],
7793
7802
 
7794
- const DEFAULT_REPLACER_SUFFIX = [
7795
7803
  // starting
7796
7804
  [
7797
7805
  // there will be no leading '/'
@@ -7799,11 +7807,20 @@ const DEFAULT_REPLACER_SUFFIX = [
7799
7807
  // If starts with '**', adding a '^' to the regular expression also works
7800
7808
  /^(?=[^^])/,
7801
7809
  function startingReplacer () {
7810
+ // If has a slash `/` at the beginning or middle
7802
7811
  return !/\/(?!$)/.test(this)
7812
+ // > Prior to 2.22.1
7803
7813
  // > If the pattern does not contain a slash /,
7804
7814
  // > Git treats it as a shell glob pattern
7805
7815
  // Actually, if there is only a trailing slash,
7806
7816
  // git also treats it as a shell glob pattern
7817
+
7818
+ // After 2.22.1 (compatible but clearer)
7819
+ // > If there is a separator at the beginning or middle (or both)
7820
+ // > of the pattern, then the pattern is relative to the directory
7821
+ // > level of the particular .gitignore file itself.
7822
+ // > Otherwise the pattern may also match at any level below
7823
+ // > the .gitignore level.
7807
7824
  ? '(?:^|\\/)'
7808
7825
 
7809
7826
  // > Otherwise, Git treats the pattern as a shell glob suitable for
@@ -7821,7 +7838,7 @@ const DEFAULT_REPLACER_SUFFIX = [
7821
7838
  // should not use '*', or it will be replaced by the next replacer
7822
7839
 
7823
7840
  // Check if it is not the last `'/**'`
7824
- (match, index, str) => index + 6 < str.length
7841
+ (_, index, str) => index + 6 < str.length
7825
7842
 
7826
7843
  // case: /**/
7827
7844
  // > A slash followed by two consecutive asterisks then a slash matches
@@ -7848,119 +7865,138 @@ const DEFAULT_REPLACER_SUFFIX = [
7848
7865
 
7849
7866
  // '*.js' matches '.js'
7850
7867
  // '*.js' doesn't match 'abc'
7851
- (match, p1) => `${p1}[^\\/]*`
7868
+ (_, p1) => `${p1}[^\\/]*`
7852
7869
  ],
7853
7870
 
7854
- // trailing wildcard
7855
7871
  [
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
- }
7872
+ // unescape, revert step 3 except for back slash
7873
+ // For example, if a user escape a '\\*',
7874
+ // after step 3, the result will be '\\\\\\*'
7875
+ /\\\\\\(?=[$.|*+(){^])/g,
7876
+ () => ESCAPE
7873
7877
  ],
7874
7878
 
7875
7879
  [
7876
- // unescape
7877
- /\\\\\\/g,
7878
- () => '\\'
7879
- ]
7880
- ]
7880
+ // '\\\\' -> '\\'
7881
+ /\\\\/g,
7882
+ () => ESCAPE
7883
+ ],
7881
7884
 
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(/|$)
7885
+ [
7886
+ // > The range notation, e.g. [a-zA-Z],
7887
+ // > can be used to match one of the characters in a range.
7888
+
7889
+ // `\` is escaped by step 3
7890
+ /(\\)?\[([^\]/]*?)(\\*)($|\])/g,
7891
+ (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE
7892
+ // '\\[bar]' -> '\\\\[bar\\]'
7893
+ ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}`
7894
+ : close === ']'
7895
+ ? endEscape.length % 2 === 0
7896
+ // A normal case, and it is a range notation
7897
+ // '[bar]'
7898
+ // '[bar\\\\]'
7899
+ ? `[${sanitizeRange(range)}${endEscape}]`
7900
+ // Invalid range notaton
7901
+ // '[bar\\]' -> '[bar\\\\]'
7902
+ : '[]'
7903
+ : '[]'
7904
+ ],
7896
7905
 
7897
7906
  // ending
7898
7907
  [
7899
7908
  // 'js' will not match 'js.'
7900
7909
  // 'ab' will not match 'abc'
7901
- /(?:[^*/])$/,
7910
+ /(?:[^*])$/,
7911
+
7912
+ // WTF!
7913
+ // https://git-scm.com/docs/gitignore
7914
+ // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1)
7915
+ // which re-fixes #24, #38
7916
+
7917
+ // > If there is a separator at the end of the pattern then the pattern
7918
+ // > will only match directories, otherwise the pattern can match both
7919
+ // > files and directories.
7902
7920
 
7903
7921
  // 'js*' will not match 'a.js'
7904
7922
  // 'js/' will not match 'a.js'
7905
7923
  // 'js' will match 'a.js' and 'a.js/'
7906
- match => `${match}(?=$|\\/)`
7924
+ match => /\/$/.test(match)
7925
+ // foo/ will not match 'foo'
7926
+ ? `${match}$`
7927
+ // foo matches 'foo' and 'foo/'
7928
+ : `${match}(?=$|\\/$)`
7907
7929
  ],
7908
7930
 
7909
- ...DEFAULT_REPLACER_SUFFIX
7910
- ]
7931
+ // trailing wildcard
7932
+ [
7933
+ /(\^|\\\/)?\\\*$/,
7934
+ (_, p1) => {
7935
+ const prefix = p1
7936
+ // '\^':
7937
+ // '/*' does not match EMPTY
7938
+ // '/*' does not match everything
7911
7939
 
7912
- const NEGATIVE_REPLACERS = [
7913
- ...DEFAULT_REPLACER_PREFIX,
7940
+ // '\\\/':
7941
+ // 'abc/*' does not match 'abc/'
7942
+ ? `${p1}[^/]+`
7914
7943
 
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.
7944
+ // 'a*' matches 'a'
7945
+ // 'a*' matches 'aa'
7946
+ : '[^/]*'
7919
7947
 
7920
- // eg:
7921
- // ['node_modules/*', '!node_modules']
7922
- // should ignore `node_modules/a.js`
7923
- [
7924
- /(?:[^*])$/,
7925
- match => `${match}(?=$|\\/$)`
7948
+ return `${prefix}(?=$|\\/$)`
7949
+ }
7926
7950
  ],
7927
-
7928
- ...DEFAULT_REPLACER_SUFFIX
7929
7951
  ]
7930
7952
 
7931
7953
  // A simple cache, because an ignore rule only has only one certain meaning
7932
- const cache = Object.create(null)
7954
+ const regexCache = Object.create(null)
7933
7955
 
7934
7956
  // @param {pattern}
7935
- const make_regex = (pattern, negative, ignorecase) => {
7936
- const r = cache[pattern]
7937
- if (r) {
7938
- return r
7939
- }
7957
+ const makeRegex = (pattern, ignoreCase) => {
7958
+ let source = regexCache[pattern]
7940
7959
 
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
- )
7960
+ if (!source) {
7961
+ source = REPLACERS.reduce(
7962
+ (prev, current) => prev.replace(current[0], current[1].bind(pattern)),
7963
+ pattern
7964
+ )
7965
+ regexCache[pattern] = source
7966
+ }
7949
7967
 
7950
- return cache[pattern] = ignorecase
7968
+ return ignoreCase
7951
7969
  ? new RegExp(source, 'i')
7952
7970
  : new RegExp(source)
7953
7971
  }
7954
7972
 
7973
+ const isString = subject => typeof subject === 'string'
7974
+
7955
7975
  // > A blank line matches no files, so it can serve as a separator for readability.
7956
7976
  const checkPattern = pattern => pattern
7957
- && typeof pattern === 'string'
7958
- && !REGEX_BLANK_LINE.test(pattern)
7977
+ && isString(pattern)
7978
+ && !REGEX_TEST_BLANK_LINE.test(pattern)
7959
7979
 
7960
7980
  // > A line starting with # serves as a comment.
7961
7981
  && pattern.indexOf('#') !== 0
7962
7982
 
7963
- const createRule = (pattern, ignorecase) => {
7983
+ const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF)
7984
+
7985
+ class IgnoreRule {
7986
+ constructor (
7987
+ origin,
7988
+ pattern,
7989
+ negative,
7990
+ regex
7991
+ ) {
7992
+ this.origin = origin
7993
+ this.pattern = pattern
7994
+ this.negative = negative
7995
+ this.regex = regex
7996
+ }
7997
+ }
7998
+
7999
+ const createRule = (pattern, ignoreCase) => {
7964
8000
  const origin = pattern
7965
8001
  let negative = false
7966
8002
 
@@ -7973,44 +8009,98 @@ const createRule = (pattern, ignorecase) => {
7973
8009
  pattern = pattern
7974
8010
  // > Put a backslash ("\") in front of the first "!" for patterns that
7975
8011
  // > begin with a literal "!", for example, `"\!important!.txt"`.
7976
- .replace(REGEX_LEADING_EXCAPED_EXCLAMATION, '!')
8012
+ .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!')
7977
8013
  // > Put a backslash ("\") in front of the first hash for patterns that
7978
8014
  // > begin with a hash.
7979
- .replace(REGEX_LEADING_EXCAPED_HASH, '#')
8015
+ .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#')
7980
8016
 
7981
- const regex = make_regex(pattern, negative, ignorecase)
8017
+ const regex = makeRegex(pattern, ignoreCase)
7982
8018
 
7983
- return {
8019
+ return new IgnoreRule(
7984
8020
  origin,
7985
8021
  pattern,
7986
8022
  negative,
7987
8023
  regex
8024
+ )
8025
+ }
8026
+
8027
+ const throwError = (message, Ctor) => {
8028
+ throw new Ctor(message)
8029
+ }
8030
+
8031
+ const checkPath = (path, originalPath, doThrow) => {
8032
+ if (!isString(path)) {
8033
+ return doThrow(
8034
+ `path must be a string, but got \`${originalPath}\``,
8035
+ TypeError
8036
+ )
7988
8037
  }
8038
+
8039
+ // We don't know if we should ignore EMPTY, so throw
8040
+ if (!path) {
8041
+ return doThrow(`path must not be empty`, TypeError)
8042
+ }
8043
+
8044
+ // Check if it is a relative path
8045
+ if (checkPath.isNotRelative(path)) {
8046
+ const r = '`path.relative()`d'
8047
+ return doThrow(
8048
+ `path should be a ${r} string, but got "${originalPath}"`,
8049
+ RangeError
8050
+ )
8051
+ }
8052
+
8053
+ return true
7989
8054
  }
7990
8055
 
7991
- class IgnoreBase {
8056
+ const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path)
8057
+
8058
+ checkPath.isNotRelative = isNotRelative
8059
+ checkPath.convert = p => p
8060
+
8061
+ class Ignore {
7992
8062
  constructor ({
7993
- ignorecase = true
8063
+ ignorecase = true,
8064
+ ignoreCase = ignorecase,
8065
+ allowRelativePaths = false
7994
8066
  } = {}) {
7995
- this._rules = []
7996
- this._ignorecase = ignorecase
7997
8067
  define(this, KEY_IGNORE, true)
8068
+
8069
+ this._rules = []
8070
+ this._ignoreCase = ignoreCase
8071
+ this._allowRelativePaths = allowRelativePaths
7998
8072
  this._initCache()
7999
8073
  }
8000
8074
 
8001
8075
  _initCache () {
8002
- this._cache = Object.create(null)
8076
+ this._ignoreCache = Object.create(null)
8077
+ this._testCache = Object.create(null)
8003
8078
  }
8004
8079
 
8005
- // @param {Array.<string>|string|Ignore} pattern
8006
- add (pattern) {
8007
- this._added = false
8080
+ _addPattern (pattern) {
8081
+ // #32
8082
+ if (pattern && pattern[KEY_IGNORE]) {
8083
+ this._rules = this._rules.concat(pattern._rules)
8084
+ this._added = true
8085
+ return
8086
+ }
8008
8087
 
8009
- if (typeof pattern === 'string') {
8010
- pattern = pattern.split(/\r?\n/g)
8088
+ if (checkPattern(pattern)) {
8089
+ const rule = createRule(pattern, this._ignoreCase)
8090
+ this._added = true
8091
+ this._rules.push(rule)
8011
8092
  }
8093
+ }
8012
8094
 
8013
- make_array(pattern).forEach(this._addPattern, this)
8095
+ // @param {Array<string> | string | Ignore} pattern
8096
+ add (pattern) {
8097
+ this._added = false
8098
+
8099
+ makeArray(
8100
+ isString(pattern)
8101
+ ? splitPattern(pattern)
8102
+ : pattern
8103
+ ).forEach(this._addPattern, this)
8014
8104
 
8015
8105
  // Some rules have just added to the ignore,
8016
8106
  // making the behavior changed.
@@ -8026,41 +8116,69 @@ class IgnoreBase {
8026
8116
  return this.add(pattern)
8027
8117
  }
8028
8118
 
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
- }
8119
+ // | ignored : unignored
8120
+ // negative | 0:0 | 0:1 | 1:0 | 1:1
8121
+ // -------- | ------- | ------- | ------- | --------
8122
+ // 0 | TEST | TEST | SKIP | X
8123
+ // 1 | TESTIF | SKIP | TEST | X
8036
8124
 
8037
- if (checkPattern(pattern)) {
8038
- const rule = createRule(pattern, this._ignorecase)
8039
- this._added = true
8040
- this._rules.push(rule)
8125
+ // - SKIP: always skip
8126
+ // - TEST: always test
8127
+ // - TESTIF: only test if checkUnignored
8128
+ // - X: that never happen
8129
+
8130
+ // @param {boolean} whether should check if the path is unignored,
8131
+ // setting `checkUnignored` to `false` could reduce additional
8132
+ // path matching.
8133
+
8134
+ // @returns {TestResult} true if a file is ignored
8135
+ _testOne (path, checkUnignored) {
8136
+ let ignored = false
8137
+ let unignored = false
8138
+
8139
+ this._rules.forEach(rule => {
8140
+ const {negative} = rule
8141
+ if (
8142
+ unignored === negative && ignored !== unignored
8143
+ || negative && !ignored && !unignored && !checkUnignored
8144
+ ) {
8145
+ return
8146
+ }
8147
+
8148
+ const matched = rule.regex.test(path)
8149
+
8150
+ if (matched) {
8151
+ ignored = !negative
8152
+ unignored = negative
8153
+ }
8154
+ })
8155
+
8156
+ return {
8157
+ ignored,
8158
+ unignored
8041
8159
  }
8042
8160
  }
8043
8161
 
8044
- filter (paths) {
8045
- return make_array(paths).filter(path => this._filter(path))
8046
- }
8162
+ // @returns {TestResult}
8163
+ _test (originalPath, cache, checkUnignored, slices) {
8164
+ const path = originalPath
8165
+ // Supports nullable path
8166
+ && checkPath.convert(originalPath)
8047
8167
 
8048
- createFilter () {
8049
- return path => this._filter(path)
8050
- }
8168
+ checkPath(
8169
+ path,
8170
+ originalPath,
8171
+ this._allowRelativePaths
8172
+ ? RETURN_FALSE
8173
+ : throwError
8174
+ )
8051
8175
 
8052
- ignores (path) {
8053
- return !this._filter(path)
8176
+ return this._t(path, cache, checkUnignored, slices)
8054
8177
  }
8055
8178
 
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]
8179
+ _t (path, cache, checkUnignored, slices) {
8180
+ if (path in cache) {
8181
+ return cache[path]
8064
8182
  }
8065
8183
 
8066
8184
  if (!slices) {
@@ -8071,34 +8189,56 @@ class IgnoreBase {
8071
8189
 
8072
8190
  slices.pop()
8073
8191
 
8074
- return this._cache[path] = slices.length
8192
+ // If the path has no parent directory, just test it
8193
+ if (!slices.length) {
8194
+ return cache[path] = this._testOne(path, checkUnignored)
8195
+ }
8196
+
8197
+ const parent = this._t(
8198
+ slices.join(SLASH) + SLASH,
8199
+ cache,
8200
+ checkUnignored,
8201
+ slices
8202
+ )
8203
+
8204
+ // If the path contains a parent directory, check the parent first
8205
+ return cache[path] = parent.ignored
8075
8206
  // > It is not possible to re-include a file if a parent directory of
8076
8207
  // > 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)
8208
+ ? parent
8209
+ : this._testOne(path, checkUnignored)
8210
+ }
8080
8211
 
8081
- // Or only test the path
8082
- : this._test(path)
8212
+ ignores (path) {
8213
+ return this._test(path, this._ignoreCache, false).ignored
8083
8214
  }
8084
8215
 
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
8216
+ createFilter () {
8217
+ return path => !this.ignores(path)
8218
+ }
8089
8219
 
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
- })
8220
+ filter (paths) {
8221
+ return makeArray(paths).filter(this.createFilter())
8222
+ }
8097
8223
 
8098
- return !matched
8224
+ // @returns {TestResult}
8225
+ test (path) {
8226
+ return this._test(path, this._testCache, true)
8099
8227
  }
8100
8228
  }
8101
8229
 
8230
+ const factory = options => new Ignore(options)
8231
+
8232
+ const isPathValid = path =>
8233
+ checkPath(path && checkPath.convert(path), path, RETURN_FALSE)
8234
+
8235
+ factory.isPathValid = isPathValid
8236
+
8237
+ // Fixes typescript
8238
+ factory.default = factory
8239
+
8240
+ module.exports = factory
8241
+
8102
8242
  // Windows
8103
8243
  // --------------------------------------------------------------
8104
8244
  /* istanbul ignore if */
@@ -8110,21 +8250,21 @@ if (
8110
8250
  || process.platform === 'win32'
8111
8251
  )
8112
8252
  ) {
8113
- const filter = IgnoreBase.prototype._filter
8114
-
8115
8253
  /* eslint no-control-regex: "off" */
8116
- const make_posix = str => /^\\\\\?\\/.test(str)
8117
- || /[^\x00-\x80]+/.test(str)
8254
+ const makePosix = str => /^\\\\\?\\/.test(str)
8255
+ || /["<>|\u0000-\u001F]+/u.test(str)
8118
8256
  ? str
8119
8257
  : str.replace(/\\/g, '/')
8120
8258
 
8121
- IgnoreBase.prototype._filter = function filterWin32 (path, slices) {
8122
- path = make_posix(path)
8123
- return filter.call(this, path, slices)
8124
- }
8125
- }
8259
+ checkPath.convert = makePosix
8126
8260
 
8127
- module.exports = options => new IgnoreBase(options)
8261
+ // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/'
8262
+ // 'd:\\foo'
8263
+ const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i
8264
+ checkPath.isNotRelative = path =>
8265
+ REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path)
8266
+ || isNotRelative(path)
8267
+ }
8128
8268
 
8129
8269
 
8130
8270
  /***/ }),
@@ -26617,6 +26757,7 @@ exports.frameworks = [
26617
26757
  slug: 'nextjs',
26618
26758
  demo: 'https://nextjs-template.vercel.app',
26619
26759
  logo: 'https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/next.svg',
26760
+ darkModeLogo: 'https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/next-dark.svg',
26620
26761
  screenshot: 'https://assets.vercel.com/image/upload/v1647366075/front/import/nextjs.png',
26621
26762
  tagline: 'Next.js makes you productive with React instantly — whether you want to build static or dynamic sites.',
26622
26763
  description: 'A Next.js app and a Serverless Function API.',
@@ -34750,6 +34891,10 @@ async function getNodeVersion(destPath, _nodeVersion, config = {}, meta = {}) {
34750
34891
  const latest = node_version_1.getLatestNodeVersion();
34751
34892
  return { ...latest, runtime: 'nodejs' };
34752
34893
  }
34894
+ if (process.env.ENABLE_EXPERIMENTAL_NODE16 === '1') {
34895
+ console.warn('Warning: Using experimental Node.js 16.x due to ENABLE_EXPERIMENTAL_NODE16=1');
34896
+ return { major: 16, range: '16.x', runtime: 'nodejs16.x' };
34897
+ }
34753
34898
  const { packageJson } = await scanParentDirs(destPath, true);
34754
34899
  let { nodeVersion } = config;
34755
34900
  let isAuto = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/build-utils",
3
- "version": "2.15.2-canary.2",
3
+ "version": "2.15.2-canary.5",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.js",
@@ -23,14 +23,14 @@
23
23
  "@types/end-of-stream": "^1.4.0",
24
24
  "@types/fs-extra": "9.0.13",
25
25
  "@types/glob": "^7.1.1",
26
- "@types/jest": "27.0.1",
26
+ "@types/jest": "27.4.1",
27
27
  "@types/js-yaml": "3.12.1",
28
28
  "@types/ms": "0.7.31",
29
29
  "@types/multistream": "2.1.1",
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.7.1",
33
+ "@vercel/frameworks": "0.7.2-canary.1",
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": "b61f049f1186ccc804cea35bcf61d16583ed6ca2"
52
+ "gitHead": "438576fc7c392e754d1fc85fc1d9f3122e80d015"
53
53
  }