@4399ywkf/core 5.0.2 → 5.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +376 -77
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +476 -129
- package/dist/index.js.map +1 -1
- package/dist/plugin/index.d.ts +3 -3
- package/dist/plugin/index.js +5 -4
- package/dist/plugin/index.js.map +1 -1
- package/dist/router/index.js +2 -2
- package/dist/router/index.js.map +1 -1
- package/dist/rspack/index.d.ts +5 -3
- package/dist/rspack/index.js +45 -22
- package/dist/rspack/index.js.map +1 -1
- package/dist/runtime/index.d.ts +17 -3
- package/dist/runtime/index.js +31 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/{schema-BuqmN_ra.d.ts → schema-VPH72NAR.d.ts} +1 -1
- package/dist/{types-BZV_2QtD.d.ts → types-BztKUufh.d.ts} +76 -1
- package/package.json +3 -1
package/dist/rspack/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/rspack/index.ts","../../src/rspack/dev.ts","../../src/config/loader.ts","../../src/rspack/base.ts","../../src/generator/plugin.ts","../../src/generator/generator.ts","../../src/router/generator.ts","../../src/generator/templates/entry.ts","../../src/generator/templates/bootstrap.ts","../../src/generator/templates/env-types.ts","../../src/generator/templates/route-types.ts","../../src/rspack/prod.ts"],"sourcesContent":["import type { Configuration } from \"@rspack/core\";\nimport { RsdoctorRspackPlugin } from \"@rsdoctor/rspack-plugin\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport { createDevConfig } from \"./dev.js\";\nimport { createProdConfig } from \"./prod.js\";\n\nexport { createBaseConfig } from \"./base.js\";\nexport { createDevConfig } from \"./dev.js\";\nexport { createProdConfig } from \"./prod.js\";\n\n/**\n * 根据环境创建 Rspack 配置\n */\nexport function createRspackConfig(\n config: Required<YwkfConfig>,\n cwd: string,\n options: { isDev?: boolean } = {}\n): Configuration {\n const isDev = options.isDev ?? process.env.NODE_ENV !== \"production\";\n\n let rspackConfig = isDev\n ? createDevConfig(config, cwd)\n : createProdConfig(config, cwd);\n\n // Rsdoctor 性能分析\n if (config.performance.rsdoctor) {\n rspackConfig.plugins = [\n ...(rspackConfig.plugins || []),\n new RsdoctorRspackPlugin({}),\n ];\n }\n\n // 用户自定义配置\n if (config.tools.rspack) {\n const userConfig = config.tools.rspack(rspackConfig, {\n isDev,\n isProd: !isDev,\n });\n\n if (userConfig) {\n rspackConfig = userConfig;\n }\n }\n\n return rspackConfig;\n}\n","import { rspack, type Configuration } from \"@rspack/core\";\nimport { merge } from \"webpack-merge\";\nimport { join } from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport { createPathResolver } from \"../config/loader.js\";\nimport { createBaseConfig } from \"./base.js\";\n\nconst require = createRequire(import.meta.url);\n\n/**\n * 将 proxy 对象格式转换为数组格式\n * webpack-dev-server v4+ 需要数组格式\n */\nfunction convertProxyToArray(\n proxy?: Record<string, string | object>\n): { context: string; target: string; changeOrigin?: boolean; secure?: boolean }[] | undefined {\n if (!proxy || Object.keys(proxy).length === 0) {\n return undefined;\n }\n\n return Object.entries(proxy).map(([context, target]) => {\n if (typeof target === \"string\") {\n return {\n context: [context],\n target,\n changeOrigin: true,\n secure: false,\n } as unknown as { context: string; target: string };\n }\n return {\n context: [context],\n changeOrigin: true,\n secure: false,\n ...(target as object),\n } as unknown as { context: string; target: string };\n });\n}\n\n/**\n * 创建开发环境 Rspack 配置\n */\nexport function createDevConfig(\n config: Required<YwkfConfig>,\n cwd: string\n): Configuration {\n const baseConfig = createBaseConfig(config, cwd);\n const { resolveApp } = createPathResolver(cwd);\n const { dev, style } = config;\n\n const styleRules: Configuration[\"module\"] = {\n rules: [\n // Less - antd\n {\n test: /\\.less$/,\n include: [\n /[\\\\/]node_modules[\\\\/].*antd/,\n /[\\\\/]node_modules[\\\\/]@4399ywkf[\\\\/]design/,\n ],\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n strictMath: false,\n math: \"always\",\n javascriptEnabled: true,\n },\n },\n },\n ],\n },\n // Less - 项目文件\n ...(style.less?.enabled !== false\n ? [\n {\n test: /\\.less$/,\n include: [resolveApp(\"src\")],\n exclude: [resolveApp(\"node_modules\")],\n oneOf: [\n {\n test: /\\.module\\.less$/,\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: {\n sourceMap: true,\n modules: {\n localIdentName:\n \"[path][name]__[local]--[hash:base64:5]\",\n },\n importLoaders: 2,\n },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n javascriptEnabled: true,\n math: \"always\",\n ...style.less?.lessOptions,\n },\n },\n },\n ],\n },\n {\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n javascriptEnabled: true,\n ...style.less?.lessOptions,\n },\n },\n },\n ],\n },\n ],\n },\n ]\n : []),\n // Sass\n ...(style.sass?.enabled !== false\n ? [\n {\n test: /\\.s[ac]ss$/i,\n include: [resolveApp(\"src\")],\n exclude: [resolveApp(\"node_modules\")],\n oneOf: [\n {\n test: /\\.module\\.s[ac]ss$/,\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: {\n sourceMap: true,\n modules: {\n localIdentName:\n \"[path][name]__[local]--[hash:base64:5]\",\n },\n importLoaders: 2,\n },\n },\n {\n loader: \"sass-loader\",\n options: {\n sourceMap: true,\n sassOptions: {\n outputStyle: \"compressed\",\n ...style.sass?.sassOptions,\n },\n },\n },\n ],\n },\n {\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"sass-loader\",\n options: {\n sourceMap: true,\n sassOptions: {\n outputStyle: \"compressed\",\n ...style.sass?.sassOptions,\n },\n },\n },\n ],\n },\n ],\n },\n ]\n : []),\n // TailwindCSS\n ...(style.tailwindcss\n ? [\n {\n test: /\\.css$/,\n include: [resolveApp(\"src/index.css\")],\n use: [\n \"style-loader\",\n \"css-loader\",\n {\n loader: \"postcss-loader\",\n options: {\n postcssOptions: {\n config: resolveApp(\"postcss.config.js\"),\n },\n },\n },\n ],\n },\n ]\n : []),\n // 其他 CSS\n {\n test: /\\.css$/,\n include: [resolveApp(\"src\"), resolveApp(\"node_modules\")],\n exclude: style.tailwindcss ? [resolveApp(\"src/index.css\")] : [],\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n ],\n },\n ],\n };\n\n const devConfig: Configuration = {\n mode: \"development\",\n devtool: \"inline-source-map\",\n\n output: {\n filename: \"[name].bundle.js\",\n clean: false,\n },\n\n stats: \"errors-only\",\n\n devServer: {\n host: dev.host,\n port: dev.port,\n compress: true,\n historyApiFallback: true,\n hot: true,\n allowedHosts: \"all\",\n client: {\n overlay: false,\n progress: true,\n },\n proxy: convertProxyToArray(dev.proxy),\n },\n\n module: styleRules,\n };\n\n return merge(baseConfig, devConfig);\n}\n","import { existsSync } from \"node:fs\";\nimport { resolve, extname } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport deepmerge from \"deepmerge\";\nimport { defaultConfig, type YwkfConfig } from \"./schema.js\";\n\n/** 支持的配置文件名 */\nconst CONFIG_FILES = [\n \"ywkf.config.ts\",\n \"ywkf.config.mts\",\n \"ywkf.config.js\",\n \"ywkf.config.mjs\",\n];\n\n/**\n * 查找配置文件\n */\nexport function findConfigFile(cwd: string): string | null {\n for (const file of CONFIG_FILES) {\n const configPath = resolve(cwd, file);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n return null;\n}\n\n/**\n * 加载 TypeScript 配置文件\n */\nasync function loadTsConfig(configPath: string): Promise<YwkfConfig> {\n const jiti = (await import(\"jiti\")).default;\n const loader = jiti(configPath, {\n interopDefault: true,\n });\n\n const config = loader(configPath);\n return config.default || config;\n}\n\n/**\n * 加载 JavaScript 配置文件\n */\nasync function loadJsConfig(configPath: string): Promise<YwkfConfig> {\n const fileUrl = pathToFileURL(configPath).href;\n const module = await import(fileUrl);\n return module.default || module;\n}\n\n/**\n * 加载配置文件\n */\nexport async function loadConfigFile(configPath: string): Promise<YwkfConfig> {\n const ext = extname(configPath);\n\n if (ext === \".ts\" || ext === \".mts\") {\n return loadTsConfig(configPath);\n }\n\n return loadJsConfig(configPath);\n}\n\n/**\n * 合并配置\n */\nexport function mergeConfig(\n userConfig: YwkfConfig,\n baseConfig: YwkfConfig = defaultConfig\n): Required<YwkfConfig> {\n return deepmerge(baseConfig, userConfig, {\n arrayMerge: (_, sourceArray) => sourceArray,\n }) as Required<YwkfConfig>;\n}\n\n/**\n * 解析并加载完整配置\n * @param cwd 工作目录\n * @returns 合并后的完整配置\n */\nexport async function resolveConfig(cwd: string): Promise<{\n config: Required<YwkfConfig>;\n configPath: string | null;\n}> {\n const configPath = findConfigFile(cwd);\n\n if (!configPath) {\n console.warn(\n \"⚠️ 未找到配置文件 (ywkf.config.ts),使用默认配置\"\n );\n return {\n config: defaultConfig as Required<YwkfConfig>,\n configPath: null,\n };\n }\n\n try {\n const userConfig = await loadConfigFile(configPath);\n const config = mergeConfig(userConfig);\n\n return { config, configPath };\n } catch (error) {\n console.error(\"❌ 配置文件加载失败:\", error);\n throw error;\n }\n}\n\n/**\n * 获取应用路径解析器\n */\nexport function createPathResolver(cwd: string) {\n return {\n resolveApp: (relativePath: string) => resolve(cwd, relativePath),\n cwd,\n };\n}\n","import { rspack, type Configuration } from \"@rspack/core\";\nimport { createRequire } from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport { createPathResolver } from \"../config/loader.js\";\nimport { YwkfGeneratorPlugin } from \"../generator/plugin.js\";\n\nconst require = createRequire(import.meta.url);\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst coreNodeModules = join(__dirname, \"../../node_modules\");\n\n/**\n * 创建基础 Rspack 配置\n */\nexport function createBaseConfig(\n config: Required<YwkfConfig>,\n cwd: string\n): Configuration {\n const { resolveApp } = createPathResolver(cwd);\n\n const {\n appName,\n appCName,\n output,\n html,\n alias: userAlias,\n microFrontend,\n router,\n } = config;\n\n // 约定式路由输出目录\n const ywkfOutputDir = resolveApp(\".ywkf\");\n\n const defaultAlias: Record<string, string> = {\n \"@\": resolveApp(\"src\"),\n \"@config\": resolveApp(\"config\"),\n \"@store\": resolveApp(\"store\"),\n \"@locales\": resolveApp(\"locales\"),\n \"@public\": resolveApp(\"public\"),\n // 约定式路由生成的文件\n \"@ywkf/routes\": join(ywkfOutputDir, \"routes.tsx\"),\n // 请求层(由 reactQueryPlugin 生成)\n \"@ywkf/request\": join(ywkfOutputDir, \"request.ts\"),\n // Store 工具(由 zustandPlugin 生成)\n \"@ywkf/store\": join(ywkfOutputDir, \"store.ts\"),\n };\n\n const alias = { ...defaultAlias, ...userAlias };\n\n return {\n // 使用 .ywkf/index.tsx 作为入口(由框架生成)\n entry: [join(ywkfOutputDir, \"index.tsx\")],\n\n resolve: {\n extensions: [\".ts\", \".tsx\", \".jsx\", \".js\", \".json\", \".mjs\"],\n symlinks: false,\n alias: {\n ...alias,\n \"process/browser.js\": require.resolve(\"process/browser.js\"),\n \"process/browser\": require.resolve(\"process/browser.js\"),\n // 确保 React 系列包从用户项目的 node_modules 解析\n react: resolveApp(\"node_modules/react\"),\n \"react-dom\": resolveApp(\"node_modules/react-dom\"),\n \"react-router\": resolveApp(\"node_modules/react-router\"),\n },\n fallback: {\n path: require.resolve(\"path-browserify\"),\n process: require.resolve(\"process/browser.js\"),\n buffer: require.resolve(\"buffer/\"),\n util: require.resolve(\"util/\"),\n stream: require.resolve(\"stream-browserify\"),\n crypto: require.resolve(\"crypto-browserify\"),\n zlib: require.resolve(\"browserify-zlib\"),\n querystring: require.resolve(\"querystring-es3\"),\n url: require.resolve(\"url/\"),\n assert: require.resolve(\"assert/\"),\n fs: false,\n net: false,\n tls: false,\n os: false,\n https: false,\n http: false,\n },\n },\n\n resolveLoader: {\n modules: [coreNodeModules, \"node_modules\"],\n },\n\n module: {\n rules: [\n {\n test: /\\.m?js$/,\n resolve: {\n fullySpecified: false,\n },\n },\n {\n test: /\\.[jt]sx?$/,\n include: [\n resolveApp(\"src\"),\n resolveApp(\"config\"),\n resolveApp(\"store\"),\n resolveApp(\"packages\"),\n ywkfOutputDir, // 约定式路由生成的文件\n ],\n exclude: [resolveApp(\"node_modules\")],\n use: [\n {\n loader: \"builtin:swc-loader\",\n options: {\n jsc: {\n parser: {\n syntax: \"typescript\",\n tsx: true,\n decorators: true,\n },\n transform: {\n react: {\n runtime: \"automatic\",\n },\n },\n target: \"es2015\",\n },\n sourceMaps: true,\n },\n },\n ],\n },\n {\n test: /\\.(png|jpg|jpeg|gif|webp|m3u8|exr|hdr|json|woff2)$/,\n include: [resolveApp(\"public\")],\n exclude: [resolveApp(\"src\"), resolveApp(\"store\")],\n type: \"asset\",\n parser: {\n dataUrlCondition: {\n maxSize: 10 * 1024,\n },\n },\n },\n {\n test: /\\.(md)$/,\n include: [resolveApp(\"src\")],\n type: \"asset/source\",\n },\n {\n test: /\\.svg$/,\n use: [\"@svgr/webpack\"],\n },\n ],\n },\n\n plugins: [\n new rspack.ProvidePlugin({\n process: \"process/browser.js\",\n Buffer: [\"buffer\", \"Buffer\"],\n }),\n new rspack.DefinePlugin({\n \"process.env\": JSON.stringify(process.env),\n }),\n new rspack.HtmlRspackPlugin({\n template: resolveApp(html.template ?? \"public/index.html\"),\n filename: \"index.html\",\n inject: \"body\",\n hash: true,\n minify: process.env.NODE_ENV === \"production\",\n favicon: resolveApp(html.favicon ?? \"public/favicon.ico\"),\n templateParameters: {\n title: html.title ?? appCName,\n mountRoot: html.mountRoot ?? appName,\n },\n }),\n new rspack.CopyRspackPlugin({\n patterns: [\n {\n from: resolveApp(\"public/images\"),\n to: \"public/images\",\n noErrorOnMissing: true,\n },\n ],\n }),\n // .ywkf 目录生成插件(传递用户配置的插件列表)\n new YwkfGeneratorPlugin({\n cwd,\n config,\n outputDir: ywkfOutputDir,\n isDev: process.env.NODE_ENV !== \"production\",\n pluginConfigs: config.plugins,\n }),\n ].filter(Boolean),\n\n output: {\n assetModuleFilename: \"images/[hash][ext]\",\n library: microFrontend.enabled ? `${appCName}-[name]` : undefined,\n chunkFilename: \"[name].[contenthash].js\",\n libraryTarget: microFrontend.enabled ? \"umd\" : undefined,\n globalObject: microFrontend.enabled ? \"window\" : undefined,\n chunkLoadingGlobal: microFrontend.enabled\n ? `chunk_global_${appName}`\n : undefined,\n publicPath: output.publicPath ?? \"/\",\n path: resolveApp(output.path ?? \"dist\"),\n },\n\n ignoreWarnings: [\n {\n module: /@testing-library\\/react/,\n message: /export 'act'/,\n },\n ],\n\n devtool: \"source-map\",\n };\n}\n","import type { Compiler } from \"@rspack/core\";\nimport { watch, existsSync } from \"fs\";\nimport { join } from \"path\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport type { YwkfPlugin, PluginHooks, PluginContext, PluginConfig } from \"../plugin/types.js\";\nimport { YwkfGenerator } from \"./generator.js\";\n\nexport interface YwkfGeneratorPluginOptions {\n /** 项目根目录 */\n cwd: string;\n /** 解析后的配置 */\n config: Required<YwkfConfig>;\n /** 输出目录(.ywkf) */\n outputDir: string;\n /** 是否开发模式 */\n isDev: boolean;\n /** 用户配置的插件列表(PluginConfig 格式) */\n pluginConfigs?: PluginConfig[];\n}\n\n/**\n * .ywkf 目录生成插件\n *\n * 在编译前生成 .ywkf 目录下的所有文件\n */\nexport class YwkfGeneratorPlugin {\n private options: YwkfGeneratorPluginOptions;\n private hasGenerated = false;\n private isWatching = false;\n private generator: YwkfGenerator | null = null;\n private pluginHooks: PluginHooks[] = [];\n private initialized = false;\n\n constructor(options: YwkfGeneratorPluginOptions) {\n this.options = options;\n }\n\n /**\n * 解析插件配置为插件实例\n */\n private async resolvePlugin(\n pluginConfig: PluginConfig\n ): Promise<YwkfPlugin | null> {\n try {\n let plugin: YwkfPlugin;\n let options: Record<string, unknown> = {};\n\n if (typeof pluginConfig === \"string\") {\n const module = await import(pluginConfig);\n plugin = module.default || module;\n } else if (Array.isArray(pluginConfig)) {\n const [pluginOrName, pluginOptions] = pluginConfig;\n options = pluginOptions;\n\n if (typeof pluginOrName === \"string\") {\n const module = await import(pluginOrName);\n plugin = module.default || module;\n } else {\n plugin = pluginOrName;\n }\n } else {\n plugin = pluginConfig;\n }\n\n // 如果是工厂函数,调用它\n if (typeof plugin === \"function\") {\n plugin = (plugin as (opts?: Record<string, unknown>) => YwkfPlugin)(options);\n }\n\n return plugin;\n } catch (error) {\n console.error(`[ywkf] 解析插件失败: ${error}`);\n return null;\n }\n }\n\n /**\n * 初始化插件钩子\n */\n private async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n const { cwd, config, isDev, pluginConfigs = [] } = this.options;\n\n // 创建插件上下文\n const context: PluginContext = {\n cwd,\n isDev,\n isProd: !isDev,\n config,\n logger: {\n info: (msg) => console.log(`[ywkf] ${msg}`),\n warn: (msg) => console.warn(`[ywkf] ${msg}`),\n error: (msg) => console.error(`[ywkf] ${msg}`),\n debug: (msg) => {\n if (process.env.DEBUG) {\n console.log(`[ywkf:debug] ${msg}`);\n }\n },\n },\n };\n\n // 解析并初始化所有插件,收集钩子\n for (const pluginConfig of pluginConfigs) {\n const plugin = await this.resolvePlugin(pluginConfig);\n if (plugin) {\n const hooks = await plugin.setup(context);\n this.pluginHooks.push(hooks);\n console.log(`[ywkf] 插件已加载: ${plugin.name}`);\n }\n }\n\n // 创建生成器\n this.generator = new YwkfGenerator(\n {\n cwd: this.options.cwd,\n config: this.options.config,\n outputDir: this.options.outputDir,\n isDev: this.options.isDev,\n },\n this.pluginHooks\n );\n\n this.initialized = true;\n }\n\n apply(compiler: Compiler): void {\n const pluginName = \"YwkfGeneratorPlugin\";\n\n // 在编译开始前生成代码\n compiler.hooks.beforeCompile.tapAsync(pluginName, async (params, callback) => {\n try {\n // 确保初始化完成\n await this.initialize();\n\n if (!this.hasGenerated && this.generator) {\n await this.generator.generate();\n this.hasGenerated = true;\n }\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // 开发模式下监听文件变化\n if (this.options.isDev && !this.isWatching) {\n this.watchPages();\n }\n }\n\n /**\n * 监听页面目录变化\n */\n private watchPages(): void {\n const { config, cwd } = this.options;\n const pagesDir = join(cwd, config.router.pagesDir || \"src/pages\");\n\n if (!existsSync(pagesDir)) {\n return;\n }\n\n this.isWatching = true;\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const watcher = watch(\n pagesDir,\n { recursive: true },\n (eventType, filename) => {\n // 只处理 tsx/jsx 文件\n if (!filename?.match(/\\.(tsx?|jsx?)$/)) {\n return;\n }\n\n // 防抖处理\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n debounceTimer = setTimeout(async () => {\n console.log(`[ywkf] 检测到页面变化: ${filename}`);\n if (this.generator) {\n await this.generator.generate();\n }\n }, 500);\n }\n );\n\n // 进程退出时关闭监听\n process.on(\"exit\", () => {\n watcher.close();\n });\n }\n}\n","import { existsSync, mkdirSync, writeFileSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport type {\n PluginHooks,\n GeneratorContext,\n CodeInjection,\n GeneratedFile,\n} from \"../plugin/types.js\";\nimport { ConventionalRouteGenerator } from \"../router/generator.js\";\nimport { generateEntry } from \"./templates/entry.js\";\nimport { generateBootstrap } from \"./templates/bootstrap.js\";\nimport { generateEnvTypes } from \"./templates/env-types.js\";\nimport { generateRouteTypes } from \"./templates/route-types.js\";\n\n/**\n * 插件钩子执行器\n */\nexport interface PluginHooksRunner {\n hooks: PluginHooks[];\n}\n\n/**\n * .ywkf 目录代码生成器\n *\n * 生成的文件:\n * - index.tsx - 应用入口\n * - routes.tsx - 约定式路由\n * - bootstrap.tsx - 启动逻辑\n * - types/routes.d.ts - 路由类型\n * - types/env.d.ts - 环境变量类型\n * - config.json - 配置快照\n */\nexport class YwkfGenerator {\n private context: GeneratorContext;\n private pluginHooks: PluginHooks[];\n private lastGeneratedContent: Map<string, string> = new Map();\n\n constructor(\n context: Omit<GeneratorContext, \"outputDir\"> & { outputDir?: string },\n pluginHooks: PluginHooks[] = []\n ) {\n this.context = {\n ...context,\n outputDir: context.outputDir || join(context.cwd, \".ywkf\"),\n };\n this.pluginHooks = pluginHooks;\n }\n\n /**\n * 生成所有文件\n */\n async generate(): Promise<void> {\n const { outputDir } = this.context;\n\n // 确保目录存在\n this.ensureDir(outputDir);\n this.ensureDir(join(outputDir, \"types\"));\n\n // 生成各个文件\n this.generateConfigSnapshot();\n this.generateRoutes();\n this.generateBootstrapFile();\n this.generateEntryFile();\n this.generateTypes();\n\n // 生成插件附加文件\n await this.generatePluginFiles();\n\n // 调用插件 afterGenerate 钩子\n for (const hooks of this.pluginHooks) {\n if (hooks.afterGenerate) {\n await hooks.afterGenerate(this.context);\n }\n }\n\n console.log(`[ywkf] 已生成 .ywkf 目录`);\n }\n\n /**\n * 生成配置快照\n */\n private generateConfigSnapshot(): void {\n const { outputDir, config } = this.context;\n const configPath = join(outputDir, \"config.json\");\n\n // 移除函数类型的配置(无法序列化)\n const serializableConfig = JSON.parse(\n JSON.stringify(config, (key, value) => {\n if (typeof value === \"function\") {\n return \"[Function]\";\n }\n return value;\n })\n );\n\n this.writeFileIfChanged(\n configPath,\n JSON.stringify(serializableConfig, null, 2)\n );\n }\n\n /**\n * 生成约定式路由\n */\n private generateRoutes(): void {\n const { cwd, outputDir, config } = this.context;\n\n if (!config.router.conventional) {\n return;\n }\n\n const pagesDir = join(cwd, config.router.pagesDir || \"src/pages\");\n const generator = new ConventionalRouteGenerator({\n pagesDir,\n outputDir,\n basename: config.router.basename,\n });\n\n const content = generator.generateCode();\n const routesPath = join(outputDir, \"routes.tsx\");\n\n this.writeFileIfChanged(routesPath, content);\n }\n\n /**\n * 生成启动文件\n */\n private generateBootstrapFile(): void {\n const { outputDir, config } = this.context;\n\n // 收集插件注入\n const injections = this.collectInjections(\"bootstrap\");\n\n // 生成基础代码\n let content = generateBootstrap(config, injections);\n\n // 调用插件修改钩子\n for (const hooks of this.pluginHooks) {\n if (hooks.modifyBootstrapCode) {\n const result = hooks.modifyBootstrapCode(content, this.context);\n if (result) {\n content = result;\n }\n }\n }\n\n const bootstrapPath = join(outputDir, \"bootstrap.tsx\");\n this.writeFileIfChanged(bootstrapPath, content);\n }\n\n /**\n * 生成入口文件\n */\n private generateEntryFile(): void {\n const { outputDir, config } = this.context;\n\n // 收集插件注入\n const injections = this.collectInjections(\"entry\");\n\n // 生成基础代码\n let content = generateEntry(config, injections);\n\n // 调用插件修改钩子\n for (const hooks of this.pluginHooks) {\n if (hooks.modifyEntryCode) {\n const result = hooks.modifyEntryCode(content, this.context);\n if (result) {\n content = result;\n }\n }\n }\n\n const entryPath = join(outputDir, \"index.tsx\");\n this.writeFileIfChanged(entryPath, content);\n }\n\n /**\n * 收集插件代码注入\n */\n private collectInjections(\n type: \"entry\" | \"bootstrap\"\n ): CodeInjection {\n const result: CodeInjection = {\n imports: [],\n topLevel: [],\n exports: [],\n };\n\n const hookName = type === \"entry\" ? \"injectEntry\" : \"injectBootstrap\";\n\n for (const hooks of this.pluginHooks) {\n const hook = hooks[hookName];\n if (hook) {\n const injection = hook(this.context);\n if (injection) {\n result.imports?.push(...(injection.imports || []));\n result.topLevel?.push(...(injection.topLevel || []));\n result.exports?.push(...(injection.exports || []));\n }\n }\n }\n\n return result;\n }\n\n /**\n * 生成插件附加文件\n */\n private async generatePluginFiles(): Promise<void> {\n const { outputDir } = this.context;\n\n for (const hooks of this.pluginHooks) {\n if (hooks.generateFiles) {\n const files = hooks.generateFiles(this.context);\n if (files) {\n for (const file of files) {\n const filePath = join(outputDir, file.path);\n const dir = join(filePath, \"..\");\n this.ensureDir(dir);\n this.writeFileIfChanged(filePath, file.content);\n }\n }\n }\n }\n }\n\n /**\n * 生成类型定义\n */\n private generateTypes(): void {\n const { outputDir, config, cwd } = this.context;\n\n // 生成环境变量类型\n const envTypesContent = generateEnvTypes(cwd, config);\n this.writeFileIfChanged(\n join(outputDir, \"types\", \"env.d.ts\"),\n envTypesContent\n );\n\n // 生成路由类型\n if (config.router.conventional) {\n const routeTypesContent = generateRouteTypes();\n this.writeFileIfChanged(\n join(outputDir, \"types\", \"routes.d.ts\"),\n routeTypesContent\n );\n }\n }\n\n /**\n * 确保目录存在\n */\n private ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n }\n\n /**\n * 只在内容变化时写入文件(避免触发不必要的热更新)\n */\n private writeFileIfChanged(filePath: string, content: string): void {\n const normalizedContent = this.normalizeContent(content);\n const lastContent = this.lastGeneratedContent.get(filePath);\n\n if (lastContent === normalizedContent) {\n return;\n }\n\n // 检查文件是否存在且内容相同\n if (existsSync(filePath)) {\n const existingContent = readFileSync(filePath, \"utf-8\");\n if (this.normalizeContent(existingContent) === normalizedContent) {\n this.lastGeneratedContent.set(filePath, normalizedContent);\n return;\n }\n }\n\n writeFileSync(filePath, content, \"utf-8\");\n this.lastGeneratedContent.set(filePath, normalizedContent);\n }\n\n /**\n * 标准化内容(去掉时间戳等动态部分)\n */\n private normalizeContent(content: string): string {\n return content\n .replace(/\\/\\/ Generated at: .+/g, \"\")\n .replace(/\\/\\*\\* Generated at: .+ \\*\\//g, \"\");\n }\n}\n","import { existsSync, readdirSync, statSync, mkdirSync, writeFileSync } from \"fs\";\nimport { join, relative, basename } from \"path\";\n\n/**\n * 路由节点配置\n */\nexport interface RouteConfig {\n /** 路由路径 */\n path: string;\n /** 页面文件(page.tsx)相对路径 */\n file?: string;\n /** 布局文件(layout.tsx)相对路径 */\n layoutFile?: string;\n /** 错误边界文件(error.tsx)相对路径 */\n errorFile?: string;\n /** 加载状态文件(loading.tsx)相对路径 */\n loadingFile?: string;\n /** 通配路由文件($.tsx)相对路径 */\n catchAllFile?: string;\n /** 组件名称 */\n name: string;\n /** 子路由 */\n children?: RouteConfig[];\n /** 是否为 index 路由 */\n index?: boolean;\n /** 是否为布局路由 */\n isLayout?: boolean;\n /** 是否为无路径布局(__prefix) */\n pathless?: boolean;\n}\n\nexport interface GeneratorOptions {\n /** 页面目录 */\n pagesDir: string;\n /** 输出目录 */\n outputDir: string;\n /** 路由 basename */\n basename?: string;\n}\n\n/**\n * 不参与路由扫描的目录名\n */\nconst EXCLUDED_DIRS = new Set([\n \"components\",\n \"hooks\",\n \"utils\",\n \"services\",\n \"models\",\n \"assets\",\n \"types\",\n \"constants\",\n \"styles\",\n]);\n\n/**\n * 约定文件名匹配\n */\nconst CONVENTION_FILES = {\n page: /^page\\.(tsx?|jsx?)$/,\n layout: /^layout\\.(tsx?|jsx?)$/,\n error: /^error\\.(tsx?|jsx?)$/,\n loading: /^loading\\.(tsx?|jsx?)$/,\n catchAll: /^\\$\\.(tsx?|jsx?)$/,\n};\n\n/**\n * Modern.js 风格约定式路由生成器\n *\n * 文件约定:\n * - page.tsx — 页面内容(叶子组件)\n * - layout.tsx — 布局组件(使用 <Outlet> 渲染子路由)\n * - error.tsx — 错误边界组件\n * - loading.tsx — 加载状态组件\n * - $.tsx — 通配/404 路由\n *\n * 目录约定:\n * - [id]/ — 动态路由 → /:id\n * - [id$]/ — 可选动态路由 → /:id?\n * - [...slug]/ — 全匹配路由 → /*\n * - __auth/ — 无路径布局(不生成 URL 片段)\n * - user.profile/ — 扁平路由(. 分隔 → /user/profile)\n */\nexport class ConventionalRouteGenerator {\n private options: GeneratorOptions;\n\n constructor(options: GeneratorOptions) {\n this.options = options;\n }\n\n generate(): RouteConfig[] {\n const { pagesDir } = this.options;\n if (!existsSync(pagesDir)) {\n console.warn(`[ywkf] 页面目录不存在: ${pagesDir}`);\n return [];\n }\n return this.scanDirectory(pagesDir, \"/\");\n }\n\n /**\n * 扫描目录,生成路由树\n */\n private scanDirectory(dir: string, routePath: string): RouteConfig[] {\n const entries = readdirSync(dir);\n\n // 查找约定文件\n const layoutFile = entries.find((e) => CONVENTION_FILES.layout.test(e));\n const pageFile = entries.find((e) => CONVENTION_FILES.page.test(e));\n const errorFile = entries.find((e) => CONVENTION_FILES.error.test(e));\n const loadingFile = entries.find((e) => CONVENTION_FILES.loading.test(e));\n const catchAllFile = entries.find((e) => CONVENTION_FILES.catchAll.test(e));\n\n // 收集子目录\n const subDirs = entries.filter((e) => {\n if (e.startsWith(\".\")) return false;\n if (EXCLUDED_DIRS.has(e)) return false;\n return statSync(join(dir, e)).isDirectory();\n });\n\n // 递归子目录\n const childRoutes: RouteConfig[] = [];\n for (const subDir of subDirs) {\n const subDirPath = join(dir, subDir);\n\n // __prefix:无路径布局\n if (subDir.startsWith(\"__\")) {\n const pathlessRoutes = this.scanDirectory(subDirPath, routePath);\n // 如果该无路径目录有 layout,将子路由包装在其中\n const pathlessLayout = readdirSync(subDirPath).find((e) =>\n CONVENTION_FILES.layout.test(e)\n );\n if (pathlessLayout) {\n const pathlessChildren = this.scanDirectory(subDirPath, routePath);\n childRoutes.push({\n path: routePath,\n name: this.generateRouteName(subDir.slice(2)),\n layoutFile: relative(this.options.pagesDir, join(subDirPath, pathlessLayout)),\n isLayout: true,\n pathless: true,\n children: pathlessChildren.filter(\n (r) => r.layoutFile !== relative(this.options.pagesDir, join(subDirPath, pathlessLayout))\n ),\n });\n } else {\n childRoutes.push(...pathlessRoutes);\n }\n continue;\n }\n\n // 计算路由路径\n const subRoutePath = this.resolveRoutePath(subDir, routePath);\n childRoutes.push(...this.scanDirectory(subDirPath, subRoutePath));\n }\n\n // 构建当前目录的路由节点\n const routeName = this.generateRouteName(routePath);\n const relPath = (file: string) => relative(this.options.pagesDir, join(dir, file));\n\n // 有 layout.tsx → 创建布局路由节点,children 为子路由\n if (layoutFile) {\n const layoutChildren: RouteConfig[] = [];\n\n // page.tsx 作为 index 子路由\n if (pageFile) {\n layoutChildren.push({\n path: routePath,\n file: relPath(pageFile),\n name: routeName + \"Index\",\n index: true,\n });\n }\n\n // 通配路由\n if (catchAllFile) {\n layoutChildren.push({\n path: \"*\",\n file: relPath(catchAllFile),\n name: routeName + \"CatchAll\",\n });\n }\n\n layoutChildren.push(...childRoutes);\n\n return [\n {\n path: routePath,\n layoutFile: relPath(layoutFile),\n errorFile: errorFile ? relPath(errorFile) : undefined,\n loadingFile: loadingFile ? relPath(loadingFile) : undefined,\n name: routeName,\n isLayout: true,\n children: layoutChildren,\n },\n ];\n }\n\n // 无 layout → page.tsx 是叶子页面\n const result: RouteConfig[] = [];\n\n if (pageFile) {\n result.push({\n path: routePath,\n file: relPath(pageFile),\n errorFile: errorFile ? relPath(errorFile) : undefined,\n name: routeName,\n });\n }\n\n if (catchAllFile) {\n result.push({\n path: \"*\",\n file: relPath(catchAllFile),\n name: routeName + \"CatchAll\",\n });\n }\n\n result.push(...childRoutes);\n return result;\n }\n\n /**\n * 解析目录名到路由路径\n *\n * - [id] → :id\n * - [id$] → :id?\n * - [...slug] → *\n * - user.profile → user/profile\n */\n private resolveRoutePath(dirName: string, parentPath: string): string {\n let segment: string;\n\n // [...slug] → *\n if (dirName.match(/^\\[\\.\\.\\.(.+)\\]$/)) {\n segment = \"*\";\n }\n // [id$] → :id? (可选动态)\n else if (dirName.match(/^\\[(.+)\\$\\]$/)) {\n const param = dirName.slice(1, -2);\n segment = `:${param}?`;\n }\n // [id] → :id\n else if (dirName.match(/^\\[(.+)\\]$/)) {\n const param = dirName.slice(1, -1);\n segment = `:${param}`;\n }\n // user.profile → user/profile (扁平路由)\n else if (dirName.includes(\".\")) {\n segment = dirName.replace(/\\./g, \"/\");\n } else {\n segment = dirName;\n }\n\n return parentPath === \"/\"\n ? `/${segment}`\n : `${parentPath}/${segment}`;\n }\n\n /**\n * 生成有效的 JS 标识符名称\n */\n private generateRouteName(path: string): string {\n const name = path\n .split(\"/\")\n .filter(Boolean)\n .map((s) =>\n s\n .replace(/^:/, \"Param\")\n .replace(/\\?$/, \"Optional\")\n .replace(/^\\*$/, \"CatchAll\")\n )\n .map((s) => {\n const cleaned = s.replace(/[^a-zA-Z0-9]/g, \"\");\n if (!cleaned) return \"\";\n return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);\n })\n .join(\"\");\n\n if (!name || /^\\d/.test(name)) {\n return \"Page\" + (name || \"Root\");\n }\n return name;\n }\n\n // ===== 代码生成 =====\n\n generateCode(): string {\n const routes = this.generate();\n const lazyImports: string[] = [];\n const errorImports: string[] = [];\n const loadingImports: string[] = [];\n\n this.collectImports(routes, lazyImports, errorImports, loadingImports);\n\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\nimport React, { lazy, Suspense } from \"react\";\nimport { createBrowserRouter, type RouteObject } from \"react-router\";\n\n// 懒加载页面组件\n${lazyImports.join(\"\\n\")}\n${errorImports.length > 0 ? \"\\n// 错误边界组件\\n\" + errorImports.join(\"\\n\") : \"\"}\n${loadingImports.length > 0 ? \"\\n// 加载状态组件\\n\" + loadingImports.join(\"\\n\") : \"\"}\n\n// 默认加载状态\nconst DefaultLoading = () => <div style={{ padding: 24, textAlign: \"center\" }}>加载中...</div>;\n\n// 懒加载包装\nfunction LazyRoute({\n Component,\n Loading = DefaultLoading,\n}: {\n Component: React.LazyExoticComponent<React.ComponentType<unknown>>;\n Loading?: React.ComponentType;\n}) {\n return (\n <Suspense fallback={<Loading />}>\n <Component />\n </Suspense>\n );\n}\n\n// 路由配置\nexport const routes: RouteObject[] = ${this.emitRouteArray(routes)};\n\n/**\n * 创建路由实例\n */\nexport function createRouter(basename?: string) {\n return createBrowserRouter(routes, { basename: basename || \"/\" });\n}\n\nexport default routes;\n`;\n }\n\n private collectImports(\n routes: RouteConfig[],\n lazyImports: string[],\n errorImports: string[],\n loadingImports: string[]\n ): void {\n for (const route of routes) {\n const name = route.name;\n const toImportPath = (f: string) => f.replace(/\\.(tsx?|jsx?)$/, \"\");\n\n if (route.isLayout && route.layoutFile) {\n lazyImports.push(\n `const ${name}Layout = lazy(() => import(\"@/pages/${toImportPath(route.layoutFile)}\"));`\n );\n }\n if (route.file) {\n lazyImports.push(\n `const ${name}Page = lazy(() => import(\"@/pages/${toImportPath(route.file)}\"));`\n );\n }\n if (route.errorFile) {\n errorImports.push(\n `const ${name}Error = lazy(() => import(\"@/pages/${toImportPath(route.errorFile)}\"));`\n );\n }\n if (route.loadingFile) {\n loadingImports.push(\n `const ${name}Loading = lazy(() => import(\"@/pages/${toImportPath(route.loadingFile)}\"));`\n );\n }\n\n if (route.children) {\n this.collectImports(route.children, lazyImports, errorImports, loadingImports);\n }\n }\n }\n\n private emitRouteArray(routes: RouteConfig[], parentPath?: string): string {\n const items = routes.map((r) => this.emitRouteObject(r, parentPath));\n return `[\\n ${items.join(\",\\n \")}\\n]`;\n }\n\n private emitRouteObject(route: RouteConfig, parentPath?: string): string {\n const parts: string[] = [];\n const name = route.name;\n\n // path\n if (route.index) {\n parts.push(\"index: true\");\n } else if (route.pathless) {\n // 无路径布局不输出 path\n } else if (route.path === \"*\") {\n parts.push(`path: \"*\"`);\n } else if (parentPath && route.path.startsWith(parentPath) && parentPath !== \"/\") {\n const rel = route.path.slice(parentPath.length + 1);\n parts.push(`path: \"${rel || \"\"}\"`);\n } else {\n parts.push(`path: \"${route.path}\"`);\n }\n\n // element\n if (route.isLayout && route.layoutFile) {\n const loadingProp = route.loadingFile ? ` Loading={${name}Loading}` : \"\";\n parts.push(`element: <LazyRoute Component={${name}Layout}${loadingProp} />`);\n } else if (route.file) {\n parts.push(`element: <LazyRoute Component={${name}Page} />`);\n }\n\n // errorElement\n if (route.errorFile) {\n parts.push(`errorElement: <LazyRoute Component={${name}Error} />`);\n }\n\n // children\n if (route.children && route.children.length > 0) {\n const childParent = route.pathless ? parentPath : route.path;\n parts.push(`children: ${this.emitRouteArray(route.children, childParent)}`);\n }\n\n return `{\\n ${parts.join(\",\\n \")}\\n }`;\n }\n\n /**\n * 写入路由文件\n */\n write(): void {\n const { outputDir } = this.options;\n const code = this.generateCode();\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(join(outputDir, \"routes.tsx\"), code, \"utf-8\");\n console.log(`[ywkf] 约定式路由已生成`);\n }\n}\n\n/**\n * 生成约定式路由\n */\nexport function generateConventionalRoutes(options: GeneratorOptions): void {\n new ConventionalRouteGenerator(options).write();\n}\n","import type { YwkfConfig } from \"../../config/schema.js\";\nimport type { CodeInjection } from \"../../plugin/types.js\";\n\n/**\n * 生成应用入口文件 (.ywkf/index.tsx)\n *\n * 基础版本只负责启动应用,微前端等功能通过插件注入\n */\nexport function generateEntry(\n config: Required<YwkfConfig>,\n injections: CodeInjection = {}\n): string {\n const imports = [\n `import \"@/index.css\";`,\n `import { runApp } from \"./bootstrap\";`,\n ...(injections.imports || []),\n ];\n\n const topLevel = injections.topLevel || [];\n const exports = injections.exports || [];\n\n // 如果有插件注入的 exports(比如微前端),使用条件启动\n const hasPluginExports = exports.length > 0;\n\n const startupCode = hasPluginExports\n ? `// 独立运行模式\nif (shouldRunIndependently !== false) {\n runApp();\n}`\n : `// 启动应用\nrunApp();`;\n\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\n${imports.join(\"\\n\")}\n\n${topLevel.length > 0 ? topLevel.join(\"\\n\") + \"\\n\" : \"\"}${exports.length > 0 ? exports.join(\"\\n\") + \"\\n\\n\" : \"\"}${startupCode}\n`;\n}\n","import type { YwkfConfig } from \"../../config/schema.js\";\nimport type { CodeInjection } from \"../../plugin/types.js\";\n\n/**\n * 生成启动文件 (.ywkf/bootstrap.tsx)\n *\n * 基础版本包含应用启动核心逻辑,微前端等功能通过插件注入\n */\nexport function generateBootstrap(\n config: Required<YwkfConfig>,\n injections: CodeInjection = {}\n): string {\n const { appName, router } = config;\n\n const routerImport = router.conventional\n ? `import { createRouter } from \"./routes\";`\n : `import { createRouter } from \"@/routes\";`;\n\n const imports = [\n `import { bootstrap, type AppConfig } from \"@4399ywkf/core/runtime\";`,\n routerImport,\n ...(injections.imports || []),\n ];\n\n const topLevel = injections.topLevel || [];\n const exports = injections.exports || [];\n\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\n${imports.join(\"\\n\")}\n\n/**\n * 应用名称\n */\nexport const APP_NAME = \"${appName}\";\n\n/**\n * 路由 basename\n */\nexport const BASENAME = \"${router.basename || \"/\"}\";\n\n/**\n * 获取用户自定义配置(如果存在)\n * 用户可在 src/app.config.ts 中导出配置来覆盖默认值\n */\nasync function getUserConfig(): Promise<Partial<AppConfig>> {\n try {\n // webpackIgnore 注释让打包器跳过模块存在性检查\n const userConfigModule = await import(/* webpackIgnore: true */ \"@/app.config\");\n return userConfigModule.default || {};\n } catch {\n // 文件不存在时返回空配置\n return {};\n }\n}\n\n/**\n * 创建应用配置\n */\nexport function createAppConfig(userConfig: Partial<AppConfig> = {}): AppConfig {\n const router = createRouter(BASENAME);\n\n const defaultConfig: AppConfig = {\n appName: APP_NAME,\n router,\n basename: BASENAME,\n rootId: APP_NAME,\n strictMode: true,\n antd: {\n enabled: true,\n },\n providers: [],\n lifecycle: {\n onMounted() {\n console.log(\\`[\\${APP_NAME}] 应用已挂载\\`);\n },\n onUnmount() {\n console.log(\\`[\\${APP_NAME}] 应用已卸载\\`);\n },\n onError(error) {\n console.error(\\`[\\${APP_NAME}] 全局错误:\\`, error);\n },\n },\n };\n\n // 深度合并用户配置\n return {\n ...defaultConfig,\n ...userConfig,\n antd: { ...defaultConfig.antd, ...userConfig.antd },\n providers: [...(defaultConfig.providers || []), ...(userConfig.providers || [])],\n lifecycle: { ...defaultConfig.lifecycle, ...userConfig.lifecycle },\n };\n}\n\n/**\n * 启动应用\n */\nexport async function runApp(): Promise<void> {\n const userConfig = await getUserConfig();\n await bootstrap(createAppConfig(userConfig));\n}\n${topLevel.length > 0 ? \"\\n\" + topLevel.join(\"\\n\") : \"\"}\n${exports.length > 0 ? \"\\n\" + exports.join(\"\\n\") : \"\"}\n`;\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { YwkfConfig } from \"../../config/schema.js\";\n\n/**\n * 生成环境变量类型定义 (.ywkf/types/env.d.ts)\n */\nexport function generateEnvTypes(\n cwd: string,\n config: Required<YwkfConfig>\n): string {\n const envVars = collectEnvVars(cwd, config);\n\n const envInterface = envVars\n .map((key) => ` readonly ${key}: string;`)\n .join(\"\\n\");\n\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\n/// <reference types=\"react\" />\n/// <reference types=\"react-dom\" />\n\ndeclare namespace NodeJS {\n interface ProcessEnv {\n${envInterface}\n readonly NODE_ENV: \"development\" | \"production\" | \"test\";\n }\n}\n\ndeclare module \"*.svg\" {\n import * as React from \"react\";\n const ReactComponent: React.FunctionComponent<\n React.SVGProps<SVGSVGElement> & { title?: string }\n >;\n export default ReactComponent;\n}\n\ndeclare module \"*.png\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.jpg\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.jpeg\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.gif\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.webp\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.css\" {\n const classes: { readonly [key: string]: string };\n export default classes;\n}\n\ndeclare module \"*.less\" {\n const classes: { readonly [key: string]: string };\n export default classes;\n}\n\ndeclare module \"*.scss\" {\n const classes: { readonly [key: string]: string };\n export default classes;\n}\n\ndeclare module \"*.md\" {\n const content: string;\n export default content;\n}\n`;\n}\n\n/**\n * 收集环境变量\n */\nfunction collectEnvVars(cwd: string, config: Required<YwkfConfig>): string[] {\n const envVars = new Set<string>();\n\n // 从 .env.public 读取\n const publicEnvPath = join(cwd, config.env.publicEnvFile || \"config/env/.env.public\");\n if (existsSync(publicEnvPath)) {\n const content = readFileSync(publicEnvPath, \"utf-8\");\n parseEnvFile(content, envVars);\n }\n\n // 从 .env.development 读取\n const devEnvPath = join(cwd, config.env.envDir || \"config/env\", \".env.development\");\n if (existsSync(devEnvPath)) {\n const content = readFileSync(devEnvPath, \"utf-8\");\n parseEnvFile(content, envVars);\n }\n\n // 从 .env.production 读取\n const prodEnvPath = join(cwd, config.env.envDir || \"config/env\", \".env.production\");\n if (existsSync(prodEnvPath)) {\n const content = readFileSync(prodEnvPath, \"utf-8\");\n parseEnvFile(content, envVars);\n }\n\n return Array.from(envVars).sort();\n}\n\n/**\n * 解析 .env 文件\n */\nfunction parseEnvFile(content: string, envVars: Set<string>): void {\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n continue;\n }\n const match = trimmed.match(/^([A-Z_][A-Z0-9_]*)\\s*=/);\n if (match) {\n envVars.add(match[1]);\n }\n }\n}\n","/**\n * 生成路由类型定义 (.ywkf/types/routes.d.ts)\n */\nexport function generateRouteTypes(): string {\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\nimport type { RouteObject } from \"react-router\";\n\ndeclare module \"@ywkf/routes\" {\n export const routes: RouteObject[];\n export function createRouter(basename?: string): ReturnType<typeof import(\"react-router\").createBrowserRouter>;\n export default routes;\n}\n`;\n}\n","import { rspack, type Configuration } from \"@rspack/core\";\nimport { merge } from \"webpack-merge\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport { createPathResolver } from \"../config/loader.js\";\nimport { createBaseConfig } from \"./base.js\";\n\n/**\n * 创建生产环境 Rspack 配置\n */\nexport function createProdConfig(\n config: Required<YwkfConfig>,\n cwd: string\n): Configuration {\n const baseConfig = createBaseConfig(config, cwd);\n const { resolveApp } = createPathResolver(cwd);\n const { style, performance, output } = config;\n\n const styleRules: Configuration[\"module\"] = {\n rules: [\n // Less - antd\n {\n test: /\\.less$/,\n include: [\n /[\\\\/]node_modules[\\\\/].*antd/,\n /[\\\\/]node_modules[\\\\/]@4399ywkf[\\\\/]design/,\n ],\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n strictMath: false,\n math: \"always\",\n javascriptEnabled: true,\n },\n },\n },\n ],\n },\n // Less - 项目文件\n ...(style.less?.enabled !== false\n ? [\n {\n test: /\\.less$/,\n include: [resolveApp(\"src\")],\n exclude: [resolveApp(\"node_modules\")],\n oneOf: [\n {\n test: /\\.module\\.less$/,\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: {\n sourceMap: true,\n modules: {\n localIdentName:\n \"[path][name]__[local]--[hash:base64:5]\",\n },\n importLoaders: 2,\n },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n javascriptEnabled: true,\n ...style.less?.lessOptions,\n },\n },\n },\n ],\n },\n {\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n javascriptEnabled: true,\n ...style.less?.lessOptions,\n },\n },\n },\n ],\n },\n ],\n },\n ]\n : []),\n // Sass\n ...(style.sass?.enabled !== false\n ? [\n {\n test: /\\.s[ac]ss$/i,\n include: [resolveApp(\"src\")],\n exclude: [resolveApp(\"node_modules\")],\n oneOf: [\n {\n test: /\\.module\\.s[ac]ss$/,\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: {\n sourceMap: true,\n modules: {\n localIdentName:\n \"[path][name]__[local]--[hash:base64:5]\",\n },\n importLoaders: 2,\n },\n },\n {\n loader: \"sass-loader\",\n options: {\n sourceMap: true,\n sassOptions: {\n outputStyle: \"compressed\",\n ...style.sass?.sassOptions,\n },\n },\n },\n ],\n },\n {\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"sass-loader\",\n options: {\n sourceMap: true,\n sassOptions: {\n outputStyle: \"compressed\",\n ...style.sass?.sassOptions,\n },\n },\n },\n ],\n },\n ],\n },\n ]\n : []),\n // TailwindCSS\n ...(style.tailwindcss\n ? [\n {\n test: /\\.css$/,\n include: [resolveApp(\"src/index.css\")],\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n \"css-loader\",\n {\n loader: \"postcss-loader\",\n options: {\n postcssOptions: {\n config: resolveApp(\"postcss.config.js\"),\n },\n },\n },\n ],\n },\n ]\n : []),\n // src 目录中的其他 CSS\n {\n test: /\\.css$/,\n include: [resolveApp(\"src\")],\n exclude: style.tailwindcss ? [resolveApp(\"src/index.css\")] : [],\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n ],\n },\n // node_modules CSS\n {\n test: /\\.css$/,\n include: [resolveApp(\"node_modules\")],\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n ],\n },\n ],\n };\n\n const prodConfig: Configuration = {\n mode: \"production\",\n devtool: \"hidden-source-map\",\n\n output: {\n filename: \"[name].[contenthash].bundle.js\",\n chunkFilename: \"[name].[contenthash].chunk.js\",\n clean: output.clean,\n },\n\n module: styleRules,\n\n plugins: [\n new rspack.CssExtractRspackPlugin({\n filename: \"[name].[contenthash:8].css\",\n chunkFilename: \"[name].[contenthash:8].chunk.css\",\n }),\n ],\n\n optimization: {\n minimize: true,\n minimizer: [\n new rspack.SwcJsMinimizerRspackPlugin({\n exclude: [resolveApp(\"node_modules\")],\n minimizerOptions: {\n compress: {\n pure_funcs: performance.dropConsole\n ? [\"console.log\", \"console.info\", \"console.debug\", \"console.warn\"]\n : [\"console.info\", \"console.debug\"],\n drop_console: false,\n drop_debugger: true,\n },\n },\n }),\n new rspack.LightningCssMinimizerRspackPlugin(),\n ],\n },\n };\n\n return merge(baseConfig, prodConfig);\n}\n"],"mappings":"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","names":["createRequire","join","existsSync","join","existsSync","mkdirSync","writeFileSync","readFileSync","join","existsSync","existsSync","join","join","existsSync","mkdirSync","readFileSync","writeFileSync","join","existsSync","require","join","require","createRequire","rspack","merge","rspack","merge"]}
|
|
1
|
+
{"version":3,"sources":["../../src/rspack/index.ts","../../src/rspack/dev.ts","../../src/config/loader.ts","../../src/rspack/base.ts","../../src/generator/plugin.ts","../../src/generator/generator.ts","../../src/router/generator.ts","../../src/generator/templates/entry.ts","../../src/generator/templates/bootstrap.ts","../../src/generator/templates/env-types.ts","../../src/generator/templates/route-types.ts","../../src/rspack/prod.ts"],"sourcesContent":["import type { Configuration } from \"@rspack/core\";\nimport { RsdoctorRspackPlugin } from \"@rsdoctor/rspack-plugin\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport { createDevConfig } from \"./dev.js\";\nimport { createProdConfig } from \"./prod.js\";\n\nexport { createBaseConfig } from \"./base.js\";\nexport { createDevConfig } from \"./dev.js\";\nexport { createProdConfig } from \"./prod.js\";\n\n/**\n * 根据环境创建 Rspack 配置\n */\nexport function createRspackConfig(\n config: Required<YwkfConfig>,\n cwd: string,\n options: { isDev?: boolean } = {}\n): Configuration {\n const isDev = options.isDev ?? process.env.NODE_ENV !== \"production\";\n\n let rspackConfig = isDev\n ? createDevConfig(config, cwd)\n : createProdConfig(config, cwd);\n\n // Rsdoctor 性能分析\n if (config.performance.rsdoctor) {\n rspackConfig.plugins = [\n ...(rspackConfig.plugins || []),\n new RsdoctorRspackPlugin({}),\n ];\n }\n\n // 用户自定义配置\n if (config.tools.rspack) {\n const userConfig = config.tools.rspack(rspackConfig, {\n isDev,\n isProd: !isDev,\n });\n\n if (userConfig) {\n rspackConfig = userConfig;\n }\n }\n\n return rspackConfig;\n}\n","import { rspack, type Configuration } from \"@rspack/core\";\nimport ReactRefreshPlugin from \"@rspack/plugin-react-refresh\";\nimport { merge } from \"webpack-merge\";\nimport { join } from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport { createPathResolver } from \"../config/loader.js\";\nimport { createBaseConfig } from \"./base.js\";\n\nconst require = createRequire(import.meta.url);\n\n/**\n * 将 proxy 对象格式转换为数组格式\n * webpack-dev-server v4+ 需要数组格式\n */\nfunction convertProxyToArray(\n proxy?: Record<string, string | object>\n): { context: string; target: string; changeOrigin?: boolean; secure?: boolean }[] | undefined {\n if (!proxy || Object.keys(proxy).length === 0) {\n return undefined;\n }\n\n return Object.entries(proxy).map(([context, target]) => {\n if (typeof target === \"string\") {\n return {\n context: [context],\n target,\n changeOrigin: true,\n secure: false,\n } as unknown as { context: string; target: string };\n }\n return {\n context: [context],\n changeOrigin: true,\n secure: false,\n ...(target as object),\n } as unknown as { context: string; target: string };\n });\n}\n\n/**\n * 创建开发环境 Rspack 配置\n */\nexport function createDevConfig(\n config: Required<YwkfConfig>,\n cwd: string\n): Configuration {\n const baseConfig = createBaseConfig(config, cwd, { isDev: true });\n const { resolveApp } = createPathResolver(cwd);\n const { dev, style } = config;\n\n const styleRules: Configuration[\"module\"] = {\n rules: [\n // Less - antd\n {\n test: /\\.less$/,\n include: [\n /[\\\\/]node_modules[\\\\/].*antd/,\n /[\\\\/]node_modules[\\\\/]@4399ywkf[\\\\/]design/,\n ],\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n strictMath: false,\n math: \"always\",\n javascriptEnabled: true,\n },\n },\n },\n ],\n },\n // Less - 项目文件\n ...(style.less?.enabled !== false\n ? [\n {\n test: /\\.less$/,\n include: [resolveApp(\"src\")],\n exclude: [resolveApp(\"node_modules\")],\n oneOf: [\n {\n test: /\\.module\\.less$/,\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: {\n sourceMap: true,\n modules: {\n localIdentName:\n \"[path][name]__[local]--[hash:base64:5]\",\n },\n importLoaders: 2,\n },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n javascriptEnabled: true,\n math: \"always\",\n ...style.less?.lessOptions,\n },\n },\n },\n ],\n },\n {\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n javascriptEnabled: true,\n ...style.less?.lessOptions,\n },\n },\n },\n ],\n },\n ],\n },\n ]\n : []),\n // Sass\n ...(style.sass?.enabled !== false\n ? [\n {\n test: /\\.s[ac]ss$/i,\n include: [resolveApp(\"src\")],\n exclude: [resolveApp(\"node_modules\")],\n oneOf: [\n {\n test: /\\.module\\.s[ac]ss$/,\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: {\n sourceMap: true,\n modules: {\n localIdentName:\n \"[path][name]__[local]--[hash:base64:5]\",\n },\n importLoaders: 2,\n },\n },\n {\n loader: \"sass-loader\",\n options: {\n sourceMap: true,\n sassOptions: {\n outputStyle: \"compressed\",\n ...style.sass?.sassOptions,\n },\n },\n },\n ],\n },\n {\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"sass-loader\",\n options: {\n sourceMap: true,\n sassOptions: {\n outputStyle: \"compressed\",\n ...style.sass?.sassOptions,\n },\n },\n },\n ],\n },\n ],\n },\n ]\n : []),\n // TailwindCSS\n ...(style.tailwindcss\n ? [\n {\n test: /\\.css$/,\n include: [resolveApp(\"src/index.css\")],\n use: [\n \"style-loader\",\n \"css-loader\",\n {\n loader: \"postcss-loader\",\n options: {\n postcssOptions: {\n config: resolveApp(\"postcss.config.js\"),\n },\n },\n },\n ],\n },\n ]\n : []),\n // 其他 CSS\n {\n test: /\\.css$/,\n include: [resolveApp(\"src\"), resolveApp(\"node_modules\")],\n exclude: style.tailwindcss ? [resolveApp(\"src/index.css\")] : [],\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n ],\n },\n ],\n };\n\n const devConfig: Configuration = {\n mode: \"development\",\n devtool: \"inline-source-map\",\n\n output: {\n filename: \"[name].bundle.js\",\n clean: false,\n },\n\n stats: \"errors-only\",\n\n plugins: [\n new ReactRefreshPlugin(),\n ],\n\n devServer: {\n host: dev.host,\n port: dev.port,\n compress: true,\n historyApiFallback: true,\n hot: true,\n allowedHosts: \"all\",\n client: {\n overlay: false,\n progress: true,\n },\n proxy: convertProxyToArray(dev.proxy),\n },\n\n module: styleRules,\n };\n\n return merge(baseConfig, devConfig);\n}\n","import { existsSync } from \"node:fs\";\nimport { resolve, extname } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport deepmerge from \"deepmerge\";\nimport { defaultConfig, type YwkfConfig } from \"./schema.js\";\n\n/** 支持的配置文件名 */\nconst CONFIG_FILES = [\n \"ywkf.config.ts\",\n \"ywkf.config.mts\",\n \"ywkf.config.js\",\n \"ywkf.config.mjs\",\n];\n\n/**\n * 查找配置文件\n */\nexport function findConfigFile(cwd: string): string | null {\n for (const file of CONFIG_FILES) {\n const configPath = resolve(cwd, file);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n return null;\n}\n\n/**\n * 加载 TypeScript 配置文件\n */\nasync function loadTsConfig(configPath: string): Promise<YwkfConfig> {\n const jiti = (await import(\"jiti\")).default;\n const loader = jiti(configPath, {\n interopDefault: true,\n });\n\n const config = loader(configPath);\n return config.default || config;\n}\n\n/**\n * 加载 JavaScript 配置文件\n */\nasync function loadJsConfig(configPath: string): Promise<YwkfConfig> {\n const fileUrl = pathToFileURL(configPath).href;\n const module = await import(fileUrl);\n return module.default || module;\n}\n\n/**\n * 加载配置文件\n */\nexport async function loadConfigFile(configPath: string): Promise<YwkfConfig> {\n const ext = extname(configPath);\n\n if (ext === \".ts\" || ext === \".mts\") {\n return loadTsConfig(configPath);\n }\n\n return loadJsConfig(configPath);\n}\n\n/**\n * 合并配置\n */\nexport function mergeConfig(\n userConfig: YwkfConfig,\n baseConfig: YwkfConfig = defaultConfig\n): Required<YwkfConfig> {\n return deepmerge(baseConfig, userConfig, {\n arrayMerge: (_, sourceArray) => sourceArray,\n }) as Required<YwkfConfig>;\n}\n\n/**\n * 解析并加载完整配置\n * @param cwd 工作目录\n * @returns 合并后的完整配置\n */\nexport async function resolveConfig(cwd: string): Promise<{\n config: Required<YwkfConfig>;\n configPath: string | null;\n}> {\n const configPath = findConfigFile(cwd);\n\n if (!configPath) {\n console.warn(\n \"⚠️ 未找到配置文件 (ywkf.config.ts),使用默认配置\"\n );\n return {\n config: defaultConfig as Required<YwkfConfig>,\n configPath: null,\n };\n }\n\n try {\n const userConfig = await loadConfigFile(configPath);\n const config = mergeConfig(userConfig);\n\n return { config, configPath };\n } catch (error) {\n console.error(\"❌ 配置文件加载失败:\", error);\n throw error;\n }\n}\n\n/**\n * 获取应用路径解析器\n */\nexport function createPathResolver(cwd: string) {\n return {\n resolveApp: (relativePath: string) => resolve(cwd, relativePath),\n cwd,\n };\n}\n","import { rspack, type Configuration } from \"@rspack/core\";\nimport { createRequire } from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport { createPathResolver } from \"../config/loader.js\";\nimport { YwkfGeneratorPlugin } from \"../generator/plugin.js\";\n\nconst require = createRequire(import.meta.url);\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst coreNodeModules = join(__dirname, \"../../node_modules\");\n\n/**\n * 创建基础 Rspack 配置\n */\nexport function createBaseConfig(\n config: Required<YwkfConfig>,\n cwd: string,\n options: { isDev?: boolean } = {}\n): Configuration {\n const isDev = options.isDev ?? process.env.NODE_ENV !== \"production\";\n const { resolveApp } = createPathResolver(cwd);\n\n const {\n appName,\n appCName,\n output,\n html,\n alias: userAlias,\n microFrontend,\n router,\n } = config;\n\n // 约定式路由输出目录\n const ywkfOutputDir = resolveApp(\".ywkf\");\n\n const defaultAlias: Record<string, string> = {\n \"@\": resolveApp(\"src\"),\n \"@config\": resolveApp(\"config\"),\n \"@store\": resolveApp(\"store\"),\n \"@locales\": resolveApp(\"locales\"),\n \"@public\": resolveApp(\"public\"),\n // 约定式路由生成的文件\n \"@ywkf/routes\": join(ywkfOutputDir, \"routes.tsx\"),\n // 请求层(由 reactQueryPlugin 生成)\n \"@ywkf/request\": join(ywkfOutputDir, \"request.ts\"),\n // Store 工具(由 zustandPlugin 生成)\n \"@ywkf/store\": join(ywkfOutputDir, \"store.ts\"),\n };\n\n const alias = { ...defaultAlias, ...userAlias };\n\n return {\n // 使用 .ywkf/index.tsx 作为入口(由框架生成)\n entry: [join(ywkfOutputDir, \"index.tsx\")],\n\n resolve: {\n extensions: [\".ts\", \".tsx\", \".jsx\", \".js\", \".json\", \".mjs\"],\n symlinks: true,\n alias: {\n ...alias,\n \"process/browser.js\": require.resolve(\"process/browser.js\"),\n \"process/browser\": require.resolve(\"process/browser.js\"),\n react: resolveApp(\"node_modules/react\"),\n \"react-dom\": resolveApp(\"node_modules/react-dom\"),\n \"react-router\": resolveApp(\"node_modules/react-router\"),\n },\n fallback: {\n path: require.resolve(\"path-browserify\"),\n process: require.resolve(\"process/browser.js\"),\n buffer: require.resolve(\"buffer/\"),\n util: require.resolve(\"util/\"),\n stream: require.resolve(\"stream-browserify\"),\n crypto: require.resolve(\"crypto-browserify\"),\n zlib: require.resolve(\"browserify-zlib\"),\n querystring: require.resolve(\"querystring-es3\"),\n url: require.resolve(\"url/\"),\n assert: require.resolve(\"assert/\"),\n fs: false,\n net: false,\n tls: false,\n os: false,\n https: false,\n http: false,\n },\n },\n\n resolveLoader: {\n modules: [coreNodeModules, \"node_modules\"],\n },\n\n module: {\n rules: [\n {\n test: /\\.m?js$/,\n resolve: {\n fullySpecified: false,\n },\n },\n {\n test: /\\.[jt]sx?$/,\n include: [\n resolveApp(\"src\"),\n resolveApp(\"config\"),\n resolveApp(\"store\"),\n resolveApp(\"packages\"),\n ywkfOutputDir, // 约定式路由生成的文件\n ],\n exclude: [resolveApp(\"node_modules\")],\n use: [\n {\n loader: \"builtin:swc-loader\",\n options: {\n jsc: {\n parser: {\n syntax: \"typescript\",\n tsx: true,\n decorators: true,\n },\n transform: {\n react: {\n runtime: \"automatic\",\n development: isDev,\n refresh: isDev,\n },\n },\n target: \"es2015\",\n },\n sourceMaps: true,\n },\n },\n ],\n },\n {\n test: /\\.(png|jpg|jpeg|gif|webp|m3u8|exr|hdr|json|woff2)$/,\n include: [resolveApp(\"public\")],\n exclude: [resolveApp(\"src\"), resolveApp(\"store\")],\n type: \"asset\",\n parser: {\n dataUrlCondition: {\n maxSize: 10 * 1024,\n },\n },\n },\n {\n test: /\\.(md)$/,\n include: [resolveApp(\"src\")],\n type: \"asset/source\",\n },\n {\n test: /\\.svg$/,\n use: [\"@svgr/webpack\"],\n },\n ],\n },\n\n plugins: [\n new rspack.ProvidePlugin({\n process: \"process/browser.js\",\n Buffer: [\"buffer\", \"Buffer\"],\n }),\n new rspack.DefinePlugin({\n \"process.env\": JSON.stringify(process.env),\n }),\n new rspack.HtmlRspackPlugin({\n template: resolveApp(html.template ?? \"public/index.html\"),\n filename: \"index.html\",\n inject: \"body\",\n hash: true,\n minify: process.env.NODE_ENV === \"production\",\n favicon: resolveApp(html.favicon ?? \"public/favicon.ico\"),\n templateParameters: {\n title: html.title ?? appCName,\n mountRoot: html.mountRoot ?? appName,\n },\n }),\n new rspack.CopyRspackPlugin({\n patterns: [\n {\n from: resolveApp(\"public/images\"),\n to: \"public/images\",\n noErrorOnMissing: true,\n },\n ],\n }),\n // .ywkf 目录生成插件(传递用户配置的插件列表)\n new YwkfGeneratorPlugin({\n cwd,\n config,\n outputDir: ywkfOutputDir,\n isDev: process.env.NODE_ENV !== \"production\",\n pluginConfigs: config.plugins,\n }),\n ].filter(Boolean),\n\n output: {\n assetModuleFilename: \"images/[hash][ext]\",\n library: microFrontend.enabled ? `${appCName}-[name]` : undefined,\n chunkFilename: \"[name].[contenthash].js\",\n libraryTarget: microFrontend.enabled ? \"umd\" : undefined,\n globalObject: microFrontend.enabled ? \"window\" : undefined,\n chunkLoadingGlobal: microFrontend.enabled\n ? `chunk_global_${appName}`\n : undefined,\n publicPath: output.publicPath ?? \"/\",\n path: resolveApp(output.path ?? \"dist\"),\n },\n\n ignoreWarnings: [\n {\n module: /@testing-library\\/react/,\n message: /export 'act'/,\n },\n ],\n\n devtool: \"source-map\",\n };\n}\n","import type { Compiler } from \"@rspack/core\";\nimport { watch, existsSync } from \"fs\";\nimport { join } from \"path\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport type { YwkfPlugin, PluginHooks, PluginContext, PluginConfig } from \"../plugin/types.js\";\nimport { YwkfGenerator } from \"./generator.js\";\n\nexport interface YwkfGeneratorPluginOptions {\n /** 项目根目录 */\n cwd: string;\n /** 解析后的配置 */\n config: Required<YwkfConfig>;\n /** 输出目录(.ywkf) */\n outputDir: string;\n /** 是否开发模式 */\n isDev: boolean;\n /** 用户配置的插件列表(PluginConfig 格式) */\n pluginConfigs?: PluginConfig[];\n}\n\n/**\n * .ywkf 目录生成插件\n *\n * 在编译前生成 .ywkf 目录下的所有文件\n */\nexport class YwkfGeneratorPlugin {\n private options: YwkfGeneratorPluginOptions;\n private hasGenerated = false;\n private isWatching = false;\n private generator: YwkfGenerator | null = null;\n private pluginHooks: PluginHooks[] = [];\n private initialized = false;\n\n constructor(options: YwkfGeneratorPluginOptions) {\n this.options = options;\n }\n\n /**\n * 解析插件配置为插件实例\n */\n private async resolvePlugin(\n pluginConfig: PluginConfig\n ): Promise<YwkfPlugin | null> {\n try {\n let plugin: YwkfPlugin;\n let options: Record<string, unknown> = {};\n\n if (typeof pluginConfig === \"string\") {\n const module = await import(pluginConfig);\n plugin = module.default || module;\n } else if (Array.isArray(pluginConfig)) {\n const [pluginOrName, pluginOptions] = pluginConfig;\n options = pluginOptions;\n\n if (typeof pluginOrName === \"string\") {\n const module = await import(pluginOrName);\n plugin = module.default || module;\n } else {\n plugin = pluginOrName;\n }\n } else {\n plugin = pluginConfig;\n }\n\n // 如果是工厂函数,调用它\n if (typeof plugin === \"function\") {\n plugin = (plugin as (opts?: Record<string, unknown>) => YwkfPlugin)(options);\n }\n\n return plugin;\n } catch (error) {\n console.error(`[ywkf] 解析插件失败: ${error}`);\n return null;\n }\n }\n\n /**\n * 初始化插件钩子\n */\n private async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n const { cwd, config, isDev, pluginConfigs = [] } = this.options;\n\n // 创建插件上下文\n const context: PluginContext = {\n cwd,\n isDev,\n isProd: !isDev,\n config,\n logger: {\n info: (msg) => {\n if (process.env.DEBUG) console.log(`[ywkf] ${msg}`);\n },\n warn: (msg) => console.warn(`[ywkf] ${msg}`),\n error: (msg) => console.error(`[ywkf] ${msg}`),\n debug: (msg) => {\n if (process.env.DEBUG) console.log(`[ywkf:debug] ${msg}`);\n },\n },\n };\n\n // 解析并初始化所有插件,收集钩子\n for (const pluginConfig of pluginConfigs) {\n const plugin = await this.resolvePlugin(pluginConfig);\n if (plugin) {\n const hooks = await plugin.setup(context);\n this.pluginHooks.push(hooks);\n if (process.env.DEBUG) console.log(`[ywkf] 插件已加载: ${plugin.name}`);\n }\n }\n\n // 创建生成器\n this.generator = new YwkfGenerator(\n {\n cwd: this.options.cwd,\n config: this.options.config,\n outputDir: this.options.outputDir,\n isDev: this.options.isDev,\n },\n this.pluginHooks\n );\n\n this.initialized = true;\n }\n\n apply(compiler: Compiler): void {\n const pluginName = \"YwkfGeneratorPlugin\";\n\n // 在编译开始前生成代码\n compiler.hooks.beforeCompile.tapAsync(pluginName, async (params, callback) => {\n try {\n // 确保初始化完成\n await this.initialize();\n\n if (!this.hasGenerated && this.generator) {\n await this.generator.generate();\n this.hasGenerated = true;\n }\n callback();\n } catch (error) {\n callback(error as Error);\n }\n });\n\n // 开发模式下监听文件变化\n if (this.options.isDev && !this.isWatching) {\n this.watchPages();\n }\n }\n\n /**\n * 监听页面目录变化\n */\n private watchPages(): void {\n const { config, cwd } = this.options;\n const pagesDir = join(cwd, config.router.pagesDir || \"src/pages\");\n\n if (!existsSync(pagesDir)) {\n return;\n }\n\n this.isWatching = true;\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const watcher = watch(\n pagesDir,\n { recursive: true },\n (eventType, filename) => {\n // 只处理 tsx/jsx 文件\n if (!filename?.match(/\\.(tsx?|jsx?)$/)) {\n return;\n }\n\n // 防抖处理\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n debounceTimer = setTimeout(async () => {\n if (process.env.DEBUG) console.log(`[ywkf] 检测到页面变化: ${filename}`);\n if (this.generator) {\n await this.generator.generate();\n }\n }, 500);\n }\n );\n\n // 进程退出时关闭监听\n process.on(\"exit\", () => {\n watcher.close();\n });\n }\n}\n","import { existsSync, mkdirSync, writeFileSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport type {\n PluginHooks,\n GeneratorContext,\n CodeInjection,\n GeneratedFile,\n} from \"../plugin/types.js\";\nimport { ConventionalRouteGenerator } from \"../router/generator.js\";\nimport { generateEntry } from \"./templates/entry.js\";\nimport { generateBootstrap } from \"./templates/bootstrap.js\";\nimport { generateEnvTypes } from \"./templates/env-types.js\";\nimport { generateRouteTypes } from \"./templates/route-types.js\";\n\n/**\n * 插件钩子执行器\n */\nexport interface PluginHooksRunner {\n hooks: PluginHooks[];\n}\n\n/**\n * .ywkf 目录代码生成器\n *\n * 生成的文件:\n * - index.tsx - 应用入口\n * - routes.tsx - 约定式路由\n * - bootstrap.tsx - 启动逻辑\n * - types/routes.d.ts - 路由类型\n * - types/env.d.ts - 环境变量类型\n * - config.json - 配置快照\n */\nexport class YwkfGenerator {\n private context: GeneratorContext;\n private pluginHooks: PluginHooks[];\n private lastGeneratedContent: Map<string, string> = new Map();\n\n constructor(\n context: Omit<GeneratorContext, \"outputDir\"> & { outputDir?: string },\n pluginHooks: PluginHooks[] = []\n ) {\n this.context = {\n ...context,\n outputDir: context.outputDir || join(context.cwd, \".ywkf\"),\n };\n this.pluginHooks = pluginHooks;\n }\n\n /**\n * 生成所有文件\n */\n async generate(): Promise<void> {\n const { outputDir } = this.context;\n\n // 确保目录存在\n this.ensureDir(outputDir);\n this.ensureDir(join(outputDir, \"types\"));\n\n // 生成各个文件\n this.generateConfigSnapshot();\n this.generateRoutes();\n this.generateBootstrapFile();\n this.generateEntryFile();\n this.generateTypes();\n\n // 生成插件附加文件\n await this.generatePluginFiles();\n\n // 调用插件 afterGenerate 钩子\n for (const hooks of this.pluginHooks) {\n if (hooks.afterGenerate) {\n await hooks.afterGenerate(this.context);\n }\n }\n\n if (process.env.DEBUG) console.log(`[ywkf] 已生成 .ywkf 目录`);\n }\n\n /**\n * 生成配置快照\n */\n private generateConfigSnapshot(): void {\n const { outputDir, config } = this.context;\n const configPath = join(outputDir, \"config.json\");\n\n // 移除函数类型的配置(无法序列化)\n const serializableConfig = JSON.parse(\n JSON.stringify(config, (key, value) => {\n if (typeof value === \"function\") {\n return \"[Function]\";\n }\n return value;\n })\n );\n\n this.writeFileIfChanged(\n configPath,\n JSON.stringify(serializableConfig, null, 2)\n );\n }\n\n /**\n * 生成约定式路由\n */\n private generateRoutes(): void {\n const { cwd, outputDir, config } = this.context;\n\n if (!config.router.conventional) {\n return;\n }\n\n const pagesDir = join(cwd, config.router.pagesDir || \"src/pages\");\n const generator = new ConventionalRouteGenerator({\n pagesDir,\n outputDir,\n basename: config.router.basename,\n });\n\n const content = generator.generateCode();\n const routesPath = join(outputDir, \"routes.tsx\");\n\n this.writeFileIfChanged(routesPath, content);\n }\n\n /**\n * 生成启动文件\n */\n private generateBootstrapFile(): void {\n const { outputDir, config } = this.context;\n\n // 收集插件注入\n const injections = this.collectInjections(\"bootstrap\");\n\n // 生成基础代码\n let content = generateBootstrap(config, injections);\n\n // 调用插件修改钩子\n for (const hooks of this.pluginHooks) {\n if (hooks.modifyBootstrapCode) {\n const result = hooks.modifyBootstrapCode(content, this.context);\n if (result) {\n content = result;\n }\n }\n }\n\n const bootstrapPath = join(outputDir, \"bootstrap.tsx\");\n this.writeFileIfChanged(bootstrapPath, content);\n }\n\n /**\n * 生成入口文件\n */\n private generateEntryFile(): void {\n const { outputDir, config } = this.context;\n\n // 收集插件注入\n const injections = this.collectInjections(\"entry\");\n\n // 生成基础代码\n let content = generateEntry(config, injections);\n\n // 调用插件修改钩子\n for (const hooks of this.pluginHooks) {\n if (hooks.modifyEntryCode) {\n const result = hooks.modifyEntryCode(content, this.context);\n if (result) {\n content = result;\n }\n }\n }\n\n const entryPath = join(outputDir, \"index.tsx\");\n this.writeFileIfChanged(entryPath, content);\n }\n\n /**\n * 收集插件代码注入\n */\n private collectInjections(\n type: \"entry\" | \"bootstrap\"\n ): CodeInjection {\n const result: CodeInjection = {\n imports: [],\n topLevel: [],\n exports: [],\n };\n\n const hookName = type === \"entry\" ? \"injectEntry\" : \"injectBootstrap\";\n\n for (const hooks of this.pluginHooks) {\n const hook = hooks[hookName];\n if (hook) {\n const injection = hook(this.context);\n if (injection) {\n result.imports?.push(...(injection.imports || []));\n result.topLevel?.push(...(injection.topLevel || []));\n result.exports?.push(...(injection.exports || []));\n }\n }\n }\n\n return result;\n }\n\n /**\n * 生成插件附加文件\n */\n private async generatePluginFiles(): Promise<void> {\n const { outputDir } = this.context;\n\n for (const hooks of this.pluginHooks) {\n if (hooks.generateFiles) {\n const files = hooks.generateFiles(this.context);\n if (files) {\n for (const file of files) {\n const filePath = join(outputDir, file.path);\n const dir = join(filePath, \"..\");\n this.ensureDir(dir);\n this.writeFileIfChanged(filePath, file.content);\n }\n }\n }\n }\n }\n\n /**\n * 生成类型定义\n */\n private generateTypes(): void {\n const { outputDir, config, cwd } = this.context;\n\n // 生成环境变量类型\n const envTypesContent = generateEnvTypes(cwd, config);\n this.writeFileIfChanged(\n join(outputDir, \"types\", \"env.d.ts\"),\n envTypesContent\n );\n\n // 生成路由类型\n if (config.router.conventional) {\n const routeTypesContent = generateRouteTypes();\n this.writeFileIfChanged(\n join(outputDir, \"types\", \"routes.d.ts\"),\n routeTypesContent\n );\n }\n }\n\n /**\n * 确保目录存在\n */\n private ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n }\n\n /**\n * 只在内容变化时写入文件(避免触发不必要的热更新)\n */\n private writeFileIfChanged(filePath: string, content: string): void {\n const normalizedContent = this.normalizeContent(content);\n const lastContent = this.lastGeneratedContent.get(filePath);\n\n if (lastContent === normalizedContent) {\n return;\n }\n\n // 检查文件是否存在且内容相同\n if (existsSync(filePath)) {\n const existingContent = readFileSync(filePath, \"utf-8\");\n if (this.normalizeContent(existingContent) === normalizedContent) {\n this.lastGeneratedContent.set(filePath, normalizedContent);\n return;\n }\n }\n\n writeFileSync(filePath, content, \"utf-8\");\n this.lastGeneratedContent.set(filePath, normalizedContent);\n }\n\n /**\n * 标准化内容(去掉时间戳等动态部分)\n */\n private normalizeContent(content: string): string {\n return content\n .replace(/\\/\\/ Generated at: .+/g, \"\")\n .replace(/\\/\\*\\* Generated at: .+ \\*\\//g, \"\");\n }\n}\n","import { existsSync, readdirSync, statSync, mkdirSync, writeFileSync } from \"fs\";\nimport { join, relative, basename } from \"path\";\n\n/**\n * 路由节点配置\n */\nexport interface RouteConfig {\n /** 路由路径 */\n path: string;\n /** 页面文件(page.tsx)相对路径 */\n file?: string;\n /** 布局文件(layout.tsx)相对路径 */\n layoutFile?: string;\n /** 错误边界文件(error.tsx)相对路径 */\n errorFile?: string;\n /** 加载状态文件(loading.tsx)相对路径 */\n loadingFile?: string;\n /** 通配路由文件($.tsx)相对路径 */\n catchAllFile?: string;\n /** 组件名称 */\n name: string;\n /** 子路由 */\n children?: RouteConfig[];\n /** 是否为 index 路由 */\n index?: boolean;\n /** 是否为布局路由 */\n isLayout?: boolean;\n /** 是否为无路径布局(__prefix) */\n pathless?: boolean;\n}\n\nexport interface GeneratorOptions {\n /** 页面目录 */\n pagesDir: string;\n /** 输出目录 */\n outputDir: string;\n /** 路由 basename */\n basename?: string;\n}\n\n/**\n * 不参与路由扫描的目录名\n */\nconst EXCLUDED_DIRS = new Set([\n \"components\",\n \"hooks\",\n \"utils\",\n \"services\",\n \"models\",\n \"assets\",\n \"types\",\n \"constants\",\n \"styles\",\n]);\n\n/**\n * 约定文件名匹配\n */\nconst CONVENTION_FILES = {\n page: /^page\\.(tsx?|jsx?)$/,\n layout: /^layout\\.(tsx?|jsx?)$/,\n error: /^error\\.(tsx?|jsx?)$/,\n loading: /^loading\\.(tsx?|jsx?)$/,\n catchAll: /^\\$\\.(tsx?|jsx?)$/,\n};\n\n/**\n * Modern.js 风格约定式路由生成器\n *\n * 文件约定:\n * - page.tsx — 页面内容(叶子组件)\n * - layout.tsx — 布局组件(使用 <Outlet> 渲染子路由)\n * - error.tsx — 错误边界组件\n * - loading.tsx — 加载状态组件\n * - $.tsx — 通配/404 路由\n *\n * 目录约定:\n * - [id]/ — 动态路由 → /:id\n * - [id$]/ — 可选动态路由 → /:id?\n * - [...slug]/ — 全匹配路由 → /*\n * - __auth/ — 无路径布局(不生成 URL 片段)\n * - user.profile/ — 扁平路由(. 分隔 → /user/profile)\n */\nexport class ConventionalRouteGenerator {\n private options: GeneratorOptions;\n\n constructor(options: GeneratorOptions) {\n this.options = options;\n }\n\n generate(): RouteConfig[] {\n const { pagesDir } = this.options;\n if (!existsSync(pagesDir)) {\n console.warn(`[ywkf] 页面目录不存在: ${pagesDir}`);\n return [];\n }\n return this.scanDirectory(pagesDir, \"/\");\n }\n\n /**\n * 扫描目录,生成路由树\n */\n private scanDirectory(dir: string, routePath: string): RouteConfig[] {\n const entries = readdirSync(dir);\n\n // 查找约定文件\n const layoutFile = entries.find((e) => CONVENTION_FILES.layout.test(e));\n const pageFile = entries.find((e) => CONVENTION_FILES.page.test(e));\n const errorFile = entries.find((e) => CONVENTION_FILES.error.test(e));\n const loadingFile = entries.find((e) => CONVENTION_FILES.loading.test(e));\n const catchAllFile = entries.find((e) => CONVENTION_FILES.catchAll.test(e));\n\n // 收集子目录\n const subDirs = entries.filter((e) => {\n if (e.startsWith(\".\")) return false;\n if (EXCLUDED_DIRS.has(e)) return false;\n return statSync(join(dir, e)).isDirectory();\n });\n\n // 递归子目录\n const childRoutes: RouteConfig[] = [];\n for (const subDir of subDirs) {\n const subDirPath = join(dir, subDir);\n\n // __prefix:无路径布局\n if (subDir.startsWith(\"__\")) {\n const pathlessRoutes = this.scanDirectory(subDirPath, routePath);\n // 如果该无路径目录有 layout,将子路由包装在其中\n const pathlessLayout = readdirSync(subDirPath).find((e) =>\n CONVENTION_FILES.layout.test(e)\n );\n if (pathlessLayout) {\n const pathlessChildren = this.scanDirectory(subDirPath, routePath);\n childRoutes.push({\n path: routePath,\n name: this.generateRouteName(subDir.slice(2)),\n layoutFile: relative(this.options.pagesDir, join(subDirPath, pathlessLayout)),\n isLayout: true,\n pathless: true,\n children: pathlessChildren.filter(\n (r) => r.layoutFile !== relative(this.options.pagesDir, join(subDirPath, pathlessLayout))\n ),\n });\n } else {\n childRoutes.push(...pathlessRoutes);\n }\n continue;\n }\n\n // 计算路由路径\n const subRoutePath = this.resolveRoutePath(subDir, routePath);\n childRoutes.push(...this.scanDirectory(subDirPath, subRoutePath));\n }\n\n // 构建当前目录的路由节点\n const routeName = this.generateRouteName(routePath);\n const relPath = (file: string) => relative(this.options.pagesDir, join(dir, file));\n\n // 有 layout.tsx → 创建布局路由节点,children 为子路由\n if (layoutFile) {\n const layoutChildren: RouteConfig[] = [];\n\n // page.tsx 作为 index 子路由\n if (pageFile) {\n layoutChildren.push({\n path: routePath,\n file: relPath(pageFile),\n name: routeName + \"Index\",\n index: true,\n });\n }\n\n // 通配路由\n if (catchAllFile) {\n layoutChildren.push({\n path: \"*\",\n file: relPath(catchAllFile),\n name: routeName + \"CatchAll\",\n });\n }\n\n layoutChildren.push(...childRoutes);\n\n return [\n {\n path: routePath,\n layoutFile: relPath(layoutFile),\n errorFile: errorFile ? relPath(errorFile) : undefined,\n loadingFile: loadingFile ? relPath(loadingFile) : undefined,\n name: routeName,\n isLayout: true,\n children: layoutChildren,\n },\n ];\n }\n\n // 无 layout → page.tsx 是叶子页面\n const result: RouteConfig[] = [];\n\n if (pageFile) {\n result.push({\n path: routePath,\n file: relPath(pageFile),\n errorFile: errorFile ? relPath(errorFile) : undefined,\n name: routeName,\n });\n }\n\n if (catchAllFile) {\n result.push({\n path: \"*\",\n file: relPath(catchAllFile),\n name: routeName + \"CatchAll\",\n });\n }\n\n result.push(...childRoutes);\n return result;\n }\n\n /**\n * 解析目录名到路由路径\n *\n * - [id] → :id\n * - [id$] → :id?\n * - [...slug] → *\n * - user.profile → user/profile\n */\n private resolveRoutePath(dirName: string, parentPath: string): string {\n let segment: string;\n\n // [...slug] → *\n if (dirName.match(/^\\[\\.\\.\\.(.+)\\]$/)) {\n segment = \"*\";\n }\n // [id$] → :id? (可选动态)\n else if (dirName.match(/^\\[(.+)\\$\\]$/)) {\n const param = dirName.slice(1, -2);\n segment = `:${param}?`;\n }\n // [id] → :id\n else if (dirName.match(/^\\[(.+)\\]$/)) {\n const param = dirName.slice(1, -1);\n segment = `:${param}`;\n }\n // user.profile → user/profile (扁平路由)\n else if (dirName.includes(\".\")) {\n segment = dirName.replace(/\\./g, \"/\");\n } else {\n segment = dirName;\n }\n\n return parentPath === \"/\"\n ? `/${segment}`\n : `${parentPath}/${segment}`;\n }\n\n /**\n * 生成有效的 JS 标识符名称\n */\n private generateRouteName(path: string): string {\n const name = path\n .split(\"/\")\n .filter(Boolean)\n .map((s) =>\n s\n .replace(/^:/, \"Param\")\n .replace(/\\?$/, \"Optional\")\n .replace(/^\\*$/, \"CatchAll\")\n )\n .map((s) => {\n const cleaned = s.replace(/[^a-zA-Z0-9]/g, \"\");\n if (!cleaned) return \"\";\n return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);\n })\n .join(\"\");\n\n if (!name || /^\\d/.test(name)) {\n return \"Page\" + (name || \"Root\");\n }\n return name;\n }\n\n // ===== 代码生成 =====\n\n generateCode(): string {\n const routes = this.generate();\n const lazyImports: string[] = [];\n const errorImports: string[] = [];\n const loadingImports: string[] = [];\n\n this.collectImports(routes, lazyImports, errorImports, loadingImports);\n\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\nimport React, { lazy, Suspense } from \"react\";\nimport { createBrowserRouter, type RouteObject } from \"react-router\";\n\n// 懒加载页面组件\n${lazyImports.join(\"\\n\")}\n${errorImports.length > 0 ? \"\\n// 错误边界组件\\n\" + errorImports.join(\"\\n\") : \"\"}\n${loadingImports.length > 0 ? \"\\n// 加载状态组件\\n\" + loadingImports.join(\"\\n\") : \"\"}\n\n// 默认加载状态\nconst DefaultLoading = () => <div style={{ padding: 24, textAlign: \"center\" }}>加载中...</div>;\n\n// 懒加载包装\nfunction LazyRoute({\n Component,\n Loading = DefaultLoading,\n}: {\n Component: React.LazyExoticComponent<React.ComponentType<unknown>>;\n Loading?: React.ComponentType;\n}) {\n return (\n <Suspense fallback={<Loading />}>\n <Component />\n </Suspense>\n );\n}\n\n// 路由配置\nexport const routes: RouteObject[] = ${this.emitRouteArray(routes)};\n\n/**\n * 创建路由实例\n */\nexport function createRouter(basename?: string) {\n return createBrowserRouter(routes, { basename: basename || \"/\" });\n}\n\nexport default routes;\n`;\n }\n\n private collectImports(\n routes: RouteConfig[],\n lazyImports: string[],\n errorImports: string[],\n loadingImports: string[]\n ): void {\n for (const route of routes) {\n const name = route.name;\n const toImportPath = (f: string) => f.replace(/\\.(tsx?|jsx?)$/, \"\");\n\n if (route.isLayout && route.layoutFile) {\n lazyImports.push(\n `const ${name}Layout = lazy(() => import(\"@/pages/${toImportPath(route.layoutFile)}\"));`\n );\n }\n if (route.file) {\n lazyImports.push(\n `const ${name}Page = lazy(() => import(\"@/pages/${toImportPath(route.file)}\"));`\n );\n }\n if (route.errorFile) {\n errorImports.push(\n `const ${name}Error = lazy(() => import(\"@/pages/${toImportPath(route.errorFile)}\"));`\n );\n }\n if (route.loadingFile) {\n loadingImports.push(\n `const ${name}Loading = lazy(() => import(\"@/pages/${toImportPath(route.loadingFile)}\"));`\n );\n }\n\n if (route.children) {\n this.collectImports(route.children, lazyImports, errorImports, loadingImports);\n }\n }\n }\n\n private emitRouteArray(routes: RouteConfig[], parentPath?: string): string {\n const items = routes.map((r) => this.emitRouteObject(r, parentPath));\n return `[\\n ${items.join(\",\\n \")}\\n]`;\n }\n\n private emitRouteObject(route: RouteConfig, parentPath?: string): string {\n const parts: string[] = [];\n const name = route.name;\n\n // path\n if (route.index) {\n parts.push(\"index: true\");\n } else if (route.pathless) {\n // 无路径布局不输出 path\n } else if (route.path === \"*\") {\n parts.push(`path: \"*\"`);\n } else if (parentPath && route.path.startsWith(parentPath) && parentPath !== \"/\") {\n const rel = route.path.slice(parentPath.length + 1);\n parts.push(`path: \"${rel || \"\"}\"`);\n } else {\n parts.push(`path: \"${route.path}\"`);\n }\n\n // element\n if (route.isLayout && route.layoutFile) {\n const loadingProp = route.loadingFile ? ` Loading={${name}Loading}` : \"\";\n parts.push(`element: <LazyRoute Component={${name}Layout}${loadingProp} />`);\n } else if (route.file) {\n parts.push(`element: <LazyRoute Component={${name}Page} />`);\n }\n\n // errorElement\n if (route.errorFile) {\n parts.push(`errorElement: <LazyRoute Component={${name}Error} />`);\n }\n\n // children\n if (route.children && route.children.length > 0) {\n const childParent = route.pathless ? parentPath : route.path;\n parts.push(`children: ${this.emitRouteArray(route.children, childParent)}`);\n }\n\n return `{\\n ${parts.join(\",\\n \")}\\n }`;\n }\n\n /**\n * 写入路由文件\n */\n write(): void {\n const { outputDir } = this.options;\n const code = this.generateCode();\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n writeFileSync(join(outputDir, \"routes.tsx\"), code, \"utf-8\");\n if (process.env.DEBUG) console.log(`[ywkf] 约定式路由已生成`);\n }\n}\n\n/**\n * 生成约定式路由\n */\nexport function generateConventionalRoutes(options: GeneratorOptions): void {\n new ConventionalRouteGenerator(options).write();\n}\n","import type { YwkfConfig } from \"../../config/schema.js\";\nimport type { CodeInjection } from \"../../plugin/types.js\";\n\n/**\n * 生成应用入口文件 (.ywkf/index.tsx)\n *\n * 基础版本只负责启动应用,微前端等功能通过插件注入\n */\nexport function generateEntry(\n config: Required<YwkfConfig>,\n injections: CodeInjection = {}\n): string {\n const imports = [\n `import \"@/index.css\";`,\n `import { runApp } from \"./bootstrap\";`,\n ...(injections.imports || []),\n ];\n\n const topLevel = injections.topLevel || [];\n const exports = injections.exports || [];\n\n const hasPluginExports = exports.length > 0;\n const hasAsyncTopLevel = topLevel.some((line) => line.includes(\"await \"));\n\n let startupBody: string;\n\n if (hasPluginExports) {\n // 子应用模式:条件启动\n startupBody = [\n ...topLevel,\n ...exports,\n ``,\n `if (shouldRunIndependently !== false) {`,\n ` runApp();`,\n `}`,\n ].join(\"\\n\");\n } else if (hasAsyncTopLevel) {\n // 主应用异步初始化模式:用 async IIFE 包装\n startupBody = [\n `(async () => {`,\n ...topLevel.map((l) => ` ${l}`),\n ` runApp();`,\n `})();`,\n ].join(\"\\n\");\n } else {\n startupBody = topLevel.length > 0\n ? [...topLevel, `runApp();`].join(\"\\n\")\n : `runApp();`;\n }\n\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\n${imports.join(\"\\n\")}\n\n${startupBody}\n`;\n}\n","import type { YwkfConfig } from \"../../config/schema.js\";\nimport type { CodeInjection } from \"../../plugin/types.js\";\n\n/**\n * 生成启动文件 (.ywkf/bootstrap.tsx)\n *\n * 基础版本包含应用启动核心逻辑,微前端等功能通过插件注入\n */\nexport function generateBootstrap(\n config: Required<YwkfConfig>,\n injections: CodeInjection = {}\n): string {\n const { appName, router } = config;\n\n const routerImport = router.conventional\n ? `import { createRouter } from \"./routes\";`\n : `import { createRouter } from \"@/routes\";`;\n\n const imports = [\n `import { bootstrap, type AppConfig } from \"@4399ywkf/core/runtime\";`,\n routerImport,\n ...(injections.imports || []),\n ];\n\n const topLevel = injections.topLevel || [];\n const exports = injections.exports || [];\n\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\n${imports.join(\"\\n\")}\n\n/**\n * 应用名称\n */\nexport const APP_NAME = \"${appName}\";\n\n/**\n * 路由 basename\n */\nexport const BASENAME = \"${router.basename || \"/\"}\";\n\n/**\n * 获取用户自定义配置(如果存在)\n * 用户可在 src/app.config.ts 中导出配置来覆盖默认值\n */\nasync function getUserConfig(): Promise<Partial<AppConfig>> {\n try {\n // webpackIgnore 注释让打包器跳过模块存在性检查\n const userConfigModule = await import(/* webpackIgnore: true */ \"@/app.config\");\n return userConfigModule.default || {};\n } catch {\n // 文件不存在时返回空配置\n return {};\n }\n}\n\n/**\n * 创建应用配置\n */\nexport function createAppConfig(userConfig: Partial<AppConfig> = {}): AppConfig {\n const effectiveBasename = userConfig.basename || BASENAME;\n const router = createRouter(effectiveBasename);\n\n const defaultConfig: AppConfig = {\n appName: APP_NAME,\n router,\n basename: effectiveBasename,\n rootId: APP_NAME,\n strictMode: true,\n antd: {\n enabled: true,\n },\n providers: [],\n lifecycle: {\n onMounted() {\n console.log(\\`[\\${APP_NAME}] 应用已挂载\\`);\n },\n onUnmount() {\n console.log(\\`[\\${APP_NAME}] 应用已卸载\\`);\n },\n onError(error) {\n console.error(\\`[\\${APP_NAME}] 全局错误:\\`, error);\n },\n },\n };\n\n // 深度合并用户配置\n return {\n ...defaultConfig,\n ...userConfig,\n antd: { ...defaultConfig.antd, ...userConfig.antd },\n providers: [...(defaultConfig.providers || []), ...(userConfig.providers || [])],\n lifecycle: { ...defaultConfig.lifecycle, ...userConfig.lifecycle },\n };\n}\n\n/**\n * 启动应用\n */\nexport async function runApp(): Promise<void> {\n const userConfig = await getUserConfig();\n await bootstrap(createAppConfig(userConfig));\n}\n${topLevel.length > 0 ? \"\\n\" + topLevel.join(\"\\n\") : \"\"}\n${exports.length > 0 ? \"\\n\" + exports.join(\"\\n\") : \"\"}\n`;\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { YwkfConfig } from \"../../config/schema.js\";\n\n/**\n * 生成环境变量类型定义 (.ywkf/types/env.d.ts)\n */\nexport function generateEnvTypes(\n cwd: string,\n config: Required<YwkfConfig>\n): string {\n const envVars = collectEnvVars(cwd, config);\n\n const envInterface = envVars\n .map((key) => ` readonly ${key}: string;`)\n .join(\"\\n\");\n\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\n/// <reference types=\"react\" />\n/// <reference types=\"react-dom\" />\n\ndeclare namespace NodeJS {\n interface ProcessEnv {\n${envInterface}\n readonly NODE_ENV: \"development\" | \"production\" | \"test\";\n }\n}\n\ndeclare module \"*.svg\" {\n import * as React from \"react\";\n const ReactComponent: React.FunctionComponent<\n React.SVGProps<SVGSVGElement> & { title?: string }\n >;\n export default ReactComponent;\n}\n\ndeclare module \"*.png\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.jpg\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.jpeg\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.gif\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.webp\" {\n const src: string;\n export default src;\n}\n\ndeclare module \"*.css\" {\n const classes: { readonly [key: string]: string };\n export default classes;\n}\n\ndeclare module \"*.less\" {\n const classes: { readonly [key: string]: string };\n export default classes;\n}\n\ndeclare module \"*.scss\" {\n const classes: { readonly [key: string]: string };\n export default classes;\n}\n\ndeclare module \"*.md\" {\n const content: string;\n export default content;\n}\n`;\n}\n\n/**\n * 收集环境变量\n */\nfunction collectEnvVars(cwd: string, config: Required<YwkfConfig>): string[] {\n const envVars = new Set<string>();\n\n // 从 .env.public 读取\n const publicEnvPath = join(cwd, config.env.publicEnvFile || \"config/env/.env.public\");\n if (existsSync(publicEnvPath)) {\n const content = readFileSync(publicEnvPath, \"utf-8\");\n parseEnvFile(content, envVars);\n }\n\n // 从 .env.development 读取\n const devEnvPath = join(cwd, config.env.envDir || \"config/env\", \".env.development\");\n if (existsSync(devEnvPath)) {\n const content = readFileSync(devEnvPath, \"utf-8\");\n parseEnvFile(content, envVars);\n }\n\n // 从 .env.production 读取\n const prodEnvPath = join(cwd, config.env.envDir || \"config/env\", \".env.production\");\n if (existsSync(prodEnvPath)) {\n const content = readFileSync(prodEnvPath, \"utf-8\");\n parseEnvFile(content, envVars);\n }\n\n return Array.from(envVars).sort();\n}\n\n/**\n * 解析 .env 文件\n */\nfunction parseEnvFile(content: string, envVars: Set<string>): void {\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n continue;\n }\n const match = trimmed.match(/^([A-Z_][A-Z0-9_]*)\\s*=/);\n if (match) {\n envVars.add(match[1]);\n }\n }\n}\n","/**\n * 生成路由类型定义 (.ywkf/types/routes.d.ts)\n */\nexport function generateRouteTypes(): string {\n return `// 此文件由 @4399ywkf/core 自动生成,请勿手动修改\n// Generated at: ${new Date().toISOString()}\n\nimport type { RouteObject } from \"react-router\";\n\ndeclare module \"@ywkf/routes\" {\n export const routes: RouteObject[];\n export function createRouter(basename?: string): ReturnType<typeof import(\"react-router\").createBrowserRouter>;\n export default routes;\n}\n`;\n}\n","import { rspack, type Configuration } from \"@rspack/core\";\nimport { merge } from \"webpack-merge\";\nimport type { YwkfConfig } from \"../config/schema.js\";\nimport { createPathResolver } from \"../config/loader.js\";\nimport { createBaseConfig } from \"./base.js\";\n\n/**\n * 创建生产环境 Rspack 配置\n */\nexport function createProdConfig(\n config: Required<YwkfConfig>,\n cwd: string\n): Configuration {\n const baseConfig = createBaseConfig(config, cwd, { isDev: false });\n const { resolveApp } = createPathResolver(cwd);\n const { style, performance, output } = config;\n\n const styleRules: Configuration[\"module\"] = {\n rules: [\n // Less - antd\n {\n test: /\\.less$/,\n include: [\n /[\\\\/]node_modules[\\\\/].*antd/,\n /[\\\\/]node_modules[\\\\/]@4399ywkf[\\\\/]design/,\n ],\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n strictMath: false,\n math: \"always\",\n javascriptEnabled: true,\n },\n },\n },\n ],\n },\n // Less - 项目文件\n ...(style.less?.enabled !== false\n ? [\n {\n test: /\\.less$/,\n include: [resolveApp(\"src\")],\n exclude: [resolveApp(\"node_modules\")],\n oneOf: [\n {\n test: /\\.module\\.less$/,\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: {\n sourceMap: true,\n modules: {\n localIdentName:\n \"[path][name]__[local]--[hash:base64:5]\",\n },\n importLoaders: 2,\n },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n javascriptEnabled: true,\n ...style.less?.lessOptions,\n },\n },\n },\n ],\n },\n {\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"less-loader\",\n options: {\n sourceMap: true,\n lessOptions: {\n javascriptEnabled: true,\n ...style.less?.lessOptions,\n },\n },\n },\n ],\n },\n ],\n },\n ]\n : []),\n // Sass\n ...(style.sass?.enabled !== false\n ? [\n {\n test: /\\.s[ac]ss$/i,\n include: [resolveApp(\"src\")],\n exclude: [resolveApp(\"node_modules\")],\n oneOf: [\n {\n test: /\\.module\\.s[ac]ss$/,\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: {\n sourceMap: true,\n modules: {\n localIdentName:\n \"[path][name]__[local]--[hash:base64:5]\",\n },\n importLoaders: 2,\n },\n },\n {\n loader: \"sass-loader\",\n options: {\n sourceMap: true,\n sassOptions: {\n outputStyle: \"compressed\",\n ...style.sass?.sassOptions,\n },\n },\n },\n ],\n },\n {\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n {\n loader: \"sass-loader\",\n options: {\n sourceMap: true,\n sassOptions: {\n outputStyle: \"compressed\",\n ...style.sass?.sassOptions,\n },\n },\n },\n ],\n },\n ],\n },\n ]\n : []),\n // TailwindCSS\n ...(style.tailwindcss\n ? [\n {\n test: /\\.css$/,\n include: [resolveApp(\"src/index.css\")],\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n \"css-loader\",\n {\n loader: \"postcss-loader\",\n options: {\n postcssOptions: {\n config: resolveApp(\"postcss.config.js\"),\n },\n },\n },\n ],\n },\n ]\n : []),\n // src 目录中的其他 CSS\n {\n test: /\\.css$/,\n include: [resolveApp(\"src\")],\n exclude: style.tailwindcss ? [resolveApp(\"src/index.css\")] : [],\n use: [\n { loader: rspack.CssExtractRspackPlugin.loader },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n ],\n },\n // node_modules CSS\n {\n test: /\\.css$/,\n include: [resolveApp(\"node_modules\")],\n use: [\n { loader: \"style-loader\" },\n {\n loader: \"css-loader\",\n options: { sourceMap: true },\n },\n ],\n },\n ],\n };\n\n const prodConfig: Configuration = {\n mode: \"production\",\n devtool: \"hidden-source-map\",\n\n output: {\n filename: \"[name].[contenthash].bundle.js\",\n chunkFilename: \"[name].[contenthash].chunk.js\",\n clean: output.clean,\n },\n\n module: styleRules,\n\n plugins: [\n new rspack.CssExtractRspackPlugin({\n filename: \"[name].[contenthash:8].css\",\n chunkFilename: \"[name].[contenthash:8].chunk.css\",\n }),\n ],\n\n optimization: {\n minimize: true,\n minimizer: [\n new rspack.SwcJsMinimizerRspackPlugin({\n exclude: [resolveApp(\"node_modules\")],\n minimizerOptions: {\n compress: {\n pure_funcs: performance.dropConsole\n ? [\"console.log\", \"console.info\", \"console.debug\", \"console.warn\"]\n : [\"console.info\", \"console.debug\"],\n drop_console: false,\n drop_debugger: true,\n },\n },\n }),\n new rspack.LightningCssMinimizerRspackPlugin(),\n ],\n },\n };\n\n return merge(baseConfig, prodConfig);\n}\n"],"mappings":";AACA,SAAS,4BAA4B;;;ACArC,OAAO,wBAAwB;AAC/B,SAAS,aAAa;AAEtB,SAAS,iBAAAA,sBAAqB;;;ACJ9B,SAAS,kBAAkB;AAC3B,SAAS,SAAS,eAAe;AACjC,SAAS,qBAAqB;AAC9B,OAAO,eAAe;AA0Gf,SAAS,mBAAmB,KAAa;AAC9C,SAAO;AAAA,IACL,YAAY,CAAC,iBAAyB,QAAQ,KAAK,YAAY;AAAA,IAC/D;AAAA,EACF;AACF;;;AClHA,SAAS,cAAkC;AAC3C,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,SAAS,QAAAC,aAAY;;;ACF9B,SAAS,OAAO,cAAAC,mBAAkB;AAClC,SAAS,QAAAC,aAAY;;;ACFrB,SAAS,cAAAC,aAAY,aAAAC,YAAW,iBAAAC,gBAAe,gBAAAC,qBAAoB;AACnE,SAAS,QAAAC,aAAY;;;ACDrB,SAAS,cAAAC,aAAY,aAAa,UAAU,WAAW,qBAAqB;AAC5E,SAAS,MAAM,gBAA0B;AA0CzC,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKD,IAAM,mBAAmB;AAAA,EACvB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU;AACZ;AAmBO,IAAM,6BAAN,MAAiC;AAAA,EAC9B;AAAA,EAER,YAAY,SAA2B;AACrC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,WAA0B;AACxB,UAAM,EAAE,SAAS,IAAI,KAAK;AAC1B,QAAI,CAACA,YAAW,QAAQ,GAAG;AACzB,cAAQ,KAAK,sDAAmB,QAAQ,EAAE;AAC1C,aAAO,CAAC;AAAA,IACV;AACA,WAAO,KAAK,cAAc,UAAU,GAAG;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,KAAa,WAAkC;AACnE,UAAM,UAAU,YAAY,GAAG;AAG/B,UAAM,aAAa,QAAQ,KAAK,CAAC,MAAM,iBAAiB,OAAO,KAAK,CAAC,CAAC;AACtE,UAAM,WAAW,QAAQ,KAAK,CAAC,MAAM,iBAAiB,KAAK,KAAK,CAAC,CAAC;AAClE,UAAM,YAAY,QAAQ,KAAK,CAAC,MAAM,iBAAiB,MAAM,KAAK,CAAC,CAAC;AACpE,UAAM,cAAc,QAAQ,KAAK,CAAC,MAAM,iBAAiB,QAAQ,KAAK,CAAC,CAAC;AACxE,UAAM,eAAe,QAAQ,KAAK,CAAC,MAAM,iBAAiB,SAAS,KAAK,CAAC,CAAC;AAG1E,UAAM,UAAU,QAAQ,OAAO,CAAC,MAAM;AACpC,UAAI,EAAE,WAAW,GAAG,EAAG,QAAO;AAC9B,UAAI,cAAc,IAAI,CAAC,EAAG,QAAO;AACjC,aAAO,SAAS,KAAK,KAAK,CAAC,CAAC,EAAE,YAAY;AAAA,IAC5C,CAAC;AAGD,UAAM,cAA6B,CAAC;AACpC,eAAW,UAAU,SAAS;AAC5B,YAAM,aAAa,KAAK,KAAK,MAAM;AAGnC,UAAI,OAAO,WAAW,IAAI,GAAG;AAC3B,cAAM,iBAAiB,KAAK,cAAc,YAAY,SAAS;AAE/D,cAAM,iBAAiB,YAAY,UAAU,EAAE;AAAA,UAAK,CAAC,MACnD,iBAAiB,OAAO,KAAK,CAAC;AAAA,QAChC;AACA,YAAI,gBAAgB;AAClB,gBAAM,mBAAmB,KAAK,cAAc,YAAY,SAAS;AACjE,sBAAY,KAAK;AAAA,YACf,MAAM;AAAA,YACN,MAAM,KAAK,kBAAkB,OAAO,MAAM,CAAC,CAAC;AAAA,YAC5C,YAAY,SAAS,KAAK,QAAQ,UAAU,KAAK,YAAY,cAAc,CAAC;AAAA,YAC5E,UAAU;AAAA,YACV,UAAU;AAAA,YACV,UAAU,iBAAiB;AAAA,cACzB,CAAC,MAAM,EAAE,eAAe,SAAS,KAAK,QAAQ,UAAU,KAAK,YAAY,cAAc,CAAC;AAAA,YAC1F;AAAA,UACF,CAAC;AAAA,QACH,OAAO;AACL,sBAAY,KAAK,GAAG,cAAc;AAAA,QACpC;AACA;AAAA,MACF;AAGA,YAAM,eAAe,KAAK,iBAAiB,QAAQ,SAAS;AAC5D,kBAAY,KAAK,GAAG,KAAK,cAAc,YAAY,YAAY,CAAC;AAAA,IAClE;AAGA,UAAM,YAAY,KAAK,kBAAkB,SAAS;AAClD,UAAM,UAAU,CAAC,SAAiB,SAAS,KAAK,QAAQ,UAAU,KAAK,KAAK,IAAI,CAAC;AAGjF,QAAI,YAAY;AACd,YAAM,iBAAgC,CAAC;AAGvC,UAAI,UAAU;AACZ,uBAAe,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,MAAM,QAAQ,QAAQ;AAAA,UACtB,MAAM,YAAY;AAAA,UAClB,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAGA,UAAI,cAAc;AAChB,uBAAe,KAAK;AAAA,UAClB,MAAM;AAAA,UACN,MAAM,QAAQ,YAAY;AAAA,UAC1B,MAAM,YAAY;AAAA,QACpB,CAAC;AAAA,MACH;AAEA,qBAAe,KAAK,GAAG,WAAW;AAElC,aAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,YAAY,QAAQ,UAAU;AAAA,UAC9B,WAAW,YAAY,QAAQ,SAAS,IAAI;AAAA,UAC5C,aAAa,cAAc,QAAQ,WAAW,IAAI;AAAA,UAClD,MAAM;AAAA,UACN,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAGA,UAAM,SAAwB,CAAC;AAE/B,QAAI,UAAU;AACZ,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM,QAAQ,QAAQ;AAAA,QACtB,WAAW,YAAY,QAAQ,SAAS,IAAI;AAAA,QAC5C,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,QAAI,cAAc;AAChB,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM,QAAQ,YAAY;AAAA,QAC1B,MAAM,YAAY;AAAA,MACpB,CAAC;AAAA,IACH;AAEA,WAAO,KAAK,GAAG,WAAW;AAC1B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,iBAAiB,SAAiB,YAA4B;AACpE,QAAI;AAGJ,QAAI,QAAQ,MAAM,kBAAkB,GAAG;AACrC,gBAAU;AAAA,IACZ,WAES,QAAQ,MAAM,cAAc,GAAG;AACtC,YAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE;AACjC,gBAAU,IAAI,KAAK;AAAA,IACrB,WAES,QAAQ,MAAM,YAAY,GAAG;AACpC,YAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE;AACjC,gBAAU,IAAI,KAAK;AAAA,IACrB,WAES,QAAQ,SAAS,GAAG,GAAG;AAC9B,gBAAU,QAAQ,QAAQ,OAAO,GAAG;AAAA,IACtC,OAAO;AACL,gBAAU;AAAA,IACZ;AAEA,WAAO,eAAe,MAClB,IAAI,OAAO,KACX,GAAG,UAAU,IAAI,OAAO;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,MAAsB;AAC9C,UAAM,OAAO,KACV,MAAM,GAAG,EACT,OAAO,OAAO,EACd;AAAA,MAAI,CAAC,MACJ,EACG,QAAQ,MAAM,OAAO,EACrB,QAAQ,OAAO,UAAU,EACzB,QAAQ,QAAQ,UAAU;AAAA,IAC/B,EACC,IAAI,CAAC,MAAM;AACV,YAAM,UAAU,EAAE,QAAQ,iBAAiB,EAAE;AAC7C,UAAI,CAAC,QAAS,QAAO;AACrB,aAAO,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC;AAAA,IAC1D,CAAC,EACA,KAAK,EAAE;AAEV,QAAI,CAAC,QAAQ,MAAM,KAAK,IAAI,GAAG;AAC7B,aAAO,UAAU,QAAQ;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,eAAuB;AACrB,UAAM,SAAS,KAAK,SAAS;AAC7B,UAAM,cAAwB,CAAC;AAC/B,UAAM,eAAyB,CAAC;AAChC,UAAM,iBAA2B,CAAC;AAElC,SAAK,eAAe,QAAQ,aAAa,cAAc,cAAc;AAErE,WAAO;AAAA,oBACQ,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMzC,YAAY,KAAK,IAAI,CAAC;AAAA,EACtB,aAAa,SAAS,IAAI,gDAAkB,aAAa,KAAK,IAAI,IAAI,EAAE;AAAA,EACxE,eAAe,SAAS,IAAI,gDAAkB,eAAe,KAAK,IAAI,IAAI,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCAqBvC,KAAK,eAAe,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWhE;AAAA,EAEQ,eACN,QACA,aACA,cACA,gBACM;AACN,eAAW,SAAS,QAAQ;AAC1B,YAAM,OAAO,MAAM;AACnB,YAAM,eAAe,CAAC,MAAc,EAAE,QAAQ,kBAAkB,EAAE;AAElE,UAAI,MAAM,YAAY,MAAM,YAAY;AACtC,oBAAY;AAAA,UACV,SAAS,IAAI,uCAAuC,aAAa,MAAM,UAAU,CAAC;AAAA,QACpF;AAAA,MACF;AACA,UAAI,MAAM,MAAM;AACd,oBAAY;AAAA,UACV,SAAS,IAAI,qCAAqC,aAAa,MAAM,IAAI,CAAC;AAAA,QAC5E;AAAA,MACF;AACA,UAAI,MAAM,WAAW;AACnB,qBAAa;AAAA,UACX,SAAS,IAAI,sCAAsC,aAAa,MAAM,SAAS,CAAC;AAAA,QAClF;AAAA,MACF;AACA,UAAI,MAAM,aAAa;AACrB,uBAAe;AAAA,UACb,SAAS,IAAI,wCAAwC,aAAa,MAAM,WAAW,CAAC;AAAA,QACtF;AAAA,MACF;AAEA,UAAI,MAAM,UAAU;AAClB,aAAK,eAAe,MAAM,UAAU,aAAa,cAAc,cAAc;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eAAe,QAAuB,YAA6B;AACzE,UAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,KAAK,gBAAgB,GAAG,UAAU,CAAC;AACnE,WAAO;AAAA,IAAQ,MAAM,KAAK,OAAO,CAAC;AAAA;AAAA,EACpC;AAAA,EAEQ,gBAAgB,OAAoB,YAA6B;AACvE,UAAM,QAAkB,CAAC;AACzB,UAAM,OAAO,MAAM;AAGnB,QAAI,MAAM,OAAO;AACf,YAAM,KAAK,aAAa;AAAA,IAC1B,WAAW,MAAM,UAAU;AAAA,IAE3B,WAAW,MAAM,SAAS,KAAK;AAC7B,YAAM,KAAK,WAAW;AAAA,IACxB,WAAW,cAAc,MAAM,KAAK,WAAW,UAAU,KAAK,eAAe,KAAK;AAChF,YAAM,MAAM,MAAM,KAAK,MAAM,WAAW,SAAS,CAAC;AAClD,YAAM,KAAK,UAAU,OAAO,EAAE,GAAG;AAAA,IACnC,OAAO;AACL,YAAM,KAAK,UAAU,MAAM,IAAI,GAAG;AAAA,IACpC;AAGA,QAAI,MAAM,YAAY,MAAM,YAAY;AACtC,YAAM,cAAc,MAAM,cAAc,aAAa,IAAI,aAAa;AACtE,YAAM,KAAK,kCAAkC,IAAI,UAAU,WAAW,KAAK;AAAA,IAC7E,WAAW,MAAM,MAAM;AACrB,YAAM,KAAK,kCAAkC,IAAI,UAAU;AAAA,IAC7D;AAGA,QAAI,MAAM,WAAW;AACnB,YAAM,KAAK,uCAAuC,IAAI,WAAW;AAAA,IACnE;AAGA,QAAI,MAAM,YAAY,MAAM,SAAS,SAAS,GAAG;AAC/C,YAAM,cAAc,MAAM,WAAW,aAAa,MAAM;AACxD,YAAM,KAAK,aAAa,KAAK,eAAe,MAAM,UAAU,WAAW,CAAC,EAAE;AAAA,IAC5E;AAEA,WAAO;AAAA,MAAU,MAAM,KAAK,SAAS,CAAC;AAAA;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,UAAM,EAAE,UAAU,IAAI,KAAK;AAC3B,UAAM,OAAO,KAAK,aAAa;AAC/B,QAAI,CAACA,YAAW,SAAS,GAAG;AAC1B,gBAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAAA,IAC1C;AACA,kBAAc,KAAK,WAAW,YAAY,GAAG,MAAM,OAAO;AAC1D,QAAI,QAAQ,IAAI,MAAO,SAAQ,IAAI,yDAAiB;AAAA,EACtD;AACF;;;ACtaO,SAAS,cACd,QACA,aAA4B,CAAC,GACrB;AACR,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA,GAAI,WAAW,WAAW,CAAC;AAAA,EAC7B;AAEA,QAAM,WAAW,WAAW,YAAY,CAAC;AACzC,QAAM,UAAU,WAAW,WAAW,CAAC;AAEvC,QAAM,mBAAmB,QAAQ,SAAS;AAC1C,QAAM,mBAAmB,SAAS,KAAK,CAAC,SAAS,KAAK,SAAS,QAAQ,CAAC;AAExE,MAAI;AAEJ,MAAI,kBAAkB;AAEpB,kBAAc;AAAA,MACZ,GAAG;AAAA,MACH,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,WAAW,kBAAkB;AAE3B,kBAAc;AAAA,MACZ;AAAA,MACA,GAAG,SAAS,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AAAA,MAC/B;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,OAAO;AACL,kBAAc,SAAS,SAAS,IAC5B,CAAC,GAAG,UAAU,WAAW,EAAE,KAAK,IAAI,IACpC;AAAA,EACN;AAEA,SAAO;AAAA,oBACU,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA,EAEzC,QAAQ,KAAK,IAAI,CAAC;AAAA;AAAA,EAElB,WAAW;AAAA;AAEb;;;ACjDO,SAAS,kBACd,QACA,aAA4B,CAAC,GACrB;AACR,QAAM,EAAE,SAAS,OAAO,IAAI;AAE5B,QAAM,eAAe,OAAO,eACxB,6CACA;AAEJ,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA,GAAI,WAAW,WAAW,CAAC;AAAA,EAC7B;AAEA,QAAM,WAAW,WAAW,YAAY,CAAC;AACzC,QAAM,UAAU,WAAW,WAAW,CAAC;AAEvC,SAAO;AAAA,oBACU,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA,EAEzC,QAAQ,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,2BAKO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,2BAKP,OAAO,YAAY,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgE/C,SAAS,SAAS,IAAI,OAAO,SAAS,KAAK,IAAI,IAAI,EAAE;AAAA,EACrD,QAAQ,SAAS,IAAI,OAAO,QAAQ,KAAK,IAAI,IAAI,EAAE;AAAA;AAErD;;;AC3GA,SAAS,cAAAC,aAAY,oBAAoB;AACzC,SAAS,QAAAC,aAAY;AAMd,SAAS,iBACd,KACA,QACQ;AACR,QAAM,UAAU,eAAe,KAAK,MAAM;AAE1C,QAAM,eAAe,QAClB,IAAI,CAAC,QAAQ,gBAAgB,GAAG,WAAW,EAC3C,KAAK,IAAI;AAEZ,SAAO;AAAA,oBACU,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzC,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0Dd;AAKA,SAAS,eAAe,KAAa,QAAwC;AAC3E,QAAM,UAAU,oBAAI,IAAY;AAGhC,QAAM,gBAAgBA,MAAK,KAAK,OAAO,IAAI,iBAAiB,wBAAwB;AACpF,MAAID,YAAW,aAAa,GAAG;AAC7B,UAAM,UAAU,aAAa,eAAe,OAAO;AACnD,iBAAa,SAAS,OAAO;AAAA,EAC/B;AAGA,QAAM,aAAaC,MAAK,KAAK,OAAO,IAAI,UAAU,cAAc,kBAAkB;AAClF,MAAID,YAAW,UAAU,GAAG;AAC1B,UAAM,UAAU,aAAa,YAAY,OAAO;AAChD,iBAAa,SAAS,OAAO;AAAA,EAC/B;AAGA,QAAM,cAAcC,MAAK,KAAK,OAAO,IAAI,UAAU,cAAc,iBAAiB;AAClF,MAAID,YAAW,WAAW,GAAG;AAC3B,UAAM,UAAU,aAAa,aAAa,OAAO;AACjD,iBAAa,SAAS,OAAO;AAAA,EAC/B;AAEA,SAAO,MAAM,KAAK,OAAO,EAAE,KAAK;AAClC;AAKA,SAAS,aAAa,SAAiB,SAA4B;AACjE,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,GAAG;AACvC;AAAA,IACF;AACA,UAAM,QAAQ,QAAQ,MAAM,yBAAyB;AACrD,QAAI,OAAO;AACT,cAAQ,IAAI,MAAM,CAAC,CAAC;AAAA,IACtB;AAAA,EACF;AACF;;;AC/HO,SAAS,qBAA6B;AAC3C,SAAO;AAAA,oBACU,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU3C;;;ALkBO,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,uBAA4C,oBAAI,IAAI;AAAA,EAE5D,YACE,SACA,cAA6B,CAAC,GAC9B;AACA,SAAK,UAAU;AAAA,MACb,GAAG;AAAA,MACH,WAAW,QAAQ,aAAaE,MAAK,QAAQ,KAAK,OAAO;AAAA,IAC3D;AACA,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA0B;AAC9B,UAAM,EAAE,UAAU,IAAI,KAAK;AAG3B,SAAK,UAAU,SAAS;AACxB,SAAK,UAAUA,MAAK,WAAW,OAAO,CAAC;AAGvC,SAAK,uBAAuB;AAC5B,SAAK,eAAe;AACpB,SAAK,sBAAsB;AAC3B,SAAK,kBAAkB;AACvB,SAAK,cAAc;AAGnB,UAAM,KAAK,oBAAoB;AAG/B,eAAW,SAAS,KAAK,aAAa;AACpC,UAAI,MAAM,eAAe;AACvB,cAAM,MAAM,cAAc,KAAK,OAAO;AAAA,MACxC;AAAA,IACF;AAEA,QAAI,QAAQ,IAAI,MAAO,SAAQ,IAAI,8CAAqB;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAA+B;AACrC,UAAM,EAAE,WAAW,OAAO,IAAI,KAAK;AACnC,UAAM,aAAaA,MAAK,WAAW,aAAa;AAGhD,UAAM,qBAAqB,KAAK;AAAA,MAC9B,KAAK,UAAU,QAAQ,CAAC,KAAK,UAAU;AACrC,YAAI,OAAO,UAAU,YAAY;AAC/B,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,SAAK;AAAA,MACH;AAAA,MACA,KAAK,UAAU,oBAAoB,MAAM,CAAC;AAAA,IAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAuB;AAC7B,UAAM,EAAE,KAAK,WAAW,OAAO,IAAI,KAAK;AAExC,QAAI,CAAC,OAAO,OAAO,cAAc;AAC/B;AAAA,IACF;AAEA,UAAM,WAAWA,MAAK,KAAK,OAAO,OAAO,YAAY,WAAW;AAChE,UAAM,YAAY,IAAI,2BAA2B;AAAA,MAC/C;AAAA,MACA;AAAA,MACA,UAAU,OAAO,OAAO;AAAA,IAC1B,CAAC;AAED,UAAM,UAAU,UAAU,aAAa;AACvC,UAAM,aAAaA,MAAK,WAAW,YAAY;AAE/C,SAAK,mBAAmB,YAAY,OAAO;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAA8B;AACpC,UAAM,EAAE,WAAW,OAAO,IAAI,KAAK;AAGnC,UAAM,aAAa,KAAK,kBAAkB,WAAW;AAGrD,QAAI,UAAU,kBAAkB,QAAQ,UAAU;AAGlD,eAAW,SAAS,KAAK,aAAa;AACpC,UAAI,MAAM,qBAAqB;AAC7B,cAAM,SAAS,MAAM,oBAAoB,SAAS,KAAK,OAAO;AAC9D,YAAI,QAAQ;AACV,oBAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgBA,MAAK,WAAW,eAAe;AACrD,SAAK,mBAAmB,eAAe,OAAO;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAA0B;AAChC,UAAM,EAAE,WAAW,OAAO,IAAI,KAAK;AAGnC,UAAM,aAAa,KAAK,kBAAkB,OAAO;AAGjD,QAAI,UAAU,cAAc,QAAQ,UAAU;AAG9C,eAAW,SAAS,KAAK,aAAa;AACpC,UAAI,MAAM,iBAAiB;AACzB,cAAM,SAAS,MAAM,gBAAgB,SAAS,KAAK,OAAO;AAC1D,YAAI,QAAQ;AACV,oBAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAYA,MAAK,WAAW,WAAW;AAC7C,SAAK,mBAAmB,WAAW,OAAO;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKQ,kBACN,MACe;AACf,UAAM,SAAwB;AAAA,MAC5B,SAAS,CAAC;AAAA,MACV,UAAU,CAAC;AAAA,MACX,SAAS,CAAC;AAAA,IACZ;AAEA,UAAM,WAAW,SAAS,UAAU,gBAAgB;AAEpD,eAAW,SAAS,KAAK,aAAa;AACpC,YAAM,OAAO,MAAM,QAAQ;AAC3B,UAAI,MAAM;AACR,cAAM,YAAY,KAAK,KAAK,OAAO;AACnC,YAAI,WAAW;AACb,iBAAO,SAAS,KAAK,GAAI,UAAU,WAAW,CAAC,CAAE;AACjD,iBAAO,UAAU,KAAK,GAAI,UAAU,YAAY,CAAC,CAAE;AACnD,iBAAO,SAAS,KAAK,GAAI,UAAU,WAAW,CAAC,CAAE;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,sBAAqC;AACjD,UAAM,EAAE,UAAU,IAAI,KAAK;AAE3B,eAAW,SAAS,KAAK,aAAa;AACpC,UAAI,MAAM,eAAe;AACvB,cAAM,QAAQ,MAAM,cAAc,KAAK,OAAO;AAC9C,YAAI,OAAO;AACT,qBAAW,QAAQ,OAAO;AACxB,kBAAM,WAAWA,MAAK,WAAW,KAAK,IAAI;AAC1C,kBAAM,MAAMA,MAAK,UAAU,IAAI;AAC/B,iBAAK,UAAU,GAAG;AAClB,iBAAK,mBAAmB,UAAU,KAAK,OAAO;AAAA,UAChD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAsB;AAC5B,UAAM,EAAE,WAAW,QAAQ,IAAI,IAAI,KAAK;AAGxC,UAAM,kBAAkB,iBAAiB,KAAK,MAAM;AACpD,SAAK;AAAA,MACHA,MAAK,WAAW,SAAS,UAAU;AAAA,MACnC;AAAA,IACF;AAGA,QAAI,OAAO,OAAO,cAAc;AAC9B,YAAM,oBAAoB,mBAAmB;AAC7C,WAAK;AAAA,QACHA,MAAK,WAAW,SAAS,aAAa;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,UAAU,KAAmB;AACnC,QAAI,CAACC,YAAW,GAAG,GAAG;AACpB,MAAAC,WAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACpC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,UAAkB,SAAuB;AAClE,UAAM,oBAAoB,KAAK,iBAAiB,OAAO;AACvD,UAAM,cAAc,KAAK,qBAAqB,IAAI,QAAQ;AAE1D,QAAI,gBAAgB,mBAAmB;AACrC;AAAA,IACF;AAGA,QAAID,YAAW,QAAQ,GAAG;AACxB,YAAM,kBAAkBE,cAAa,UAAU,OAAO;AACtD,UAAI,KAAK,iBAAiB,eAAe,MAAM,mBAAmB;AAChE,aAAK,qBAAqB,IAAI,UAAU,iBAAiB;AACzD;AAAA,MACF;AAAA,IACF;AAEA,IAAAC,eAAc,UAAU,SAAS,OAAO;AACxC,SAAK,qBAAqB,IAAI,UAAU,iBAAiB;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB,SAAyB;AAChD,WAAO,QACJ,QAAQ,0BAA0B,EAAE,EACpC,QAAQ,iCAAiC,EAAE;AAAA,EAChD;AACF;;;AD1QO,IAAM,sBAAN,MAA0B;AAAA,EACvB;AAAA,EACA,eAAe;AAAA,EACf,aAAa;AAAA,EACb,YAAkC;AAAA,EAClC,cAA6B,CAAC;AAAA,EAC9B,cAAc;AAAA,EAEtB,YAAY,SAAqC;AAC/C,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,cACZ,cAC4B;AAC5B,QAAI;AACF,UAAI;AACJ,UAAI,UAAmC,CAAC;AAExC,UAAI,OAAO,iBAAiB,UAAU;AACpC,cAAM,SAAS,MAAM,OAAO;AAC5B,iBAAS,OAAO,WAAW;AAAA,MAC7B,WAAW,MAAM,QAAQ,YAAY,GAAG;AACtC,cAAM,CAAC,cAAc,aAAa,IAAI;AACtC,kBAAU;AAEV,YAAI,OAAO,iBAAiB,UAAU;AACpC,gBAAM,SAAS,MAAM,OAAO;AAC5B,mBAAS,OAAO,WAAW;AAAA,QAC7B,OAAO;AACL,mBAAS;AAAA,QACX;AAAA,MACF,OAAO;AACL,iBAAS;AAAA,MACX;AAGA,UAAI,OAAO,WAAW,YAAY;AAChC,iBAAU,OAA0D,OAAO;AAAA,MAC7E;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,gDAAkB,KAAK,EAAE;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAA4B;AACxC,QAAI,KAAK,aAAa;AACpB;AAAA,IACF;AAEA,UAAM,EAAE,KAAK,QAAQ,OAAO,gBAAgB,CAAC,EAAE,IAAI,KAAK;AAGxD,UAAM,UAAyB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,QAAQ,CAAC;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,QACN,MAAM,CAAC,QAAQ;AACb,cAAI,QAAQ,IAAI,MAAO,SAAQ,IAAI,UAAU,GAAG,EAAE;AAAA,QACpD;AAAA,QACA,MAAM,CAAC,QAAQ,QAAQ,KAAK,UAAU,GAAG,EAAE;AAAA,QAC3C,OAAO,CAAC,QAAQ,QAAQ,MAAM,UAAU,GAAG,EAAE;AAAA,QAC7C,OAAO,CAAC,QAAQ;AACd,cAAI,QAAQ,IAAI,MAAO,SAAQ,IAAI,gBAAgB,GAAG,EAAE;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAGA,eAAW,gBAAgB,eAAe;AACxC,YAAM,SAAS,MAAM,KAAK,cAAc,YAAY;AACpD,UAAI,QAAQ;AACV,cAAM,QAAQ,MAAM,OAAO,MAAM,OAAO;AACxC,aAAK,YAAY,KAAK,KAAK;AAC3B,YAAI,QAAQ,IAAI,MAAO,SAAQ,IAAI,0CAAiB,OAAO,IAAI,EAAE;AAAA,MACnE;AAAA,IACF;AAGA,SAAK,YAAY,IAAI;AAAA,MACnB;AAAA,QACE,KAAK,KAAK,QAAQ;AAAA,QAClB,QAAQ,KAAK,QAAQ;AAAA,QACrB,WAAW,KAAK,QAAQ;AAAA,QACxB,OAAO,KAAK,QAAQ;AAAA,MACtB;AAAA,MACA,KAAK;AAAA,IACP;AAEA,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAM,UAA0B;AAC9B,UAAM,aAAa;AAGnB,aAAS,MAAM,cAAc,SAAS,YAAY,OAAO,QAAQ,aAAa;AAC5E,UAAI;AAEF,cAAM,KAAK,WAAW;AAEtB,YAAI,CAAC,KAAK,gBAAgB,KAAK,WAAW;AACxC,gBAAM,KAAK,UAAU,SAAS;AAC9B,eAAK,eAAe;AAAA,QACtB;AACA,iBAAS;AAAA,MACX,SAAS,OAAO;AACd,iBAAS,KAAc;AAAA,MACzB;AAAA,IACF,CAAC;AAGD,QAAI,KAAK,QAAQ,SAAS,CAAC,KAAK,YAAY;AAC1C,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAmB;AACzB,UAAM,EAAE,QAAQ,IAAI,IAAI,KAAK;AAC7B,UAAM,WAAWC,MAAK,KAAK,OAAO,OAAO,YAAY,WAAW;AAEhE,QAAI,CAACC,YAAW,QAAQ,GAAG;AACzB;AAAA,IACF;AAEA,SAAK,aAAa;AAClB,QAAI,gBAAsD;AAE1D,UAAM,UAAU;AAAA,MACd;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,MAClB,CAAC,WAAW,aAAa;AAEvB,YAAI,CAAC,UAAU,MAAM,gBAAgB,GAAG;AACtC;AAAA,QACF;AAGA,YAAI,eAAe;AACjB,uBAAa,aAAa;AAAA,QAC5B;AAEA,wBAAgB,WAAW,YAAY;AACrC,cAAI,QAAQ,IAAI,MAAO,SAAQ,IAAI,sDAAmB,QAAQ,EAAE;AAChE,cAAI,KAAK,WAAW;AAClB,kBAAM,KAAK,UAAU,SAAS;AAAA,UAChC;AAAA,QACF,GAAG,GAAG;AAAA,MACR;AAAA,IACF;AAGA,YAAQ,GAAG,QAAQ,MAAM;AACvB,cAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,EACH;AACF;;;AD3LA,IAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,IAAM,kBAAkBC,MAAK,WAAW,oBAAoB;AAKrD,SAAS,iBACd,QACA,KACA,UAA+B,CAAC,GACjB;AACf,QAAM,QAAQ,QAAQ,SAAS,QAAQ,IAAI,aAAa;AACxD,QAAM,EAAE,WAAW,IAAI,mBAAmB,GAAG;AAE7C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,EACF,IAAI;AAGJ,QAAM,gBAAgB,WAAW,OAAO;AAExC,QAAM,eAAuC;AAAA,IAC3C,KAAK,WAAW,KAAK;AAAA,IACrB,WAAW,WAAW,QAAQ;AAAA,IAC9B,UAAU,WAAW,OAAO;AAAA,IAC5B,YAAY,WAAW,SAAS;AAAA,IAChC,WAAW,WAAW,QAAQ;AAAA;AAAA,IAE9B,gBAAgBA,MAAK,eAAe,YAAY;AAAA;AAAA,IAEhD,iBAAiBA,MAAK,eAAe,YAAY;AAAA;AAAA,IAEjD,eAAeA,MAAK,eAAe,UAAU;AAAA,EAC/C;AAEA,QAAM,QAAQ,EAAE,GAAG,cAAc,GAAG,UAAU;AAE9C,SAAO;AAAA;AAAA,IAEL,OAAO,CAACA,MAAK,eAAe,WAAW,CAAC;AAAA,IAExC,SAAS;AAAA,MACP,YAAY,CAAC,OAAO,QAAQ,QAAQ,OAAO,SAAS,MAAM;AAAA,MAC1D,UAAU;AAAA,MACV,OAAO;AAAA,QACL,GAAG;AAAA,QACH,sBAAsBD,SAAQ,QAAQ,oBAAoB;AAAA,QAC1D,mBAAmBA,SAAQ,QAAQ,oBAAoB;AAAA,QACvD,OAAO,WAAW,oBAAoB;AAAA,QACtC,aAAa,WAAW,wBAAwB;AAAA,QAChD,gBAAgB,WAAW,2BAA2B;AAAA,MACxD;AAAA,MACA,UAAU;AAAA,QACR,MAAMA,SAAQ,QAAQ,iBAAiB;AAAA,QACvC,SAASA,SAAQ,QAAQ,oBAAoB;AAAA,QAC7C,QAAQA,SAAQ,QAAQ,SAAS;AAAA,QACjC,MAAMA,SAAQ,QAAQ,OAAO;AAAA,QAC7B,QAAQA,SAAQ,QAAQ,mBAAmB;AAAA,QAC3C,QAAQA,SAAQ,QAAQ,mBAAmB;AAAA,QAC3C,MAAMA,SAAQ,QAAQ,iBAAiB;AAAA,QACvC,aAAaA,SAAQ,QAAQ,iBAAiB;AAAA,QAC9C,KAAKA,SAAQ,QAAQ,MAAM;AAAA,QAC3B,QAAQA,SAAQ,QAAQ,SAAS;AAAA,QACjC,IAAI;AAAA,QACJ,KAAK;AAAA,QACL,KAAK;AAAA,QACL,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,eAAe;AAAA,MACb,SAAS,CAAC,iBAAiB,cAAc;AAAA,IAC3C;AAAA,IAEA,QAAQ;AAAA,MACN,OAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,YACP,gBAAgB;AAAA,UAClB;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,YACP,WAAW,KAAK;AAAA,YAChB,WAAW,QAAQ;AAAA,YACnB,WAAW,OAAO;AAAA,YAClB,WAAW,UAAU;AAAA,YACrB;AAAA;AAAA,UACF;AAAA,UACA,SAAS,CAAC,WAAW,cAAc,CAAC;AAAA,UACpC,KAAK;AAAA,YACH;AAAA,cACE,QAAQ;AAAA,cACR,SAAS;AAAA,gBACP,KAAK;AAAA,kBACH,QAAQ;AAAA,oBACN,QAAQ;AAAA,oBACR,KAAK;AAAA,oBACL,YAAY;AAAA,kBACd;AAAA,kBACA,WAAW;AAAA,oBACT,OAAO;AAAA,sBACL,SAAS;AAAA,sBACT,aAAa;AAAA,sBACb,SAAS;AAAA,oBACX;AAAA,kBACF;AAAA,kBACA,QAAQ;AAAA,gBACV;AAAA,gBACA,YAAY;AAAA,cACd;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,SAAS,CAAC,WAAW,QAAQ,CAAC;AAAA,UAC9B,SAAS,CAAC,WAAW,KAAK,GAAG,WAAW,OAAO,CAAC;AAAA,UAChD,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,kBAAkB;AAAA,cAChB,SAAS,KAAK;AAAA,YAChB;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,SAAS,CAAC,WAAW,KAAK,CAAC;AAAA,UAC3B,MAAM;AAAA,QACR;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,KAAK,CAAC,eAAe;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAAA,IAEA,SAAS;AAAA,MACP,IAAI,OAAO,cAAc;AAAA,QACvB,SAAS;AAAA,QACT,QAAQ,CAAC,UAAU,QAAQ;AAAA,MAC7B,CAAC;AAAA,MACD,IAAI,OAAO,aAAa;AAAA,QACtB,eAAe,KAAK,UAAU,QAAQ,GAAG;AAAA,MAC3C,CAAC;AAAA,MACD,IAAI,OAAO,iBAAiB;AAAA,QAC1B,UAAU,WAAW,KAAK,YAAY,mBAAmB;AAAA,QACzD,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,QAAQ,QAAQ,IAAI,aAAa;AAAA,QACjC,SAAS,WAAW,KAAK,WAAW,oBAAoB;AAAA,QACxD,oBAAoB;AAAA,UAClB,OAAO,KAAK,SAAS;AAAA,UACrB,WAAW,KAAK,aAAa;AAAA,QAC/B;AAAA,MACF,CAAC;AAAA,MACD,IAAI,OAAO,iBAAiB;AAAA,QAC1B,UAAU;AAAA,UACR;AAAA,YACE,MAAM,WAAW,eAAe;AAAA,YAChC,IAAI;AAAA,YACJ,kBAAkB;AAAA,UACpB;AAAA,QACF;AAAA,MACF,CAAC;AAAA;AAAA,MAED,IAAI,oBAAoB;AAAA,QACtB;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,OAAO,QAAQ,IAAI,aAAa;AAAA,QAChC,eAAe,OAAO;AAAA,MACxB,CAAC;AAAA,IACH,EAAE,OAAO,OAAO;AAAA,IAEhB,QAAQ;AAAA,MACN,qBAAqB;AAAA,MACrB,SAAS,cAAc,UAAU,GAAG,QAAQ,YAAY;AAAA,MACxD,eAAe;AAAA,MACf,eAAe,cAAc,UAAU,QAAQ;AAAA,MAC/C,cAAc,cAAc,UAAU,WAAW;AAAA,MACjD,oBAAoB,cAAc,UAC9B,gBAAgB,OAAO,KACvB;AAAA,MACJ,YAAY,OAAO,cAAc;AAAA,MACjC,MAAM,WAAW,OAAO,QAAQ,MAAM;AAAA,IACxC;AAAA,IAEA,gBAAgB;AAAA,MACd;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IAEA,SAAS;AAAA,EACX;AACF;;;AFhNA,IAAME,WAAUC,eAAc,YAAY,GAAG;AAM7C,SAAS,oBACP,OAC6F;AAC7F,MAAI,CAAC,SAAS,OAAO,KAAK,KAAK,EAAE,WAAW,GAAG;AAC7C,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM;AACtD,QAAI,OAAO,WAAW,UAAU;AAC9B,aAAO;AAAA,QACL,SAAS,CAAC,OAAO;AAAA,QACjB;AAAA,QACA,cAAc;AAAA,QACd,QAAQ;AAAA,MACV;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAS,CAAC,OAAO;AAAA,MACjB,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,GAAI;AAAA,IACN;AAAA,EACF,CAAC;AACH;AAKO,SAAS,gBACd,QACA,KACe;AACf,QAAM,aAAa,iBAAiB,QAAQ,KAAK,EAAE,OAAO,KAAK,CAAC;AAChE,QAAM,EAAE,WAAW,IAAI,mBAAmB,GAAG;AAC7C,QAAM,EAAE,KAAK,MAAM,IAAI;AAEvB,QAAM,aAAsC;AAAA,IAC1C,OAAO;AAAA;AAAA,MAEL;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAAA,QACA,KAAK;AAAA,UACH,EAAE,QAAQ,eAAe;AAAA,UACzB;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,EAAE,WAAW,KAAK;AAAA,UAC7B;AAAA,UACA;AAAA,YACE,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,WAAW;AAAA,cACX,aAAa;AAAA,gBACX,YAAY;AAAA,gBACZ,MAAM;AAAA,gBACN,mBAAmB;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAEA,GAAI,MAAM,MAAM,YAAY,QACxB;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,SAAS,CAAC,WAAW,KAAK,CAAC;AAAA,UAC3B,SAAS,CAAC,WAAW,cAAc,CAAC;AAAA,UACpC,OAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,KAAK;AAAA,gBACH,EAAE,QAAQ,eAAe;AAAA,gBACzB;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,SAAS;AAAA,sBACP,gBACE;AAAA,oBACJ;AAAA,oBACA,eAAe;AAAA,kBACjB;AAAA,gBACF;AAAA,gBACA;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,aAAa;AAAA,sBACX,mBAAmB;AAAA,sBACnB,MAAM;AAAA,sBACN,GAAG,MAAM,MAAM;AAAA,oBACjB;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,YACA;AAAA,cACE,KAAK;AAAA,gBACH,EAAE,QAAQ,eAAe;AAAA,gBACzB;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS,EAAE,WAAW,KAAK;AAAA,gBAC7B;AAAA,gBACA;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,aAAa;AAAA,sBACX,mBAAmB;AAAA,sBACnB,GAAG,MAAM,MAAM;AAAA,oBACjB;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,IACA,CAAC;AAAA;AAAA,MAEL,GAAI,MAAM,MAAM,YAAY,QACxB;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,SAAS,CAAC,WAAW,KAAK,CAAC;AAAA,UAC3B,SAAS,CAAC,WAAW,cAAc,CAAC;AAAA,UACpC,OAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,KAAK;AAAA,gBACH,EAAE,QAAQ,eAAe;AAAA,gBACzB;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,SAAS;AAAA,sBACP,gBACE;AAAA,oBACJ;AAAA,oBACA,eAAe;AAAA,kBACjB;AAAA,gBACF;AAAA,gBACA;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,aAAa;AAAA,sBACX,aAAa;AAAA,sBACb,GAAG,MAAM,MAAM;AAAA,oBACjB;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,YACA;AAAA,cACE,KAAK;AAAA,gBACH,EAAE,QAAQ,eAAe;AAAA,gBACzB;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS,EAAE,WAAW,KAAK;AAAA,gBAC7B;AAAA,gBACA;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,aAAa;AAAA,sBACX,aAAa;AAAA,sBACb,GAAG,MAAM,MAAM;AAAA,oBACjB;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,IACA,CAAC;AAAA;AAAA,MAEL,GAAI,MAAM,cACN;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,SAAS,CAAC,WAAW,eAAe,CAAC;AAAA,UACrC,KAAK;AAAA,YACH;AAAA,YACA;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,SAAS;AAAA,gBACP,gBAAgB;AAAA,kBACd,QAAQ,WAAW,mBAAmB;AAAA,gBACxC;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,IACA,CAAC;AAAA;AAAA,MAEL;AAAA,QACE,MAAM;AAAA,QACN,SAAS,CAAC,WAAW,KAAK,GAAG,WAAW,cAAc,CAAC;AAAA,QACvD,SAAS,MAAM,cAAc,CAAC,WAAW,eAAe,CAAC,IAAI,CAAC;AAAA,QAC9D,KAAK;AAAA,UACH,EAAE,QAAQ,eAAe;AAAA,UACzB;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,EAAE,WAAW,KAAK;AAAA,UAC7B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAA2B;AAAA,IAC/B,MAAM;AAAA,IACN,SAAS;AAAA,IAET,QAAQ;AAAA,MACN,UAAU;AAAA,MACV,OAAO;AAAA,IACT;AAAA,IAEA,OAAO;AAAA,IAEP,SAAS;AAAA,MACP,IAAI,mBAAmB;AAAA,IACzB;AAAA,IAEA,WAAW;AAAA,MACT,MAAM,IAAI;AAAA,MACV,MAAM,IAAI;AAAA,MACV,UAAU;AAAA,MACV,oBAAoB;AAAA,MACpB,KAAK;AAAA,MACL,cAAc;AAAA,MACd,QAAQ;AAAA,QACN,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,MACA,OAAO,oBAAoB,IAAI,KAAK;AAAA,IACtC;AAAA,IAEA,QAAQ;AAAA,EACV;AAEA,SAAO,MAAM,YAAY,SAAS;AACpC;;;AU1QA,SAAS,UAAAC,eAAkC;AAC3C,SAAS,SAAAC,cAAa;AAQf,SAAS,iBACd,QACA,KACe;AACf,QAAM,aAAa,iBAAiB,QAAQ,KAAK,EAAE,OAAO,MAAM,CAAC;AACjE,QAAM,EAAE,WAAW,IAAI,mBAAmB,GAAG;AAC7C,QAAM,EAAE,OAAO,aAAa,OAAO,IAAI;AAEvC,QAAM,aAAsC;AAAA,IAC1C,OAAO;AAAA;AAAA,MAEL;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,UACA;AAAA,QACF;AAAA,QACA,KAAK;AAAA,UACH,EAAE,QAAQC,QAAO,uBAAuB,OAAO;AAAA,UAC/C;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,EAAE,WAAW,KAAK;AAAA,UAC7B;AAAA,UACA;AAAA,YACE,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,WAAW;AAAA,cACX,aAAa;AAAA,gBACX,YAAY;AAAA,gBACZ,MAAM;AAAA,gBACN,mBAAmB;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAEA,GAAI,MAAM,MAAM,YAAY,QACxB;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,SAAS,CAAC,WAAW,KAAK,CAAC;AAAA,UAC3B,SAAS,CAAC,WAAW,cAAc,CAAC;AAAA,UACpC,OAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,KAAK;AAAA,gBACH,EAAE,QAAQA,QAAO,uBAAuB,OAAO;AAAA,gBAC/C;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,SAAS;AAAA,sBACP,gBACE;AAAA,oBACJ;AAAA,oBACA,eAAe;AAAA,kBACjB;AAAA,gBACF;AAAA,gBACA;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,aAAa;AAAA,sBACX,mBAAmB;AAAA,sBACnB,GAAG,MAAM,MAAM;AAAA,oBACjB;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,YACA;AAAA,cACE,KAAK;AAAA,gBACH,EAAE,QAAQA,QAAO,uBAAuB,OAAO;AAAA,gBAC/C;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS,EAAE,WAAW,KAAK;AAAA,gBAC7B;AAAA,gBACA;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,aAAa;AAAA,sBACX,mBAAmB;AAAA,sBACnB,GAAG,MAAM,MAAM;AAAA,oBACjB;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,IACA,CAAC;AAAA;AAAA,MAEL,GAAI,MAAM,MAAM,YAAY,QACxB;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,SAAS,CAAC,WAAW,KAAK,CAAC;AAAA,UAC3B,SAAS,CAAC,WAAW,cAAc,CAAC;AAAA,UACpC,OAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,KAAK;AAAA,gBACH,EAAE,QAAQA,QAAO,uBAAuB,OAAO;AAAA,gBAC/C;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,SAAS;AAAA,sBACP,gBACE;AAAA,oBACJ;AAAA,oBACA,eAAe;AAAA,kBACjB;AAAA,gBACF;AAAA,gBACA;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,aAAa;AAAA,sBACX,aAAa;AAAA,sBACb,GAAG,MAAM,MAAM;AAAA,oBACjB;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,YACA;AAAA,cACE,KAAK;AAAA,gBACH,EAAE,QAAQA,QAAO,uBAAuB,OAAO;AAAA,gBAC/C;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS,EAAE,WAAW,KAAK;AAAA,gBAC7B;AAAA,gBACA;AAAA,kBACE,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACP,WAAW;AAAA,oBACX,aAAa;AAAA,sBACX,aAAa;AAAA,sBACb,GAAG,MAAM,MAAM;AAAA,oBACjB;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,IACA,CAAC;AAAA;AAAA,MAEL,GAAI,MAAM,cACN;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,SAAS,CAAC,WAAW,eAAe,CAAC;AAAA,UACrC,KAAK;AAAA,YACH,EAAE,QAAQA,QAAO,uBAAuB,OAAO;AAAA,YAC/C;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,SAAS;AAAA,gBACP,gBAAgB;AAAA,kBACd,QAAQ,WAAW,mBAAmB;AAAA,gBACxC;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,IACA,CAAC;AAAA;AAAA,MAEL;AAAA,QACE,MAAM;AAAA,QACN,SAAS,CAAC,WAAW,KAAK,CAAC;AAAA,QAC3B,SAAS,MAAM,cAAc,CAAC,WAAW,eAAe,CAAC,IAAI,CAAC;AAAA,QAC9D,KAAK;AAAA,UACH,EAAE,QAAQA,QAAO,uBAAuB,OAAO;AAAA,UAC/C;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,EAAE,WAAW,KAAK;AAAA,UAC7B;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAEA;AAAA,QACE,MAAM;AAAA,QACN,SAAS,CAAC,WAAW,cAAc,CAAC;AAAA,QACpC,KAAK;AAAA,UACH,EAAE,QAAQ,eAAe;AAAA,UACzB;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,EAAE,WAAW,KAAK;AAAA,UAC7B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAA4B;AAAA,IAChC,MAAM;AAAA,IACN,SAAS;AAAA,IAET,QAAQ;AAAA,MACN,UAAU;AAAA,MACV,eAAe;AAAA,MACf,OAAO,OAAO;AAAA,IAChB;AAAA,IAEA,QAAQ;AAAA,IAER,SAAS;AAAA,MACP,IAAIA,QAAO,uBAAuB;AAAA,QAChC,UAAU;AAAA,QACV,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,IAEA,cAAc;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,QACT,IAAIA,QAAO,2BAA2B;AAAA,UACpC,SAAS,CAAC,WAAW,cAAc,CAAC;AAAA,UACpC,kBAAkB;AAAA,YAChB,UAAU;AAAA,cACR,YAAY,YAAY,cACpB,CAAC,eAAe,gBAAgB,iBAAiB,cAAc,IAC/D,CAAC,gBAAgB,eAAe;AAAA,cACpC,cAAc;AAAA,cACd,eAAe;AAAA,YACjB;AAAA,UACF;AAAA,QACF,CAAC;AAAA,QACD,IAAIA,QAAO,kCAAkC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAEA,SAAOC,OAAM,YAAY,UAAU;AACrC;;;AX7OO,SAAS,mBACd,QACA,KACA,UAA+B,CAAC,GACjB;AACf,QAAM,QAAQ,QAAQ,SAAS,QAAQ,IAAI,aAAa;AAExD,MAAI,eAAe,QACf,gBAAgB,QAAQ,GAAG,IAC3B,iBAAiB,QAAQ,GAAG;AAGhC,MAAI,OAAO,YAAY,UAAU;AAC/B,iBAAa,UAAU;AAAA,MACrB,GAAI,aAAa,WAAW,CAAC;AAAA,MAC7B,IAAI,qBAAqB,CAAC,CAAC;AAAA,IAC7B;AAAA,EACF;AAGA,MAAI,OAAO,MAAM,QAAQ;AACvB,UAAM,aAAa,OAAO,MAAM,OAAO,cAAc;AAAA,MACnD;AAAA,MACA,QAAQ,CAAC;AAAA,IACX,CAAC;AAED,QAAI,YAAY;AACd,qBAAe;AAAA,IACjB;AAAA,EACF;AAEA,SAAO;AACT;","names":["createRequire","join","existsSync","join","existsSync","mkdirSync","writeFileSync","readFileSync","join","existsSync","existsSync","join","join","existsSync","mkdirSync","readFileSync","writeFileSync","join","existsSync","require","join","require","createRequire","rspack","merge","rspack","merge"]}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as AppContextValue, A as AppConfig, P as ProviderConfig, M as MicroAppConfig } from '../types-
|
|
2
|
-
export { a as AntdConfig, L as LifecycleHooks } from '../types-
|
|
1
|
+
import { b as AppContextValue, A as AppConfig, P as ProviderConfig, M as MicroAppConfig } from '../types-BztKUufh.js';
|
|
2
|
+
export { a as AntdConfig, L as LifecycleHooks, c as RequestConfig, R as Result } from '../types-BztKUufh.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import * as react from 'react';
|
|
5
5
|
import { ReactNode, Component, ErrorInfo, ComponentType } from 'react';
|
|
@@ -108,6 +108,20 @@ declare function createMicroApp(getConfig: (props?: MicroAppConfig) => AppConfig
|
|
|
108
108
|
*/
|
|
109
109
|
update(props?: MicroAppConfig): Promise<void>;
|
|
110
110
|
};
|
|
111
|
+
/**
|
|
112
|
+
* Garfish 子应用 provider
|
|
113
|
+
*
|
|
114
|
+
* Garfish 要求子应用导出 provider 函数,接收 { dom, basename, props },
|
|
115
|
+
* 返回 { render, destroy } 对象。
|
|
116
|
+
*/
|
|
117
|
+
declare function createGarfishProvider(getConfig: (overrides?: Partial<AppConfig>) => AppConfig): (providerContext: {
|
|
118
|
+
dom: Element;
|
|
119
|
+
basename: string;
|
|
120
|
+
props?: Record<string, unknown>;
|
|
121
|
+
}) => {
|
|
122
|
+
render(): void;
|
|
123
|
+
destroy(): void;
|
|
124
|
+
};
|
|
111
125
|
/**
|
|
112
126
|
* 判断是否在微前端环境中运行
|
|
113
127
|
*/
|
|
@@ -117,4 +131,4 @@ declare function isMicroAppEnv(): boolean;
|
|
|
117
131
|
*/
|
|
118
132
|
declare function getMicroAppPublicPath(): string;
|
|
119
133
|
|
|
120
|
-
export { AppConfig, AppContext, AppContextProvider, AppContextValue, ErrorBoundary, type ErrorBoundaryProps, MicroAppConfig, ProviderConfig, RootProvider, type RootProviderProps, bootstrap, createMicroApp, createProvider, getMicroAppPublicPath, isMicroAppEnv, unmount, useApp, useAppName, useBasename, useEnv, useIsDev };
|
|
134
|
+
export { AppConfig, AppContext, AppContextProvider, AppContextValue, ErrorBoundary, type ErrorBoundaryProps, MicroAppConfig, ProviderConfig, RootProvider, type RootProviderProps, bootstrap, createGarfishProvider, createMicroApp, createProvider, getMicroAppPublicPath, isMicroAppEnv, unmount, useApp, useAppName, useBasename, useEnv, useIsDev };
|
package/dist/runtime/index.js
CHANGED
|
@@ -371,6 +371,36 @@ function createMicroApp(getConfig) {
|
|
|
371
371
|
}
|
|
372
372
|
};
|
|
373
373
|
}
|
|
374
|
+
function createGarfishProvider(getConfig) {
|
|
375
|
+
let garfishRoot = null;
|
|
376
|
+
return function provider(providerContext) {
|
|
377
|
+
const { dom, basename } = providerContext;
|
|
378
|
+
return {
|
|
379
|
+
render() {
|
|
380
|
+
const config = getConfig({ basename });
|
|
381
|
+
const resolvedConfig = { ...config, basename };
|
|
382
|
+
const rootId = resolvedConfig.rootId || "root";
|
|
383
|
+
let rootElement = dom.querySelector(`#${rootId}`);
|
|
384
|
+
if (!rootElement) {
|
|
385
|
+
rootElement = document.createElement("div");
|
|
386
|
+
rootElement.id = rootId;
|
|
387
|
+
dom.appendChild(rootElement);
|
|
388
|
+
}
|
|
389
|
+
garfishRoot = createRoot(rootElement);
|
|
390
|
+
garfishRoot.render(/* @__PURE__ */ jsx4(RootProvider, { config: resolvedConfig }));
|
|
391
|
+
if (resolvedConfig.lifecycle?.onMounted) {
|
|
392
|
+
setTimeout(() => resolvedConfig.lifecycle?.onMounted?.(), 0);
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
destroy() {
|
|
396
|
+
if (garfishRoot) {
|
|
397
|
+
garfishRoot.unmount();
|
|
398
|
+
garfishRoot = null;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
};
|
|
403
|
+
}
|
|
374
404
|
function isMicroAppEnv() {
|
|
375
405
|
if (window.__POWERED_BY_QIANKUN__) {
|
|
376
406
|
return true;
|
|
@@ -392,6 +422,7 @@ export {
|
|
|
392
422
|
ErrorBoundary,
|
|
393
423
|
RootProvider,
|
|
394
424
|
bootstrap,
|
|
425
|
+
createGarfishProvider,
|
|
395
426
|
createMicroApp,
|
|
396
427
|
createProvider,
|
|
397
428
|
getMicroAppPublicPath,
|