Skip to content

Commit

Permalink
chore: wip
Browse files Browse the repository at this point in the history
chore: wip
  • Loading branch information
chrisbbreuer committed Jan 18, 2025
1 parent ccf56ac commit 8dc5b80
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .vscode/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ destructurable
dtsx
entrypoints
heroicons
iconify
localtunnels
lockb
mkcert
Expand All @@ -27,12 +28,16 @@ Postcardware
postcompile
prefetch
preinstall
shikijs
socio
softprops
Solana
stacksjs
tlsx
twoslash
typecheck
unconfig
unocss
unplugin
unref
upath
Expand Down
5 changes: 4 additions & 1 deletion eslint.config.js → eslint.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ESLintConfig } from '@stacksjs/eslint-config'
import stacks from '@stacksjs/eslint-config'

export default stacks({
const config: ESLintConfig = stacks({
stylistic: {
indent: 2,
quotes: 'single',
Expand All @@ -13,3 +14,5 @@ export default stacks({
'fixtures/**',
],
})

export default config
12 changes: 6 additions & 6 deletions fixtures/output/0005.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ declare function createProcessingState(): ProcessingState;
declare function createImportTrackingState(): ImportTrackingState;
declare function indentMultilineType(type: string, baseIndent: string, isLast: boolean): string;
declare function inferValueType(value: string): string;
declare function inferArrayType(value: string, state?: ProcessingState, preserveLineBreaks): string;
declare function inferComplexObjectType(value: string, state?: ProcessingState, indentLevel): string;
declare function inferArrayType(value: string, state?: ProcessingState, preserveLineBreaks?: boolean): string;
declare function inferComplexObjectType(value: string, state?: ProcessingState, indentLevel?: number): string;
declare function inferConstArrayType(value: string, state?: ProcessingState): string;
declare function inferConstType(value: string, state: ProcessingState): string;
declare function inferTypeFromDefaultValue(defaultValue: string): string;
Expand Down Expand Up @@ -48,16 +48,16 @@ declare function processModuleBlock(cleanDeclaration: string, declarationText: s
export declare function processSpecificDeclaration(declarationWithoutComments: string, fullDeclaration: string, state: ProcessingState): void;
declare function processSourceFile(content: string, state: ProcessingState): void;
declare function processImports(line: string, state: ImportTrackingState): void;
declare function processType(declaration: string, isExported): string;
declare function processType(declaration: string, isExported?: boolean): string;
declare function processTypeExport(line: string, state: ProcessingState): void;
declare function processVariable(declaration: string, isExported: boolean, state: ProcessingState): string;
declare function processFunction(declaration: string, usedTypes?: Set<string>, isExported): string;
declare function processFunction(declaration: string, usedTypes?: Set<string>, isExported?: boolean): string;
declare function getCleanDeclaration(declaration: string): string;
declare function processGeneratorFunction(declaration: string): string;
declare function processInterface(declaration: string, isExported): string;
declare function processInterface(declaration: string, isExported?: boolean): string;
declare function processModule(declaration: string): string;
declare function processObjectMethod(declaration: string): ProcessedMethod;
declare function processObjectProperties(content: string, state?: ProcessingState, indentLevel): Array<{ key: string, value: string }>;
declare function processObjectProperties(content: string, state?: ProcessingState, indentLevel?: number): Array<{ key: string, value: string }>;
declare function processPropertyValue(value: string, indentLevel: number, state?: ProcessingState): string;
declare function trackTypeUsage(content: string, state: ImportTrackingState): void;
declare function trackValueUsage(content: string, state: ImportTrackingState): void;
Expand Down
9 changes: 7 additions & 2 deletions fixtures/output/0007.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ export declare interface Cert {
privateKey: string
}
export declare function generateRandomSerial(verbose?: boolean): string;
export declare function calculateValidityDates(options: { validityDays?: number, validityYears?: number, notBeforeDays?: number, verbose?: boolean }): void;
export declare function calculateValidityDates(options: {
validityDays?: number
validityYears?: number
notBeforeDays?: number
verbose?: boolean
}): void;
declare function generateCertificateExtensions(options: CertificateOptions): void;
export declare function createRootCA(options: CAOptions): Promise<GenerateCertReturn>;
export declare function createRootCA(options: CAOptions = {}): Promise<GenerateCertReturn>;
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;
Expand Down
13 changes: 12 additions & 1 deletion fixtures/output/0009.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
export declare function loadConfig<T>({ name, cwd, defaultConfig, endpoint, headers): Promise<T>;
import type { Config } from './types';

export declare function loadConfig<T>({
name,
cwd,
defaultConfig,
endpoint,
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
}: Config<T>): Promise<T>;

export * from './types'
export * from './utils'
8 changes: 4 additions & 4 deletions fixtures/output/imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { something as dts } from './generate';

export declare function actionsPath(path?: string): string;
export declare function corePath(path?: string): string;
export declare function frameworkPath(path?: string, options?: { relative?: , boolean, cwd?: , string }): string;
export declare function frameworkPath(path?: string, options?: { relative?: boolean, cwd?: string }): string;
export declare function storagePath(path?: string): string;
export declare function projectPath(filePath, options?: { relative: , boolean }): string;
export declare function userActionsPath(path?: string, options?: { relative: , true }): string;
export declare function builtUserActionsPath(path?: string, options?: { relative: , boolean }): string;
export declare function projectPath(filePath = '', options?: { relative: boolean }): string;
export declare function userActionsPath(path?: string, options?: { relative: true }): string;
export declare function builtUserActionsPath(path?: string, options?: { relative: boolean }): string;
export declare function homeDir(path?: string): string;
export declare type LibraryType = 'vue-components' | 'web-components' | 'functions'
export declare function libraryEntryPath(type: LibraryType): string;
Expand Down
97 changes: 92 additions & 5 deletions src/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ function extractFunctionSignature(declaration: string, verbose?: boolean | strin
rest = restAfterGenerics.trim()
debugLog('signature-after-generics', `Remaining content: ${rest}`, verbose)

// Extract parameters
// Extract parameters with full object type support
const { params, rest: restAfterParams } = extractParams(rest, verbose)
rest = restAfterParams.trim()
debugLog('signature-after-params', `Remaining content: ${rest}`, verbose)
Expand All @@ -205,10 +205,20 @@ function extractFunctionSignature(declaration: string, verbose?: boolean | strin
const { returnType } = extractReturnType(rest)
debugLog('signature-return', `Extracted return type: ${returnType}`, verbose)

// Handle object parameter types
let processedParams = params
if (params.includes('{')) {
const objectMatch = params.match(/\{([^}]+)\}:\s*([^)]+)/)
if (objectMatch) {
const [, paramList, typeRef] = objectMatch
processedParams = `{ ${paramList} }: ${typeRef}`
}
}

const signature = {
name,
generics,
params,
params: processedParams,
returnType,
}

Expand Down Expand Up @@ -2046,12 +2056,89 @@ function processVariable(declaration: string, isExported: boolean, state: Proces
* Process function declarations with overloads
*/
function processFunction(declaration: string, usedTypes?: Set<string>, isExported = true, verbose?: boolean | string[]): string {
const normalizedDeclaration = declaration.trim().replace(/\s+/g, ' ')
const normalizedDeclaration = declaration.trim()
const signature = extractFunctionSignature(normalizedDeclaration, verbose)

// Clean up params
// Clean up all parameters - both object destructuring and regular parameters
if (signature.params) {
signature.params = cleanParameterTypes(signature.params)
// Handle regular parameters
if (!signature.params.includes('{')) {
const cleanedParams = signature.params
.split(',')
.map((param) => {
const paramTrimmed = param.trim()
if (!paramTrimmed)
return null

// Handle parameters with default values and type annotations
if (paramTrimmed.includes('=')) {
const [paramPart] = paramTrimmed.split(/\s*=\s*/)
const paramWithoutDefault = paramPart.trim()

// If there's an explicit type annotation, use it
if (paramWithoutDefault.includes(':')) {
const [paramName, paramType] = paramWithoutDefault.split(':').map(p => p.trim())
return `${paramName}?: ${paramType}`
}

// Infer type from default value if no explicit type
const defaultValue = paramTrimmed.split(/\s*=\s*/)[1].trim()
const inferredType = defaultValue === '{}'
? paramTrimmed.includes(':') ? paramTrimmed.split(':')[1].trim().split('=')[0].trim() : 'Record<string, unknown>'
: defaultValue === ''
? 'string'
: typeof eval(defaultValue)

return `${paramWithoutDefault}?: ${inferredType}`
}

// Handle parameters without default values
if (paramTrimmed.includes(':')) {
const [paramName, paramType] = paramTrimmed.split(':').map(p => p.trim())
const isOptional = paramName.endsWith('?')
const cleanName = paramName.replace(/\?$/, '')
return `${cleanName}${isOptional ? '?' : ''}: ${paramType}`
}

return paramTrimmed
})
.filter(Boolean)
.join(', ')

signature.params = cleanedParams
}
// Handle object destructuring (existing code)
else {
const paramMatch = declaration.match(/\{([^}]+)\}:\s*([^)]+)/)
if (paramMatch) {
const [, paramList, typeRef] = paramMatch

const cleanedParams = paramList
.split(',')
.map((param) => {
const paramTrimmed = param.trim()
if (!paramTrimmed)
return null

const hasDefaultValue = paramTrimmed.includes('=')
const [paramName] = paramTrimmed.split(/\s*=\s*/)
const nameOnly = paramName.trim()

const isOptional = hasDefaultValue || nameOnly.endsWith('?')
const cleanName = nameOnly.replace(/\?$/, '')

if (cleanName.includes(':')) {
const [name, type] = cleanName.split(':').map(p => p.trim())
return `${name}${isOptional ? '?' : ''}: ${type}`
}

return `${cleanName}${isOptional ? '?' : ''}`
})
.filter(Boolean)

signature.params = `{ ${cleanedParams.join(', ')} }: ${typeRef.trim()}`
}
}
}

// Preserve type predicates and complete return types
Expand Down

0 comments on commit 8dc5b80

Please sign in to comment.