foo)
+
+ },
+ docs: {// for example:
+ //possessive: {desc: "+This will be appended to the existing entry." },
+ //namedgroup: {tip: "This will overwrite the existing entry." }
+ }
+};
+
+/*
+RegExr: Learn, Build, & Test RegEx
+Copyright (C) 2017 gskinner.com, inc.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+/*
+The PCRE profile is almost a straight copy of the core profile.
+*/
+let y$1 = true,
+ n$1 = false;
+let pcre = {
+ id: "pcre",
+ label: "PCRE",
+ browser: false,
+ flags: {
+ "u": n$1,
+ "y": n$1
+ },
+ badEscChars: "uUlLN".split("").reduce((o, c) => {
+ o[c] = y$1;
+ return o;
+ }, {}),
+ escCharCodes: {
+ "v": n$1 // vertical tab // PCRE support \v as vertical whitespace
+
+ },
+ tokens: {
+ "escunicodeu": n$1,
+ // \uFFFF
+ "escunicodeub": n$1 // \u{00A9}
+ // octalo PCRE 8.34+
+
+ },
+ substTokens: {
+ "subst_$esc": n$1,
+ // $$
+ "subst_$&match": n$1,
+ // $&
+ "subst_$before": n$1,
+ // $`
+ "subst_$after": n$1 // $'
+
+ },
+ config: {
+ "reftooctalalways": n$1,
+ // does a single digit reference \1 become an octal? (vs remain an unmatched ref)
+ "substdecomposeref": n$1,
+ // will a subst reference decompose? (ex. \3 becomes "\" & "3" if < 3 groups)
+ "looseesc": n$1 // should unrecognized escape sequences match the character (ex. \u could match "u") // disabled when `u` flag is set
+
+ },
+ docs: {
+ "escoctal": {
+ ext: "+The syntax \\o{FFF}
is also supported.
"
+ },
+ "numref": {
+ ext: "There are multiple syntaxes for this feature: \\1
\\g1
\\g{1}
.
" + "The latter syntaxes support relative values preceded by +
or -
. For example \\g-1
would match the group preceding the reference.
"
+ },
+ "lazy": {
+ ext: "+This behaviour is reversed by the ungreedy (U
) flag/modifier.
"
+ }
+ }
+};
+
+/*
+RegExr: Learn, Build, & Test RegEx
+Copyright (C) 2017 gskinner.com, inc.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+/*
+The javascript profile disables a large number of features.
+
+Note that JS warnings are currently added in addJSWarnings in the ExpresssionLexer.
+*/
+let n$2 = false;
+
+function test(expr, flag) {
+ try {
+ return new RegExp(expr, flag) && undefined;
+ } catch (e) {
+ return n$2;
+ }
+}
+
+function testFlag(flag) {
+ return test(".", flag);
+}
+
+let unicodeFlag = testFlag("u");
+let stickyFlag = testFlag("y");
+let dotallFlag = testFlag("s");
+let lookbehind = test("(?<=A)");
+let namedgroup = test("(?B)");
+let unicodecat = test("\\p{Ll}", "u"); // disabled when `u` flag is not set
+
+let javascript = {
+ id: "js",
+ label: "JavaScript",
+ browser: true,
+ flags: {
+ "s": dotallFlag,
+ // warning
+ "x": n$2,
+ "u": unicodeFlag,
+ // warning
+ "y": stickyFlag,
+ // warning
+ "U": n$2
+ },
+ escCharCodes: {
+ "a": n$2,
+ // bell
+ "e": n$2 // escape
+
+ },
+ escCharTypes: {
+ "A": n$2,
+ // bos
+ "G": n$2,
+ // prevmatchend
+ "h": n$2,
+ // hwhitespace
+ "H": n$2,
+ // nothwhitespace
+ "K": n$2,
+ // keepout
+ "N": n$2,
+ // notlinebreak
+ "R": n$2,
+ // newline
+ "v": n$2,
+ // vwhitespace
+ "V": n$2,
+ // notvwhitespace
+ "X": n$2,
+ // unicodegrapheme
+ "Z": n$2,
+ // eos
+ "z": n$2 // abseos
+
+ },
+ unicodeScripts: unicodecat,
+ unicodeCategories: unicodecat,
+ posixCharClasses: n$2,
+ modes: n$2,
+ tokens: {
+ // classes:
+ // also in escCharSpecials and specialChars
+ "unicodecat": unicodecat,
+ // \p{Ll} \P{^Ll} \pL
+ "notunicodecat": unicodecat,
+ // \P{Ll} \p{^Ll} \PL
+ "unicodescript": unicodecat,
+ // \p{Cherokee} \P{^Cherokee}
+ "notunicodescript": unicodecat,
+ // \P{Cherokee} \p{^Cherokee}
+ "posixcharclass": n$2,
+ // [[:alpha:]]
+ // esc:
+ // also in escCharCodes and escCharSpecials
+ "escunicodeub": unicodeFlag,
+ // \u{00A9}
+ "escunicodexb": n$2,
+ // \x{00A9}
+ "escsequence": n$2,
+ // \Q...\E
+ "escoctalo": n$2,
+ // \o{377}
+ // group:
+ "namedgroup": namedgroup,
+ // (?Pfoo) (?foo) (?'name'foo)
+ "atomic": n$2,
+ // (?>foo|bar)
+ "define": n$2,
+ // (?(DEFINE)foo)
+ "branchreset": n$2,
+ // (?|(a)|(b))
+ // lookaround:
+ "poslookbehind": lookbehind,
+ // (?<=foo) // warning
+ "neglookbehind": lookbehind,
+ // (? \k'name' \k{name} (?P=name) \g{name}
+ "extnumref": n$2,
+ // \g{-1} \g{+1} \g{1} \g1 \g-1
+ "recursion": n$2,
+ // (?R) (?0) \g<0> \g'0'
+ "numsubroutine": n$2,
+ // \g<1> \g'-1' (?1) (?-1)
+ "namedsubroutine": n$2,
+ // \g \g'name' (?&name) (?P>name)
+ // quantifiers:
+ // also in specialChars
+ "possessive": n$2,
+ // special:
+ "conditional": n$2,
+ // (?(?=if)then|else)
+ "conditionalif": n$2,
+ // (?=if) any lookaround
+ "conditionalelse": n$2,
+ // |
+ "conditionalgroup": n$2,
+ // (?(1)a|b) (?(-1)a|b) (?(name)a|b)
+ "mode": n$2,
+ // (?i-x) see modes above
+ "comment": n$2 // (?#comment)
+
+ },
+ config: {
+ "forwardref": n$2,
+ // \1(a)
+ "nestedref": n$2,
+ // (\1a|b)+
+ "ctrlcodeerr": n$2,
+ // does \c error, or decompose?
+ "unicodenegated": n$2,
+ // \p{^etc}
+ "namedgroupalt": n$2 // if false, only support (?foo)
+
+ },
+ substTokens: {
+ "subst_0match": n$2,
+ // $0 \0 \{0}
+ "subst_$bgroup": n$2,
+ // ${1} ${99}
+ "subst_bsgroup": n$2 // \1 \99
+
+ },
+ docs: {
+ "subst_group": {
+ ext: ""
+ },
+ // remove other syntaxes.
+ "namedgroup": {
+ ext: ""
+ },
+ // remove other syntaxes.
+ "unicodecat": {
+ ext: "Requires the u
flag.
" + "For a list of values, see this MDN page.
"
+ } // notunicodecat, unicodescript, notunicodescript are copied from unicodecat below.
+
+ }
+};
+javascript.docs.notunicodecat = javascript.docs.unicodescript = javascript.docs.notunicodescript = javascript.docs.unicodecat;
+
+/*
+RegExr: Learn, Build, & Test RegEx
+Copyright (C) 2017 gskinner.com, inc.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+let profiles = {
+ core
+};
+profiles.pcre = merge(core, pcre);
+profiles.js = merge(core, javascript);
+
+function merge(p1, p2) {
+ // merges p1 into p2, essentially just a simple deep copy without array support.
+ for (let n in p1) {
+ if (p2[n] === false) {
+ continue;
+ } else if (typeof p1[n] === "object") {
+ p2[n] = merge(p1[n], p2[n] || {});
+ } else if (p2[n] === undefined) {
+ p2[n] = p1[n];
+ }
+ }
+
+ return p2;
+}
+
+module.exports = profiles;
+//# sourceMappingURL=profiles.js.map
diff --git a/packages/next/lib/load-custom-routes.ts b/packages/next/lib/load-custom-routes.ts
index e66f6885be44a..19227cec0e66b 100644
--- a/packages/next/lib/load-custom-routes.ts
+++ b/packages/next/lib/load-custom-routes.ts
@@ -9,7 +9,9 @@ import {
import { execOnce } from '../next-server/lib/utils'
import * as Log from '../build/output/log'
// @ts-ignore
-import Lexer from './regexr/expression-lexer'
+import Lexer from 'next/dist/compiled/regexr-lexer/lexer'
+// @ts-ignore
+import lexerProfiles from 'next/dist/compiled/regexr-lexer/profiles'
export type RouteHas =
| {
@@ -338,6 +340,7 @@ function checkCustomRoutes(
if (hasItem.value) {
const matcher = new RegExp(`^${hasItem.value}$`)
const lexer = new Lexer()
+ lexer.profile = lexerProfiles.js
lexer.parse(`/${matcher.source}/`)
Object.keys(lexer.namedGroups).forEach((groupKey) => {
diff --git a/packages/next/package.json b/packages/next/package.json
index d188702ea2be5..c8e96027df4bd 100644
--- a/packages/next/package.json
+++ b/packages/next/package.json
@@ -227,6 +227,7 @@
"postcss-preset-env": "6.7.0",
"postcss-scss": "3.0.4",
"recast": "0.18.5",
+ "regexr": "https://github.com/ijjk/regexr-lexer.git#3bcf3d1c4bc6dd9239c47acb1fb7b419823f8337",
"resolve-url-loader": "3.1.2",
"sass-loader": "10.0.5",
"schema-utils": "2.7.1",
diff --git a/packages/next/taskfile.js b/packages/next/taskfile.js
index c88180356350d..bae2e36933fd8 100644
--- a/packages/next/taskfile.js
+++ b/packages/next/taskfile.js
@@ -1,6 +1,6 @@
// eslint-disable-next-line import/no-extraneous-dependencies
const notifier = require('node-notifier')
-const { relative, basename, resolve } = require('path')
+const { relative, basename, resolve, join, dirname } = require('path')
const { Module } = require('module')
// Note:
@@ -687,9 +687,20 @@ export async function path_to_regexp(task, opts) {
.target('dist/compiled/path-to-regexp')
}
+export async function copy_regexr_lexer(task, opts) {
+ await task
+ .source(
+ join(
+ relative(__dirname, dirname(require.resolve('regexr/package.json'))),
+ 'lexer-dist/**/*'
+ )
+ )
+ .target('compiled/regexr-lexer')
+}
+
export async function precompile(task, opts) {
await task.parallel(
- ['browser_polyfills', 'path_to_regexp', 'copy_ncced'],
+ ['browser_polyfills', 'path_to_regexp', 'copy_ncced', 'copy_regexr_lexer'],
opts
)
}
diff --git a/yarn.lock b/yarn.lock
index 9d044714858c4..9e045e0b14168 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -13725,6 +13725,10 @@ regexpu-core@^4.7.1:
unicode-match-property-ecmascript "^1.0.4"
unicode-match-property-value-ecmascript "^1.2.0"
+"regexr@https://github.com/ijjk/regexr-lexer.git#3bcf3d1c4bc6dd9239c47acb1fb7b419823f8337":
+ version "3.8.0"
+ resolved "https://github.com/ijjk/regexr-lexer.git#3bcf3d1c4bc6dd9239c47acb1fb7b419823f8337"
+
registry-auth-token@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20"