Skip to content

Commit

Permalink
chore: improve output structure
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbbreuer committed Nov 27, 2024
1 parent b5ffe42 commit 4e0296a
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 83 deletions.
5 changes: 3 additions & 2 deletions fixtures/output/0002.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import type { BunPlugin } from 'bun';
import type { DtsGenerationOption } from '@stacksjs/dtsx';
import { generate } from '@stacksjs/dtsx';

export { generate }
export type { DtsGenerationOption };
export type { DtsGenerationOption }
export declare function dts(options?: DtsGenerationOption): BunPlugin;

export { generate }

export default dts;
3 changes: 2 additions & 1 deletion fixtures/output/0006.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Collection } from '@stacksjs/collections';

export declare let quotes: Collection<string[]>;

export {
align,
box,
Expand Down Expand Up @@ -59,6 +61,5 @@ export {
white,
yellow,
} from 'kolorist'
export declare let quotes: Collection<string[]>;

export * as kolorist from 'kolorist'
5 changes: 3 additions & 2 deletions fixtures/output/0007.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { CAOptions, CertificateOptions, GenerateCertReturn, TlsOption } from './types';
import { default as forge, pki, tls } from 'node-forge';

export { forge, pki, tls }
export declare interface Cert {
certificate: string
privateKey: string
Expand All @@ -13,4 +12,6 @@ export declare function createRootCA(options: CAOptions): Promise<GenerateCertRe
export declare function generateCertificate(options: CertificateOptions): Promise<GenerateCertReturn>;
export declare function addCertToSystemTrustStoreAndSaveCert(cert: Cert, caCert: string, options?: TlsOption): Promise<string>;
export declare function storeCertificate(cert: Cert, options?: TlsOption): string;
export declare function storeCACertificate(caCert: string, options?: TlsOption): string;
export declare function storeCACertificate(caCert: string, options?: TlsOption): string;

export { forge, pki, tls }
5 changes: 3 additions & 2 deletions fixtures/output/0009.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { actionsPath } from '@stacksjs/path';

export { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep, toNamespacedPath }
declare type ParsedPath,
relative,
resolve,
Expand All @@ -16,4 +15,6 @@ export declare function userActionsPath(path?: string, options?: { relative: , t
export declare function builtUserActionsPath(path?: string, options?: { relative: , boolean }): string;
export declare function homeDir(path?: string): string;
export declare function libraryEntryPath(type: LibraryType): string;
export declare function examplesPath(type?: 'vue-components' | 'web-components'): string;
export declare function examplesPath(type?: 'vue-components' | 'web-components'): string;

export { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep, toNamespacedPath }
5 changes: 3 additions & 2 deletions fixtures/output/exports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import type { SomeOtherType } from '@stacksjs/types';
import { dtsConfig } from './config';
import { generate, something as dts } from './generate';

export type { SomeOtherType }
export type { BunRegisterPlugin } from 'bun'

export { generate, dtsConfig, type BunPlugin }
export type { SomeOtherType };
export type { BunRegisterPlugin } from 'bun';
export { config } from './config'

export * from './extract'
Expand Down
2 changes: 1 addition & 1 deletion fixtures/output/type.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { DtsGenerationOption } from '@stacksjs/dtsx';

export type { DtsGenerationOption };
export type { DtsGenerationOption }
export declare type AuthStatus = 'authenticated' | 'unauthenticated'

export type ComplexUnionIntersection =
Expand Down
141 changes: 68 additions & 73 deletions src/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -616,93 +616,75 @@ function extractCompleteObjectContent(value: string): string | null {
*/
function formatOutput(state: ProcessingState): string {
const imports = new Set<string>()
const declarations: string[] = []
const exports: string[] = []
const defaultExports: string[] = []
const exportAllStatements: string[] = []

// Deduplicate and format imports
state.dtsLines
.filter(line => line.startsWith('import'))
.forEach(imp => imports.add(imp.replace(/;+$/, '')))

// Get all non-import lines, clean up semicolons and comments
const declarations = state.dtsLines
.filter(line => !line.startsWith('import'))
.map((line) => {
// Remove any standalone comment lines
if (line.trim().startsWith('/*') || line.trim().startsWith('*') || line.trim().startsWith('//')) {
return ''
}

// Clean up any multiple semicolons and ensure all declarations end with one
const trimmed = line.trim()
if (!trimmed)
return ''

// Don't add semicolons to export * statements or when one already exists
if (trimmed.startsWith('export *') || trimmed.endsWith(';')) {
return trimmed
}

// Add semicolon to type exports that don't have one
if (trimmed.startsWith('export type')) {
return `${trimmed};`
}

return trimmed.replace(/;+$/, ';')
})
.filter(line => line.trim()) // Remove empty lines after comment removal
// Process all lines and categorize them
state.dtsLines.forEach((line) => {
const trimmed = line.trim()
if (!trimmed)
return

// Add default exports from state.defaultExports
const defaultExports = Array.from(state.defaultExports)
.map(exp => exp.trim().replace(/;+$/, ';'))
if (trimmed.startsWith('import')) {
imports.add(trimmed.replace(/;+$/, ''))
}
else if (trimmed.startsWith('export {')) {
exports.push(trimmed)
}
else if (trimmed.startsWith('export default')) {
defaultExports.push(trimmed)
}
else if (trimmed.startsWith('export *')) {
exportAllStatements.push(trimmed)
}
else {
declarations.push(trimmed)
}
})

// Organize declarations by type
const exportAllStatements = declarations.filter(line => line.trim().startsWith('export *'))
const otherDeclarations = declarations.filter(line => !line.trim().startsWith('export *'))
// Add default exports from state
Array.from(state.defaultExports)
.forEach(exp => defaultExports.push(exp.trim().replace(/;+$/, ';')))

// Construct the output with proper spacing
// Construct the output with proper ordering
const parts: string[] = []

// Add imports with a line break after if there are any
// 1. Add imports
if (imports.size > 0) {
parts.push(
...Array.from(imports).map(imp => `${imp};`),
'',
)
parts.push(...Array.from(imports).map(imp => `${imp};`), '')
}

// 2. Add declarations
if (declarations.length > 0) {
parts.push(...declarations)
}

// Add other declarations
if (otherDeclarations.length > 0) {
parts.push(...otherDeclarations)
// 3. Add regular exports
if (exports.length > 0) {
if (parts.length > 0)
parts.push('')
parts.push(...exports)
}

// Position export * statements based on whether there's a default export
// 4. Add export * statements
if (exportAllStatements.length > 0) {
if (defaultExports.length > 0) {
// Add export * statements before default export
if (parts.length > 0) {
parts.push('')
}
parts.push(...exportAllStatements)
}
else {
// Add export * statements at the end
if (parts.length > 0) {
parts.push('')
}
parts.push(...exportAllStatements)
}
if (parts.length > 0)
parts.push('')
parts.push(...exportAllStatements)
}

// Add default exports last if there are any
// 5. Add default exports last
if (defaultExports.length > 0) {
if (parts.length > 0) {
if (parts.length > 0)
parts.push('')
}
parts.push(...defaultExports)
}

// Clean up and return
// Clean up comments and join
return parts
.map(line => line.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '')) // Remove comments
.map(line => line.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, ''))
.join('\n')
.trim()
}
Expand Down Expand Up @@ -2032,14 +2014,27 @@ function handleTypeImports(types: string, module: string, state: ImportTrackingS
state.typeImports.set(module, new Set())
}

types.split(',').forEach((type) => {
const [original, alias] = type.trim().split(/\s+as\s+/).map(t => t.trim())
// Only track the import source, don't mark as used yet
state.typeImports.get(module)!.add(original)
state.typeExportSources.set(original, module)
// Split types by comma and handle multiline
const typesList = types.split(',').map(type => type.trim()).filter(Boolean).map((type) => {
// Remove line breaks and normalize whitespace
return type.replace(/\s+/g, ' ').trim()
})

typesList.forEach((type) => {
const [original, alias] = type.split(/\s+as\s+/).map(t => t.trim())

// Skip if empty or invalid
if (!original || original === '{' || original === '}')
return

// Remove 'type ' prefix if present
const cleanType = original.replace(/^type\s+/, '')

state.typeImports.get(module)!.add(cleanType)
state.typeExportSources.set(cleanType, module)

if (alias) {
state.valueAliases.set(alias, original)
state.valueAliases.set(alias, cleanType)
}
})
}
Expand Down

0 comments on commit 4e0296a

Please sign in to comment.