@antv/dumi-theme-antv
Version:
AntV website theme based on dumi2.
230 lines (215 loc) • 12.2 kB
JavaScript
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
/**
* 从代码字符串中提取依赖,并生成 package.json 的 dependencies 对象。
*
* @param {string} codeString 包含代码的字符串。
* @returns {object} 一个符合 package.json dependencies 格式的对象。
*/
export function generateDependencies() {
var codeString = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var ext = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'js';
// 1. 初始化固定的依赖
var dependencies = {};
// 2. 定义正则表达式来匹配 import 语句的来源
// 这个正则表达式可以处理以下情况:
// - import defaultExport from 'package-name';
// - import { namedExport } from 'package-name';
// - import * as name from 'package-name';
// - import 'package-name'; (用于副作用)
// - import defaultExport from '@scoped/package-name/sub-path';
//
// 解析:
// - `import(?:.*from)?` : 匹配 "import" 关键字,以及可选的 "... from" 部分。
// - `\s+` : 匹配一个或多个空格。
// - `['"]` : 匹配单引号或双引号。
// - `([^'"]+)` : 核心捕获组。匹配引号内的所有字符,这就是我们需要的包路径。
// - `['"]` : 匹配结束的引号。
// - `/g` : 全局匹配,查找所有符合条件的导入。
var importRegex = /import(?:.*from)?\s+['"]([^'"]+)['"]/g;
// 使用 Set 来存储找到的包,可以自动去重
var foundPackages = new Set();
// 3. 遍历所有匹配项
var match;
while ((match = importRegex.exec(codeString)) !== null) {
// 捕获组 match[1] 包含了完整的导入路径,例如 '@antv/g2' 或 'react-dom/client'
var importPath = match[1];
// 4. 过滤掉相对路径和绝对路径
if (importPath.startsWith('.') || importPath.startsWith('/')) {
continue;
}
// 5. 提取根包名
// 这可以处理像 'react-dom/client' 这样的深层导入,我们只需要 'react-dom'
// 或者像 '@antv/g2/es/chart',我们只需要 '@antv/g2'
var rootPackage = void 0;
var pathParts = importPath.split('/');
if (importPath.startsWith('@')) {
// 对于作用域包 (scoped package),例如 @antv/g2,根包名是前两部分
rootPackage = "".concat(pathParts[0], "/").concat(pathParts[1]);
} else {
// 对于普通包,根包名是第一部分
rootPackage = pathParts[0];
}
foundPackages.add(rootPackage);
}
// 6. 将找到的包添加到最终的依赖对象中
var _iterator = _createForOfIteratorHelper(foundPackages),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var pkg = _step.value;
// 如果不是固定的依赖,就添加并设置为 'latest'
if (!Object.prototype.hasOwnProperty.call(dependencies, pkg)) {
dependencies[pkg] = "latest";
}
}
// VisionSnap限制只要是jsx就必须装React。
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
if (ext === 'jsx' || ext === 'tsx') {
dependencies["react"] = "^18";
dependencies["react-dom"] = "^18";
}
if (ext === 'vue') {
dependencies["vue"] = "^3";
}
if (dependencies['@antv/s2'] || dependencies['@antv/s2-react'] || dependencies['@antv/s2-react-components']) {
dependencies = _objectSpread(_objectSpread({}, dependencies), {}, {
"@ant-design/icons": "^6.1.0",
"@antv/s2": "^2.4.9",
"@antv/s2-react": "^2.2.3",
"@antv/s2-react-components": "^2.1.2",
"antd": "^5.27.6",
"insert-css": "^2.0.0",
"react": "^18.3.1",
"react-color": "^2.19.3",
"react-dom": "^18.3.1",
"@antv/g2": "^5.4.2"
});
}
return dependencies;
}
/**
* 基于代码内容,启发式地判断其最合适的文件扩展名。
* @param {string} code - 要分析的前端代码字符串。
* @returns {'vue' | 'tsx' | 'jsx' | 'ts' | 'js'} - 推断出的文件扩展名(不含点)。
*/
export function getLanguageExtension(code) {
// --- 特征检测函数 ---
/**
* 检查代码是否包含 Vue 单文件组件 (SFC) 的特征。
* 这是最优先的检查,因为Vue的SFC结构非常独特。
*/
var containsVue = function containsVue(text) {
// 检查点 1: Vue 3 <script setup> 语法(最强信号)
// 匹配 <script setup> 或 <script lang="ts" setup>
var scriptSetupRegex = /<script\s+(?:lang="ts"\s+)?setup>/;
if (scriptSetupRegex.test(text)) {
return true;
}
// 检查点 2: 顶层 <template> 块(非常强的信号)
// 使用 'm' (multiline) 标志,'^' 匹配每行的开头。
var templateRegex = /^\s*<template.*>/m;
if (templateRegex.test(text)) {
return true;
}
// 检查点 3: 导入 Vue 核心库(通用信号)
// 匹配 import ... from 'vue'
var vueImportRegex = /import\s+.*?\s+from\s*['"]vue['"]/;
if (vueImportRegex.test(text)) {
return true;
}
// 检查点 4: Vue 2 Options API 特征(辅助信号)
// 匹配 export default { ... data|methods|computed ... } 结构
var optionsApiRegex = /\bexport\s+default\s*{[\s\S]*?\b(data|methods|computed|watch)\b/;
if (optionsApiRegex.test(text)) {
return true;
}
return false;
};
var containsJsx = function containsJsx(text) {
var jsxRegex = /<(?![\s!=])([a-zA-Z][a-zA-Z0-9-]*|\/|)/;
return jsxRegex.test(text);
};
var containsTypeScript = function containsTypeScript(text) {
var typeDefinitionRegex = /\b(interface|type)\s+[A-Z][a-zA-Z0-9]*\b/;
if (typeDefinitionRegex.test(text)) return true;
var typeAnnotationRegex = /:\s*([A-Z][a-zA-Z0-9<>.]*|string|number|boolean|any\[?\]?)/;
if (typeAnnotationRegex.test(text)) return true;
var tsKeywordsRegex = /\b(as|implements|private|public|protected|readonly)\s+[a-zA-Z]/;
if (tsKeywordsRegex.test(text)) return true;
return false;
};
// --- 决策逻辑(Vue优先) ---
if (containsVue(code)) {
return 'vue';
}
// 如果不是Vue,则回退到原有的React/JS逻辑
if (containsJsx(code)) {
if (containsTypeScript(code)) {
return 'tsx';
}
return 'jsx';
} else {
if (containsTypeScript(code)) {
return 'ts';
}
return 'js';
}
}
export function wrap2VisionSnap() {
var codeBlock = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var ext = getLanguageExtension(codeBlock);
var mainFile = ext === 'vue' ? "/src/index.js" : "/src/index.".concat(ext);
var appFile = "/src/App.".concat(ext);
var dependencies = generateDependencies(codeBlock, ext);
var rootElementType = dependencies['@antv/f2'] ? 'canvas' : 'div';
var dependenciesJSON = {
"name": "AntV-adapted-project",
"version": "1.0.0",
"main": mainFile,
"dependencies": dependencies
};
var mainFileCode = ext === 'vue' ? "import { createApp } from 'vue';\nimport App from './App.vue';\n\nconst app = createApp(App);\napp.mount('#app');\n" : "\n// --- Adapter Script ---\n\n// 1. \u627E\u5230\u7F16\u8F91\u5668\u73AF\u5883\u63D0\u4F9B\u7684\u6839\u8282\u70B9 #root\nconst rootElement = document.getElementById('root');\n\nif (rootElement) {\n // 2. \u5728 #root \u5185\u90E8\u521B\u5EFA\u4E00\u4E2A ".concat(rootElementType, "\n const containerElement = document.createElement('").concat(rootElementType, "');\n\n // 3. \u5C06\u8FD9\u4E2A div \u7684 id \u8BBE\u7F6E\u4E3A 'container'\uFF0C\u4EE5\u6EE1\u8DB3\u7528\u6237\u4EE3\u7801\u7684\u9700\u6C42\n containerElement.id = 'container';\n\n // 4. \u5C06\u5B83\u6DFB\u52A0\u5230 #root \u4E2D\n rootElement.appendChild(containerElement);\n\n // 5. \u73B0\u5728 DOM \u4E2D\u5DF2\u7ECF\u5B58\u5728 #container\uFF0C\u5B89\u5168\u5730\u5BFC\u5165\u5E76\u6267\u884C\u7528\u6237\u7684\u4EE3\u7801\n import('./App.").concat(ext, "');\n\n}\n ");
return {
modules: _defineProperty(_defineProperty({
'/package.json': {
fpath: '/package.json',
code: JSON.stringify(dependenciesJSON, null, 2)
}
}, mainFile, {
fpath: mainFile,
code: mainFileCode
}), appFile, {
fpath: appFile,
code: codeBlock
})
};
}
export function wrap2Sandpack() {
var codeBlock = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
// const regex = /^```[\w-]*\n([\s\S]*?)\n?```$/m;
// const match = codeBlock.match(regex);
// if (match) {
return {
"/package.json": {
code: "{\n \"name\": \"AntV-AI-Code\",\n \"version\": \"1.0.0\",\n \"main\": \"/index.tsx\",\n \"dependencies\": ".concat(JSON.stringify(generateDependencies(codeBlock), null, 2), "\n }")
},
"/index.tsx": {
code: codeBlock
},
"/index.html": {
code: "<!DOCTYPE html>\n<html>\n<head>\n <title>Vanilla JS Example</title>\n</head>\n<body>\n <div id=\"root\"></div>\n <div id=\"container\"></div>\n <script src=\"index.tsx\"></script>\n</body>\n</html>"
}
};
}