diff --git a/bin/cli.ts b/bin/cli.ts index fafeba8..5aa7e19 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -1,8 +1,8 @@ +import type { DtsGenerationConfig, DtsGenerationOption } from '../src/types' +import { resolve } from 'node:path' import { CAC } from '@stacksjs/cli' import { version } from '../package.json' import { generate } from '../src/generate' -import type { DtsGenerationOption, DtsGenerationConfig } from '../src/types' -import { resolve } from 'node:path' const cli = new CAC('dtsx') @@ -22,7 +22,7 @@ cli .option('--root ', 'Root directory of the project', { default: defaultOptions.root }) .option('--entrypoints ', 'Entry point files (comma-separated)', { default: defaultOptions.entrypoints?.join(','), - type: [String] + type: [String], }) .option('--outdir ', 'Output directory for generated .d.ts files', { default: defaultOptions.outdir }) .option('--keep-comments', 'Keep comments in generated .d.ts files', { default: defaultOptions.keepComments }) @@ -48,7 +48,8 @@ cli // } await generate(config) - } catch (error) { + } + catch (error) { console.error('Error generating .d.ts files:', error) process.exit(1) } diff --git a/build.ts b/build.ts index 8e28219..5df2d4d 100644 --- a/build.ts +++ b/build.ts @@ -13,7 +13,8 @@ await Bun.build({ try { await generateDeclarationsFromFiles() console.log('Generated declarations') -} catch (error) { +} +catch (error) { console.error('Error generating declarations:', error) } diff --git a/bun.lockb b/bun.lockb index a721972..a4a2aea 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/eslint.config.js b/eslint.config.js index 8667c7b..d24b632 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -10,6 +10,6 @@ export default stacks({ jsonc: true, yaml: true, ignores: [ - 'fixtures/**' - ] + 'fixtures/**', + ], }) diff --git a/package.json b/package.json index 40e1bee..44dbccc 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "module": "./dist/index.js", "types": "./dist/index.d.ts", "bin": { - "dts": "./dist/cli.js" + "dtsx": "./dist/cli.js" }, "files": [ "dist" @@ -56,39 +56,11 @@ "docs:preview": "vitepress preview docs" }, "devDependencies": { - "@eslint-community/eslint-plugin-eslint-comments": "^4.4.0", - "@eslint/markdown": "^6.2.0", - "@prettier/plugin-xml": "^3.4.1", "@stacksjs/cli": "^0.65.0", "@stacksjs/development": "^0.65.0", - "@stacksjs/eslint-config": "^3.7.3-stacks-1.12", - "@stacksjs/eslint-plugin": ">=0.1.3", - "@stacksjs/storage": "^0.66.0", - "@stylistic/eslint-plugin": "^2.9.0", + "@stacksjs/eslint-config": "^3.8.1-beta.2", "@types/bun": "^1.1.11", - "@typescript-eslint/eslint-plugin": "^8.10.0", - "@typescript-eslint/parser": "^8.10.0", - "@vitest/eslint-plugin": "^1.1.7", "c12": "^2.0.1", - "eslint": "^9.12.0", - "eslint-config-flat-gitignore": "^0.3.0", - "eslint-flat-config-utils": "^0.4.0", - "eslint-merge-processors": "^0.1.0", - "eslint-plugin-antfu": "^2.7.0", - "eslint-plugin-command": "^0.2.6", - "eslint-plugin-format": ">=0.1.2", - "eslint-plugin-import-x": "^4.3.1", - "eslint-plugin-jsdoc": "^50.4.3", - "eslint-plugin-jsonc": "^2.16.0", - "eslint-plugin-n": "^17.11.1", - "eslint-plugin-no-only-tests": "^3.3.0", - "eslint-plugin-perfectionist": "^3.9.1", - "eslint-plugin-regexp": "^2.6.0", - "eslint-plugin-toml": "^0.11.1", - "eslint-plugin-unicorn": "^55.0.0", - "eslint-plugin-unused-imports": "^4.1.4", - "eslint-plugin-yml": "^1.14.0", - "local-pkg": "^0.5.0", "neverthrow": "^8.0.0", "tinyglobby": "^0.2.9", "vitepress": "^1.4.1" diff --git a/pkgx.yaml b/pkgx.yaml index b51a299..587759a 100644 --- a/pkgx.yaml +++ b/pkgx.yaml @@ -1,2 +1,2 @@ dependencies: - bun.sh: ^1.1.30 + bun.sh: ^1.1.31 diff --git a/scripts/generate-dts.ts b/scripts/generate-dts.ts index feb5db5..a5b519c 100644 --- a/scripts/generate-dts.ts +++ b/scripts/generate-dts.ts @@ -1,4 +1,4 @@ -import path from 'path' +import path from 'node:path' import { generate } from '../src' console.log('Generating output...', path.join(__dirname, '..')) diff --git a/scripts/generate-output.ts b/scripts/generate-output.ts index 4977c0f..3327d34 100644 --- a/scripts/generate-output.ts +++ b/scripts/generate-output.ts @@ -1,4 +1,4 @@ -import path from 'path' +import path from 'node:path' import { generate } from '../src' console.log('Generating output...', path.join(__dirname, '..')) diff --git a/src/extract.ts b/src/extract.ts index 85c5381..7ddbda1 100644 --- a/src/extract.ts +++ b/src/extract.ts @@ -4,8 +4,8 @@ import { formatComment, formatDeclarations } from './utils' export async function extractTypeFromSource(filePath: string): Promise { const fileContent = await readFile(filePath, 'utf-8') let declarations = '' - let usedTypes = new Set() - let importMap = new Map>() + const usedTypes = new Set() + const importMap = new Map>() // Handle re-exports const reExportRegex = /export\s*(?:\*|\{[^}]*\})\s*from\s*['"]([^'"]+)['"]/g @@ -25,7 +25,7 @@ export async function extractTypeFromSource(filePath: string): Promise { const processImports = (imports: string | undefined, isType: boolean) => { if (imports) { - const types = imports.replace(/[{}]/g, '').split(',').map(t => { + const types = imports.replace(/[{}]/g, '').split(',').map((t) => { const [name, alias] = t.split(' as ').map(s => s.trim()) return { name: name.replace(/^type\s+/, ''), alias: alias || name.replace(/^type\s+/, '') } }) @@ -37,12 +37,14 @@ export async function extractTypeFromSource(filePath: string): Promise { processImports(namedImports1, !!isTypeImport) processImports(namedImports2, !!isTypeImport) - if (defaultImport1) importMap.get(from)!.add(defaultImport1) - if (defaultImport2) importMap.get(from)!.add(defaultImport2) + if (defaultImport1) + importMap.get(from)!.add(defaultImport1) + if (defaultImport2) + importMap.get(from)!.add(defaultImport2) } // Handle exports with comments - const exportRegex = /(\/\*\*[\s\S]*?\*\/\s*)?(export\s+(?:async\s+)?(?:function|const|let|var|class|interface|type)\s+\w+[\s\S]*?)(?=\n\s*(?:\/\*\*|export|$))/g; + const exportRegex = /(\/\*\*[\s\S]*?\*\/\s*)?(export\s+(?:async\s+)?(?:function|const|let|var|class|interface|type)\s+\w[\s\S]*?)(?=\n\s*(?:\/\*\*|export|$))/g let match while ((match = exportRegex.exec(fileContent)) !== null) { const [, comment, exportStatement] = match @@ -54,13 +56,14 @@ export async function extractTypeFromSource(filePath: string): Promise { const functionSignature = formattedExport.match(/^.*?\)/) if (functionSignature) { let params = functionSignature[0].slice(functionSignature[0].indexOf('(') + 1, -1) - params = params.replace(/\s*=\s*[^,)]+/g, '') // Remove default values + params = params.replace(/\s*=[^,)]+/g, '') // Remove default values const returnType = formattedExport.match(/\):\s*([^{]+)/) formattedExport = `export declare function ${formattedExport.split('function')[1].split('(')[0].trim()}(${params})${returnType ? `: ${returnType[1].trim()}` : ''};` } - } else if (formattedExport.startsWith('export const') || formattedExport.startsWith('export let') || formattedExport.startsWith('export var')) { + } + else if (formattedExport.startsWith('export const') || formattedExport.startsWith('export let') || formattedExport.startsWith('export var')) { formattedExport = formattedExport.replace(/^export\s+(const|let|var)/, 'export declare $1') - formattedExport = formattedExport.split('=')[0].trim() + ';' + formattedExport = `${formattedExport.split('=')[0].trim()};` } declarations += `${formattedComment}\n${formattedExport}\n\n` @@ -83,7 +86,7 @@ export async function extractTypeFromSource(filePath: string): Promise { }) if (importDeclarations) { - declarations = importDeclarations + '\n' + declarations + declarations = `${importDeclarations}\n${declarations}` } // Apply final formatting diff --git a/src/generate.ts b/src/generate.ts index b968e90..64398b0 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -1,10 +1,10 @@ import type { DtsGenerationConfig, DtsGenerationOption } from './types' -import { rm, mkdir } from 'node:fs/promises' -import { join, relative, dirname, parse } from 'node:path' +import { mkdir, rm } from 'node:fs/promises' +import { dirname, join, parse, relative } from 'node:path' +import { glob } from 'tinyglobby' import { config } from './config' -import { writeToFile, getAllTypeScriptFiles, checkIsolatedDeclarations } from './utils' import { extractTypeFromSource } from './extract' -import { glob } from 'tinyglobby' +import { checkIsolatedDeclarations, getAllTypeScriptFiles, writeToFile } from './utils' export async function generateDeclarationsFromFiles(options?: DtsGenerationConfig): Promise { // console.log('Generating declaration files...', options) @@ -24,7 +24,8 @@ export async function generateDeclarationsFromFiles(options?: DtsGenerationConfi let files: string[] if (options?.entrypoints) { files = await glob(options.entrypoints, { cwd: options.root ?? options.cwd, absolute: true }) - } else { + } + else { files = await getAllTypeScriptFiles(options?.root) } @@ -46,13 +47,15 @@ export async function generateDeclarationsFromFiles(options?: DtsGenerationConfi await writeToFile(outputPath, fileDeclarations) // console.log(`Generated ${outputPath}`) - } else { + } + else { console.warn(`No declarations extracted for ${file}`) } } // console.log('Declaration file generation complete') - } catch (error) { + } + catch (error) { console.error('Error generating declarations:', error) } } diff --git a/src/utils.ts b/src/utils.ts index 527ea84..586d4b1 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ +import type { DtsGenerationConfig } from './types' import { readdir, readFile } from 'node:fs/promises' import { extname, join } from 'node:path' import { config } from './config' -import { type DtsGenerationConfig } from './types' export async function writeToFile(filePath: string, content: string): Promise { await Bun.write(filePath, content) @@ -26,14 +26,15 @@ export async function checkIsolatedDeclarations(options?: DtsGenerationConfig): const tsconfig = JSON.parse(tsconfigContent) return tsconfig.compilerOptions?.isolatedDeclarations === true - } catch (error) { + } + catch (error) { return false } } export function formatDeclarations(declarations: string): string { const lines = declarations.split('\n') - const formattedLines = lines.map(line => { + const formattedLines = lines.map((line) => { // Trim trailing spaces line = line.trimEnd() @@ -61,20 +62,22 @@ export function formatDeclarations(declarations: string): string { result = result.replace(/\/\*\*\n([^*]*)(\n \*\/)/g, (match, content) => { const formattedContent = content .split('\n') - .map((line: string) => ` *${line.trim() ? ' ' + line.trim() : ''}`) + .map((line: string) => ` *${line.trim() ? ` ${line.trim()}` : ''}`) .join('\n') return `/**\n${formattedContent}\n */` }) - return result.trim() + '\n' + return `${result.trim()}\n` } export function formatComment(comment: string): string { const lines = comment.split('\n') return lines .map((line, index) => { - if (index === 0) return '/**' - if (index === lines.length - 1) return ' */' + if (index === 0) + return '/**' + if (index === lines.length - 1) + return ' */' const trimmedLine = line.replace(/^\s*\*?\s?/, '').trim() return ` * ${trimmedLine}` }) diff --git a/test/dts.test.ts b/test/dts.test.ts index d3260bc..e9f2966 100644 --- a/test/dts.test.ts +++ b/test/dts.test.ts @@ -1,8 +1,8 @@ -import { describe, it, expect, afterEach } from 'bun:test' -import { join } from 'node:path' -import { generate } from '../src/generate' import type { DtsGenerationOption } from '../src/types' +import { afterEach, describe, expect, it } from 'bun:test' import { rm } from 'node:fs/promises' +import { join } from 'node:path' +import { generate } from '../src/generate' describe('dts-generation', () => { const testDir = join(__dirname, '../fixtures') @@ -119,7 +119,8 @@ describe('dts-generation', () => { // Clean up generated files try { await rm(generatedDir, { recursive: true, force: true }) - } catch (error) { + } + catch (error) { console.error('Error cleaning up generated files:', error) } })