-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaddon.json
11 lines (11 loc) · 10.9 KB
/
addon.json
1
2
3
4
5
6
7
8
9
10
11
[
{
"enabled": true,
"compilerCode": "import tsMorphCompiler, { TSMorphProjectTypeId, SourceFileTypeId } from \"@/tree/code-compiler/ts-morph/compiler\";\r\nimport type { TSMorphProjectType, TSMorphSourceFileType } from \"@/tree/code-compiler/ts-morph/compiler\";\r\nimport type { deleteNodeByBreadcrumbFunc, getNodeByBreadcrumbFunc, postNodeByBreadcrumbFunc, putNodeByBreadcrumbFunc, TreeNodeType } from \"@/tree/lib/type\";\r\nimport type { TreeCompilerType } from \"@/tree/tree-compiler/type\";\r\nimport normalizePath from \"normalize-path\";\r\nimport path from \"path\";\r\n\r\nexport const NextJSTypeId = 'densyakun-nextjs';\r\n\r\nexport type NextJSType = TreeNodeType & {\r\n type: typeof NextJSTypeId;\r\n pages: { [key: string]: TSMorphSourceFileType };\r\n unresolvedPages: NextJSUnresolvedPageType[];\r\n customApp?: TSMorphSourceFileType;\r\n customDocument?: TSMorphSourceFileType;\r\n otherSourceFiles: TSMorphSourceFileType[];\r\n};\r\n\r\nexport const NextJSUnresolvedPageTypeId = 'densyakun-nextjs-unresolved-page';\r\n\r\nexport type NextJSUnresolvedPageType = TreeNodeType & {\r\n type: typeof NextJSUnresolvedPageTypeId;\r\n route: string;\r\n sourceFile: TSMorphSourceFileType;\r\n};\r\n\r\nfunction setSourceFilesToNextJS(nextJS: NextJSType, sourceFiles: TSMorphSourceFileType[]) {\r\n const nextEnvIndex = sourceFiles.findIndex(sourceFile => sourceFile.relativeFilePath === \"next-env.d.ts\");\r\n\r\n const sourceFilesWithoutNextEnv = nextEnvIndex === -1\r\n ? [...sourceFiles]\r\n : [...sourceFiles.toSpliced(nextEnvIndex, 1)];\r\n\r\n const otherSourceFiles: TSMorphSourceFileType[] = [];\r\n\r\n const filesInAppRouter: TSMorphSourceFileType[] = [];\r\n for (const sourceFile of sourceFilesWithoutNextEnv) {\r\n if (normalizePath(sourceFile.relativeFilePath).startsWith(\"app/\"))\r\n filesInAppRouter.push(sourceFile);\r\n else\r\n otherSourceFiles.push(sourceFile);\r\n }\r\n\r\n if (filesInAppRouter.length) {\r\n // TODO App Router\r\n\r\n nextJS.pages = {};\r\n nextJS.unresolvedPages = [];\r\n nextJS.otherSourceFiles = otherSourceFiles;\r\n } else {\r\n // Pages Router\r\n const otherSourceFiles_: TSMorphSourceFileType[] = [];\r\n const pages: { [key: string]: TSMorphSourceFileType } = {};\r\n const unresolvedPages: NextJSUnresolvedPageType[] = [];\r\n let customApp: TSMorphSourceFileType | undefined;\r\n let customDocument: TSMorphSourceFileType | undefined;\r\n for (const sourceFile of otherSourceFiles) {\r\n const normalizedPath = normalizePath(sourceFile.relativeFilePath);\r\n\r\n if (normalizedPath.startsWith(\"pages/\")) {\r\n const a = path.dirname(normalizedPath).split(\"/\").splice(1);\r\n const b = path.basename(normalizedPath, path.extname(normalizedPath));\r\n if (b === \"_app\" && !a.length) {\r\n customApp = sourceFile;\r\n } else if (b === \"_document\" && !a.length) {\r\n customDocument = sourceFile;\r\n } else {\r\n let route = \"/\";\r\n if (a.length) route += a.join(\"/\");\r\n if (b !== \"index\") {\r\n if (a.length) route += \"/\";\r\n route += b;\r\n }\r\n\r\n if (pages[route]) {\r\n // /xxx/index.tsx よりも /xxx.tsx が優先される\r\n if (b === \"index\")\r\n unresolvedPages.push({\r\n type: \"densyakun-nextjs-unresolved-page\",\r\n route,\r\n sourceFile,\r\n });\r\n else {\r\n unresolvedPages.push({\r\n type: \"densyakun-nextjs-unresolved-page\",\r\n route,\r\n sourceFile: pages[route],\r\n });\r\n pages[route] = sourceFile;\r\n }\r\n } else\r\n pages[route] = sourceFile;\r\n }\r\n } else\r\n otherSourceFiles_.push(sourceFile);\r\n }\r\n\r\n nextJS.pages = pages;\r\n nextJS.unresolvedPages = unresolvedPages;\r\n nextJS.customApp = customApp;\r\n nextJS.customDocument = customDocument;\r\n nextJS.otherSourceFiles = otherSourceFiles_;\r\n }\r\n}\r\n\r\nfunction getSourceFilesInNextJS(nextJS: NextJSType) {\r\n const sourceFiles = [\r\n ...Object.values(nextJS.pages),\r\n ...nextJS.unresolvedPages.map(unresolvedPage => unresolvedPage.sourceFile),\r\n ...nextJS.otherSourceFiles,\r\n ];\r\n\r\n if (nextJS.customApp)\r\n sourceFiles.push(nextJS.customApp);\r\n if (nextJS.customDocument)\r\n sourceFiles.push(nextJS.customDocument);\r\n\r\n return sourceFiles;\r\n}\r\n\r\nfunction decompile(tree: TreeNodeType): TreeNodeType {\r\n if (tree.type === TSMorphProjectTypeId) {\r\n // TODO Next.jsアプリであるかどうか判定する\r\n\r\n const nextJS: NextJSType = {\r\n type: NextJSTypeId,\r\n pages: {},\r\n unresolvedPages: [],\r\n otherSourceFiles: [],\r\n };\r\n\r\n setSourceFilesToNextJS(nextJS, (tree as TSMorphProjectType).sourceFiles);\r\n\r\n return nextJS;\r\n }\r\n\r\n return tree;\r\n}\r\n\r\nfunction compile(tree: TreeNodeType): TreeNodeType {\r\n if (tree.type === NextJSTypeId) {\r\n const sourceFiles = getSourceFilesInNextJS(tree as NextJSType);\r\n\r\n return {\r\n type: TSMorphProjectTypeId,\r\n sourceFiles,\r\n } as TSMorphProjectType;\r\n }\r\n\r\n return tree;\r\n}\r\n\r\nconst getNodeByBreadcrumbFuncMap: { [key: string]: getNodeByBreadcrumbFunc } = {\r\n [NextJSTypeId]: (node, breadcrumb) => {\r\n return Object.values((node as NextJSType).pages).find(({ filePath }) => filePath === breadcrumb)\r\n || (node as NextJSType).unresolvedPages.find(({ sourceFile }) => sourceFile.filePath === breadcrumb)\r\n || (node as NextJSType).customApp?.filePath === breadcrumb && (node as NextJSType).customApp\r\n || (node as NextJSType).customDocument?.filePath === breadcrumb && (node as NextJSType).customDocument\r\n || (node as NextJSType).otherSourceFiles.find(({ filePath }) => filePath === breadcrumb);\r\n },\r\n [NextJSUnresolvedPageTypeId]: (node, breadcrumb) =>\r\n tsMorphCompiler.getNodeByBreadcrumbFuncMap[SourceFileTypeId]((node as NextJSUnresolvedPageType).sourceFile, breadcrumb)\r\n ,\r\n};\r\n\r\nconst postNodeByBreadcrumbFuncMap: { [key: string]: postNodeByBreadcrumbFunc } = {\r\n [NextJSTypeId]: (node, newChildNode) => {\r\n const sourceFiles = getSourceFilesInNextJS(node as NextJSType);\r\n sourceFiles.push(newChildNode as TSMorphSourceFileType);\r\n setSourceFilesToNextJS(node as NextJSType, sourceFiles);\r\n return (newChildNode as TSMorphSourceFileType).filePath;\r\n },\r\n};\r\n\r\nconst putNodeByBreadcrumbFuncMap: { [key: string]: putNodeByBreadcrumbFunc } = {\r\n [NextJSTypeId]: (node, breadcrumb, newChildNode) => {\r\n const sourceFiles = getSourceFilesInNextJS(node as NextJSType);\r\n for (let index = 0; index < sourceFiles.length; index++) {\r\n const { filePath } = sourceFiles[index];\r\n if (filePath === breadcrumb) {\r\n const res = sourceFiles.splice(index, 1, newChildNode as TSMorphSourceFileType)[0];\r\n setSourceFilesToNextJS(node as NextJSType, sourceFiles);\r\n return res;\r\n }\r\n }\r\n return undefined;\r\n },\r\n};\r\n\r\nconst deleteNodeByBreadcrumbFuncMap: { [key: string]: deleteNodeByBreadcrumbFunc } = {\r\n [NextJSTypeId]: (node, breadcrumb) => {\r\n const sourceFiles = getSourceFilesInNextJS(node as NextJSType);\r\n for (let index = 0; index < sourceFiles.length; index++) {\r\n const { filePath } = sourceFiles[index];\r\n if (filePath === breadcrumb) {\r\n const res = sourceFiles.splice(index, 1)[0];\r\n setSourceFilesToNextJS(node as NextJSType, sourceFiles);\r\n return res;\r\n }\r\n }\r\n },\r\n};\r\n\r\nexport default { decompile, compile, getNodeByBreadcrumbFuncMap, postNodeByBreadcrumbFuncMap, putNodeByBreadcrumbFuncMap, deleteNodeByBreadcrumbFuncMap } as TreeCompilerType;",
"editorCode": "import type { EditorType, getNodeEditorFunc, TreeNodeListItemType } from \"@/tree/lib/type\";\r\nimport type { NextJSType, NextJSUnresolvedPageType } from \"./compiler\";\r\nimport { NextJSTypeId, NextJSUnresolvedPageTypeId } from \"./compiler\";\r\nimport tsMorphEditor from \"@/tree/code-compiler/ts-morph/editor\";\r\nimport { SourceFileTypeId } from \"@/tree/code-compiler/ts-morph/compiler\";\r\n\r\nconst getNodeEditorFuncMap: { [key: string]: getNodeEditorFunc } = {\r\n [NextJSTypeId]: (nodeTree, breadcrumbPaths, node) => {\r\n const itemLists: { [key: string]: TreeNodeListItemType[] } = {\r\n \"Pages\": Object.keys((node as NextJSType).pages).map(key => {\r\n const sourceFile = (node as NextJSType).pages[key];\r\n\r\n return {\r\n breadcrumb: { path: sourceFile.filePath, label: sourceFile.filePath },\r\n text: key,\r\n color: \"hsl(0, 0%, 75%)\",\r\n };\r\n }),\r\n \"Custom app\": (node as NextJSType).customApp\r\n ? [{\r\n breadcrumb: { path: (node as NextJSType).customApp!.filePath, label: (node as NextJSType).customApp!.filePath },\r\n text: \"Source file\",\r\n color: \"hsl(0, 0%, 75%)\",\r\n }]\r\n : []\r\n ,\r\n \"Custom document\": (node as NextJSType).customDocument\r\n ? [{\r\n breadcrumb: { path: (node as NextJSType).customDocument!.filePath, label: (node as NextJSType).customDocument!.filePath },\r\n text: \"Source file\",\r\n color: \"hsl(0, 0%, 75%)\",\r\n }]\r\n : []\r\n ,\r\n \"Other source files\": Object.values((node as NextJSType).otherSourceFiles).map(sourceFile => ({\r\n breadcrumb: { path: sourceFile.filePath, label: sourceFile.filePath },\r\n text: sourceFile.relativeFilePath,\r\n color: \"hsl(0, 0%, 75%)\",\r\n })),\r\n };\r\n\r\n if ((node as NextJSType).unresolvedPages.length)\r\n itemLists[\"Unresolved pages\"] = (node as NextJSType).unresolvedPages.map(({ route, sourceFile }) => ({\r\n breadcrumb: { path: sourceFile.filePath, label: sourceFile.filePath },\r\n text: sourceFile.relativeFilePath + ` (${route})`,\r\n color: \"hsl(0, 50%, 75%)\",\r\n }));\r\n\r\n return {\r\n title: \"Next.js\",\r\n itemLists,\r\n topItemListKeys: [\"Unresolved pages\"],\r\n };\r\n },\r\n [NextJSUnresolvedPageTypeId]: (nodeTree, breadcrumbPaths, node, treeCompilers, setter) => ({\r\n title: \"Unresolved page\",\r\n itemLists: tsMorphEditor.getNodeEditorFuncMap[SourceFileTypeId](nodeTree, breadcrumbPaths, (node as NextJSUnresolvedPageType).sourceFile, treeCompilers, sourceFile => setter({\r\n ...node,\r\n sourceFile,\r\n } as NextJSUnresolvedPageType))?.itemLists,\r\n dataTexts: [\r\n `Route: ${(node as NextJSUnresolvedPageType).route}`,\r\n ],\r\n }),\r\n};\r\n\r\nexport default { getNodeEditorFuncMap } as EditorType;",
"name": "Next.js test",
"description": "Tree Compiler for Next.js",
"author": "Densyakun",
"website": ""
}
]