UNPKG

slightning-coco-widget--webpack

Version:

SLIGHTNING 的 CoCo 控件框架 —— webpack 相关工具。

338 lines (337 loc) 12.7 kB
"use strict"; 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; }