{"version":3,"file":"index.cjs","sources":["../src/const.ts","../src/helpers.ts","../src/core/FSRouter.ts","../src/core/FSTree.ts","../src/ReactApp.ts","../src/plugin.ts"],"sourcesContent":["export const pkgName = process.env.PKG_NAME;\nexport const pkgVersion = process.env.PKG_VERSION;\nexport const officialLink = 'https://github.com/FrontEndDev-org/vite-plugin-app';\n","import nodePath from 'node:path';\nimport nodeFS from 'node:fs';\n\nexport function indentLine(line: string, size = 0) {\n    return ' '.repeat(size) + line;\n}\n\ntype JSXLike = {\n    tag: string;\n    props?: Record<string, string>;\n    children?: JSXLike[];\n};\n\nexport function jsxLikeStringify(jsxLike: JSXLike) {\n    const stringify = (jsx: JSXLike): string => {\n        const arg1 = jsx.props\n            ? `{${Object.entries(jsx.props)\n                  .map(([key, value]) => `${key}: ${value}`)\n                  .join(', ')}}`\n            : 'null';\n        const arg2 = jsx.children ? ', ' + jsx.children.map(stringify).join(', ') : '';\n        return `createElement(${jsx.tag}, ${arg1}${arg2})`;\n    };\n    return stringify(jsxLike);\n}\n","import { indentLine, jsxLikeStringify } from '../helpers';\nimport type { FSNode, FSTree } from './FSTree';\nimport nodePath from 'path';\n\nclass PageRoute {\n    parent?: LayoutRoute;\n    constructor(readonly fsNode: FSNode) {}\n\n    get id() {\n        return this.fsNode.id;\n    }\n\n    get path() {\n        const paths = [this.fsNode.path];\n        const find = (p?: FSNode) => {\n            if (!p) return;\n\n            // 有分组 depth = 1 结束\n            if (p.group && p.depth === 1) {\n                paths.unshift(p.group);\n                return;\n            }\n\n            // 直到包含路由的节点为止\n            if (!p.group && p.layout) return;\n\n            paths.unshift(p.path);\n            find(p.parent);\n        };\n\n        find(this.fsNode.parent);\n        return paths.length === 0 || (paths.length === 1 && paths.at(0) === '') ? '' : nodePath.join(...paths);\n    }\n\n    render(indent = 0, tabSize = 4) {\n        const indent_1 = indent * tabSize;\n        const indent_2 = (indent + 1) * tabSize;\n        const lines = [\n            //\n            indentLine('{', indent_1),\n        ];\n\n        // path\n        lines.push(indentLine(`path: ${JSON.stringify(this.path)},`, indent_2));\n\n        // element\n        const pageName = FSRouter.makePageComponentName(this.fsNode.id);\n        const element = jsxLikeStringify({\n            tag: 'Suspense',\n            props: {},\n            children: [{ tag: pageName }],\n        });\n        lines.push(indentLine(`element: ${element},`, indent_2));\n        lines.push(indentLine('},', indent_1));\n\n        return lines;\n    }\n}\n\nclass LayoutRoute {\n    parent?: LayoutRoute;\n    children: (LayoutRoute | PageRoute)[] = [];\n    constructor(readonly fsNode: FSNode) {}\n\n    get id() {\n        return this.fsNode.id;\n    }\n\n    render(indent = 0, tabSize = 4) {\n        const indent_1 = indent * tabSize;\n        const indent_2 = (indent + 1) * tabSize;\n        const lines = [\n            //\n            indentLine('{', indent_1),\n        ];\n\n        // element\n        const layoutName = FSRouter.makeLayoutComponentName(this.fsNode.id);\n        const element = jsxLikeStringify({\n            tag: 'Suspense',\n            props: {},\n            children: [{ tag: layoutName }],\n        });\n        lines.push(indentLine(`element: ${element},`, indent_2));\n\n        if (this.children.length) {\n            lines.push(indentLine('children: [', indent_2));\n            lines.push(...this.children.flatMap((child) => child.render(indent + 2, tabSize)));\n            lines.push(indentLine('],', indent_2));\n        }\n\n        lines.push(indentLine('},', indent_1));\n        return lines;\n    }\n}\n\nexport class FSRouter {\n    constructor(readonly fsTree: FSTree) {}\n\n    pageRoutes = new Map<number, PageRoute>();\n    addPageNode(fsNode: FSNode) {\n        this.pageRoutes.set(fsNode.id, new PageRoute(fsNode));\n    }\n\n    layoutRoutes = new Map<number, LayoutRoute>();\n    addLayoutNode(fsNode: FSNode) {\n        this.layoutRoutes.set(fsNode.id, new LayoutRoute(fsNode));\n    }\n\n    build() {\n        this.pageRoutes.forEach((pageRoute) => {\n            const find = (node: FSNode) => {\n                if (node.layout) {\n                    const layoutRoute = this.layoutRoutes.get(node.id);\n\n                    if (layoutRoute) {\n                        pageRoute.parent = layoutRoute;\n                        layoutRoute.children.push(pageRoute);\n                        return;\n                    }\n                }\n\n                if (node.parent) find(node.parent);\n            };\n\n            find(pageRoute.fsNode);\n        });\n\n        this.layoutRoutes.forEach((layoutRoute) => {\n            const find = (node: FSNode) => {\n                const parent = node.parent;\n                if (!parent) return;\n\n                // 独立分组布局根节点\n                if (node.group && node.depth === 1) return;\n\n                if (parent.layout) {\n                    const parentRoute = this.layoutRoutes.get(parent.id);\n\n                    if (parentRoute) {\n                        layoutRoute.parent = parentRoute;\n                        parentRoute.children.push(layoutRoute);\n                        return;\n                    }\n                }\n\n                find(parent);\n            };\n\n            find(layoutRoute.fsNode);\n        });\n    }\n\n    render(tabSize = 4) {\n        const importPages = ['// pages'];\n        const importLayouts = ['// layouts'];\n\n        const pageLines: string[] = [];\n        this.pageRoutes.forEach((route) => {\n            const importName = FSRouter.makePageComponentName(route.id);\n            importPages.push(`const ${importName} = lazy(() => import(\"${route.fsNode.page}\"));`);\n\n            if (!route.parent) {\n                pageLines.push(...route.render(0, tabSize));\n            }\n        });\n\n        const layoutLines: string[] = [];\n        this.layoutRoutes.forEach((route) => {\n            const importName = FSRouter.makeLayoutComponentName(route.id);\n            importLayouts.push(`const ${importName} = lazy(() => import(\"${route.fsNode.layout}\"));`);\n\n            if (!route.parent) {\n                layoutLines.push(...route.render(0, tabSize));\n            }\n        });\n\n        return [\n            '/**',\n            ' * generated by pkg-name-for-test@pkg-version-for-test',\n            ' * @ref https://github.com/FrontEndDev-org/vite-plugin-app',\n            ' * @ref https://reactrouter.com/',\n            ' */',\n            '',\n            'import { Suspense, lazy, createElement } from \"react\";',\n            'import { Outlet } from \"react-router-dom\";',\n            '',\n            ...importPages,\n            '',\n            ...importLayouts,\n            '',\n            'export const routes = [',\n            ...pageLines,\n            ...layoutLines,\n            '];',\n            '',\n        ].join('\\n');\n    }\n\n    // TODO\n    update() {}\n\n    static makeLayoutComponentName(id: number) {\n        return 'Layout_' + id;\n    }\n\n    static makePageComponentName(id: number) {\n        return 'Page_' + id;\n    }\n}\n","import nodePath from 'path';\nimport crypto from 'crypto';\nimport { indentLine } from '../helpers';\nimport { officialLink, pkgName, pkgVersion } from '../const';\nimport { FSRouter } from './FSRouter';\n\nexport type PageMeta = {\n    page: string;\n    depth: number;\n    group?: string;\n    dir: string;\n    name: string;\n};\n\nexport class FSNode {\n    id: number;\n\n    /**\n     * 分组\n     */\n    group?: string;\n\n    /**\n     * 深度，起始为 0\n     */\n    depth: number;\n    /**\n     * 【唯一】所在目录，相对于 cwd\n     */\n    dir: string;\n    /**\n     * 路径名\n     */\n    name: string;\n    /**\n     * 页面，未声明页面时为空字符串\n     * @ref https://reactrouter.com/en/main/route/route#elementcomponent\n     */\n    page: string;\n    /**\n     * https://reactrouter.com/en/main/start/concepts#layout-routes\n     */\n    layout?: string;\n    /**\n     * @ref https://reactrouter.com/en/main/route/loader\n     */\n    loader?: string;\n    /**\n     * @ref https://reactrouter.com/en/main/route/action\n     */\n    action?: string;\n    /**\n     * @ref https://reactrouter.com/en/main/route/error-element\n     */\n    error?: string;\n    /**\n     * @ref https://react.dev/reference/react/Suspense\n     */\n    loading?: string;\n    children: FSNode[] = [];\n    parent?: FSNode;\n\n    private _resolveFile(fileNames: string[]) {\n        const index = this.tree.options.resolveExist(this, fileNames);\n        // 不能用 at，因为 index 可能为 -1\n        const fileName = fileNames[index];\n        return fileName && nodePath.join(this.tree.cwd, this.dir, fileName);\n    }\n\n    constructor(\n        readonly tree: FSTree,\n        pageMeta: PageMeta,\n    ) {\n        const { page, depth, group, dir, name } = pageMeta;\n\n        this.id = this.tree.nextId();\n        this.group = group;\n        this.depth = depth;\n        this.dir = dir;\n        this.name = name;\n        this.page = page ? nodePath.join(tree.cwd, page) : '';\n        this.layout = this._resolveFile(['layout.tsx', 'layout.jsx']);\n        this.loader = this._resolveFile(['loader.tsx', 'loader.jsx']);\n        this.action = this._resolveFile(['action.tsx', 'action.jsx']);\n        this.error = this._resolveFile(['error.tsx', 'error.jsx']);\n\n        const depthRoutes = this.tree.defaultMap.get(depth) || [];\n        depthRoutes.push(this);\n        this.tree.defaultMap.set(depth, depthRoutes);\n        this.tree.dirMap.set(dir, this);\n\n        if (group) {\n            const groupRoutes = this.tree.groupMap.get(group) || [];\n            groupRoutes.push(this);\n            this.tree.groupMap.set(group, groupRoutes);\n        }\n\n        if (this.page) {\n            this.tree.fsRouter.addPageNode(this);\n        }\n\n        if (this.layout) {\n            this.tree.fsRouter.addLayoutNode(this);\n        }\n\n        if (depth === 0) {\n            this.tree.root = this;\n        }\n\n        this._linking();\n    }\n\n    update(meta: PageMeta) {\n        Object.assign(this, meta);\n    }\n\n    get path() {\n        return this.name === '.' ? '' : this.name.startsWith('[') && this.name.endsWith(']') ? ':' + this.name.slice(1, -1) : this.name;\n    }\n\n    private _linking() {\n        const { depth, dir } = this;\n        const parentDepth = depth - 1;\n        const parentDir = nodePath.dirname(dir);\n        const parentName = nodePath.basename(parentDir);\n        const parentGroup = depth > 0 ? this.group : undefined;\n\n        if (depth < 1) return;\n\n        const parent = this.tree.dirMap.get(parentDir);\n\n        if (parent) {\n            this.parent = parent;\n            parent.children.push(this);\n        } else {\n            const newParent = new FSNode(this.tree, {\n                depth: parentDepth,\n                page: '',\n                dir: parentDir,\n                name: parentName,\n                group: parentGroup,\n            });\n\n            this.parent = newParent;\n            newParent.children.push(this);\n        }\n    }\n\n    static parse(page: string): PageMeta {\n        const segments = page.split('/');\n        // 去除末尾 page.tsx\n        // path/to/page.tsx -> [path, to, page.tsx]\n        // -> [path, to]\n        segments.pop();\n        const depth = segments.length;\n        const name = segments.at(-1) || '.';\n        const dir = segments.join('/') || '.';\n        const firstSeg = segments.at(0);\n        const group = depth > 0 && firstSeg?.startsWith('(') && firstSeg?.endsWith(')') ? firstSeg?.slice(1, -1) : undefined;\n        return { page, depth, dir, name, group };\n    }\n}\n\nexport type FSTreeOptions = {\n    cwd: string;\n    resolveExist: (page: FSNode, fileNames: string[]) => number;\n};\n\nexport class FSTree {\n    root?: FSNode;\n    dirMap = new Map<string, FSNode>();\n    defaultMap = new Map<number, FSNode[]>();\n    groupMap = new Map<string, FSNode[]>();\n    idSet = new Set<string>();\n    fsRouter = new FSRouter(this);\n\n    constructor(readonly options: FSTreeOptions) {}\n\n    get cwd() {\n        return this.options.cwd;\n    }\n\n    mount(pages: string[]) {\n        pages.forEach((page) => {\n            const meta = FSNode.parse(page);\n            const fsPage = this.dirMap.get(meta.dir);\n\n            if (fsPage) {\n                fsPage.update(meta);\n            } else {\n                new FSNode(this, meta);\n            }\n        });\n        this.fsRouter.build();\n    }\n\n    // TODO\n    update(pages: string[], parent: string) {}\n\n    render(tabSize = 4) {\n        return this.fsRouter.render(tabSize);\n    }\n\n    private _id = 0;\n    nextId() {\n        return this._id++;\n    }\n\n    static makeLayoutComponentName(id: number) {\n        return 'Layout_' + id;\n    }\n\n    static makePageComponentName(id: number) {\n        return 'Page_' + id;\n    }\n}\n","import nodeFS from 'fs';\nimport { glob } from 'glob';\nimport nodePath from 'path';\nimport { createLogger, normalizePath, type Logger, type ViteDevServer } from 'vite';\nimport { pkgName } from './const';\nimport { FSTree } from './core/FSTree';\nimport type { PluginOptions } from './types';\n\nexport class ReactApp {\n    logger: Logger;\n    fsTree: FSTree;\n    absApp: string;\n\n    constructor(\n        readonly options: PluginOptions,\n        readonly cwd = process.cwd(),\n    ) {\n        this.logger = createLogger(options.logLevel, { prefix: `[${pkgName}]` });\n        this.logger.info(`new Options: ${JSON.stringify(options)}`);\n        this.absApp = nodePath.join(this.cwd, options.appDir);\n        this.fsTree = new FSTree({\n            cwd: nodePath.join('/', options.appDir),\n            resolveExist: (page, fileNames) => {\n                return fileNames.findIndex((fileName) => {\n                    const absFile = nodePath.join(this.absApp, page.dir, fileName);\n                    return nodeFS.existsSync(absFile) && nodeFS.statSync(absFile).isFile();\n                });\n            },\n        });\n    }\n\n    get output() {\n        const output = this.fsTree.render();\n        this.logger.info(`Generated: ${output}`);\n        return output;\n    }\n\n    private _inApp(path: string) {\n        return path.startsWith(this.absApp);\n    }\n\n    setup({ watcher }: ViteDevServer) {\n        this.logger.info(`setup`);\n\n        watcher.on('unlink', async (path) => {\n            if (!this._inApp(path)) return;\n\n            await this.removeFile(path);\n        });\n\n        watcher.on('add', async (path) => {\n            if (!this._inApp(path)) return;\n\n            await this.addFile(path);\n        });\n\n        watcher.on('change', async (path) => {\n            if (!this._inApp(path)) return;\n\n            await this.updateFile(path);\n        });\n\n        this.start();\n    }\n\n    start() {\n        this.logger.info(`start`);\n        const pageFiles = glob\n            .sync('**/page.{jsx,tsx}', {\n                cwd: this.absApp,\n                nodir: true,\n                dot: false,\n            })\n            .map(normalizePath);\n        // .sort((a, b) => a.split(nodePath.sep).length - b.split(nodePath.sep).length);\n        this.logger.info(`Page files: ${JSON.stringify(pageFiles)}`);\n        this.fsTree.mount(pageFiles);\n    }\n\n    async addFile(file: string) {\n        this.logger.info(`Add file: ${file}`);\n        this.start();\n    }\n\n    async updateFile(file: string) {\n        this.logger.info(`Update file: ${file}`);\n        this.start();\n    }\n\n    async removeFile(file: string) {\n        this.logger.info(`Remove file: ${file}`);\n        this.start();\n    }\n}\n","import type { Plugin } from 'vite';\nimport type { PluginOptions, UserPluginOptions } from './types';\nimport { ReactApp } from './ReactApp';\nimport { pkgName } from './const';\n\n// @ref https://cn.vitejs.dev/guide/api-plugin#virtual-modules-convention\nconst virtualModuleId = 'virtual:react-app';\nconst resolvedVirtualModuleId = '\\0' + virtualModuleId;\n\nexport function reactApp(userPluginOptions: UserPluginOptions = {}): Plugin {\n    let reactApp: ReactApp | null = null;\n\n    return {\n        name: pkgName,\n        enforce: 'pre',\n\n        async configResolved(config) {\n            const defaults: PluginOptions = {\n                debug: false,\n                appDir: 'src/app',\n                logLevel: 'error',\n                disableLazy: false,\n                caseSensitive: false,\n            };\n            reactApp = new ReactApp(Object.assign(defaults, userPluginOptions) as PluginOptions, config.root);\n        },\n\n        configureServer(server) {\n            reactApp?.setup(server);\n        },\n\n        resolveId(id) {\n            if (id !== virtualModuleId) return;\n\n            return resolvedVirtualModuleId;\n        },\n\n        async load(id) {\n            if (id !== resolvedVirtualModuleId) return;\n\n            return reactApp?.output;\n        },\n    };\n}\n"],"names":["createLogger","glob","normalizePath","reactApp"],"mappings":"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"}