slightning-coco-widget--webpack
Version:
SLIGHTNING 的 CoCo 控件框架 —— webpack 相关工具。
338 lines (337 loc) • 12.7 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BYPASS_KEY_WORDS = exports.BYPASS_FULL_KEY_WORDS = exports.BYPASS_MAP = void 0;
exports.includesFullKeyWords = includesFullKeyWords;
exports.includesKeyWords = includesKeyWords;
exports.replaceKeyWordsInString = replaceKeyWordsInString;
exports.bypassAddImport = bypassAddImport;
exports.ASTBypassAddImport = ASTBypassAddImport;
exports.bypassKeyWordsCheck = bypassKeyWordsCheck;
exports.ASTBypassKeyWordsCheck = ASTBypassKeyWordsCheck;
exports.bypassRestrictions = bypassRestrictions;
const t = __importStar(require("@babel/types"));
const parser_1 = require("@babel/parser");
const traverse_1 = __importDefault(require("@babel/traverse"));
const generator_1 = __importDefault(require("@babel/generator"));
const template = __importStar(require("@babel/template"));
exports.BYPASS_MAP = {
"XMLHttpRequest": {
replace: "XML_Http_Request",
importSource: "slightning-coco-widget--webpack/runtime/bypass/xml-http-request"
},
"XMLHttpRequestEventTarget": {
replace: "XML_Http_RequestEventTarget",
importSource: "slightning-coco-widget--webpack/runtime/bypass/xml-http-request-event-target"
},
"fetch": {
importSource: "slightning-coco-widget--webpack/runtime/bypass/fetch"
},
".fetch": {
replace: "._fetch"
},
"location": {},
"parent.location": {
replace: "parent._location"
},
"top.location": {
replace: "top._location"
},
"WebSocket": {
replace: "Web_Socket",
importSource: "slightning-coco-widget--webpack/runtime/bypass/web-socket"
},
"WebSocketError": {
replace: "Web_SocketError",
importSource: "slightning-coco-widget--webpack/runtime/bypass/web-socket-error"
},
"WebSocketStream": {
replace: "Web_SocketStream",
importSource: "slightning-coco-widget--webpack/runtime/bypass/web-socket-stream"
},
"codemao": {},
"socketcv.codemao.cn": {
replace: "socketcv_.codemao_.cn"
}
};
exports.BYPASS_FULL_KEY_WORDS = Object.entries(exports.BYPASS_MAP).filter(([, bypass]) => bypass.replace != null).map(([name]) => name);
function includesFullKeyWords(value) {
return exports.BYPASS_FULL_KEY_WORDS.some((name) => {
return value.includes(name);
});
}
exports.BYPASS_KEY_WORDS = Object.keys(exports.BYPASS_MAP);
function includesKeyWords(value) {
return exports.BYPASS_KEY_WORDS.some((name) => {
return value.includes(name);
});
}
function replaceKeyWordsInString(value) {
for (const [search, bypass] of Object.entries(exports.BYPASS_MAP)) {
if (bypass.replace != null) {
value = value.split(search).join(bypass.replace);
}
}
return value;
}
function bypassAddImport(source) {
if (!includesFullKeyWords(source)) {
return source;
}
const AST = (0, parser_1.parse)(source, {
sourceType: "unambiguous"
});
ASTBypassAddImport(AST);
return (0, generator_1.default)(AST).code;
}
function ASTBypassAddImport(AST) {
imports = {};
(0, traverse_1.default)(AST, BypassAddImportVisitor);
for (const [name, source] of Object.entries(imports)) {
AST.program.body.unshift(t.importDeclaration([t.importDefaultSpecifier(t.identifier(name))], t.stringLiteral(source)));
}
}
let imports = {};
const BypassAddImportVisitor = {
Identifier(identifierPath) {
const { parentPath, node: identifier } = identifierPath;
if (parentPath.isImportSpecifier() ||
parentPath.isExportSpecifier()) {
return;
}
if (parentPath.isObjectProperty({ key: identifier }) ||
parentPath.isObjectMethod({ key: identifier }) ||
parentPath.isClassProperty({ key: identifier }) ||
parentPath.isClassMethod({ key: identifier })) {
return;
}
const { name: identifierName } = identifier;
if (identifierPath.scope.getBinding(identifierName) != undefined) {
return;
}
const bypass = exports.BYPASS_MAP[identifierName];
if (bypass != null && bypass.importSource != null) {
imports[identifierName] = bypass.importSource;
}
}
};
function bypassKeyWordsCheck(source) {
if (!includesFullKeyWords(source)) {
return source;
}
const AST = (0, parser_1.parse)(source, {
sourceType: "unambiguous"
});
ASTBypassKeyWordsCheck(AST);
return (0, generator_1.default)(AST).code;
}
function ASTBypassKeyWordsCheck(AST) {
var _a;
(0, traverse_1.default)(AST, BypassKeyWordsCheckVisitor);
for (const comment of (_a = AST.comments) !== null && _a !== void 0 ? _a : []) {
comment.value = replaceKeyWordsInString(comment.value);
}
}
const BypassKeyWordsCheckVisitor = {
ImportSpecifier(path) {
replaceInIdentifier(path.get("local"));
},
ExportSpecifier(path) {
replaceInIdentifier(path.get("local"));
},
ExportNamedDeclaration(path) {
const { node } = path;
const declaration = path.get("declaration");
if (declaration.node != null) {
path.insertBefore(declaration.node);
node.declaration = null;
node.specifiers.push(...getDeclarationNames(declaration).map((name) => t.exportSpecifier(t.identifier(name), t.identifier(name))));
}
},
ObjectProperty: setPropertyKeyComputed,
ObjectMethod: setPropertyKeyComputed,
ClassProperty: setPropertyKeyComputed,
ClassMethod: setPropertyKeyComputed,
MemberExpression(memberExpressionPath) {
const { node: memberExpression } = memberExpressionPath;
if (memberExpression.computed) {
return;
}
const { property } = memberExpression;
if (t.isIdentifier(property) && includesKeyWords(property.name)) {
memberExpression.property = t.stringLiteral(property.name);
memberExpression.computed = true;
}
else if (t.isStringLiteral(property) && includesKeyWords(property.value)) {
memberExpression.computed = true;
}
},
Identifier(identifierPath) {
const { parentPath, node: identifier } = identifierPath;
if (parentPath.isImportSpecifier() ||
parentPath.isExportSpecifier()) {
return;
}
if (parentPath.isMemberExpression({ property: identifier, computed: false }) ||
parentPath.isObjectProperty({ key: identifier, computed: false }) ||
parentPath.isObjectMethod({ key: identifier, computed: false }) ||
parentPath.isClassProperty({ key: identifier, computed: false }) ||
parentPath.isClassMethod({ key: identifier, computed: false })) {
return;
}
replaceInIdentifier(identifierPath);
},
StringLiteral(stringLiteralPath) {
var _a, _b;
const { parentPath, node: stringLiteral } = stringLiteralPath;
if (parentPath.isImportDeclaration() ||
parentPath.isExportDeclaration()) {
return;
}
for (const [name, bypass] of Object.entries(exports.BYPASS_MAP)) {
if (bypass.replace == null) {
continue;
}
if (stringLiteral.value.includes(name)) {
const strings = stringLiteral.value.split(name);
stringLiteralPath.replaceWith(t.stringLiteral((_a = strings.shift()) !== null && _a !== void 0 ? _a : ""));
while (strings.length > 0) {
stringLiteralPath.replaceWith(t.binaryExpression("+", t.binaryExpression("+", stringLiteralPath.node, getStringReplaceExpression(bypass)), t.stringLiteral((_b = strings.shift()) !== null && _b !== void 0 ? _b : "")));
}
return;
}
}
},
TemplateLiteral(path) {
const { node } = path;
for (const [name, bypass] of Object.entries(exports.BYPASS_MAP)) {
if (bypass.replace == null) {
continue;
}
for (let i = node.quasis.length - 1; i >= 0; i--) {
const parts = node.quasis[i].value.raw.split(name);
node.quasis.splice(i, 1, ...parts.map((part) => ({
type: "TemplateElement",
value: {
raw: part
},
tail: false
})));
for (let j = 1; j < parts.length; j++) {
node.expressions.splice(i, 0, getStringReplaceExpression(bypass));
}
}
}
}
};
function getDeclarationNames(declarationPath) {
const { node: declaration } = declarationPath;
const result = [];
if (declarationPath.isVariableDeclaration()) {
for (const declaratorPath of declarationPath.get("declarations")) {
const idPath = declaratorPath.get("id");
if (idPath.isIdentifier()) {
result.push(idPath.node.name);
}
else {
declarationNames = [];
idPath.traverse(GetDeclarationNamesVisitor);
result.push(...declarationNames);
}
}
}
else if (t.isFunctionDeclaration(declaration) ||
t.isClassDeclaration(declaration)) {
if (t.isIdentifier(declaration.id)) {
result.push(declaration.id.name);
}
}
return result;
}
const GetDeclarationNamesVisitor = {
Property(propertyPath) {
propertyPath.get("value").skip();
},
AssignmentExpression(assignmentExpressionPath) {
assignmentExpressionPath.get("right").skip();
},
Identifier(identifierPath) {
const { parentPath: objectPath, node: identifier } = identifierPath;
if (objectPath.isObjectProperty({ key: identifier })) {
return;
}
declarationNames.push(identifier.name);
}
};
let declarationNames = [];
function setPropertyKeyComputed(propertyPath) {
const { node: property } = propertyPath;
if (property.computed) {
return;
}
const { key } = property;
if (t.isIdentifier(key) && includesKeyWords(key.name)) {
property.key = t.stringLiteral(key.name);
property.computed = true;
}
else if (t.isStringLiteral(key) && includesKeyWords(key.value)) {
property.computed = true;
}
}
function replaceInIdentifier(identifierPath) {
const { node: identifier } = identifierPath;
identifier.name = replaceKeyWordsInString(identifier.name);
}
function getStringReplaceExpression(bypass) {
var _a;
return StringReplaceTemplate({ STRING: t.stringLiteral((_a = bypass.replace) !== null && _a !== void 0 ? _a : "") });
}
const StringReplaceTemplate = template.expression(`
STRING.replace(/_/g, "")
`);
function bypassRestrictions(source) {
if (!includesFullKeyWords(source)) {
return source;
}
const AST = (0, parser_1.parse)(source, {
sourceType: "unambiguous"
});
ASTBypassAddImport(AST);
ASTBypassKeyWordsCheck(AST);
return (0, generator_1.default)(AST).code;
}