diff --git a/.changeset/long-phones-stand.md b/.changeset/long-phones-stand.md new file mode 100644 index 00000000..884bc7f1 --- /dev/null +++ b/.changeset/long-phones-stand.md @@ -0,0 +1,5 @@ +--- +'vite-plugin-kit-routes': patch +--- + +manage kit-route cli for vite.config.ts config file diff --git a/packages/vite-plugin-kit-routes/src/lib/ast.spec.ts b/packages/vite-plugin-kit-routes/src/lib/ast.spec.ts new file mode 100644 index 00000000..c58949ba --- /dev/null +++ b/packages/vite-plugin-kit-routes/src/lib/ast.spec.ts @@ -0,0 +1,52 @@ +import { describe, expect, it } from 'vitest' + +import { getExportsFromFile } from './ast.js' + +describe('getExportsFromFile', () => { + it('should find default export', () => { + const code = ` + const config = { foo: 'bar' } + export default config + ` + const result = getExportsFromFile(code) + expect(result).toBeDefined() + expect(result.type).toBe('Identifier') + expect(result.name).toBe('config') + }) + + it('should find named export', () => { + const code = ` + const config = { foo: 'bar' } + export const myConfig = config + ` + const result = getExportsFromFile(code, 'myConfig') + expect(result).toBeDefined() + expect(result.type).toBe('Identifier') + expect(result.name).toBe('config') + }) + + it('should handle re-exported named exports', () => { + const code = ` + const config = { foo: 'bar' } + export { config as myConfig } + ` + const result = getExportsFromFile(code, 'myConfig') + expect(result).toBeDefined() + expect(result).toBe('config') + }) + + it('should return null for non-existent export', () => { + const code = ` + const config = { foo: 'bar' } + export default config + ` + const result = getExportsFromFile(code, 'nonExistent') + expect(result).toBeNull() + }) + + it('should handle invalid code gracefully', () => { + const code = 'invalid code' + const result = getExportsFromFile(code) + expect(result).toBeNull() + }) +}) diff --git a/packages/vite-plugin-kit-routes/src/lib/ast.ts b/packages/vite-plugin-kit-routes/src/lib/ast.ts index 4f7c86bf..1761f2bb 100644 --- a/packages/vite-plugin-kit-routes/src/lib/ast.ts +++ b/packages/vite-plugin-kit-routes/src/lib/ast.ts @@ -115,6 +115,54 @@ export const getActionsOfServerPages = (pathFile: string) => { return { actions, withLoad } } +export const getExportsFromFile = (code: string, exportName?: string) => { + try { + const codeParsed = parse(code) + let result: any = null + + visit(codeParsed, { + visitExportNamedDeclaration(path) { + if (exportName) { + // Looking for a specific named export + const specifiers = path.node.specifiers + if (specifiers) { + specifiers.forEach((specifier) => { + if (specifier.exported.name === exportName && specifier.local) { + result = specifier.local.name + } + }) + } + + const declaration = path.node.declaration + if (declaration?.type === 'VariableDeclaration') { + declaration.declarations.forEach((declaration) => { + if ( + declaration.type === 'VariableDeclarator' && + declaration.id.type === 'Identifier' && + declaration.id.name === exportName + ) { + result = declaration.init + } + }) + } + } + return false + }, + visitExportDefaultDeclaration(path) { + if (!exportName) { + result = path.node.declaration + } + return false + }, + }) + + return result + } catch (error) { + formatError(error, 'config file') + return null + } +} + const formatError = (error: unknown, fullPath: string) => { if (error instanceof Error) { if (error.message.includes('Unexpected token (')) { diff --git a/packages/vite-plugin-kit-routes/src/lib/bin.ts b/packages/vite-plugin-kit-routes/src/lib/bin.ts index dac18883..1bed86da 100644 --- a/packages/vite-plugin-kit-routes/src/lib/bin.ts +++ b/packages/vite-plugin-kit-routes/src/lib/bin.ts @@ -5,6 +5,7 @@ import { Command } from 'commander' import { green, Log } from '@kitql/helpers' import { getRelativePackagePath, read } from '@kitql/internals' +import { getExportsFromFile } from './ast.js' import { run } from './plugin.js' const program = new Command() @@ -13,21 +14,23 @@ const log = new Log('kit-routes') async function loadConfigFromFile(filePath: string, exportName?: string) { try { const resolvedPath = path.resolve(process.cwd(), filePath) - const configModule = await import(resolvedPath) + const code = read(resolvedPath) + if (!code) { + log.error(`Could not read file: ${resolvedPath}`) + return null + } - if (exportName) { - if (!configModule[exportName]) { + const result = getExportsFromFile(code, exportName) + if (!result) { + if (exportName) { log.error(`There is no 'export const ${exportName}' in '${filePath}'`) - return null + } else { + log.error(`There is no default export in '${resolvedPath}'`) } - return configModule[exportName] - } - - if (!configModule.default) { - log.error(`There is no default export in '${resolvedPath}'`) return null } - return configModule.default + + return result } catch (error) { return null } @@ -38,6 +41,8 @@ async function loadConfig(configPath?: string) { const [filePath, exportName] = configPath.split('#') const userConfig = await loadConfigFromFile(filePath, exportName) if (userConfig) return userConfig + // If config set, but not found, return null + return null } // Try vite.config.ts with _kitRoutesConfig @@ -73,9 +78,8 @@ program log.info(` Config object should look like this: ${green(`import { kitRoutes, type Options } from 'vite-plugin-kit-routes' - import type { KIT_ROUTES } from '$lib/ROUTES' - - export const _kitRoutesConfig: Options = { + + export const _kitRoutesConfig: Options = { // ... }`)} `) diff --git a/packages/vite-plugin-kit-routes/src/lib/plugins.spec.ts b/packages/vite-plugin-kit-routes/src/lib/plugins.spec.ts index b6cdf047..809e2c71 100644 --- a/packages/vite-plugin-kit-routes/src/lib/plugins.spec.ts +++ b/packages/vite-plugin-kit-routes/src/lib/plugins.spec.ts @@ -307,6 +307,7 @@ describe('getFilesUnder', () => { expect(getFilesUnder(location)).toMatchInlineSnapshot(` [ "ROUTES.ts", + "ast.spec.ts", "ast.ts", "bin.ts", "format.ts",