From c77843c521231e6d21d73172fe8ebb5ff20cb43c Mon Sep 17 00:00:00 2001 From: Simian Date: Wed, 15 May 2024 08:21:21 -0600 Subject: [PATCH 1/2] feat: add schema-based indexing to generateIndexFile hook --- packages/kanel/src/hooks/generateIndexFile.ts | 89 ++++++++++++++++++- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/packages/kanel/src/hooks/generateIndexFile.ts b/packages/kanel/src/hooks/generateIndexFile.ts index 2cc54df3..9cf310dc 100644 --- a/packages/kanel/src/hooks/generateIndexFile.ts +++ b/packages/kanel/src/hooks/generateIndexFile.ts @@ -25,6 +25,11 @@ type ExportsItem = { exportAsType: boolean; }; +type SchemaExports = { + items: Record; + path: string; +}; + function stringifyExportItem(item: ExportsItem): string { const prefix = item.exportAsType ? "type " : ""; return `${prefix}${item.wasExportedAs === "default" ? "default as " : ""}${ @@ -32,12 +37,37 @@ function stringifyExportItem(item: ExportsItem): string { }`; } +function getSchemaFromPath(path: string, outputPath: string): string { + const relpath = relative(outputPath, path); + const relparts = relpath.split("/"); + + // Make sure path is part of a schema path + if (relparts.length === 2) { + return relparts[0]; + } + + return null; +} + export const makeGenerateIndexFile: ( config: GenerateIndexFileConfig, ) => PreRenderHook = (config) => (outputAcc, instantiatedConfig) => { const allExports: Record = {}; + const schemaExports: Record = {}; + const { outputPath } = instantiatedConfig; for (const path of Object.keys(outputAcc)) { + const schema = getSchemaFromPath(path, outputPath); + + if (schema && !schemaExports[schema]) { + schemaExports[schema] = { + path: join(outputPath, schema), + items: { [path]: [] }, + }; + } else if (schema) { + schemaExports[schema].items[path] = []; + } + const file = outputAcc[path]; allExports[path] = []; for (const declaration of file.declarations) { @@ -50,23 +80,74 @@ export const makeGenerateIndexFile: ( } const { name, exportAs, declarationType } = declaration; - allExports[path].push({ + const declarationItem = { name, wasExportedAs: exportAs, exportAsType: ["typeDeclaration", "interface"].includes( declarationType, ), - }); + } + + // Add to the global index + allExports[path].push(declarationItem); + + // Add to the schema index + if (schema) { + schemaExports[schema].items[path].push(declarationItem); + } } } + const schemaIndexFiles: Record = {}; + for (const schema of Object.keys(schemaExports)) { + const schemaPath = schemaExports[schema].path; + const schemaLines = Object.keys(schemaExports[schema].items).map((itemPath) => { + const schemaDeclExports = schemaExports[schema].items[itemPath]; + if (schemaDeclExports.length === 0) { + return ""; + } + + let relativePath = relative(schemaPath, itemPath); + // Fix Windows-style paths in import line + if (sep === "\\") { + relativePath = relativePath.replaceAll("\\", "/"); + } + + const line = `export { ${schemaDeclExports + .map(stringifyExportItem) + .join(", ")} } from './${relativePath}';`; + + return line; + }); + + const schemaIndexFile: FileContents = { + declarations: [ + { + declarationType: "generic", + lines: schemaLines, + }, + ], + }; + + const schemaIndexPath = join(schemaPath, "index"); + schemaIndexFiles[schemaIndexPath] = schemaIndexFile; + } + + // Return now if using schema-indexes to avoid a conflicting global index + if (Object.values(schemaIndexFiles).length > 0) { + return { + ...outputAcc, + ...schemaIndexFiles, + }; + } + const lines = Object.keys(allExports).map((path) => { const exports = allExports[path]; if (exports.length === 0) { return ""; } - let relativePath = relative(instantiatedConfig.outputPath, path); + let relativePath = relative(outputPath, path); // Fix Windows-style paths in import line if (sep === "\\") { relativePath = relativePath.replaceAll("\\", "/"); @@ -88,7 +169,7 @@ export const makeGenerateIndexFile: ( ], }; - const path = join(instantiatedConfig.outputPath, "index"); + const path = join(outputPath, "index"); return { ...outputAcc, From deb49e18e079d463e4cffe7ebe594d8c09b81f0b Mon Sep 17 00:00:00 2001 From: Simian Loco Date: Wed, 15 May 2024 10:50:04 -0600 Subject: [PATCH 2/2] fix: linting error fixes --- packages/kanel/src/hooks/generateIndexFile.ts | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/packages/kanel/src/hooks/generateIndexFile.ts b/packages/kanel/src/hooks/generateIndexFile.ts index 9cf310dc..8d926c23 100644 --- a/packages/kanel/src/hooks/generateIndexFile.ts +++ b/packages/kanel/src/hooks/generateIndexFile.ts @@ -86,7 +86,7 @@ export const makeGenerateIndexFile: ( exportAsType: ["typeDeclaration", "interface"].includes( declarationType, ), - } + }; // Add to the global index allExports[path].push(declarationItem); @@ -101,24 +101,26 @@ export const makeGenerateIndexFile: ( const schemaIndexFiles: Record = {}; for (const schema of Object.keys(schemaExports)) { const schemaPath = schemaExports[schema].path; - const schemaLines = Object.keys(schemaExports[schema].items).map((itemPath) => { - const schemaDeclExports = schemaExports[schema].items[itemPath]; - if (schemaDeclExports.length === 0) { - return ""; - } - - let relativePath = relative(schemaPath, itemPath); - // Fix Windows-style paths in import line - if (sep === "\\") { - relativePath = relativePath.replaceAll("\\", "/"); - } - - const line = `export { ${schemaDeclExports - .map(stringifyExportItem) - .join(", ")} } from './${relativePath}';`; - - return line; - }); + const schemaLines = Object.keys(schemaExports[schema].items).map( + (itemPath) => { + const schemaDeclExports = schemaExports[schema].items[itemPath]; + if (schemaDeclExports.length === 0) { + return ""; + } + + let relativePath = relative(schemaPath, itemPath); + // Fix Windows-style paths in import line + if (sep === "\\") { + relativePath = relativePath.replaceAll("\\", "/"); + } + + const line = `export { ${schemaDeclExports + .map(stringifyExportItem) + .join(", ")} } from './${relativePath}';`; + + return line; + }, + ); const schemaIndexFile: FileContents = { declarations: [