refactor: identifier escapes + "self" group (#339)
Co-authored-by: Ven <vendicated@riseup.net>
This commit is contained in:
parent
4974c53f9c
commit
989bd36eeb
|
@ -84,7 +84,9 @@
|
||||||
"no-extra-semi": "error",
|
"no-extra-semi": "error",
|
||||||
"consistent-return": ["warn", { "treatUndefinedAsUnspecified": true }],
|
"consistent-return": ["warn", { "treatUndefinedAsUnspecified": true }],
|
||||||
"dot-notation": "error",
|
"dot-notation": "error",
|
||||||
"no-useless-escape": "error",
|
"no-useless-escape": ["error", {
|
||||||
|
"extra": "i"
|
||||||
|
}],
|
||||||
"no-fallthrough": "error",
|
"no-fallthrough": "error",
|
||||||
"for-direction": "error",
|
"for-direction": "error",
|
||||||
"no-async-promise-executor": "error",
|
"no-async-promise-executor": "error",
|
||||||
|
|
|
@ -62,7 +62,8 @@
|
||||||
"packageManager": "pnpm@7.13.4",
|
"packageManager": "pnpm@7.13.4",
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"patchedDependencies": {
|
"patchedDependencies": {
|
||||||
"eslint-plugin-path-alias@1.0.0": "patches/eslint-plugin-path-alias@1.0.0.patch"
|
"eslint-plugin-path-alias@1.0.0": "patches/eslint-plugin-path-alias@1.0.0.patch",
|
||||||
|
"eslint@8.28.0": "patches/eslint@8.28.0.patch"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webExt": {
|
"webExt": {
|
||||||
|
|
45
patches/eslint@8.28.0.patch
Normal file
45
patches/eslint@8.28.0.patch
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
diff --git a/lib/rules/no-useless-escape.js b/lib/rules/no-useless-escape.js
|
||||||
|
index 2046a148a17fd1d5f3a4bbc9f45f7700259d11fa..f4898c6b57355a4fd72c43a9f32bf1a36a6ccf4a 100644
|
||||||
|
--- a/lib/rules/no-useless-escape.js
|
||||||
|
+++ b/lib/rules/no-useless-escape.js
|
||||||
|
@@ -97,12 +97,30 @@ module.exports = {
|
||||||
|
escapeBackslash: "Replace the `\\` with `\\\\` to include the actual backslash character."
|
||||||
|
},
|
||||||
|
|
||||||
|
- schema: []
|
||||||
|
+ schema: [{
|
||||||
|
+ type: "object",
|
||||||
|
+ properties: {
|
||||||
|
+ extra: {
|
||||||
|
+ type: "string",
|
||||||
|
+ default: ""
|
||||||
|
+ },
|
||||||
|
+ extraCharClass: {
|
||||||
|
+ type: "string",
|
||||||
|
+ default: ""
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ additionalProperties: false
|
||||||
|
+ }]
|
||||||
|
},
|
||||||
|
|
||||||
|
create(context) {
|
||||||
|
+ const options = context.options[0] || {};
|
||||||
|
+ const { extra, extraCharClass } = options || ''
|
||||||
|
const sourceCode = context.getSourceCode();
|
||||||
|
|
||||||
|
+ const NON_CHARCLASS_ESCAPES = union(REGEX_NON_CHARCLASS_ESCAPES, new Set(extra))
|
||||||
|
+ const CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set(extraCharClass))
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Reports a node
|
||||||
|
* @param {ASTNode} node The node to report
|
||||||
|
@@ -238,7 +256,7 @@ module.exports = {
|
||||||
|
.filter(charInfo => charInfo.escaped)
|
||||||
|
|
||||||
|
// Filter out characters that are valid to escape, based on their position in the regular expression.
|
||||||
|
- .filter(charInfo => !(charInfo.inCharClass ? REGEX_GENERAL_ESCAPES : REGEX_NON_CHARCLASS_ESCAPES).has(charInfo.text))
|
||||||
|
+ .filter(charInfo => !(charInfo.inCharClass ? CHARCLASS_ESCAPES : NON_CHARCLASS_ESCAPES).has(charInfo.text))
|
||||||
|
|
||||||
|
// Report all the remaining characters.
|
||||||
|
.forEach(charInfo => report(node, charInfo.index, charInfo.text));
|
|
@ -4,6 +4,9 @@ patchedDependencies:
|
||||||
eslint-plugin-path-alias@1.0.0:
|
eslint-plugin-path-alias@1.0.0:
|
||||||
hash: m6sma4g6bh67km3q6igf6uxaja
|
hash: m6sma4g6bh67km3q6igf6uxaja
|
||||||
path: patches/eslint-plugin-path-alias@1.0.0.patch
|
path: patches/eslint-plugin-path-alias@1.0.0.patch
|
||||||
|
eslint@8.28.0:
|
||||||
|
hash: 7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
|
path: patches/eslint@8.28.0.patch
|
||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
'@types/diff': ^5.0.2
|
'@types/diff': ^5.0.2
|
||||||
|
@ -50,7 +53,7 @@ devDependencies:
|
||||||
diff: 5.1.0
|
diff: 5.1.0
|
||||||
discord-types: 1.3.26
|
discord-types: 1.3.26
|
||||||
esbuild: 0.15.16
|
esbuild: 0.15.16
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
eslint-import-resolver-alias: 1.1.2
|
eslint-import-resolver-alias: 1.1.2
|
||||||
eslint-plugin-header: 3.1.1_eslint@8.28.0
|
eslint-plugin-header: 3.1.1_eslint@8.28.0
|
||||||
eslint-plugin-path-alias: 1.0.0_m6sma4g6bh67km3q6igf6uxaja_eslint@8.28.0
|
eslint-plugin-path-alias: 1.0.0_m6sma4g6bh67km3q6igf6uxaja_eslint@8.28.0
|
||||||
|
@ -216,7 +219,7 @@ packages:
|
||||||
'@typescript-eslint/type-utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a
|
'@typescript-eslint/type-utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a
|
||||||
'@typescript-eslint/utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a
|
'@typescript-eslint/utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
ignore: 5.2.0
|
ignore: 5.2.0
|
||||||
natural-compare-lite: 1.4.0
|
natural-compare-lite: 1.4.0
|
||||||
regexpp: 3.2.0
|
regexpp: 3.2.0
|
||||||
|
@ -241,7 +244,7 @@ packages:
|
||||||
'@typescript-eslint/types': 5.45.0
|
'@typescript-eslint/types': 5.45.0
|
||||||
'@typescript-eslint/typescript-estree': 5.45.0_typescript@4.9.3
|
'@typescript-eslint/typescript-estree': 5.45.0_typescript@4.9.3
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
typescript: 4.9.3
|
typescript: 4.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -268,7 +271,7 @@ packages:
|
||||||
'@typescript-eslint/typescript-estree': 5.45.0_typescript@4.9.3
|
'@typescript-eslint/typescript-estree': 5.45.0_typescript@4.9.3
|
||||||
'@typescript-eslint/utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a
|
'@typescript-eslint/utils': 5.45.0_hsf322ms6xhhd4b5ne6lb74y4a
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
tsutils: 3.21.0_typescript@4.9.3
|
tsutils: 3.21.0_typescript@4.9.3
|
||||||
typescript: 4.9.3
|
typescript: 4.9.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -312,7 +315,7 @@ packages:
|
||||||
'@typescript-eslint/scope-manager': 5.45.0
|
'@typescript-eslint/scope-manager': 5.45.0
|
||||||
'@typescript-eslint/types': 5.45.0
|
'@typescript-eslint/types': 5.45.0
|
||||||
'@typescript-eslint/typescript-estree': 5.45.0_typescript@4.9.3
|
'@typescript-eslint/typescript-estree': 5.45.0_typescript@4.9.3
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
eslint-scope: 5.1.1
|
eslint-scope: 5.1.1
|
||||||
eslint-utils: 3.0.0_eslint@8.28.0
|
eslint-utils: 3.0.0_eslint@8.28.0
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
|
@ -894,7 +897,7 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=7.7.0'
|
eslint: '>=7.7.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-path-alias/1.0.0_m6sma4g6bh67km3q6igf6uxaja_eslint@8.28.0:
|
/eslint-plugin-path-alias/1.0.0_m6sma4g6bh67km3q6igf6uxaja_eslint@8.28.0:
|
||||||
|
@ -902,7 +905,7 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^7
|
eslint: ^7
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
nanomatch: 1.2.13
|
nanomatch: 1.2.13
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -914,7 +917,7 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=5.0.0'
|
eslint: '>=5.0.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-unused-imports/2.0.0_5am2datodjm2qi4eijrjrnoz54:
|
/eslint-plugin-unused-imports/2.0.0_5am2datodjm2qi4eijrjrnoz54:
|
||||||
|
@ -928,7 +931,7 @@ packages:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/eslint-plugin': 5.45.0_czs5uoqkd3podpy6vgtsxfc7au
|
'@typescript-eslint/eslint-plugin': 5.45.0_czs5uoqkd3podpy6vgtsxfc7au
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
eslint-rule-composer: 0.3.0
|
eslint-rule-composer: 0.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -959,7 +962,7 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=5'
|
eslint: '>=5'
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.28.0
|
eslint: 8.28.0_7wc6icvgtg3uswirb5tpsbjnbe
|
||||||
eslint-visitor-keys: 2.1.0
|
eslint-visitor-keys: 2.1.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
@ -973,7 +976,7 @@ packages:
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/eslint/8.28.0:
|
/eslint/8.28.0_7wc6icvgtg3uswirb5tpsbjnbe:
|
||||||
resolution: {integrity: sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==}
|
resolution: {integrity: sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
@ -1020,6 +1023,7 @@ packages:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
patched: true
|
||||||
|
|
||||||
/espree/9.4.0:
|
/espree/9.4.0:
|
||||||
resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==}
|
resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
import { debounce } from "@utils/debounce";
|
import { debounce } from "@utils/debounce";
|
||||||
import { makeCodeblock } from "@utils/misc";
|
import { makeCodeblock } from "@utils/misc";
|
||||||
|
import { canonicalizeMatch, canonicalizeReplace, ReplaceFn } from "@utils/patches";
|
||||||
import { search } from "@webpack";
|
import { search } from "@webpack";
|
||||||
import { Button, Clipboard, Forms, Margins, Parser, React, Switch, Text, TextInput } from "@webpack/common";
|
import { Button, Clipboard, Forms, Margins, Parser, React, Switch, Text, TextInput } from "@webpack/common";
|
||||||
|
|
||||||
|
@ -41,20 +42,29 @@ const findCandidates = debounce(function ({ find, setModule, setError }) {
|
||||||
setModule([keys[0], candidates[keys[0]]]);
|
setModule([keys[0], candidates[keys[0]]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
function ReplacementComponent({ module, match, replacement, setReplacementError }) {
|
interface ReplacementComponentProps {
|
||||||
|
module: [id: number, factory: Function];
|
||||||
|
match: string | RegExp;
|
||||||
|
replacement: string | ReplaceFn;
|
||||||
|
setReplacementError(error: any): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ReplacementComponent({ module, match, replacement, setReplacementError }: ReplacementComponentProps) {
|
||||||
const [id, fact] = module;
|
const [id, fact] = module;
|
||||||
const [compileResult, setCompileResult] = React.useState<[boolean, string]>();
|
const [compileResult, setCompileResult] = React.useState<[boolean, string]>();
|
||||||
|
|
||||||
const [patchedCode, matchResult, diff] = React.useMemo(() => {
|
const [patchedCode, matchResult, diff] = React.useMemo(() => {
|
||||||
const src: string = fact.toString().replaceAll("\n", "");
|
const src: string = fact.toString().replaceAll("\n", "");
|
||||||
|
const canonicalMatch = canonicalizeMatch(match);
|
||||||
try {
|
try {
|
||||||
var patched = src.replace(match, replacement);
|
const canonicalReplace = canonicalizeReplace(replacement, "YourPlugin");
|
||||||
|
var patched = src.replace(canonicalMatch, canonicalReplace as string);
|
||||||
setReplacementError(void 0);
|
setReplacementError(void 0);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setReplacementError((e as Error).message);
|
setReplacementError((e as Error).message);
|
||||||
return ["", [], []];
|
return ["", [], []];
|
||||||
}
|
}
|
||||||
const m = src.match(match);
|
const m = src.match(canonicalMatch);
|
||||||
return [patched, m, makeDiff(src, patched, m)];
|
return [patched, m, makeDiff(src, patched, m)];
|
||||||
}, [id, match, replacement]);
|
}, [id, match, replacement]);
|
||||||
|
|
||||||
|
@ -179,9 +189,10 @@ function ReplacementInput({ replacement, setReplacement, replacementError }) {
|
||||||
{Object.entries({
|
{Object.entries({
|
||||||
"$$": "Insert a $",
|
"$$": "Insert a $",
|
||||||
"$&": "Insert the entire match",
|
"$&": "Insert the entire match",
|
||||||
"$`": "Insert the substring before the match",
|
"$`\u200b": "Insert the substring before the match",
|
||||||
"$'": "Insert the substring after the match",
|
"$'": "Insert the substring after the match",
|
||||||
"$n": "Insert the nth capturing group ($1, $2...)"
|
"$n": "Insert the nth capturing group ($1, $2...)",
|
||||||
|
"$self": "Insert the plugin instance",
|
||||||
}).map(([placeholder, desc]) => (
|
}).map(([placeholder, desc]) => (
|
||||||
<Forms.FormText key={placeholder}>
|
<Forms.FormText key={placeholder}>
|
||||||
{Parser.parse("`" + placeholder + "`")}: {desc}
|
{Parser.parse("`" + placeholder + "`")}: {desc}
|
||||||
|
@ -206,7 +217,7 @@ function ReplacementInput({ replacement, setReplacement, replacementError }) {
|
||||||
function PatchHelper() {
|
function PatchHelper() {
|
||||||
const [find, setFind] = React.useState<string>("");
|
const [find, setFind] = React.useState<string>("");
|
||||||
const [match, setMatch] = React.useState<string>("");
|
const [match, setMatch] = React.useState<string>("");
|
||||||
const [replacement, setReplacement] = React.useState<string | Function>("");
|
const [replacement, setReplacement] = React.useState<string | ReplaceFn>("");
|
||||||
|
|
||||||
const [replacementError, setReplacementError] = React.useState<string>();
|
const [replacementError, setReplacementError] = React.useState<string>();
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { wordsFromPascal, wordsToTitle } from "@utils/text";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
|
||||||
import previewExampleText from "~fileContent/previewExample.tsx";
|
import previewExampleText from "~fileContent/previewExample.tsx";
|
||||||
import cssText from "~fileContent/style.css";
|
import cssText from "~fileContent/shiki.css";
|
||||||
|
|
||||||
import { Settings } from "../../Vencord";
|
import { Settings } from "../../Vencord";
|
||||||
import { shiki } from "./api/shiki";
|
import { shiki } from "./api/shiki";
|
||||||
|
@ -44,8 +44,8 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "codeBlock:{react:function",
|
find: "codeBlock:{react:function",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /codeBlock:\{react:function\((.),(.),(.)\)\{/,
|
match: /codeBlock:\{react:function\((\i),(\i),(\i)\)\{/,
|
||||||
replace: "$&return Vencord.Plugins.plugins.ShikiCodeblocks.renderHighlighter($1,$2,$3);",
|
replace: "$&return $self.renderHighlighter($1,$2,$3);",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
.shiki-root {
|
.shiki-container {
|
||||||
border-radius: 4px;
|
border: 4px;
|
||||||
|
|
||||||
/* fallback background */
|
/* fallback background */
|
||||||
background-color: var(--background-secondary);
|
background-color: var(--background-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shiki-root {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.shiki-root code {
|
.shiki-root code {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
55
src/utils/patches.ts
Normal file
55
src/utils/patches.ts
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a modification for Discord's desktop app
|
||||||
|
* Copyright (c) 2022 Vendicated and contributors
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { PatchReplacement } from "./types";
|
||||||
|
|
||||||
|
export type ReplaceFn = (match: string, ...groups: string[]) => string;
|
||||||
|
|
||||||
|
export function canonicalizeMatch(match: RegExp | string) {
|
||||||
|
if (typeof match === "string") return match;
|
||||||
|
const canonSource = match.source
|
||||||
|
.replaceAll("\\i", "[A-Za-z_$][\\w$]*");
|
||||||
|
return new RegExp(canonSource, match.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function canonicalizeReplace(replace: string | ReplaceFn, pluginName: string) {
|
||||||
|
if (typeof replace === "function") return replace;
|
||||||
|
return replace.replaceAll("$self", `Vencord.Plugins.plugins.${pluginName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function canonicalizeDescriptor<T>(descriptor: TypedPropertyDescriptor<T>, canonicalize: (value: T) => T) {
|
||||||
|
if (descriptor.get) {
|
||||||
|
const original = descriptor.get;
|
||||||
|
descriptor.get = function () {
|
||||||
|
return canonicalize(original.call(this));
|
||||||
|
};
|
||||||
|
} else if (descriptor.value) {
|
||||||
|
descriptor.value = canonicalize(descriptor.value);
|
||||||
|
}
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function canonicalizeReplacement(replacement: Pick<PatchReplacement, "match" | "replace">, plugin: string) {
|
||||||
|
const descriptors = Object.getOwnPropertyDescriptors(replacement);
|
||||||
|
descriptors.match = canonicalizeDescriptor(descriptors.match, canonicalizeMatch);
|
||||||
|
descriptors.replace = canonicalizeDescriptor(
|
||||||
|
descriptors.replace,
|
||||||
|
replace => canonicalizeReplace(replace, plugin),
|
||||||
|
);
|
||||||
|
Object.defineProperties(replacement, descriptors);
|
||||||
|
}
|
|
@ -19,6 +19,8 @@
|
||||||
import { Command } from "@api/Commands";
|
import { Command } from "@api/Commands";
|
||||||
import { Promisable } from "type-fest";
|
import { Promisable } from "type-fest";
|
||||||
|
|
||||||
|
import type { ReplaceFn } from "./patches";
|
||||||
|
|
||||||
// exists to export default definePlugin({...})
|
// exists to export default definePlugin({...})
|
||||||
export default function definePlugin<P extends PluginDef>(p: P & Record<string, any>) {
|
export default function definePlugin<P extends PluginDef>(p: P & Record<string, any>) {
|
||||||
return p;
|
return p;
|
||||||
|
@ -26,7 +28,7 @@ export default function definePlugin<P extends PluginDef>(p: P & Record<string,
|
||||||
|
|
||||||
export interface PatchReplacement {
|
export interface PatchReplacement {
|
||||||
match: string | RegExp;
|
match: string | RegExp;
|
||||||
replace: string | ((match: string, ...groups: string[]) => string);
|
replace: string | ReplaceFn;
|
||||||
predicate?(): boolean;
|
predicate?(): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
import { WEBPACK_CHUNK } from "@utils/constants";
|
import { WEBPACK_CHUNK } from "@utils/constants";
|
||||||
import Logger from "@utils/Logger";
|
import Logger from "@utils/Logger";
|
||||||
|
import { canonicalizeReplacement } from "@utils/patches";
|
||||||
|
import { PatchReplacement } from "@utils/types";
|
||||||
|
|
||||||
import { _initWebpack } from ".";
|
import { _initWebpack } from ".";
|
||||||
|
|
||||||
|
@ -135,15 +137,17 @@ function patchPush() {
|
||||||
if (code.includes(patch.find)) {
|
if (code.includes(patch.find)) {
|
||||||
patchedBy.add(patch.plugin);
|
patchedBy.add(patch.plugin);
|
||||||
|
|
||||||
// @ts-ignore we change all patch.replacement to array in plugins/index
|
// we change all patch.replacement to array in plugins/index
|
||||||
for (const replacement of patch.replacement) {
|
for (const replacement of patch.replacement as PatchReplacement[]) {
|
||||||
if (replacement.predicate && !replacement.predicate()) continue;
|
if (replacement.predicate && !replacement.predicate()) continue;
|
||||||
const lastMod = mod;
|
const lastMod = mod;
|
||||||
const lastCode = code;
|
const lastCode = code;
|
||||||
|
|
||||||
|
canonicalizeReplacement(replacement, patch.plugin);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const newCode = code.replace(replacement.match, replacement.replace);
|
const newCode = code.replace(replacement.match, replacement.replace as string);
|
||||||
if (newCode === code && !replacement.noWarn) {
|
if (newCode === code && !patch.noWarn) {
|
||||||
logger.warn(`Patch by ${patch.plugin} had no effect (Module id is ${id}): ${replacement.match}`);
|
logger.warn(`Patch by ${patch.plugin} had no effect (Module id is ${id}): ${replacement.match}`);
|
||||||
if (IS_DEV) {
|
if (IS_DEV) {
|
||||||
logger.debug("Function Source:\n", code);
|
logger.debug("Function Source:\n", code);
|
||||||
|
|
Loading…
Reference in a new issue