api #

static analysis for TypeScript and Svelte

34 modules · 257 declarations

Modules
#

AliasLostDiagnostic
#

diagnostics.ts view source

{ aliasName: string; file: string; message: string; severity: "error" | "warning"; kind: "alias_lost"; line?: number | undefined; column?: number | undefined; } import {AliasLostDiagnostic} from 'svelte-docinfo/diagnostics.js';

An exported type alias loses its name at use sites.

The alias's right-hand side (an indexed access or conditional — z.infer<typeof S>, valibot's InferOutput) resolves to a pre-existing interned type that TypeScript never retroactively stamps an alias symbol on, so unannotated positions document the expansion instead of the name. Fires only where nothing self-heals: a loss the alias registry recovers (typeInfo emits {kind: 'reference', name} at use sites) is suppressed, as are literal-only unions (z.enum outputs) and brand-like intersections (.brand()) — readable degradations with no author-side fix worth demanding. @nodocs on the declaration suppresses. The author-side escape for a flagged alias is a nominal symbol, e.g. interface Foo extends z.infer<typeof S> {} where applicable.

Always warning, query-time category (recomputed each query()).

aliasName

Name of the alias whose right-hand side resolves to a nameless type.

type string

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "alias_lost"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

AliasRegistry
#

typescript-extract-type-json.ts view source

AliasRegistry import type {AliasRegistry} from 'svelte-docinfo/typescript-extract-type-json.js';

Identity-keyed registry of exported alias-lost type aliases, consulted by the tree builder at nameless positions behind written-name recovery. Built per analysis cycle by buildAliasRegistry (typescript-alias-registry.ts); undefined wherever no pre-pass ran (registry recovery disabled, written recovery unaffected).

byType

Checker type identity → the winning alias (compareStrings name-then-module tie-break).

type Map<Type, AliasRegistryEntry>

byMemberSet

Union member-set key (unionMemberSetKey) → the winning alias, for registered unions only. Consulted at optional-widened positions, where a null-bearing union flattens with the widening undefined into a type object the identity lookup can never match — the registered members survive by identity inside the widened union, so the set matches exactly.

type Map<string, AliasRegistryEntry>

warnedAliasLost

Alias declarations the alias_lost warning has fired for this cycle. Re-export synthesis re-analyzes canonical declarations (synthesizeCrossFileAlias, within-file renames), so one declaration can reach warnAliasLost from several analyzing sites in a cycle — this set dedupes to one warning per declaration. It rides on the registry because the registry is the one cycle-scoped object every warn site already holds (the warning is gated on a registry being in hand).

type Set<TypeAliasDeclaration>

AliasRegistryEntry
#

AliasRegistrySource
#

typescript-alias-registry.ts view source

AliasRegistrySource import type {AliasRegistrySource} from 'svelte-docinfo/typescript-alias-registry.js';

One emitted module offered to the pre-pass: the program's source file (for a Svelte module, the svelte2tsx *virtual* — program.getSourceFile returns undefined for a raw .svelte id, so the caller resolves through virtualPath) and its ModuleJson.path, which becomes AliasRegistryEntry.module and ships verbatim on recovered reference nodes — analyzeCore derives it with the same extractPath call that mints ModuleJson.path, and normalizeModulePathsInTypes deliberately skips the module key, so a caller passing anything else (an absolute path, a virtual-suffixed one) would publish it unrewritten.

sourceFile

type SourceFile

modulePath

type string

AnalysisLanguageService
#

typescript-program.ts view source

AnalysisLanguageService import type {AnalysisLanguageService} from 'svelte-docinfo/typescript-program.js';

Persistent language-service handle that drives a ts.Program incrementally.

Owns the LS, document registry, and a `Map<path, {content, version, scriptKind}>` of "owned" files (real source files + virtuals pushed via setFile). Files not in the owned map are read from disk on demand by the LS host.

Each setFile(path, entry) bumps the version when content or script kind differs from cache, so the next getProgram() reparses only the changed file. Calling getProgram() with no version bumps returns the same ts.Program as the previous call (reference-stable when nothing changed).

see also

  • ``createAnalysisSession`` in session.ts for the high-level API that wraps this with content cache + svelte virtual cache + analysis pipeline.

getProgram

Get the current ts.Program.

Returns the same reference as the previous call when no setFile / deleteFile invalidated state in between. Returns a fresh ts.Program (sharing parsed ASTs for unchanged files via the document registry) when versions changed.

type (): Program

returns Program

throws

  • Error - if the underlying LS returned undefined (should not happen

getCompilerOptions

The merged compiler options the service was constructed with — parsed tsconfig with the caller's compilerOptions overrides applied per-key.

Cheap accessor over the construction-time loadTsconfig result; prefer it over getProgram().getCompilerOptions() when only the options are needed — getProgram() forces the LS to sync and parse every root file.

Treat the returned object as read-only: it is the same reference the LS host serves via getCompilationSettings, so mutating it would desync consumers (e.g., the session's default import resolver) from the checker.

type (): CompilerOptions

returns CompilerOptions

setFile

Set or replace a file's content (real path or virtual path).

  • New file: added to the owned map with version 1.
  • Existing file with identical content and script kind: no-op (version unchanged).
  • Existing file with new content or script kind: version bumped.

type (path: string, entry: VirtualFileEntry): boolean

path

type string

entry

returns boolean

true when the file was added or its version bumped, false on no-op.

deleteFile

Remove a file from the owned set.

type (path: string): boolean

path

type string
returns boolean

true when the file was tracked, false when it was unknown.

hasFile

Whether the given path is currently tracked.

type (path: string): boolean

path

type string
returns boolean

dispose

Release LS resources.

Calls ts.LanguageService.dispose() and clears the owned map. The service must not be used after disposal.

type (): void

returns void

AnalysisLanguageServiceOptions
#

typescript-program.ts view source

AnalysisLanguageServiceOptions import type {AnalysisLanguageServiceOptions} from 'svelte-docinfo/typescript-program.js';

inheritance

documentRegistry?

Optional document registry for AST sharing across services.

Pass an explicit registry to share parsed source files when running multiple language services (e.g., LSP integration). Defaults to a fresh registry per service when omitted.

type DocumentRegistry

AnalysisLog
#

log.ts view source

also exported from index.ts

AnalysisLog import type {AnalysisLog} from 'svelte-docinfo/log.js';

Minimal logger interface for analysis functions.

Intentionally narrow so that both @fuzdev/fuz_util's Logger class and Vite's built-in logger satisfy it without adapters or casts.

examples

// Stderr logger for CLI usage const log: AnalysisLog = { info: (msg) => console.error(msg), warn: (msg) => console.error(`warning: ${msg}`), error: (msg) => console.error(`error: ${msg}`), };

info

type (msg: string): void

msg

type string
returns void

warn

type (msg: string): void

msg

type string
returns void

error

type (msg: string): void

msg

type string
returns void

AnalysisProgramOptions
#

typescript-program.ts view source

AnalysisProgramOptions import type {AnalysisProgramOptions} from 'svelte-docinfo/typescript-program.js';

inheritance

virtualFiles?

Virtual files to seed the program, keyed by virtual path.

Used to include svelte2tsx transformed outputs alongside real source files, enabling full type resolution for Svelte components via the checker. SvelteVirtualFile satisfies the entry shape structurally, so transform results can be passed as entries directly.

On a LanguageService, virtuals can also be added/replaced/removed after construction via setFile / deleteFile.

type Map<string, VirtualFileEntry>

AnalysisSession
#

session.ts view source

also exported from index.ts

AnalysisSession import type {AnalysisSession} from 'svelte-docinfo/session.js';

Persistent analysis handle.

Concurrency: not safe across overlapping calls. Serialize externally (each caller awaits the previous setFile/setFiles before starting the next). The LS underneath is sync, but the resolver phase awaits I/O for async resolvers (Vite/Rollup), so the session does cross await boundaries.

Cache-hit semantics: per-entry, all-or-nothing. The implementation must not split the guarantee across separate caches (e.g. transform-cache hit + lex re-run). The match criterion is mode-discriminated:

  • lex+resolve mode: existing.content === incoming.content AND existing.resolverIdentity === incoming.resolverIdentity.
  • pre-resolved mode: existing.content === incoming.content AND arraysShallowEqual(existing.preResolvedDepsSnapshot, incoming.dependencies).

Mode flips (an entry previously ingested as lex+resolve now arrives with dependencies, or vice versa) always cache-miss.

Deferred resolutions: a cache hit reuses the entry's dependency edges, but an import specifier that resolved to nothing isn't a settled answer — its target may be ingested later, and the file that changes then is the *dep*, not the importer, so the importer would stay a cache hit with a missing edge. A setFiles that adds paths therefore retries the unresolved specifiers of already-owned entries and updates their edges in place, retiring any resolver_failed that has since resolved. This is the one way an entry changes without being re-ingested; it consumes no resolver work for files whose imports all resolved, and none at all for pre-resolved callers, whose edges are theirs to declare.

Promise resolution: setFile / setFiles resolve only after the serial LS push (phase 3) completes for every file in the batch. Awaiting the returned promise is sufficient — no separate flush step.

Owned ⊇ emitted: ingest is additive and ungated — any file can be pushed, and owned entries are served to the checker from memory before the disk fallback, so non-source files (unsaved buffers, virtual-only helpers, configs) can shape type resolution in the modules that import them. query() gates the *module set* through isSource: only owned files under sourceOptions.sourcePaths and not matching exclude emit a ModuleJson. The gate emits no diagnostics — query() logs the gated count as info, and list() reports the full owned set for introspection. By default the session completes the owned set itself: contextClosure ingests the in-root non-source dependency closure (e.g. internal/ modules public files import) so those files are version-tracked rather than pinned at their first disk read.

setFile

Ingest one file's content into the session. Idempotent on cache hit.

type (file: SourceFileInfo, opts?: SetFileOptions | undefined): Promise<SetFileResult>

file

opts?

optional
returns Promise<SetFileResult>

{changed, diagnostics}changed: false indicates a cache-hit no-op where the cached ingest diagnostics are returned.

setFiles

Ingest a batch of files. Additive — never removes; use deleteFile for removal. Cache hits are folded into the result with changed: false.

type (files: readonly SourceFileInfo[], opts?: SetFileOptions | undefined): Promise<SetFilesResult>

files

type readonly SourceFileInfo[]

opts?

optional
returns Promise<SetFilesResult>

deleteFile

Drop a file from the session and evict from the LS.

type (id: string): Promise<void>

id

type string
returns Promise<void>

has

Whether the given file ID is currently owned by the session.

type (id: string): boolean

id

type string
returns boolean

list

Snapshot of currently-owned file IDs (sort order is insertion order).

type (): readonly string[]

returns readonly string[]

query

Run a two-phase analysis pass against the current owned set, gated by isSource — owned files outside sourcePaths (or matching exclude) provide checker context but emit no module (see "Owned ⊇ emitted" above).

type (opts?: QueryOptions | undefined): { modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[]; diagnostics: ({ ...; } | ... 14 more ... | { ...; })[]; }

opts?

optional
returns { modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceL...

analyzed modules and analysis-pass diagnostics. Ingest diagnostics from prior setFile/setFiles calls are NOT included here — concat with those returns for the full picture.

throws

  • Error - if `onDuplicates: 'throw'` and duplicates exist

allIngestDiagnostics

Concatenated ingest-time diagnostics across every owned entry — the cumulative view of every setFile/setFiles return, kept current as entries are added/replaced/deleted.

Lets long-lived consumers (Vite plugin, LSP) publish the full ingest picture without tracking per-batch returns themselves. Cheap: walks the owned map.

type (): ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

returns ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

getProgram

The LS-backed ts.Program, for incremental consumers doing their own checker work over analyzed declarations (e.g., a docgen provider converting ts.Types into its own structured model).

Freshness caveat: returns whatever the most recent ingest produced — the same reference as the prior call when no file version bumped, else a fresh program reusing unchanged ASTs via the document registry. A retained reference goes stale after any setFile / setFiles / deleteFile; re-call after mutating. Subject to the session's concurrency contract above; invalid after dispose().

type (): Program

returns Program

dispose

Release LS resources and clear the owned set. The session must not be used after disposal.

type (): void

returns void

AnalysisSessionOptions
#

session.ts view source

also exported from index.ts

AnalysisSessionOptions import type {AnalysisSessionOptions} from 'svelte-docinfo/session.js';

Options for createAnalysisSession.

documentRegistry flows through to the underlying LanguageService only. tsconfig and compilerOptions drive the LS's construction-time loadTsconfig parse — the session's only tsconfig parse. The lazy default ImportResolver reuses the LS's merged options via getCompilerOptions(), so module resolution and the checker see the same merge semantics — user-supplied compilerOptions override parsed tsconfig keys, but never bypass the tsconfig.json file requirement. The parse is a construction-time snapshot: a tsconfig.json edit mid-session is not picked up — create a new session.

projectRoot and virtualFiles from the LS options shape are excluded — the session derives projectRoot from sourceOptions and manages svelte2tsx virtuals internally per file.

inheritance

extends: Omit< AnalysisLanguageServiceOptions, 'projectRoot' | 'virtualFiles' >

sourceOptions

Module source options for path extraction and source filtering.

Must be a fully-constructed ModuleSourceOptions — the session re-runs normalizeSourceOptions (idempotent) but does not apply any defaults. Pass through createSourceOptions(projectRoot, overrides?) to merge with DEFAULT_SOURCE_OPTIONS. (The SourceOptionsOverrides ergonomic shape — exclude-callback form included — exists only on AnalyzeFromFilesOptions.sourceOptions and the Vite plugin, where the defaults merge happens inside createSourceOptions.)

type ModuleSourceOptions

resolveImport?

Session-default custom import resolver used when no per-call override is supplied — a bare ResolveImportFn or a token-paired ImportResolver (see ResolveImport). A bare function is normalized once at construction, so its synthesized identity is stable for the session's lifetime (cache reuse works). When omitted, the session lazily constructs the TS+tsconfig default on first use.

type ResolveImport

contextClosure?

Own the in-root non-source dependency closure as context files (default true).

After each ingest batch, the session reads from disk any file the batch's imports resolved to that is under projectRoot, fails isSource (outside sourcePaths or matching exclude — e.g. the src/lib/internal/ convention), has no node_modules/dot-directory segments, and has an analyzer type — transitively, until the closure converges. Context files are owned but never emit modules (query() gates them), so this changes no output; what it changes is *freshness*: an owned file's edit version-bumps the LS, whereas a disk-resolved file is read once and pinned for the session's lifetime. Watch-style consumers (the Vite plugin) gate their watchers on isSource(file) || session.has(file), so context-file edits trigger re-analysis and public output tracks internal types live.

Context batches always ingest in lex+resolve mode (their edges exist only to walk the closure — context files emit nothing), so a fully pre-resolved consumer whose files import in-root non-source paths constructs the default resolver after all. Context ingest diagnostics surface via allIngestDiagnostics(), not the batch return, and setFiles results stay keyed by the caller's input IDs. Unreadable candidates are skipped silently (the LS disk fallback covers them).

Context files are never evicted: once owned they stay owned (and, under the Vite plugin, watched) for the session's lifetime, even when no importer remains.

Set false only when the caller supplies every file the checker needs (the internal analyze() wrapper does): TS/JS context is covered by the LS disk fallback either way, but a gated .svelte dependency resolves only through the closure's ingest (svelte2tsx runs there — the disk fallback serves raw Svelte the checker can't parse), so analyzeFromFiles() keeps the closure on despite being one-shot.

type boolean

log?

Optional logger for session-level messages.

type AnalysisLog

analyze
#

analyze.ts view source

also exported from index.ts

(options: AnalyzeOptions): Promise<{ modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[]; diagnostics: ({ ...; } | ... 14 more ... | { ...; })[]; }> import {analyze} from 'svelte-docinfo/analyze.js';

Analyze library source files and extract metadata (one-shot).

Wraps a single-use AnalysisSession. For repeated analyses of the same source set (e.g., a Vite plugin reacting to file edits), use createAnalysisSession directly.

options

returns

Promise<{ modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...;...

analyzed modules (sorted alphabetically) + concatenated ingest + query diagnostics

throws

  • Error - if `sourceOptions` validation fails or `tsconfig.json` is

analyzeCore
#

analyze-core.ts view source

(inputs: AnalyzeCoreInputs): { modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[]; diagnostics: ({ ...; } | ... 14 more ... | { ...; })[]; } import {analyzeCore} from 'svelte-docinfo/analyze-core.js';

inputs

returns

{ modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceL...

AnalyzeCoreInputs
#

analyze-core.ts view source

AnalyzeCoreInputs import type {AnalyzeCoreInputs} from 'svelte-docinfo/analyze-core.js';

Inputs to analyzeCore. The caller (one-shot wrapper or session.query) is responsible for normalizing sourceOptions, obtaining the program, and pre-transforming Svelte files into svelteVirtualFiles.

transformFailedIds carries the IDs of .svelte files whose svelte2tsx transform threw at ingest. The dispatch synthesizes a placeholder ModuleJson (partial: true, empty declarations) for each so consumers see the file's existence in modules even though analysis couldn't run. Identifying these via a sibling Set keeps svelteVirtualFiles a clean "files we can analyze" map; the failure side-channel doesn't pollute it.

sourceFiles

type readonly SourceFileInfo[]

sourceOptions

type ModuleSourceOptions

program

type Program

svelteVirtualFiles

type ReadonlyMap<string, SvelteVirtualFile>

transformFailedIds?

Svelte file IDs whose svelte2tsx transform failed at ingest.

type ReadonlySet<string>

contextSvelteFiles?

Gated Svelte files (owned but failing isSource — the internal/ convention) whose virtuals are in svelteVirtualFiles. Analyzed only when an emitted component alias references them, as canonical-fill context for resolveComponentAliases — their modules never emit and their analysis diagnostics are dropped (partial on the canonical propagates to the filled alias instead).

type readonly SourceFileInfo[]

onDuplicates?

type OnDuplicates

log?

type AnalysisLog

analyzeDeclaration
#

typescript-exports.ts view source

(symbol: Symbol, sourceFile: SourceFile, ctx: ExtractContext): DeclarationAnalysis import {analyzeDeclaration} from 'svelte-docinfo/typescript-exports.js';

Analyze a TypeScript symbol and extract rich metadata.

This is a high-level function that combines TSDoc parsing with TypeScript type analysis to produce complete declaration metadata. Suitable for use in documentation generators, IDE integrations, and other tooling.

symbol

the TypeScript symbol to analyze

type Symbol

sourceFile

the source file containing the symbol

type SourceFile

ctx

the extraction pass's context (checker, diagnostics, externality predicate, alias registry)

returns

DeclarationAnalysis

complete declaration metadata including docs, types, and parameters, plus nodocs flag

analyzeExports
#

typescript-exports.ts view source

(sourceFile: SourceFile, ctx: ExtractContext, options: ModuleSourceOptions): ModuleExportsAnalysis import {analyzeExports} from 'svelte-docinfo/typescript-exports.js';

Analyze all exports from a TypeScript source file.

Extracts the module-level comment via extractModuleComment (skipped for svelte2tsx virtual files — see the inline note), star exports via extractStarExports, and all exported declarations with complete metadata. Handles re-exports by:

  • Same-name re-exports: tracked in reExports for alsoExportedFrom building
  • Renamed re-exports: included as new declarations with aliasOf metadata
  • Star exports (export * from): tracked in starExports for namespace-level info
  • Direct external re-exports: tracked in externalReExports/externalStarExports (specifier as written; import-then-export and source-chained forms stay silent)

This is a mid-level function (above the individual extract* helpers, below analyze) suitable for building documentation, API explorers, or analysis tools. For standard SvelteKit library layouts, use createSourceOptions(process.cwd()).

sourceFile

the TypeScript source file to analyze

type SourceFile

ctx

the extraction pass's context (see ExtractContext) — analyzeModule and analyzeSvelteModule construct it via createExtractContext; a direct caller owns the construction, deciding every field explicitly (tests use mockExtractContext). Its isExternalFile must be derived from the same options passed here: this function derives its own path-keyed twin (createIsExternalPath) from options, and the two externality axes are expected to agree

options

module source options for path extraction in re-exports

returns

ModuleExportsAnalysis

module comment, declarations, re-exports (source + external), and star exports (source + external)

analyzeFromFiles
#

analyze.ts view source

also exported from index.ts

(options: AnalyzeFromFilesOptions): Promise<{ modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; ... 4 more ...; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[]; diagnostics: ({ ...; } | ... 14 more ... | { ...; })[]; }> import {analyzeFromFiles} from 'svelte-docinfo/analyze.js';

Analyze a library from files on disk with automatic file discovery.

Recommended high-level API for one-shot use (CLI, build-time generation):

  1. DiscoverydiscoverSourceFiles (exports-first, glob fallback)
  2. Ingest — push discovered files into a single-use session
  3. Analysissession.query()

options

returns

Promise<{ modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...;...

analyzed modules + concatenated ingest, discovery, and query diagnostics

throws

  • Error - if `sourceOptions` validation fails or `tsconfig.json` is missing

AnalyzeFromFilesOptions
#

analyze.ts view source

also exported from index.ts

AnalyzeFromFilesOptions import type {AnalyzeFromFilesOptions} from 'svelte-docinfo/analyze.js';

Options for analyzeFromFiles.

see also

  • ``AnalyzeOptions`` for the build-tool-integration API where you supply sourceFiles and a fully-formed sourceOptions: ModuleSourceOptions directly.

projectRoot

Absolute path to project root directory.

type string

sourceOptions?

Partial overrides for default source options (SvelteKit src/lib layout).

type SourceOptionsOverrides

onDuplicates?

Behavior when duplicate declaration names are found across modules.

type OnDuplicates

log?

Optional logger for status and diagnostic messages.

type AnalysisLog

include?

Glob patterns to include (relative to projectRoot; an absolute pattern inside the root relativizes, an out-of-root one throws — see normalizeIncludePatterns).

Filters glob-based discovery. Providing include under the default discovery: 'auto' collapses the chain to glob immediately; combining with discovery: 'exports' throws.

Explicit patterns also widen the source scope: their static bases join sourceOptions.sourcePaths (see widenSourcePathsForInclude), so include-discovered files outside the configured source paths still emit modules, with paths relative to the widened set's common root. A pattern with no static base ('**\/*.ts', a literal root file) scopes the whole project root as source and logs an info line; an out-of-root base ('../other/**') throws.

When omitted, the glob fallback derives an include from sourceOptions.sourcePaths via deriveIncludePatterns, so custom sourcePaths (e.g., ['packages/foo']) survive the fallback instead of silently defaulting to src/lib.

type string[]

exclude?

Glob patterns to exclude — takes precedence over sourceOptions.exclude (no merge between the two). An array replaces the default patterns wholesale; the callback form extends them without restating them ((defaults) => [...defaults, '**\/*.gen.ts'] — see ExcludeOption). The callback always receives the built-in defaults, even when sourceOptions.exclude is also set (that value is superseded whole). The always-on baseline (node_modules + dot-directories below a matched source path) applies beneath it and is unaffected by overrides.

type ExcludeOption

resolveDependencies?

Whether to resolve import dependencies (default true).

When false, the session uses a no-op resolver that always returns null, so ModuleJson.dependencies / dependents stay empty. analyzeFromFiles's discovery layer does not pre-populate SourceFileInfo.dependencies, so the session's pre-resolved fast path isn't reachable through this API — to exercise it, drive analyze or createAnalysisSession directly with files whose dependencies field is already filled in by your build tool.

type boolean

default `true`

resolveImport?

Optional custom import resolver — a bare ResolveImportFn or a token-paired ImportResolver (see ResolveImport). One-shot use doesn't benefit from a stable cache identity, so the bare function form is the natural choice here; for long-lived consumers (Vite plugin, LSP) construct an ImportResolver with a stable identity and pass it via createAnalysisSession so cache hits survive across calls.

Cannot be combined with resolveDependencies: false — resolution is then off, so the resolver would never be consulted; passing both throws.

type ResolveImport

discovery?

Discovery strategy for source files.

type Discovery

default 'auto'

distDir?

Dist directory name for exports-based discovery.

type string

default 'dist'

analyzeModule
#

analyze-core.ts view source

(sourceFile: SourceFileInfo & { dependents?: readonly string[] | undefined; }, program: Program, options: ModuleSourceOptions, diagnostics: ({ symbolName: string; ... 5 more ...; column?: number | undefined; } | ... 14 more ... | { ...; })[], log?: AnalysisLog | undefined, aliasRegistry?: AliasRegistry | undefined): { ...; } | undefined import {analyzeModule} from 'svelte-docinfo/analyze-core.js';

Analyze a single non-Svelte source file and extract module metadata.

sourceFile

type SourceFileInfo & { dependents?: readonly string[] | undefined; }

program

type Program

options

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

log?

optional

aliasRegistry?

optional

returns

{ path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

AnalyzeOptions
#

analyze.ts view source

also exported from index.ts

AnalyzeOptions import type {AnalyzeOptions} from 'svelte-docinfo/analyze.js';

Options for analyze.

Requires pre-loaded SourceFileInfo arrays — use analyzeFromFiles for automatic file discovery and loading from disk, or createAnalysisSession for incremental use.

sourceFiles

Source files to analyze (must have content loaded). Files outside sourceOptions.sourcePaths or matching exclude emit no module — they still feed the checker as in-memory content, so passing extra files (unsaved buffers, virtual-only helpers) shapes type resolution without polluting the output.

type readonly SourceFileInfo[]

sourceOptions

Module source options for path extraction and source filtering.

type ModuleSourceOptions

onDuplicates?

Behavior when duplicate declaration names are found across modules.

type OnDuplicates

log?

Optional logger for status and diagnostic messages.

type AnalysisLog

resolveImport?

Optional custom import resolver for the session default — a bare ResolveImportFn or a token-paired ImportResolver (see ResolveImport). For one-shot analyze() the session is single-use, so a bare function is the natural form; pass an ImportResolver with a stable identity only if you have a reason to control the cache scope.

type ResolveImport

AnalyzeResultJson
#

analyze-core.ts view source

also exported from index.ts

{ modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceL... import {AnalyzeResultJson} from 'svelte-docinfo/analyze-core.js';

Result of analyze, analyzeFromFiles, and AnalysisSession.query.

Modules sorted alphabetically by path. Diagnostics are query-time (analysis-pass) diagnostics only when produced by session.query; one-shot wrappers concatenate ingest + query diagnostics into this same array.

Schema-validated round-trip

The envelope is a Zod schema (AnalyzeResultJson) — both fields default to [], so JSON.stringify(result, compactReplacer) strips empty arrays on the wire and AnalyzeResultJson.parse(JSON.parse(json)) restores them. Consumers programmatically ingesting analysis JSON should parse through the schema to get defaults restored; raw-JSON consumers (e.g., jq) treat missing keys as null-equivalent (jq '.diagnostics | length' returns 0 on {}) and don't need the parse step.

Construction sites (one-shot wrappers, session.query) hand back hand-built objects without re-running .parse() — the inner modules and diagnostics arrays are already Zod-validated upstream, and the envelope schema is the type contract, not a validation gate.

See AnalyzeResultJsonWire for the serialized input-side shape published on virtual:svelte-docinfo.

modules

type { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

AnalyzeResultJsonWire
#

analyze-core.ts view source

also exported from index.ts

AnalyzeResultJsonWire import type {AnalyzeResultJsonWire} from 'svelte-docinfo/analyze-core.js';

Serialized wire shape of an analysis result, as published by the Vite plugin on virtual:svelte-docinfo — the input-side counterpart to AnalyzeResultJson (the validated output of .parse()).

The two fields are deliberately asymmetric:

  • modules is ModuleJsonInput (the z.input of ModuleJson) because the plugin runs it through compactReplacer, which strips .default([]) arrays and .default(false) booleans. Default-bearing fields therefore arrive undefined.
  • diagnostics is the output Diagnostic — the plugin serializes it without the replacer, and Diagnostic has no defaults to strip, so the array is always present and the shape matches runtime exactly.

Consumers restore defaults by parsing through AnalyzeResultJson.

Note this describes the Vite virtual module specifically. The CLI runs the whole envelope through compactReplacer, so its JSON may additionally omit an empty diagnostics array — CLI consumers should parse through AnalyzeResultJson rather than assume this shape.

modules

type { path: string; declarations?: ({ kind: "function"; name: string; returnType?: string | undefined; returnTypeInfo?: TypeJson | undefined; returnDescription?: string | undefined; ... 16 more ...; genericParams?: { ...; }[] | undefined; } | ... 7 more ... | { ...; })[] | undefined; ... 7 more ...; partial?: boolean | ...

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

AnalyzerType
#

source.ts view source

also exported from index.ts

AnalyzerType import type {AnalyzerType} from 'svelte-docinfo/source.js';

Analyzer type for source files.

  • 'typescript' — TypeScript/JS files analyzed via TypeScript compiler API
  • 'svelte' — Svelte components analyzed via svelte2tsx + TypeScript compiler API
  • 'css' — CSS files included as modules with no declarations
  • 'json' — JSON files included as modules with no declarations

analyzeSvelteModule
#

svelte.ts view source

(sourceFile: SourceFileInfo & { dependents?: readonly string[] | undefined; }, modulePath: string, checker: TypeChecker, options: ModuleSourceOptions, diagnostics: ({ ...; } | ... 14 more ... | { ...; })[], program: Program, virtualFile: SvelteVirtualFile, aliasRegistry?: AliasRegistry | undefined): ModuleAnalysis | undefined import {analyzeSvelteModule} from 'svelte-docinfo/svelte.js';

Analyze a Svelte module using checker-backed analysis.

Requires the svelte2tsx virtual output to be included in the TypeScript program (via createAnalysisProgram({ virtualFiles })). Provides full type resolution for:

  • Imported prop types (let {x}: ImportedProps = $props())
  • <script module> exports (constants, types, re-exports)
  • Star exports and re-exports from Svelte files

sourceFile

the original Svelte source file

type SourceFileInfo & { dependents?: readonly string[] | undefined; }

modulePath

module path relative to source root; feeds ModuleJson.path and the component name, never Diagnostic.file (which is project-root-relative — a different base)

type string

checker

TypeScript type checker (from the program containing virtual files)

type TypeChecker

options

module source options for path extraction

diagnostics

diagnostics collector for non-fatal issues

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

program

TypeScript program containing the virtual file

type Program

virtualFile

pre-transformed virtual file data

aliasRegistry?

the analyzed set's alias registry (see buildAliasRegistry), or undefined when no pre-pass ran

optional

returns

ModuleAnalysis | undefined

module analysis with declarations, re-exports, and star exports; undefined if the virtual file is not found in the program

analyzeTypescriptModule
#

typescript-exports.ts view source

(sourceFileInfo: SourceFileInfo & { dependents?: readonly string[] | undefined; }, tsSourceFile: SourceFile, modulePath: string, ctx: ExtractContext, options: ModuleSourceOptions): ModuleAnalysis import {analyzeTypescriptModule} from 'svelte-docinfo/typescript-exports.js';

Analyze a TypeScript file and extract module metadata.

Wraps analyzeExports and adds dependency information via extractDependencies from the source file info if available.

This is a high-level function suitable for building documentation or library metadata. For lower-level analysis, use analyzeExports directly.

sourceFileInfo

the source file info (from file system, build pipeline, or other source)

type SourceFileInfo & { dependents?: readonly string[] | undefined; }

tsSourceFile

TypeScript source file from the program

type SourceFile

modulePath

the module path (relative to source root)

type string

ctx

the extraction pass's context (see analyzeExports for the construction contract)

options

module source options for path extraction

returns

ModuleAnalysis

module metadata and re-export information

applyHeritageExternalTypes
#

typescript-extract-shared.ts view source

(declaration: DeclarationJsonBuild, heritageTypes: readonly ExpressionWithTypeArguments[], ctx: ExtractContext): void import {applyHeritageExternalTypes} from 'svelte-docinfo/typescript-extract-shared.js';

Set a declaration's externalTypes from its own heritage entries — the interface/class counterpart of filterDocumentedProperties' annotation walk, and the one place the two heritage-bearing extractors express it.

Interfaces and classes enumerate own members only, so nothing is *filtered* — what the field records there is the external types the heritage composition reaches whose contributions members therefore never enumerates: interface Props extends HTMLButtonAttributes records the bag, directly or through a local base chain, exactly as the same interface annotating $props() records it on the component. Local bases reached and fully enumerated nowhere are the extends field's business, not this one.

Only extends entries are passed by either caller: an interface has no other clause kind, and a class's implements adds no members.

declaration

heritageTypes

type readonly ExpressionWithTypeArguments[]

ctx

returns

void

mutates

  • declaration — sets `externalTypes` when the walk finds any, left absent when not

applyToDeclaration
#

tsdoc.ts view source

(declaration: MemberJsonBuild | DeclarationJsonBuild, tsdoc: TsdocParsedComment | undefined, isMember?: boolean): void import {applyToDeclaration} from 'svelte-docinfo/tsdoc.js';

Apply parsed TSDoc metadata to a declaration.

Consolidates the common pattern of assigning TSDoc fields to declarations, with conditional assignment for array fields (only if non-empty).

declaration

declaration object to update

type MemberJsonBuild | DeclarationJsonBuild

tsdoc

parsed TSDoc comment (if available)

type TsdocParsedComment | undefined

isMember

whether declaration is a member of a container; function *members* carry defaultValue (the documented behavior when a callback is omitted) while top-level function declarations never do

type boolean
default false

returns

void

mutates

  • declaration — adds docComment, deprecatedMessage, internalMessage, examples, seeAlso, throws, since, mutates, defaultValue fields

applyVirtualFiles
#

typescript-program.ts view source

(host: CompilerHost, virtualFiles: ReadonlyMap<string, VirtualFileEntry>): ReadonlyMap<string, VirtualFileEntry> import {applyVirtualFiles} from 'svelte-docinfo/typescript-program.js';

Decorate a compiler host so virtualFiles shadow the filesystem — getSourceFile (honoring per-entry scriptKind), fileExists, readFile, and directoryExists.

Entries are copied to minimal {content, scriptKind} records so the host's closures don't retain larger caller objects (a SvelteVirtualFile's source map, say) for the program's lifetime. The copied map is returned so callers layering module resolution on top (.svelte specifier mapping) can key it off the same snapshot instead of re-capturing the caller's map. The entry set is fixed at decoration time — the returned ReadonlyMap and the directory index are built in the same pass, so no host answer can be served from a staler view of the set than another (a LanguageService is the mutable counterpart; see createAnalysisLanguageService).

host

type CompilerHost

virtualFiles

type ReadonlyMap<string, VirtualFileEntry>

returns

ReadonlyMap<string, VirtualFileEntry>

the copied entries, keyed by path

mutates

  • host — replaces `getSourceFile`, `fileExists`, `readFile`, and

baselineExcludesForBase
#

source-config.ts view source

(base: string): string[] import {baselineExcludesForBase} from 'svelte-docinfo/source-config.js';

Anchor the baseline exclusion globs below a discovery base directory.

Anchoring is what preserves the escape hatch at discovery time: the ignores for base .hidden/src are .hidden/src/**\/node_modules/** etc., which don't match the base's own dot segment. '' anchors at the project root. Used as glob ignore by globFiles (per include-pattern base) and discoverFromExports (below the source dir).

base

type string

returns

string[]

buildAliasRegistry
#

typescript-alias-registry.ts view source

(sources: readonly AliasRegistrySource[], checker: TypeChecker): AliasRegistry import {buildAliasRegistry} from 'svelte-docinfo/typescript-alias-registry.js';

Build the alias registry for one analysis cycle.

Registration walks each source's export table and registers an export when it:

  • survives the svelte2tsx filters on virtuals (default and generated $$/__sveltets_ names skipped)
  • is declared in the file (star-projected bindings skipped, mirroring analyzeExports's locality rule)
  • resolves — through local export clauses, @nodocs-free ones only — to a TypeAliasDeclaration in the *same* file (a re-export of another module's alias registers from that module when it's emitted, and never when it's gated — gated aliases have no doc page for a reference to land on; merged value+type symbols select the type-space node via selectDeclarationNode)
  • is non-generic (instantiations are per-argument type objects — the declared type of a generic alias never matches a use site)
  • carries no @nodocs on either declaration of a merged pair
  • is alias-lost (isAliasLostType) and passes the safety gate

Ambiguity — two aliases over one lost type (type A = z.infer<typeof S> beside type B of the same, z.infer vs z.output, cross-module, type A = B over a lost B) resolves to a global single winner via compareStrings on name then module, so one type documents under one name everywhere (coherent cross-linking, deterministic regardless of iteration order). The member-set side index is derived from the settled winners, so the two indexes can't disagree.

sources

the emitted modules (Svelte modules via their virtuals — see AliasRegistrySource)

type readonly AliasRegistrySource[]

checker

the program's type checker (registry entries are valid exactly as long as this checker's types are)

type TypeChecker

returns

AliasRegistry

byKind
#

diagnostics.ts view source

also exported from index.ts

<K extends DiagnosticKind>(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | ... 14 more ... | { ...; })[], kind: K): (Extract<...> | ... 14 more ... | Extract<...>)[] import {byKind} from 'svelte-docinfo/diagnostics.js';

Get diagnostics of a specific kind, narrowed to the matching variant.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

kind

type K

returns

(Extract<{ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; }, { kind: K; }> | ... 14 more ... | Extract<...>)[]

generics

byKind<K extends DiagnosticKind>
K
constraint DiagnosticKind

ClassDeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "class"; extends: string[]; externalTypes: string[]; implements: string[]; members: ({ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; ... 4 more ...; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: number | un... import {ClassDeclarationJson} from 'svelte-docinfo/types.js';

A class declaration. Has members, extends, implements.

kind

type "class"

extends

Extended base class — 0 or 1 entries (TypeScript allows only one base). An array so every heritage field (extends, implements, externalTypes, InterfaceDeclarationJson.extends) shares one shape; consumers iterate heritage uniformly instead of branching on kind.

Verbatim text of this declaration's own heritage clause (as is implements), so it is spelled as this module wrote it and resolves in its scope — a local rename stays the local name, where externalTypes resolves renames because its walk crosses modules.

type string[]

see also

  • ``implements`` (this variant), InterfaceDeclarationJson.extends for the other verbatim heritage fields, externalTypes (this variant) for the resolved external reach.

externalTypes

External types the extends chain reaches whose contributions members never enumerates — the class counterpart of InterfaceDeclarationJson.externalTypes, descending through local base classes. implements contributes nothing: an implemented interface adds no members, the class declares its own.

Entry normalization (rename resolution, type-parameter substitution, text-dedupe, source order) matches TypeDeclarationJson.externalTypes.

type string[]

implements

Implemented interfaces.

type string[]

members

Class members: methods, properties, constructors, getters/setters — own members only, inherited members excluded whatever their origin.

type ({ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: nu...

alsoExportedFrom

Module paths (relative to sourceRoot) that re-export this declaration under the same name. The canonical declaration lives in this module's declarations array; these paths are additional import locations for the same thing.

The same edges appear from the re-exporting side as ModuleJson.reExports — use that when asking "what does this module re-export" instead of inverting these arrays. The two can disagree at the margins: a reExports entry whose canonical declaration is @nodocs (or whose module isn't in the analyzed set) has no back-link here.

Consumer note: To build a complete re-export map, scan two fields:

  1. alsoExportedFrom on each declaration — same-name re-exports
  2. aliasOf on declarations — renamed re-exports (separate declarations)

type string[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

aliasOf?

For renamed re-exports (export {foo as bar}), points to the original declaration. This declaration's name is the alias; aliasOf.name is the original name.

For renames out of the default slot (export {default as bar} from './x' where ./x is export default ...), aliasOf.name is 'default' — the canonical's actual symbol name. Consumers locate the canonical by (aliasOf.module, aliasOf.name).

Svelte component exception: when the source is a .svelte file (e.g., export {default as Foo} from './X.svelte'), the canonical's name is the component name (derived from the filename), so aliasOf.name is the component name ('X'), NOT 'default'. Consumers that branch on aliasOf.name === 'default' to detect default-rename should additionally check whether aliasOf.module ends with .svelte.

Different from alsoExportedFrom: aliases create new API surface names, while alsoExportedFrom tracks additional import paths for the same name.

type { module: string; name: string; }

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

ClassMemberDiagnostic
#

diagnostics.ts view source

{ className: string; memberName: string; file: string; message: string; severity: "error" | "warning"; kind: "class_member_failed"; line?: number | undefined; column?: number | undefined; } import {ClassMemberDiagnostic} from 'svelte-docinfo/diagnostics.js';

Class member analysis failed.

className

Name of the class.

type string

memberName

Name of the member that failed.

type string

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "class_member_failed"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

cleanComment
#

tsdoc.ts view source

(commentText: string): string | undefined import {cleanComment} from 'svelte-docinfo/tsdoc.js';

Clean raw JSDoc comment text by removing comment markers and leading asterisks.

Transforms /** ... *\/ style comments into clean text.

commentText

the raw comment text including /** and *\/ markers

type string

returns

string | undefined

cleaned comment text, or undefined if empty after cleaning

examples

cleanComment('/** Hello world *\/') // => 'Hello world' cleanComment('/**\n * Line 1\n * Line 2\n *\/') // => 'Line 1\nLine 2'

CliOptions
#

cli.ts view source

CliOptions import type {CliOptions} from 'svelte-docinfo/cli.js';

CLI options parsed from command line arguments.

include?

File patterns to include (undefined = use exports discovery or defaults).

Relative to the project root; an absolute pattern inside it relativizes, an out-of-root one throws.

type string[]

exclude?

File patterns to exclude (undefined = use defaults — test/spec files and internal/ directories).

When provided, fully replaces the defaults — no array merge. Passing a custom --exclude pattern drops the default test/spec/internal/ filters unless the caller re-includes them explicitly (the API's exclude-callback form has no CLI equivalent). The always-on baseline (node_modules + dot-directories below a source path) applies beneath it and is unaffected by overrides.

type string[]

output?

Output file path (undefined = stdout).

type string

resolveDependencies?

Whether to resolve dependencies. Mapped from the --no-resolve-dependencies flag (commander populates true by default; false when the flag is passed). Optional here so external callers can omit it; treated as true when undefined.

type boolean

discovery?

Discovery strategy (undefined = 'auto').

Mapped from --discovery <auto|exports|glob>.

type Discovery

distDir?

Dist directory name for exports-based discovery (undefined = 'dist').

type string

sourceDir?

Source directories, relative to project root or absolute inside it (undefined = ['src/lib']); an out-of-root entry throws.

Repeatable. Drives the implicit include glob in the glob-discovery fallback (via deriveIncludePatterns inside discoverSourceFiles) so custom source directories survive without needing an explicit --include.

type string[]

sourceRoot?

Source root for module path extraction, relative to project root or absolute inside it (undefined = single sourceDir or longest common prefix).

Module paths in output are stripped of <projectRoot>/<sourceRoot>/. Pass . (or "") to keep module paths project-relative — useful when sourceDir entries share no common prefix. The . form is normalized to "" inside normalizeSourceOptions.

type string

onDuplicates?

Behavior when duplicate declaration names are found across modules (undefined = emit duplicate_declaration diagnostic, no dispatch).

Duplicate detection always runs regardless of this option — the diagnostic is the data, this option is the dispatch action.

type "throw" | "warn"

only?

Glob patterns to filter the emitted modules array against ModuleJson.path (undefined = emit all analyzed modules).

Repeatable. Output-only filter: full-project analysis still runs so re-exports, dependents, and alsoExportedFrom stay correct against the complete owned set. Diagnostics aren't filtered — they may reference modules dropped from output.

type string[]

quiet?

Whether to suppress info messages to stderr. Treated as false when undefined.

type boolean

pretty?

Whether to pretty-print JSON output. Treated as false when undefined.

type boolean

compactReplacer
#

declaration-helpers.ts view source

also exported from index.ts

(key: string, value: unknown): unknown import {compactReplacer} from 'svelte-docinfo/declaration-helpers.js';

JSON replacer that strips Zod default values for compact serialization.

Strips empty arrays and false booleans — both are Zod .default() values restored on .parse(), so the round-trip is lossless for svelte-docinfo types. Assumes all boolean fields in the schema default to false — a true-defaulted boolean would need its false values preserved, breaking the round-trip.

One keyed exemption: value is never stripped. TypeJson's literal nodes carry data there ({kind: 'literal', value: false} is the literal type false, required by the schema), not a defaulted flag — no other output field is named value, and any future one must not be a false-defaulted boolean.

Root-value caveat: JSON.stringify([], compactReplacer) returns the JS undefined (not the string '[]'), and JSON.stringify(false, compactReplacer) returns the JS undefined too. Object-rooted callers (AnalyzeResultJson envelope, CLI output) don't hit this — empty inner arrays strip and AnalyzeResultJson.parse restores them on the consumer side. Array-rooted callers (Vite plugin, anyone splicing the JSON into a source template) must handle the empty case themselves before calling this; see vite.ts:updateOutputFromQuery for the pattern.

Two guard tests in declaration-helpers.test.ts lock this in:

  • every z.boolean().default in types.ts uses false — source-regex check that fails on a new z.boolean().default(true).
  • `parse → stringify(compactReplacer) → parse is a faithful round-trip across every variant` — exercises every variant and member through a full round-trip, catching regressions where a .default(false) or .default([]) is removed (or a new field is added that the replacer drops but Zod doesn't restore).

key

type string

value

type unknown

returns

unknown

examples

const result = await analyze({sourceFiles, sourceOptions}); const json = JSON.stringify(result, compactReplacer); // On the consumer side, restore Zod defaults: const restored = AnalyzeResultJson.parse(JSON.parse(json));

compareStrings
#

postprocess.ts view source

(a: string, b: string): number import {compareStrings} from 'svelte-docinfo/postprocess.js';

Case-insensitive string comparator for deterministic output ordering.

Case-folded comparison first (so Analyze and analyze sort together instead of all uppercase before all lowercase), then a code-unit tiebreak — so equal-ignoring-case strings still compare unequal and the result is an exact total order. Unlike localeCompare (host-locale/ICU-dependent, so byte-identical input can serialize in different orders on different machines), both passes use Unicode default mappings only and are environment-independent. All output ordering goes through this comparator — never bare localeCompare or default Array.prototype.sort.

a

type string

b

type string

returns

number

ComponentDeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "component"; externalTypes: string[]; props: { examples: string[]; seeAlso: string[]; throws: { description: string; type?: string | undefined; }[]; name: string; type: string; optional: boolean; bindable: boolean; ... 5 more ...; parameters?: { ...; }[] | undefined; }[]; ... 17 more ...; sourceLine?: number... import {ComponentDeclarationJson} from 'svelte-docinfo/types.js';

A Svelte component declaration. Has props, externalTypes, acceptsChildren.

kind

type "component"

externalTypes

External types whose properties are filtered out of props — the attribute bags a component forwards, such as HTMLButtonAttributes or SvelteHTMLElements['button'].

Covers every way props compose them: an intersection or union branch, a bare or indexed-access annotation, and interface Props extends Bag (directly or through a local base). Entries carry the written form with the same normalizations as TypeDeclarationJson.externalTypes: import renames at the definition site resolve to the exported name, and a type parameter bound inside the descent substitutes its written argument — interface A<T> extends HTMLAttributes<T> reached via `Props extends A<HTMLDivElement> records HTMLAttributes<HTMLDivElement>`. The component's *own* generics stay in scope and emit as written (HTMLAttributes<T> beside the genericParams documenting T). Each distinct bag appears once, in source order; a local name is used only when it hides a definition the walk cannot traverse (a mapped or conditional type). Names carry no module, so two distinct bags sharing an exported name collapse to one entry.

type string[]

see also

  • ``TypeDeclarationJson.externalTypes`` for the full entry contract, InterfaceDeclarationJson.externalTypes for the field on the props interface itself. Field shapes mirror TS syntax.

props

Svelte component props.

type { examples: string[]; seeAlso: string[]; throws: { description: string; type?: string | undefined; }[]; name: string; type: string; optional: boolean; bindable: boolean; deprecatedMessage?: string | undefined; ... 4 more ...; parameters?: { ...; }[] | undefined; }[]

acceptsChildren

Whether the component accepts children (explicit children prop, inherited, or implicit template usage).

type boolean

alsoExportedFrom

Module paths (relative to sourceRoot) that re-export this declaration under the same name. The canonical declaration lives in this module's declarations array; these paths are additional import locations for the same thing.

The same edges appear from the re-exporting side as ModuleJson.reExports — use that when asking "what does this module re-export" instead of inverting these arrays. The two can disagree at the margins: a reExports entry whose canonical declaration is @nodocs (or whose module isn't in the analyzed set) has no back-link here.

Consumer note: To build a complete re-export map, scan two fields:

  1. alsoExportedFrom on each declaration — same-name re-exports
  2. aliasOf on declarations — renamed re-exports (separate declarations)

type string[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

lang?

Script language. undefined means TypeScript (default), 'js' for JavaScript-only components.

type "js"

aliasOf?

For renamed re-exports (export {foo as bar}), points to the original declaration. This declaration's name is the alias; aliasOf.name is the original name.

For renames out of the default slot (export {default as bar} from './x' where ./x is export default ...), aliasOf.name is 'default' — the canonical's actual symbol name. Consumers locate the canonical by (aliasOf.module, aliasOf.name).

Svelte component exception: when the source is a .svelte file (e.g., export {default as Foo} from './X.svelte'), the canonical's name is the component name (derived from the filename), so aliasOf.name is the component name ('X'), NOT 'default'. Consumers that branch on aliasOf.name === 'default' to detect default-rename should additionally check whether aliasOf.module ends with .svelte.

Different from alsoExportedFrom: aliases create new API surface names, while alsoExportedFrom tracks additional import paths for the same name.

type { module: string; name: string; }

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

ComponentPropJson
#

types.ts view source

also exported from index.ts

{ examples: string[]; seeAlso: string[]; throws: { description: string; type?: string | undefined; }[]; name: string; type: string; optional: boolean; bindable: boolean; deprecatedMessage?: string | undefined; ... 4 more ...; parameters?: { ...; }[] | undefined; } import {ComponentPropJson} from 'svelte-docinfo/types.js';

Component prop information for Svelte components.

Standalone schema (not extending ParameterJson) because component props have different semantics: named attributes with no positional order (<Foo {a} {b} /> = <Foo {b} {a} />), no rest parameters, and support for two-way binding via $bindable rune.

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

Prop name as declared in the component's $props() type.

type string

type

Resolved TypeScript type string.

type string

optional

Whether the prop is optional in the component's props type.

type boolean

bindable

Whether the prop uses the $bindable() rune, enabling two-way binding.

type boolean

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

typeInfo?

Structured type; absent when type is the whole story (see TypeJson).

type TypeJson

description?

Description from JSDoc on the prop's type declaration.

type string

defaultValue?

Default value expression from destructuring or @default tag.

type string

parameters?

Structured parameters for callable props (e.g., Snippet<[text: string]>).

Present when the prop has extractable parameters, absent otherwise. Only populated when there are actual parameters — bare Snippet / Snippet<[]> does not set this field. Intentionally .optional() rather than .default([]) (see the array-field policy note above): absence is a meaningful signal, not an empty list.

type { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

ComponentPropJsonInput
#

types.ts view source

{ name: string; type: string; examples?: string[] | undefined; deprecatedMessage?: string | undefined; seeAlso?: string[] | undefined; throws?: { description: string; type?: string | undefined; }[] | undefined; ... 6 more ...; parameters?: { ...; }[] | undefined; } import type {ComponentPropJsonInput} from 'svelte-docinfo/types.js';

name

Prop name as declared in the component's $props() type.

type string

type

Resolved TypeScript type string.

type string

examples?

Code examples from @example tags.

type string[]

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

seeAlso?

Related items from @see tags, in raw TSDoc format.

type string[]

throws?

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

since?

Version introduced, from @since tag.

type string

typeInfo?

Structured type; absent when type is the whole story (see TypeJson).

type TypeJson

optional?

Whether the prop is optional in the component's props type.

type boolean

description?

Description from JSDoc on the prop's type declaration.

type string

defaultValue?

Default value expression from destructuring or @default tag.

type string

bindable?

Whether the prop uses the $bindable() rune, enabling two-way binding.

type boolean

parameters?

Structured parameters for callable props (e.g., Snippet<[text: string]>).

Present when the prop has extractable parameters, absent otherwise. Only populated when there are actual parameters — bare Snippet / Snippet<[]> does not set this field. Intentionally .optional() rather than .default([]) (see the array-field policy note above): absence is a meaningful signal, not an empty list.

type { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

computeDependents
#

postprocess.ts view source

(files: readonly SourceFileInfo[]): (SourceFileInfo & { dependents?: readonly string[] | undefined; })[] import {computeDependents} from 'svelte-docinfo/postprocess.js';

Compute bidirectional dependencies from source files.

This function ensures that if file A has file B in its dependencies, then file B will have file A in its dependents. This provides consistent output regardless of whether callers provide one-directional or bidirectional dependency information.

Returns new SourceFileInfo objects when computed dependents exist or when paths needed posixification; otherwise the original input objects flow through ===-equal (fast path for session callers, who already pass POSIX paths and may have no inferable dependents for a given file).

files

source files with optional dependency information

type readonly SourceFileInfo[]

returns

(SourceFileInfo & { dependents?: readonly string[] | undefined; })[]

new array with bidirectional dependencies computed

examples

// Input: Calculator.svelte has dependencies: [math.ts] // Output: Calculator.svelte has dependencies: [math.ts] // math.ts has dependents: [Calculator.svelte] const filesWithBidirectional = computeDependents(files);

ConstructorMemberJson
#

types.ts view source

also exported from index.ts

{ kind: "constructor"; name: "constructor" | "(construct)"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 13 more ...; sourceLin... import {ConstructorMemberJson} from 'svelte-docinfo/types.js';

A constructor member (class constructor, construct signature). Has parameters, overloads — but not returnType/returnDescription (constructors always return their class).

name is narrowed to two literal sentinels: 'constructor' for class constructors and '(construct)' for interface/type-alias construct signatures (which share kind: 'constructor' but originate from getConstructSignatures() on a non-class type — no user-chosen identifier exists). The literal is preserved (rather than omitted) so getDisplayName and consumer renderers reading member.name keep working without a constructor-specific branch.

kind

type "constructor"

name

type "constructor" | "(construct)"

parameters

Function/method/constructor parameters.

type { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

overloads

Overload signatures (when there are multiple public overloads). Includes all public overloads. The implementation signature is excluded. Empty when there are no overloads (single signature).

type { typeSignature: string; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 4 more ...; returnDescription?: string | undefined; }[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

createAnalysisLanguageService
#

typescript-program.ts view source

(options?: AnalysisLanguageServiceOptions | undefined, log?: AnalysisLog | undefined): AnalysisLanguageService import {createAnalysisLanguageService} from 'svelte-docinfo/typescript-program.js';

Create a persistent language service for incremental analysis.

The LS owns parsed source ASTs and checker state across calls. Use the returned handle to push file-content updates (setFile / deleteFile) between analysis passes; subsequent getProgram() calls return either the same ts.Program (no changes since last call) or a fresh one that reuses unchanged files via the document registry.

options?

configuration options

optional

log?

optional logger for info messages

optional

returns

AnalysisLanguageService

the language service handle

throws

  • Error - if tsconfig.json is not found

examples

const ls = createAnalysisLanguageService({projectRoot}); ls.setFile('/abs/path/to/foo.ts', {content: 'export const x = 1;'}); const program = ls.getProgram(); // ... use program ... ls.setFile('/abs/path/to/foo.ts', {content: 'export const x = 2;'}); // bumps version const program2 = ls.getProgram(); // fresh program, foo.ts reparsed ls.dispose();

createAnalysisProgram
#

typescript-program.ts view source

(options?: AnalysisProgramOptions | undefined, log?: AnalysisLog | undefined): Program import {createAnalysisProgram} from 'svelte-docinfo/typescript-program.js';

Create TypeScript program for one-shot analysis.

Use createAnalysisLanguageService instead when you need to analyze the same source set multiple times — the LS path reuses parsed ASTs and checker state across calls.

options?

configuration options for program creation

optional

log?

optional logger for info messages

optional

returns

Program

the TypeScript program

throws

  • Error - if tsconfig.json is not found

examples

const program = createAnalysisProgram({projectRoot: process.cwd()});

createAnalysisSession
#

session.ts view source

also exported from index.ts

(options: AnalysisSessionOptions): AnalysisSession import {createAnalysisSession} from 'svelte-docinfo/session.js';

Create a persistent analysis session.

options

returns

AnalysisSession

examples

Vite plugin integration

const session = createAnalysisSession({sourceOptions, resolveImport, log}); await session.setFiles(initialFiles); const result = session.query(); // on watcher events: await session.setFile({id, content}); await session.deleteFile(removedId); const next = session.query(); // on shutdown: session.dispose();

One-shot via the public wrapper

// Equivalent to `analyze(...)` — the wrapper goes through a session internally. const session = createAnalysisSession({sourceOptions}); try { await session.setFiles(sourceFiles); return session.query({onDuplicates: 'throw'}); } finally { session.dispose(); }

createBlockedSpecifierChecker
#

exports.ts view source

(parsed: ParsedExports): ((specifier: string) => boolean) | null import {createBlockedSpecifierChecker} from 'svelte-docinfo/exports.js';

Build a predicate deciding whether an export specifier is blocked, per Node's resolution semantics: an exact (starless) key wins outright, else the best-matching wildcard key (comparePatternKeys) decides — and when that winner's target is null, the subpath is not exported.

Blocking is only observable when blocked keys exist, so this returns null for the common no-blocked-keys case and callers skip specifier computation entirely.

Exported for consumers reading ParsedExports.blocked directly — this is the one implementation of the interpretation rule.

parsed

returns

((specifier: string) => boolean) | null

createDefaultResolver
#

dep-resolver.ts view source

(compilerOptions: CompilerOptions, projectRoot: string, host?: ModuleResolutionHost): ImportResolver import {createDefaultResolver} from 'svelte-docinfo/dep-resolver.js';

Create the default ImportResolver (TypeScript + tsconfig).

Uses ts.resolveModuleName against host (default ts.sys) — no ts.Program is built. Identity is a fresh symbol per call, so each session that constructs its own default gets a unique cache scope. Multiple sessions sharing one resolver instance share the cache scope (correct, since resolver state is shared too).

ts.resolveModuleName cannot resolve real .svelte files (no compiler option teaches it the extension), so relative and absolute .svelte specifiers — with or without the extension written — fall back to manual resolution against fromFile through the same host. Non-relative .svelte specifiers (tsconfig paths aliases, package subpaths) stay unresolved; supply a custom resolveImport for those setups.

The resolution cache lives for the resolver's lifetime and caches failed lookups alongside successful ones, so invalidate clears it — the session calls that whenever its owned set's membership changed (see ImportResolver).

compilerOptions

parsed tsconfig (from loadTsconfig, or the LS handle's getCompilerOptions())

type CompilerOptions

projectRoot

absolute project root for the module-resolution cache

type string

host

resolution surface; the session passes an owned-content-aware host so dependency edges see the same world the checker does (in-memory files, including ones in directories that exist nowhere on disk), disk-only callers take the ts.sys default

type ModuleResolutionHost
default ts.sys

returns

ImportResolver

createExtractContext
#

typescript-extract-shared.ts view source

(program: Program, checker: TypeChecker, options: ModuleSourceOptions, diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | ... 14 more ... | { ...; })[], aliasRegistry: AliasRegistry | undefined): ExtractContext import {createExtractContext} from 'svelte-docinfo/typescript-extract-shared.js';

The module dispatchers' ExtractContext construction — analyzeModule and analyzeSvelteModule are where the program is in hand, and both want the same answers from it. One owner so the derived fields can't drift or be forgotten by a third dispatcher: isExternalFile comes from the very options the pass will be handed (analyzeExports derives its own isExternalPath from that object, and the two axes must agree), and exactOptionalPropertyTypes is read off the *merged* compiler options rather than the raw tsconfig, so a session-level override reaches the strip gate (optionalWidened).

Direct callers outside the dispatchers (tests, fixture harnesses, subpath consumers) build the object literal themselves and decide every field explicitly — see mockExtractContext in src/test/test-helpers.ts.

program

type Program

checker

type TypeChecker

options

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

aliasRegistry

type AliasRegistry | undefined

returns

ExtractContext

createIsExternalFile
#

createIsExternalPath
#

typescript-program.ts view source

(options: ModuleSourceOptions): (file: string) => boolean import {createIsExternalPath} from 'svelte-docinfo/typescript-program.js';

Path-string counterpart of IsExternalFile, for call sites that hold a file path rather than a ts.SourceFile (re-export classification). Same rule, with declaration-file suffixes standing in for isDeclarationFile.

Deliberately distinct from isSource: isSource answers "does this file emit a module?" while this answers "is this file outside the project?" — an in-root file can fail isSource (the src/lib/internal/ convention, user excludes) while remaining project-local, and conflating the two mis-files project-local re-exports as external-package facts.

options

returns

(file: string) => boolean

createOwnedDirIndex
#

createSourceOptions
#

source-config.ts view source

also exported from index.ts

(projectRoot: string, overrides?: SourceOptionsOverrides | undefined): ModuleSourceOptions import {createSourceOptions} from 'svelte-docinfo/source-config.js';

Create complete, normalized, validated source options from project root and optional overrides.

Merges overrides with DEFAULT_SOURCE_OPTIONS, then normalizes via normalizeSourceOptions — so the returned object always has an absolute projectRoot, slash-stripped path entries, and an explicit sourceRoot (auto-derived for multi-path layouts). Throws on validation failure.

projectRoot

path to project root (typically process.cwd()); resolved to absolute

type string

overrides?

optional overrides for default options

optional

returns

ModuleSourceOptions

throws

  • Error - if validation fails (empty `sourcePaths`, or `sourceRoot` not a prefix of all `sourcePaths`)

examples

// Standard SvelteKit library const options = createSourceOptions(process.cwd());
// Multiple source directories const options = createSourceOptions(process.cwd(), { sourcePaths: ['src/lib', 'src/routes'], sourceRoot: 'src', });
// Extend the default exclusions (callback form — see `ExcludeOption`) const options = createSourceOptions(process.cwd(), { exclude: (defaults) => [...defaults, '**\/*.gen.ts'], });
// Replace the default exclusions wholesale const options = createSourceOptions(process.cwd(), { exclude: ['**\/*.test.ts', '**\/*.internal.ts'], });

createSourceOptionsWithInclude
#

source-config.ts view source

(projectRoot: string, overrides: SourceOptionsOverrides | undefined, include: readonly string[] | undefined, log?: AnalysisLog | undefined): ModuleSourceOptions import {createSourceOptionsWithInclude} from 'svelte-docinfo/source-config.js';

Create source options with include-pattern widening applied.

The include-aware form of createSourceOptions, used by the discovery entry points (analyzeFromFiles, the Vite plugin): builds options from overrides, then unions each include pattern's static base into sourcePaths via widenSourcePathsForInclude so include-discovered files pass the query-time source gate. When the set widens, options are rebuilt from the original overrides so sourceRoot derivation and validation (including the projectRoot-escape throw) see the final set — re-normalizing the first result would bake a derived sourceRoot in as if explicit and fail validation against the widened bases. Owning both steps here keeps that original-overrides requirement an implementation detail instead of a caller contract.

Logs when a pattern contributes the '' base: a root-crossing glob ('**\/*.ts') or a literal root file ('vite.config.ts') scopes the whole project root as source — the baseline exclusions (node_modules, dot-directories) shrink that cliff but don't remove it, so the widening leaves a trace instead of happening silently.

projectRoot

path to project root (typically process.cwd()); resolved to absolute

type string

overrides

optional overrides for default options

type SourceOptionsOverrides | undefined

include

explicit include patterns (absent or empty means plain createSourceOptions); in-root absolute patterns relativize via normalizeIncludePatterns

type readonly string[] | undefined

log?

receives the root-scoping info line

optional

returns

ModuleSourceOptions

throws

  • Error - if validation fails, including a widened base or an absolute

DeclarationAnalysis
#

declaration-build.ts view source

DeclarationAnalysis import type {DeclarationAnalysis} from 'svelte-docinfo/declaration-build.js';

Result of analyzing a single declaration.

Produced by analyzeDeclaration (in typescript-exports.ts) and Svelte component analysis. Used by analyzeModule to filter @nodocs declarations before output.

Uses DeclarationJsonBuild (not DeclarationJsonInput) because declarations are constructed incrementally — Zod validation happens at the ModuleJson.parse() boundary.

declaration

The analyzed declaration metadata (pre-validation).

type DeclarationJsonBuild

nodocs

Whether the declaration is marked @nodocs (should be excluded from documentation).

type boolean

DeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more .... import {DeclarationJson} from 'svelte-docinfo/types.js';

Metadata for an exported declaration (function, type, class, component, etc.).

Discriminated union on kind — each variant has only the fields relevant to that kind. Use isKind (in declaration-helpers.ts) to narrow, or check declaration.kind directly.

DeclarationJsonBuild
#

declaration-build.ts view source

DeclarationJsonBuild import type {DeclarationJsonBuild} from 'svelte-docinfo/declaration-build.js';

Permissive type for constructing declarations incrementally before Zod validation.

Used by internal analysis functions (analyzeDeclaration, extractFunctionInfo, etc.) that build declarations by mutating a plain object. The discriminated union schema validates the final shape at the ModuleJson.parse() boundary.

name?

type string

kind

type "function" | "type" | "variable" | "class" | "interface" | "enum" | "component" | "snippet" | "namespace"

docComment?

type string

typeSignature?

type string

modifiers?

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

sourceLine?

type number

parameters?

type { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

returnType?

type string

returnTypeInfo?

type TypeJson

returnDescription?

type string

genericParams?

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

overloads?

type { typeSignature: string; parameters?: { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[] | undefined; ... 4 more ...; return...

examples?

type string[]

deprecatedMessage?

type string

internalMessage?

type string

seeAlso?

type string[]

throws?

type { type?: string | undefined; description: string; }[]

since?

type string

mutates?

type Record<string, string>

extends?

type string[]

externalTypes?

type string[]

implements?

type string[]

members?

type MemberJsonBuild[]

props?

type { name: string; type: string; examples?: string[] | undefined; deprecatedMessage?: string | undefined; seeAlso?: string[] | undefined; throws?: { description: string; type?: string | undefined; }[] | undefined; ... 6 more ...; parameters?: { ...; }[] | undefined; }[]

acceptsChildren?

type boolean

lang?

type "js"

alsoExportedFrom?

type string[]

aliasOf?

type { module: string; name: string; }

reactivity?

type "$state" | "$state.raw" | "$derived" | "$derived.by"

partial?

type boolean

module?

Source module path for kind: 'namespace' declarations (export * as ns from './x').

type string

defaultValue?

Default value documented via @default. Variable declarations only.

type string

mergedValue?

The exported name also carries a value meaning. Type/interface declarations only.

type boolean

typeInfo?

Structured type. Variable and type-alias declarations only; see TypeJson.

type TypeJson

DeclarationJsonInput
#

types.ts view source

{ kind: "function"; name: string; returnType?: string | undefined; returnTypeInfo?: TypeJson | undefined; returnDescription?: string | undefined; parameters?: { name: string; ... 6 more ...; propertyDescriptions?: Record<...> | undefined; }[] | undefined; ... 15 more ...; genericParams?: { ...; }[] | undefined; } | ... import type {DeclarationJsonInput} from 'svelte-docinfo/types.js';

DeclarationKind
#

types.ts view source

also exported from index.ts

"function" | "type" | "variable" | "class" | "interface" | "enum" | "component" | "snippet" | "namespace" import {DeclarationKind} from 'svelte-docinfo/types.js';

The kind of top-level exported declaration.

Does not include 'constructor' — constructors only appear as MemberKind (nested in classes, interfaces, or types with construct signatures), never as top-level module exports.

DeclarationModifier
#

types.ts view source

also exported from index.ts

"public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter" import {DeclarationModifier} from 'svelte-docinfo/types.js';

TypeScript modifier keywords extracted from declarations.

Only modifiers that appear on public API members are included. Private members (including #field syntax) are filtered out during analysis. Protected members are included as part of the extension API.

DEFAULT_SOURCE_OPTIONS
#

source-config.ts view source

also exported from index.ts

SourceOptionsDefaults import {DEFAULT_SOURCE_OPTIONS} from 'svelte-docinfo/source-config.js';

Default partial options for standard SvelteKit library structure.

Does not include projectRoot — use createSourceOptions to create complete options with your project root.

exclude is the single source of truth for filtering: globs applied at both discovery time (by globFiles/discoverFromExports) and analysis time (by isSource() against project-root-relative paths).

see also

  • ``createSourceOptions`` for the typical way to build complete options

deriveIncludePatterns
#

files.ts view source

also exported from index.ts

(sourcePaths: readonly string[]): string[] import {deriveIncludePatterns} from 'svelte-docinfo/files.js';

Build an include pattern array from source paths.

Each path becomes a <path>/**\/*.{ts,js,svelte,css,json} glob. Used by discoverSourceFiles to derive a default include from sourceOptions.sourcePaths when no explicit pattern is supplied — keeps the glob fallback consistent with custom sourcePaths instead of silently defaulting to src/lib.

The '' source path (the whole project root — an explicit '', a normalized '.', or a root-crossing include base) derives a bare **\/*.{...} glob: prefixing it would produce a leading-slash pattern, which tinyglobby treats as absolute from the filesystem root.

sourcePaths

type readonly string[]

returns

string[]

examples

deriveIncludePatterns(['packages/foo', 'packages/bar']) // => ['packages/foo/**\/*.{ts,js,svelte,css,json}', 'packages/bar/**\/*.{ts,js,svelte,css,json}']

detectReactivity
#

typescript-extract-shared.ts view source

(initializer: Expression | undefined): "$state" | "$state.raw" | "$derived" | "$derived.by" | undefined import {detectReactivity} from 'svelte-docinfo/typescript-extract-shared.js';

Detect a Svelte 5 reactivity rune from a variable or property initializer.

Inspects the AST since runes erase to their inner type after type-checking. Returns undefined for any non-rune expression. See the Reactivity enum in types.ts for the rationale on running this on every file regardless of extension.

initializer

type Expression | undefined

returns

"$state" | "$state.raw" | "$derived" | "$derived.by" | undefined

Diagnostic
#

diagnostics.ts view source

also exported from index.ts

{ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; } import {Diagnostic} from 'svelte-docinfo/diagnostics.js';

Discriminated union of all diagnostic variants.

DiagnosticKind
#

diagnostics.ts view source

also exported from index.ts

"type_extraction_failed" | "signature_analysis_failed" | "class_member_failed" | "svelte_prop_failed" | "legacy_props" | "module_skipped" | "module_unreadable" | "import_parse_failed" | ... 7 more ... | "alias_lost" import {DiagnosticKind} from 'svelte-docinfo/diagnostics.js';

Discriminant for Diagnostic variant types.

DiagnosticSeverity
#

diagnostics.ts view source

also exported from index.ts

"error" | "warning" import {DiagnosticSeverity} from 'svelte-docinfo/diagnostics.js';

Diagnostic severity levels.

  • 'error' — analysis failed, declaration may be incomplete or missing data
  • 'warning' — partial success, something seems off but analysis continued

discoverFromExports
#

exports.ts view source

(options: ExportsDiscoveryOptions): Promise<ExportsDiscoveryResult> import {discoverFromExports} from 'svelte-docinfo/exports.js';

Discover source files using package.json exports field.

Reads package.json, parses exports, maps dist paths to source paths, expands wildcard patterns, and loads file content.

Returns {files: null} when no package.json or no exports field exists, signaling the caller to fall back to glob discovery. Returns {files: []} when exports exist but resolve no source files (likely misconfigured mapping).

For concrete exports, maps directly to source paths and verifies existence. For wildcard exports, globs the source directory for matching files.

Null-target keys are honored with Node's resolution semantics: a subpath whose most-specific matching key is null is not exported, so its file is not discovered — "./internal/*": null beside the usual "./*.js" wildcards keeps src/lib/internal/ out of discovery exactly as it keeps the subpaths unresolvable for consumers (the src/lib/internal/ convention's exports half).

options

discovery configuration

returns

Promise<ExportsDiscoveryResult>

ExportsDiscoveryResult with discovered files and any error diagnostics

discoverSourceFiles
#

discovery.ts view source

also exported from index.ts

(options: DiscoverSourceFilesOptions): Promise<DiscoverSourceFilesResult> import {discoverSourceFiles} from 'svelte-docinfo/discovery.js';

Discover source files from a project root.

Used internally by analyzeFromFiles for the discovery step. Standalone consumers can call it directly when they want the discovered file list without running full analysis.

Strategy is selected by discovery:

  • 'auto' (default) — try exports first, fall back to glob.
  • 'exports'exports only; throws if exports is missing or resolves to no source files. Combining with include is a configuration error and also throws.
  • 'glob' — glob only; include parameterizes the search.

Exclusion globs come from sourceOptions.exclude (the single source of truth, also applied at analysis time by isSource()). Beneath it, the always-on baseline (node_modules + dot-directories, see hasBaselineExcludedSegment in source-config.ts) applies at both stages and is not affected by exclude overrides.

options

discovery configuration

returns

Promise<DiscoverSourceFilesResult>

discovered files (content loaded) and any diagnostics from the exports step

throws

  • Error - in strict `'exports'` mode when `exports` is missing or

examples

const sourceOptions = createSourceOptions(process.cwd()); const {files, diagnostics} = await discoverSourceFiles({sourceOptions});

DiscoverSourceFilesOptions
#

discovery.ts view source

also exported from index.ts

DiscoverSourceFilesOptions import type {DiscoverSourceFilesOptions} from 'svelte-docinfo/discovery.js';

Options for discoverSourceFiles.

sourceOptions

Source options used to resolve the source directory for exports-based discovery.

sourceOptions.projectRoot is the resolution base for include globs and the sourceOptions.exclude glob patterns. Build via createSourceOptions (which normalizes) or pass a normalized return from normalizeSourceOptions.

sourceOptions.exclude is the single source of truth for exclusion globs — applied at both this discovery stage and analysis time (via isSource()).

type ModuleSourceOptions

include?

Glob patterns to include (relative to projectRoot; an absolute pattern inside the root relativizes, an out-of-root one throws — see normalizeIncludePatterns).

Filter for glob-based discovery. When discovery is 'auto' (default), providing include collapses the chain to glob immediately. Combining include with discovery: 'exports' throws.

When omitted, the glob fallback derives an include pattern from sourceOptions.sourcePaths via deriveIncludePatterns, so custom sourcePaths (e.g., ['packages/foo']) discover files instead of silently defaulting to src/lib.

type string[]

discovery?

Discovery strategy.

type Discovery

default 'auto'

see also

  • {@link Discovery} for semantics of each variant

distDir?

Dist directory name relative to projectRoot, used for exports-based discovery.

Maps dist paths from package.json exports back to source paths.

type string

default 'dist'

log?

Optional logger for status messages.

type AnalysisLog

DiscoverSourceFilesResult
#

discovery.ts view source

also exported from index.ts

DiscoverSourceFilesResult import type {DiscoverSourceFilesResult} from 'svelte-docinfo/discovery.js';

files

Discovered source files with content already loaded.

type SourceFileInfo[]

diagnostics

Diagnostics collected during discovery (e.g., malformed package.json exports).

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

Discovery
#

discovery.ts view source

also exported from index.ts

Discovery import type {Discovery} from 'svelte-docinfo/discovery.js';

Discovery strategy for source files.

  • 'auto' (default) — try package.json exports first, fall back to glob patterns when exports is missing or resolves to nothing
  • 'exports' — package.json exports only, throw if exports is missing or resolves to no source files (strict mode for libraries that should always declare their public surface via exports)
  • 'glob' — skip exports entirely, use glob patterns

Providing include patterns implies 'glob' semantics regardless of mode — when discovery: 'auto' and include is set, the auto fallback chain collapses to glob immediately. Combining discovery: 'exports' with include is a configuration error (the modes are contradictory) and throws at discovery time.

DuplicateCommentDiagnostic
#

diagnostics.ts view source

{ commentType: "module_comment" | "doc_comment"; file: string; message: string; severity: "error" | "warning"; kind: "duplicate_comment"; line?: number | undefined; column?: number | undefined; } import {DuplicateCommentDiagnostic} from 'svelte-docinfo/diagnostics.js';

Duplicate comment sources detected (e.g., both HTML and JSDoc @module, or both HTML @component and JSDoc for component docComment).

commentType

Which comment type is duplicated.

type "module_comment" | "doc_comment"

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "duplicate_comment"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

DuplicateDeclaration
#

postprocess.ts view source

also exported from index.ts

DuplicateDeclaration import type {DuplicateDeclaration} from 'svelte-docinfo/postprocess.js';

A duplicate declaration with its full metadata and module path.

declaration

The full declaration metadata.

type { kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ....

module

Module path where this declaration is defined.

type string

DuplicateDeclarationDiagnostic
#

diagnostics.ts view source

{ declarationName: string; modules: string[]; file: string; message: string; severity: "error" | "warning"; kind: "duplicate_declaration"; line?: number | undefined; column?: number | undefined; } import {DuplicateDeclarationDiagnostic} from 'svelte-docinfo/diagnostics.js';

A declaration name appears in more than one module.

Library docs assume a flat namespace — two modules exporting the same name collide when consumers import {name}. Emitted at warning severity so the analysis result remains usable; consumers who want it fatal can promote via onDuplicates: 'throw' or by inspecting the diagnostic. The default slot (name === 'default') is excluded — every module owns its own.

declarationName

The duplicated declaration name.

type string

modules

Module paths where the name was defined (>= 2).

ModuleJson.path values — relative to sourceRoot, so a different base than the record's file (project-root-relative, like every diagnostic). The two disagree textually whenever sourceRoot is non-empty; each names what it says it names, a module vs. a file.

type string[]

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "duplicate_declaration"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

emitCallOrConstructSignature
#

typescript-extract-shared.ts view source

(getSignatures: () => readonly Signature[], signatureKind: "call" | "construct", resolveTsdocNode: (sig: Signature) => Node | undefined, paramValidationFallbackNode: Node, declaration: DeclarationJsonBuild, ctx: ExtractContext, errorContext: { ...; }): void import {emitCallOrConstructSignature} from 'svelte-docinfo/typescript-extract-shared.js';

Append a (call) or (construct) signature member to a declaration.

Captures the extraction logic shared by interface processing (extractTypeInfo) and type-alias property processing (extractTypeAliasProperties): type signature, parameters, generics, overloads, and TSDoc. The TSDoc source node is supplied by the caller — interfaces look it up in node.members (skipping TSDoc when no inline signature is declared, even if one is inherited), type aliases use sig.getDeclaration().

getSignatures

thunk to retrieve getCallSignatures() / getConstructSignatures(); called inside the try so checker errors are captured as diagnostics

type () => readonly Signature[]

signatureKind

'call' (member kind: function, includes returnType) or 'construct' (member kind: constructor, no returnType)

type "call" | "construct"

resolveTsdocNode

callback returning the AST node to parse TSDoc from, or undefined to skip TSDoc resolution

type (sig: Signature) => Node | undefined

paramValidationFallbackNode

location used by validateParamKeys when resolveTsdocNode returns undefined

type Node

declaration

parent declaration (mutated; appended to members)

ctx

errorContext

type { node: Node; kindLabel: string; }

returns

void

mutates

  • declaration — appends a member when signatures are present;

ensureLexerReady
#

dep-resolver.ts view source

(): Promise<void> import {ensureLexerReady} from 'svelte-docinfo/dep-resolver.js';

Ensure es-module-lexer's wasm runtime is initialized.

Idempotent and cheap after the first call. The session awaits this once at the top of setFiles so phase 1's per-file lex is purely synchronous.

returns

Promise<void>

EnumDeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "enum"; members: ({ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 ... import {EnumDeclarationJson} from 'svelte-docinfo/types.js';

An enum declaration. Has members for enum values.

kind

type "enum"

members

Enum members: name/value pairs with optional JSDoc.

type ({ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: nu...

alsoExportedFrom

Module paths (relative to sourceRoot) that re-export this declaration under the same name. The canonical declaration lives in this module's declarations array; these paths are additional import locations for the same thing.

The same edges appear from the re-exporting side as ModuleJson.reExports — use that when asking "what does this module re-export" instead of inverting these arrays. The two can disagree at the margins: a reExports entry whose canonical declaration is @nodocs (or whose module isn't in the analyzed set) has no back-link here.

Consumer note: To build a complete re-export map, scan two fields:

  1. alsoExportedFrom on each declaration — same-name re-exports
  2. aliasOf on declarations — renamed re-exports (separate declarations)

type string[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

aliasOf?

For renamed re-exports (export {foo as bar}), points to the original declaration. This declaration's name is the alias; aliasOf.name is the original name.

For renames out of the default slot (export {default as bar} from './x' where ./x is export default ...), aliasOf.name is 'default' — the canonical's actual symbol name. Consumers locate the canonical by (aliasOf.module, aliasOf.name).

Svelte component exception: when the source is a .svelte file (e.g., export {default as Foo} from './X.svelte'), the canonical's name is the component name (derived from the filename), so aliasOf.name is the component name ('X'), NOT 'default'. Consumers that branch on aliasOf.name === 'default' to detect default-rename should additionally check whether aliasOf.module ends with .svelte.

Different from alsoExportedFrom: aliases create new API surface names, while alsoExportedFrom tracks additional import paths for the same name.

type { module: string; name: string; }

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

errorsOf
#

diagnostics.ts view source

also exported from index.ts

(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]): ({ ...; } | ... 14 more ... | { ...; })[] import {errorsOf} from 'svelte-docinfo/diagnostics.js';

Get all error-severity diagnostics.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

returns

({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

ExcludeOption
#

source-config.ts view source

also exported from index.ts

ExcludeOption import type {ExcludeOption} from 'svelte-docinfo/source-config.js';

Exclude patterns as accepted by the override surfaces (createSourceOptions, analyzeFromFiles, the Vite plugin — not the CLI, whose --exclude is array-only).

An array replaces DEFAULT_SOURCE_OPTIONS.exclude wholesale; the callback form receives a fresh copy of those defaults and returns the list to use, so extending them doesn't require restating them:

exclude: (defaults) => [...defaults, '**\/*.gen.ts'] // add a pattern exclude: (defaults) => defaults.filter((p) => p !== '**\/internal/**') // drop one

The callback runs at most once per built options object (include-pattern widening rebuilds options from the already-resolved array). Resolved to a plain array before normalization; ModuleSourceOptions.exclude never carries the function form.

ExportEntry
#

exports.ts view source

ExportEntry import type {ExportEntry} from 'svelte-docinfo/exports.js';

A parsed entry from package.json exports field.

specifier

The export specifier (e.g., ".", "./*.js").

type string

isPattern

Whether the specifier contains a wildcard (*).

type boolean

conditions

Resolved dist paths by condition (e.g., {types: "./dist/index.d.ts", default: "./dist/index.js"}).

type Record<string, string>

ExportsDiscoveryOptions
#

exports.ts view source

ExportsDiscoveryOptions import type {ExportsDiscoveryOptions} from 'svelte-docinfo/exports.js';

Options for discoverFromExports.

projectRoot

Absolute path to project root.

type string

distDir?

Dist directory name relative to projectRoot. Default: 'dist'.

type string

sourceDir?

Source directory name relative to projectRoot. Default: 'src/lib'.

type string

exclude?

Glob patterns to exclude from discovered files.

type string[]

ExportsDiscoveryResult
#

exports.ts view source

ExportsDiscoveryResult import type {ExportsDiscoveryResult} from 'svelte-docinfo/exports.js';

Result of discovering source files from package.json exports.

Self-contained: includes both the discovered files and any error diagnostics (e.g., files that exist but could not be read).

files

Discovered source files, or null if no exports field found. Empty array means exports field exists but resolved no source files (likely a misconfigured dist-to-source mapping).

type SourceFileInfo[] | null

diagnostics

Error diagnostics for files that exist but could not be read.

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

ExportSurface
#

postprocess.ts view source

also exported from index.ts

ExportSurface import type {ExportSurface} from 'svelte-docinfo/postprocess.js';

A module's resolved export surface — see resolveExportSurface.

entries

Surface entries, sorted by name (case-insensitive order, compareStrings).

type ExportSurfaceEntry[]

unresolvedStarExports

Star targets (own or transitive) absent from the analyzed set — their projected names are unknown, so the surface is incomplete.

type string[]

externalStarExports

External star specifiers reachable from this module (own or transitive) — their projected names are unknowable without analyzing the package.

type string[]

ExportSurfaceEntry
#

postprocess.ts view source

also exported from index.ts

ExportSurfaceEntry import type {ExportSurfaceEntry} from 'svelte-docinfo/postprocess.js';

One name on a module's resolved export surface.

name

Exported name, in the docinfo model's terms — Svelte components appear under their filename-derived name (the model's convention for default exports of .svelte files), not 'default'.

type string

via

How the name reaches this module's surface: an own declaration (including synthesized aliases), a same-name re-export edge, a direct external re-export, or projection through export * from './x'.

type "declaration" | "reExport" | "external" | "star"

module?

Canonical module path, when known (undefined for external entries).

type string

declaration?

The canonical declaration, when present in the analyzed set.

type { kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ....

specifier?

Package specifier for external entries (as written in the statement).

type string

originalName?

Name inside the external package when renamed.

type string

typeOnly?

Type-only re-export — the name is erased at runtime.

type boolean

starFrom?

For star-projected entries: the starExports target the name arrived through.

type string

ExternalReExportJson
#

types.ts view source

also exported from index.ts

{ name: string; specifier: string; typeOnly: boolean; originalName?: string | undefined; sourceLine?: number | undefined; } import {ExternalReExportJson} from 'svelte-docinfo/types.js';

A re-export whose immediate target is outside the analyzed source set — export {x} from 'pkg', export {x as y} from 'pkg', or export * as ns from 'pkg'.

specifier is the module specifier as written (usually a package name); there is no canonical declaration to resolve, so these entries are flat facts about the statement rather than edges into the module graph.

Only statements that *directly* reference the external specifier are captured. Forms that stay silent: import {x} from 'pkg'; export {x}; (import-then-export), re-export chains that reach a package through another source module (that module owns the entry), and specifiers the checker can't resolve. Statement-level @nodocs suppresses the entry.

name

Public exported name from this module.

type string

specifier

Module specifier as written in the statement (e.g. 'pkg').

type string

typeOnly

Whether the statement or specifier is type-only — see ReExportJson.typeOnly.

type boolean

originalName?

The name inside the external module when renamed (export {x as y} from 'pkg''x'). Omitted for same-name re-exports and namespace form (export * as ns).

type string

sourceLine?

1-based line of the export specifier in this module's source.

type number

ExternalReExportJsonInput
#

types.ts view source

{ name: string; specifier: string; originalName?: string | undefined; typeOnly?: boolean | undefined; sourceLine?: number | undefined; } import type {ExternalReExportJsonInput} from 'svelte-docinfo/types.js';

name

Public exported name from this module.

type string

specifier

Module specifier as written in the statement (e.g. 'pkg').

type string

originalName?

The name inside the external module when renamed (export {x as y} from 'pkg''x'). Omitted for same-name re-exports and namespace form (export * as ns).

type string

typeOnly?

Whether the statement or specifier is type-only — see ReExportJson.typeOnly.

type boolean

sourceLine?

1-based line of the export specifier in this module's source.

type number

extractClassInfo
#

typescript-extract-class.ts view source

(node: Node, declaration: DeclarationJsonBuild, ctx: ExtractContext): void import {extractClassInfo} from 'svelte-docinfo/typescript-extract-class.js';

Extract class information with rich member metadata.

node

the declaration AST node

type Node

declaration

the declaration to populate

ctx

the extraction pass's context

returns

void

mutates

  • declaration — adds extends, implements, genericParams, members

ExtractContext
#

typescript-extract-shared.ts view source

ExtractContext import type {ExtractContext} from 'svelte-docinfo/typescript-extract-shared.js';

The pass-scoped, cross-cutting state one extraction run threads through the extractor seams — analyzeDeclaration down to the resolveTypeInfo call sites. Constructed once per module walk (analyzeExports, analyzeSvelteModule) or per direct call (tests, fixture harnesses).

Membership is deliberately tight: only state that is constant for the pass and consumed across extractor boundaries belongs here. Per-declaration inputs (nodes, symbols, parsed TSDoc, written annotations, names) stay positional parameters.

checker

type TypeChecker

diagnostics

Accumulator for non-fatal issues — mutated via Array.push throughout the pass.

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

isExternalFile

Predicate for external source files (node_modules, out-of-tree declarations).

type (sourceFile: SourceFile): boolean

sourceFile

type SourceFile
returns boolean

aliasRegistry

Identity-keyed registry of the analyzed set's exported alias-lost type aliases (buildAliasRegistry in typescript-alias-registry.ts), or undefined when no pre-pass ran — registry recovery is then disabled while written-name recovery keeps working. A required field so every construction site decides explicitly.

type AliasRegistry | undefined

exactOptionalPropertyTypes

The program's exactOptionalPropertyTypes compiler option — read it off program.getCompilerOptions(). Consumed by optionalWidened, which documents the strip-gating policy. A required field so every construction site decides explicitly, like aliasRegistry.

type boolean

extractDependencies
#

source-config.ts view source

(sourceFile: SourceFileInfo & { dependents?: readonly string[] | undefined; }, options: ModuleSourceOptions): { dependencies: string[]; dependents: string[]; } import {extractDependencies} from 'svelte-docinfo/source-config.js';

Extract dependencies and dependents for a module from source file info.

Filters to only include source modules (excludes external packages, node_modules, tests). Returns sorted arrays of module paths (relative to sourceRoot) for deterministic output.

Native paths in sourceFile.dependencies/dependents are accepted — isSource and extractPath posixify their inputs, so direct callers with hand-built input need not pre-normalize.

Accepts SourceFileInfo plus an optional dependents field — the public input type carries only dependencies (caller-supplied opt-in), while dependents is computed downstream by computeDependents and flows through as an enriched shape.

sourceFile

the source file info to extract dependencies from

type SourceFileInfo & { dependents?: readonly string[] | undefined; }

options

module source options for filtering and path extraction

returns

{ dependencies: string[]; dependents: string[]; }

sorted arrays of module paths (relative to sourceRoot) for dependencies and dependents

extractEnumInfo
#

typescript-extract-type.ts view source

(node: Node, declaration: DeclarationJsonBuild, ctx: ExtractContext): void import {extractEnumInfo} from 'svelte-docinfo/typescript-extract-type.js';

Extract enum member information from an enum declaration.

Iterates node.members to extract each enum member's name, initializer value, type, and JSDoc. Members are represented as MemberJson with kind 'variable'.

node

type Node

declaration

ctx

returns

void

mutates

  • declaration — adds members and typeSignature

extractFunctionInfo
#

typescript-extract-function.ts view source

(node: Node, symbol: Symbol, declaration: DeclarationJsonBuild, tsdoc: TsdocParsedComment | undefined, ctx: ExtractContext): void import {extractFunctionInfo} from 'svelte-docinfo/typescript-extract-function.js';

Extract function/method information including parameters with descriptions and default values.

node

the declaration AST node

type Node

symbol

the TypeScript symbol

type Symbol

declaration

the declaration to populate

tsdoc

parsed TSDoc comment (if available)

type TsdocParsedComment | undefined

ctx

the extraction pass's context

returns

void

mutates

  • declaration — adds typeSignature, returnType, returnDescription, parameters, genericParams, overloads (and `partial: true` on signature failure)

extractHtmlModuleComment
#

svelte.ts view source

(svelteSource: string): string | undefined import {extractHtmlModuleComment} from 'svelte-docinfo/svelte.js';

Extract @module comment from HTML comments in Svelte source.

Scans all <!-- ... --> comments for one containing @module at the start of a line. This allows @component and @module to coexist as separate HTML comments. Works for template-only components.

svelteSource

the full Svelte source code

type string

returns

string | undefined

the cleaned module comment text, or undefined if no @module HTML comment found

extractModifiers
#

typescript-extract-shared.ts view source

(modifiers: readonly ModifierLike[] | undefined): ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[] import {extractModifiers} from 'svelte-docinfo/typescript-extract-shared.js';

Extract modifier keywords from a node's modifiers.

Returns an array of modifier strings like ['public', 'readonly', 'static'].

modifiers

type readonly ModifierLike[] | undefined

returns

("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

extractModuleComment
#

typescript-exports.ts view source

(sourceFile: SourceFile): string | undefined import {extractModuleComment} from 'svelte-docinfo/typescript-exports.js';

Extract module-level comment.

sourceFile

type SourceFile

returns

string | undefined

cleaned module comment text (with @module line removed), or undefined if no @module comment found

see also

extractModuleScriptContent
#

svelte.ts view source

(svelteSource: string): string | undefined import {extractModuleScriptContent} from 'svelte-docinfo/svelte.js';

Extract the content of the module <script> tag from Svelte source.

Counterpart of extractScriptContent: matches only module scripts, so the two partition a source's script tags consistently.

svelteSource

type string

returns

string | undefined

the module script tag content, or undefined if no module script is found

extractPath
#

source-config.ts view source

(sourceId: string, options: ModuleSourceOptions): string import {extractPath} from 'svelte-docinfo/source-config.js';

Extract module path relative to source root from absolute source ID.

Uses proper path semantics: strips projectRoot/sourceRoot/ prefix.

sourceId

absolute path to the source file

type string

options

module source options for path extraction

returns

string

examples

const options = createSourceOptions('/home/user/project'); extractPath('/home/user/project/src/lib/foo.ts', options) // => 'foo.ts' extractPath('/home/user/project/src/lib/nested/bar.svelte', options) // => 'nested/bar.svelte'
const options = createSourceOptions('/home/user/project', { sourcePaths: ['src/lib', 'src/routes'], sourceRoot: 'src', }); extractPath('/home/user/project/src/lib/foo.ts', options) // => 'lib/foo.ts' extractPath('/home/user/project/src/routes/page.svelte', options) // => 'routes/page.svelte'

extractScriptContent
#

svelte.ts view source

(svelteSource: string): string | undefined import {extractScriptContent} from 'svelte-docinfo/svelte.js';

Extract the content of the main <script> tag from Svelte source — commented-out scripts skipped, module scripts (<script module>, <script context="module">) excluded.

svelteSource

type string

returns

string | undefined

the script tag content, or undefined if no matching script tag is found

extractSignatureParameters
#

typescript-extract-shared.ts view source

(sig: Signature, ctx: ExtractContext, tsdocParams: Record<string, string> | undefined): { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[] import {extractSignatureParameters} from 'svelte-docinfo/typescript-extract-shared.js';

Extract parameters from a TypeScript signature with TSDoc descriptions and default values.

Shared helper for extracting parameter information from both standalone functions and class methods/constructors.

sig

the TypeScript signature to extract parameters from

type Signature

ctx

the extraction pass's context (checker + alias registry)

tsdocParams

record of parameter names to TSDoc descriptions (from TsdocParsedComment.params)

type Record<string, string> | undefined

returns

{ name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

array of ParameterJson objects

extractSnippetParameters
#

svelte.ts view source

(snippetType: Type, checker: TypeChecker, aliasRegistry: AliasRegistry | undefined, writtenNode?: TypeNode | undefined): { ...; }[] import {extractSnippetParameters} from 'svelte-docinfo/svelte.js';

Extract structured parameters from a Snippet<[...]> type.

Snippet is an interface, so type arguments are on TypeReference (accessed via checker.getTypeArguments), not on aliasTypeArguments (which is only for type aliases).

Returns full ParameterJson input objects (with optional and rest always set) for runtime consistency with extractSignatureParameters in typescript-extract-shared.ts. Optional tuple elements are widened to include undefined — under exactOptionalPropertyTypes too, unlike properties — so the element type is stripped unconditionally via getTypeSignature and optional: true carries it alone. Rest elements report like rest signature parameters — rest: true with the printed array form (...rest: B[] carries B[]) — and a variadic spread (...T) carries the spread type itself, mirroring the structured typeInfo tuple (buildTuple). Callers pass the bare Snippet<...> TypeReference — a union wrapping it (optional widening, | null) reports no type arguments.

snippetType

type Type

checker

type TypeChecker

aliasRegistry

the analyzed set's alias registry, or undefined when no pre-pass ran — feeds typeInfo name recovery like the prop-level tree

type AliasRegistry | undefined

writtenNode?

the written annotation the snippet type came from, when one exists — feeds typeInfo name recovery, the same node the caller hands the prop-level tree so the two projections can't disagree

type TypeNode
optional

returns

{ name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

array of parameter info for the snippet's tuple type arguments, or [] for bare Snippet / Snippet<[]>

extractSvelteModuleComment
#

svelte.ts view source

(scriptContent: string): string | undefined import {extractSvelteModuleComment} from 'svelte-docinfo/svelte.js';

Extract module-level comment from Svelte script content.

Parses the script content as TypeScript and delegates to extractModuleComment for the shared @module tag detection logic. Works on either script's content — instance <script> and <script module> (see extractScriptContent/extractModuleScriptContent).

scriptContent

the content of a <script> or <script module> tag

type string

returns

string | undefined

the cleaned module comment text, or undefined if none found

extractTypeAliasProperties
#

typescript-extract-type-properties.ts view source

(node: TypeAliasDeclaration, nodeType: Type, declaration: DeclarationJsonBuild, ctx: ExtractContext): void import {extractTypeAliasProperties} from 'svelte-docinfo/typescript-extract-type-properties.js';

Extract properties from a type alias via the TypeScript checker API.

Handles object literals, intersections, mapped types (Partial, Pick, Readonly, etc.), type references, and function types. Extracts:

  • Named properties (with readonly/optional detection, TSDoc from declarations)
  • Index signatures (string/number)
  • Call signatures ((call))
  • Construct signatures ((construct))

node

type TypeAliasDeclaration

nodeType

type Type

declaration

ctx

returns

void

mutates

  • declaration — adds members

extractTypeInfo
#

typescript-extract-type.ts view source

(node: Node, declaration: DeclarationJsonBuild, ctx: ExtractContext): void import {extractTypeInfo} from 'svelte-docinfo/typescript-extract-type.js';

Extract type/interface information with rich property metadata.

node

the declaration AST node

type Node

declaration

the declaration to populate

ctx

the extraction pass's context

returns

void

mutates

  • declaration — adds typeSignature, genericParams, extends, externalTypes, members (and `partial: true` on extraction failure)

extractVariableInfo
#

typescript-extract-function.ts view source

(node: Node, symbol: Symbol, declaration: DeclarationJsonBuild, ctx: ExtractContext): void import {extractVariableInfo} from 'svelte-docinfo/typescript-extract-function.js';

Extract variable information.

node

the declaration AST node

type Node

symbol

the TypeScript symbol

type Symbol

declaration

the declaration to populate

ctx

the extraction pass's context

returns

void

mutates

  • declaration — adds typeSignature, reactivity (when initialized with a Svelte rune)

filterDocumentedProperties
#

typescript-extract-shared.ts view source

(type: Type, typeNode: Node, checker: TypeChecker, isExternalFile: IsExternalFile): { properties: Symbol[]; externalTypes: string[]; } import {filterDocumentedProperties} from 'svelte-docinfo/typescript-extract-shared.js';

Reduce a type's properties to the ones consumers can see, and collect the external type references that contributed the dropped ones.

Two axes drop a property, both by declaration:

  • Origin (isExternalProperty) — the property comes from node_modules or a declaration file. Structure-agnostic: TypeScript preserves original declaration sources on derived properties, so the test gives the right answer through utility-type wrappers (Partial, Pick, OmitStrict) too. A property with no declarations (synthesized) is treated as local and kept.
  • Visibility (isPrivateProperty) — the property is private or a # field of a class this type projects. Only classes can declare either, so this is a no-op on every other shape; it exists because a class *type* reaches here whenever a structural container names one (`type X = LocalClass, type X = LocalGen<string>`), and what the class's own declaration hides an alias over it must hide too.

Applies to any composition shape — intersection, union, bare reference, indexed-access — not only intersections. The labels naming the dropped external contributors come from an AST walk (collectExternalTypeRefs) — the authoritative source for the &/|/index-access shape inference would otherwise erase — which descends through project-local names so a bag inherited via interface Props extends Bag is labeled like an inline Bag & {…} branch. Private properties are dropped silently: they are the project's own code, with nothing to attribute.

type

type Type

typeNode

type Node

checker

type TypeChecker

isExternalFile

returns

{ properties: Symbol[]; externalTypes: string[]; }

finalizeDiagnostics
#

analyze-core.ts view source

(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[], options: { ...; }): void import {finalizeDiagnostics} from 'svelte-docinfo/analyze-core.js';

Run the diagnostic boundary passes in their required order: virtual position remap first (remapVirtualDiagnosticPositions), then path normalization (normalizeDiagnosticPaths — it strips the virtual suffix the remap matches file against, so the reverse order silently keeps virtual positions). The one call for callers assembling modules themselves through analyzeModule / analyzeSvelteModule; using it makes the ordering unrepresentable instead of a contract to remember. Omit virtualFiles when no Svelte virtuals are in play.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

options

type { projectRoot: string; virtualFiles?: Iterable<SvelteVirtualFile> | undefined; }

returns

void

mutates

  • diagnostics — — rewrites positions, `file`, and `message`

findDuplicates
#

postprocess.ts view source

also exported from index.ts

(modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[]): Map<...> import {findDuplicates} from 'svelte-docinfo/postprocess.js';

Find duplicate declaration names across modules.

A duplicate is two *different things* sharing a name in the flat namespace. Occurrences are compared by canonical identity — aliasOf chains are resolved first, so an alias and its canonical (or two aliases of the same canonical) are one thing, not a collision. Documenting a same-name re-export (which synthesizes an alias) or re-exporting a component under its own name (export {default as Foo} from './Foo.svelte') therefore doesn't flag. When a name does flag, all occurrences are reported, aliases included.

Callers can decide how to handle duplicates (throw, warn, ignore).

modules

type { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

returns

Map<string, DuplicateDeclaration[]>

Map of declaration names to their DuplicateDeclaration occurrences (only includes duplicates)

examples

const duplicates = findDuplicates(modules); if (duplicates.size > 0) { for (const [name, occurrences] of duplicates) { console.error(`"${name}" found in:`); for (const {declaration, module} of occurrences) { console.error(` - ${module}:${declaration.sourceLine} (${declaration.kind})`); } } throw new Error(`Found ${duplicates.size} duplicate declaration names`); }

formatDiagnostic
#

diagnostics.ts view source

also exported from index.ts

(diagnostic: { symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; }): string import {formatDiagnostic} from 'svelte-docinfo/diagnostics.js';

Format a diagnostic for display.

Assumes diagnostic.file is project-root-relative (the contract enforced by analyze / analyzeFromFiles). The displayed path is prefixed with ./.

diagnostic

the diagnostic to format

type { symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; }

returns

string

formatted string like './file.ts:10:5: error: message'

examples

for (const d of errorsOf(diagnostics)) { console.error(formatDiagnostic(d)); }

FunctionDeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } import {FunctionDeclarationJson} from 'svelte-docinfo/types.js';

A function declaration. Has parameters, returnType, returnDescription, overloads.

kind

type "function"

parameters

Function/method/constructor parameters.

type { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

overloads

Overload signatures (when there are multiple public overloads). Includes all public overloads. The implementation signature is excluded. Empty when there are no overloads (single signature).

type { typeSignature: string; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 4 more ...; returnDescription?: string | undefined; }[]

alsoExportedFrom

Module paths (relative to sourceRoot) that re-export this declaration under the same name. The canonical declaration lives in this module's declarations array; these paths are additional import locations for the same thing.

The same edges appear from the re-exporting side as ModuleJson.reExports — use that when asking "what does this module re-export" instead of inverting these arrays. The two can disagree at the margins: a reExports entry whose canonical declaration is @nodocs (or whose module isn't in the analyzed set) has no back-link here.

Consumer note: To build a complete re-export map, scan two fields:

  1. alsoExportedFrom on each declaration — same-name re-exports
  2. aliasOf on declarations — renamed re-exports (separate declarations)

type string[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

returnType?

Function/method return type.

type string

returnTypeInfo?

Structured return type; absent when returnType is the whole story (see TypeJson).

type TypeJson

returnDescription?

Return value description from @returns tag.

type string

aliasOf?

For renamed re-exports (export {foo as bar}), points to the original declaration. This declaration's name is the alias; aliasOf.name is the original name.

For renames out of the default slot (export {default as bar} from './x' where ./x is export default ...), aliasOf.name is 'default' — the canonical's actual symbol name. Consumers locate the canonical by (aliasOf.module, aliasOf.name).

Svelte component exception: when the source is a .svelte file (e.g., export {default as Foo} from './X.svelte'), the canonical's name is the component name (derived from the filename), so aliasOf.name is the component name ('X'), NOT 'default'. Consumers that branch on aliasOf.name === 'default' to detect default-rename should additionally check whether aliasOf.module ends with .svelte.

Different from alsoExportedFrom: aliases create new API surface names, while alsoExportedFrom tracks additional import paths for the same name.

type { module: string; name: string; }

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

FunctionMemberJson
#

types.ts view source

also exported from index.ts

{ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: num... import {FunctionMemberJson} from 'svelte-docinfo/types.js';

A function member (method, call signature, method signature). Has parameters, returnType, returnDescription, overloads.

optional reflects a ? token on the declaration (e.g., foo?(): void on an interface or type literal). Always false for index/call/construct signatures and for class methods (TypeScript disallows optional methods on classes).

name is the user-chosen method/property identifier, except for call signatures on interfaces and type aliases where it is the literal sentinel '(call)'.

kind

type "function"

name

User-chosen identifier, or the literal '(call)' sentinel for unnamed call signatures.

type string

optional

Whether the member has a ? token in its declaration.

type boolean

parameters

Function/method/constructor parameters.

type { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

overloads

Overload signatures (when there are multiple public overloads). Includes all public overloads. The implementation signature is excluded. Empty when there are no overloads (single signature).

type { typeSignature: string; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 4 more ...; returnDescription?: string | undefined; }[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

defaultValue?

Default value documented via @default — for a callable member, typically the behavior used when the callback is omitted. Always tag-authored (structural containers have no initializers). Members only: top-level function declarations and overloads never carry one.

type string

returnType?

Function/method return type.

type string

returnTypeInfo?

Structured return type; absent when returnType is the whole story (see TypeJson).

type TypeJson

returnDescription?

Return value description from @returns tag.

type string

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

generateImport
#

declaration-helpers.ts view source

also exported from index.ts

(declaration: { kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; }, modulePath: string, libraryName: string): string import {generateImport} from 'svelte-docinfo/declaration-helpers.js';

Generate TypeScript import statement for a declaration.

Produces import type for type/interface declarations, import for values — including type/interface declarations marked mergedValue (a merged value+type symbol like a schema/type pair is importable as a runtime value, so a type-only import would break value use).

Default export handling: when declaration.name === 'default', emits import X from '...' with the binding derived by PascalCasing the module path. ('default' is the symbol's actual name in JS — import X from 'mod' is sugar for import {default as X} from 'mod'.)

declaration

the DeclarationJson to generate an import for

type { kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ....

modulePath

module path relative to source root (e.g., foo.ts)

type string

libraryName

package name for the import specifier (e.g., @pkg/lib)

type string

returns

string

formatted import statement string

examples

generateImport({name: 'Foo', kind: 'type'}, 'foo.ts', '@pkg/lib') // => "import type {Foo} from '@pkg/lib/foo.js';" generateImport({name: 'default', kind: 'function'}, 'foo-bar.ts', '@pkg/lib') // => "import FooBar from '@pkg/lib/foo-bar.js';"

see also

  • ``getDisplayName`` for the divergent default-slot fallback used as a display label (the literal 'default', since a label has no use for a synthesized JS binding).

GenericParamJson
#

types.ts view source

also exported from index.ts

{ name: string; constraint?: string | undefined; defaultType?: string | undefined; } import {GenericParamJson} from 'svelte-docinfo/types.js';

Generic type parameter metadata extracted from declarations like <T extends string = unknown>.

Present on functions, classes, interfaces, type aliases, and Svelte components that declare generic type parameters.

name

Parameter name like T.

type string

constraint?

Constraint like string from T extends string.

type string

defaultType?

Default type like unknown from T = unknown.

type string

getComponentName
#

source.ts view source

(modulePath: string): string import {getComponentName} from 'svelte-docinfo/source.js';

Extract component name from a Svelte module path.

modulePath

type string

returns

string

examples

getComponentName('Alert.svelte') // => 'Alert' getComponentName('components/Button.svelte') // => 'Button'

getDefaultAnalyzer
#

source.ts view source

also exported from index.ts

(path: string): AnalyzerType | null import {getDefaultAnalyzer} from 'svelte-docinfo/source.js';

Default analyzer resolver based on file extension.

  • .svelte'svelte'
  • .ts, .js'typescript'
  • .css'css'
  • .json'json'
  • Other extensions → null (skip)

path

type string

returns

AnalyzerType | null

getDisplayName
#

declaration-helpers.ts view source

also exported from index.ts

(declaration: { kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: number | undefined; } | ... 10 more ... | { ...; }): string import {getDisplayName} from 'svelte-docinfo/declaration-helpers.js';

Format declaration or member name with generic parameters for display.

Default-slot entries return the literal 'default' (the symbol's actual name in JS). Renderers that want a richer label (PascalCased module path, an explicit "default export" header) should branch on name === 'default' themselves before calling this.

declaration

the DeclarationJson or MemberJson to format

type { kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: num...

returns

string

name with generic parameters appended (e.g., Map<K, V>)

examples

getDisplayName({name: 'Map', kind: 'type', genericParams: [{name: 'K'}, {name: 'V'}]}) // => 'Map<K, V>'

see also

  • ``generateImport`` for the divergent default-slot fallback used in import-statement generation (PascalCased module path, since an import needs a JS identifier binding, not a label).

getLocalExportStatement
#

typescript-extract-shared.ts view source

(exportSymbol: Symbol, sourceFile: SourceFile): { node: ExportSpecifier | NamespaceExport; statement: ExportDeclaration; } | undefined import {getLocalExportStatement} from 'svelte-docinfo/typescript-extract-shared.js';

The local export statement and binding node for an alias export symbol — {node, statement} where node is the ExportSpecifier (or, for export * as ns, the NamespaceExport) and statement its ExportDeclaration.

Returns undefined when the statement isn't in sourceFile: merged symbols can put a foreign declaration first, and parsing JSDoc or positions there would attribute another module's content here.

exportSymbol

type Symbol

sourceFile

type SourceFile

returns

{ node: ExportSpecifier | NamespaceExport; statement: ExportDeclaration; } | undefined

getNodeLocation
#

typescript-extract-shared.ts view source

(node: Node): { file: string; line: number; column: number; } import {getNodeLocation} from 'svelte-docinfo/typescript-extract-shared.js';

Extract line and column from a TypeScript node. Returns 1-based line and column numbers.

node

type Node

returns

{ file: string; line: number; column: number; }

getNonOptionalType
#

typescript-extract-shared.ts view source

(type: Type, checker: TypeChecker, optional: boolean): Type import {getNonOptionalType} from 'svelte-docinfo/typescript-extract-shared.js';

The type of an optional declaration with the widening undefined member removed — the counterpart to getTypeSignature's optional strip for structural queries, taking the position's optionality the same way (false is identity).

A union with undefined reports no call signatures of its own, so under strictNullChecks an optional method (fn?(a: string): number) or function-typed property resolves to ((a: string) => number) | undefined and reads as non-callable, silently costing it typeSignature, parameters, and returnType. Analogous to getNonNullableType, but leaves null in place: fn?: (() => void) | null really isn't callable, and reporting it as a function would hide the null.

A null-free union goes through getNonNullableType, which rebuilds the union rather than picking a member — so a union of callables (fn?: (() => void) | (() => number)) keeps its combined call signature. A null-bearing union is returned unchanged: null poisons callability regardless, so there's nothing to recover by stripping undefined from it.

The selection itself is optionalWideningTarget's — the same owner getTypeSignature and the TypeJson builder select through, so the structural queries can't drift from the printed and structured outputs.

Every callability query routes through this with the member's own optionality, in both widening modes — the property site (populatePropertyMember) and the method sites (interface and class) alike. At an optional position an undefined member — widened or written — is the same runtime observation as absence, already carried by optional: true, so under exactOptionalPropertyTypes a written fn?: (() => void) | undefined classifies callable like fn?: () => void (that spelling is often forced there — assigning a possibly-undefined handler to the property requires it). | null stays demoted per the paragraph above — null is a real value absence doesn't imply. The printed and structured outputs still gate their strips on optionalWidened, where a written undefined is content. On the method sites the strip is identity under the flag anyway — method syntax can't write | undefined.

type

type Type

checker

type TypeChecker

optional

type boolean

returns

Type

getSourceRoot
#

source-config.ts view source

(options: ModuleSourceOptions): string import {getSourceRoot} from 'svelte-docinfo/source-config.js';

Get the effective sourceRoot from options.

Returns sourceRoot if provided, otherwise:

  • Single sourcePath: returns that path
  • Multiple sourcePaths: derives the longest common directory prefix

options

returns

string

the effective source root path

getTypeSignature
#

typescript-extract-shared.ts view source

(type: Type, checker: TypeChecker, optional: boolean): string import {getTypeSignature} from 'svelte-docinfo/typescript-extract-shared.js';

Type signature of a declaration — for an optional one, with the implicit | undefined widening removed. The single chokepoint pairing optional with the strip, so a call site can't apply one without the other. The target selection itself lives in optionalWideningTarget (in typescript-extract-type-json.ts), shared with the TypeJson builder so the flat string and the tree can't drift.

The checker widens every optional property and parameter to include undefined, which is redundant with optional: true in the output. Removing it with checker.getNonNullableType drops null too, so x?: string | null printed as "string" and x?: null as "never" — both silently wrong. Filtering undefined out of type.types and rejoining the members is no better: it loses the alias name, the printer's member order, and the parens that keep function members legal.

So null-bearing unions are trimmed on the printed union instead, where TypeScript always emits a top-level undefined last — truncated unions ('a' | ... 11 more ... | undefined) included. Every other union keeps taking getNonNullableType, which prints an optional function type without the union parens the trim would leave behind (() => void, not (() => void)).

Applies to the structured fields only. A callable's typeSignature comes from checker.signatureToString, which has no flag to omit the widening, so it renders optional parameters as the checker does — (a?: number | undefined): void.

A non-union optional is printed as written, since there's no widening member to remove: x?: undefined stays "undefined" (stripping would leave never, the same silent-wrong shape as the null cases above), and x?: unknown stays "unknown" (getNonNullableType would answer {}). See optionalWideningTarget for the full case split.

Under exactOptionalPropertyTypes the checker doesn't widen optional properties at all, so property sites gate the strip off via optionalWidened (passing false here) — every undefined there is author-written (x?: T | undefined is a distinct type from x?: T in that mode) and stripping would trim it. Parameter and tuple-element sites pass optional unconditionally: the flag governs properties only, and both keep widening under it.

type

type Type

checker

type TypeChecker

optional

type boolean

returns

string

globFiles
#

files.ts view source

(options: GlobFilesOptions): Promise<SourceFileInfo[]> import {globFiles} from 'svelte-docinfo/files.js';

Discover source files via glob patterns.

The always-on baseline exclusions (node_modules + dot-directories, see baselineExcludesForBase) apply as glob ignores anchored below each pattern's static base — so a root-crossing include ('**\/*.ts') can't rake in node_modules, while an include rooted in a dot directory ('.hidden/src/**') still matches, mirroring isSource's matched-sourcePath relativity.

options

glob configuration

returns

Promise<SourceFileInfo[]>

array of source files with content loaded

throws

  • Error - if any matched file cannot be read — the pool rejects on the first read failure

examples

const files = await globFiles({ projectRoot: process.cwd(), include: deriveIncludePatterns(['src/lib']), exclude: DEFAULT_SOURCE_OPTIONS.exclude, });

GlobFilesOptions
#

files.ts view source

GlobFilesOptions import type {GlobFilesOptions} from 'svelte-docinfo/files.js';

Options for globFiles.

projectRoot

Absolute path to project root.

type string

include

Glob patterns to include (relative to projectRoot).

type readonly string[]

exclude?

Optional glob patterns to exclude.

type string[]

hasBaselineExcludedSegment
#

source-config.ts view source

(relPath: string): boolean import {hasBaselineExcludedSegment} from 'svelte-docinfo/source-config.js';

Whether a base-relative path contains an always-excluded directory segment.

The always-on baseline: node_modules directories and dot-directories (.svelte-kit, .git, .cache, …) are never source. Matched against the path *relative to the matched source path*, not the project root — so an explicit dot-dir source path (sourcePaths: ['.hidden/src']) still works: the dot segment sits in the base, not the remainder. That relativity is the opt-out; there is no flag. Deliberately only these two families — dist/build/coverage are ordinary names a project can legitimately keep source in, and over-excluding fails silently.

Only directory segments are checked; the final segment (the file itself) is not, so a dotfile like .config.ts inside a source dir passes.

Deliberately NOT part of DEFAULT_SOURCE_OPTIONS.exclude: user exclude replaces the defaults wholesale and would silently strip the baseline. baselineExcludesForBase is the discovery-time glob form.

relPath

POSIX path relative to a matched source path / discovery base

type string

returns

boolean

hasDocContent
#

tsdoc.ts view source

({ text, params, ...tags }: TsdocParsedComment): boolean import {hasDocContent} from 'svelte-docinfo/tsdoc.js';

Whether a parsed comment carries any documentation — description text or an extracted tag.

Type machinery parses to an empty result (@type/@typedef/@template tags populate no fields), so doc-hunting walks (component docComment) use this to keep lower-precedence sources like the HTML @component comment reachable instead of letting an annotation claim the doc slot with empty text. Structural over the parsed result — any field beyond text/params counts when present — so it can't drift from parseComment's extraction or from TsdocParsedComment gaining fields.

__0

returns

boolean

hasErrors
#

diagnostics.ts view source

also exported from index.ts

(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]): boolean import {hasErrors} from 'svelte-docinfo/diagnostics.js';

Check if any error-severity diagnostics were collected.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

returns

boolean

hasWarnings
#

diagnostics.ts view source

also exported from index.ts

(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]): boolean import {hasWarnings} from 'svelte-docinfo/diagnostics.js';

Check if any warning-severity diagnostics were collected.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

returns

boolean

ImportParseDiagnostic
#

diagnostics.ts view source

{ file: string; message: string; severity: "error" | "warning"; kind: "import_parse_failed"; line?: number | undefined; column?: number | undefined; } import {ImportParseDiagnostic} from 'svelte-docinfo/diagnostics.js';

Import parsing failed during dependency resolution.

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "import_parse_failed"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

ImportResolver
#

dep-resolver.ts view source

also exported from index.ts

ImportResolver import type {ImportResolver} from 'svelte-docinfo/dep-resolver.js';

Token-paired import resolver.

identity is a stable opaque token that keys the session's resolve cache alongside content. Cache hits require both (a) byte-for-byte identical source content and (b) identity equality. Naive function-reference keys would silently destroy cache reuse when callers wrap the resolver in fresh closures (a very common pattern in Vite/Rollup plugins) — opaque tokens lift the responsibility to the caller, where it can be done correctly.

resolve

Resolve an import specifier to an absolute file path, or null.

type (specifier: string, fromFile: string): string | Promise<string | null> | null

specifier

type string

fromFile

type string
returns string | Promise<string | null> | null

identity

Stable opaque token identifying this resolver's cache scope.

Two ImportResolvers with identity === to each other are treated as cache-equivalent. string for human-readable identities (e.g., 'vite-plugin-container'); symbol for generated sentinels.

type string | symbol

invalidate?

Drop any cached resolution state. Optional — implement it when the resolver caches results across calls, and especially when it caches *failed* lookups, which go stale the moment a previously-missing file appears.

The session calls this at the start of a batch whenever its owned file set gained or lost a path since this resolver last ran, so a dep ingested after an importer already failed to resolve it still produces an edge. Content-only changes never trigger it (they can't change what exists). Files appearing on *disk* without being ingested are invisible to the session — a resolver caching disk misses owns that invalidation itself.

type (): void

returns void

includePatternBase
#

source-config.ts view source

(pattern: string): string | null import {includePatternBase} from 'svelte-docinfo/source-config.js';

Static base directory of a discovery include pattern.

picomatch.scan().base for glob patterns ('src/other/**\/*.ts''src/other'); a literal non-glob pattern names a file, so it contributes its directory ('src/foo.ts''src', a root file → ''); a negated pattern has no base (null). Shared by widenSourcePathsForInclude (scope widening), globFiles (anchoring the baseline exclusions), and createSourceOptionsWithInclude (detecting root-scoping patterns to log).

Patterns are expected projectRoot-relative — the discovery seams (createSourceOptionsWithInclude, discoverSourceFiles) run normalizeIncludePatterns first, which relativizes in-root absolute patterns and throws on out-of-root ones, so no absolute pattern reaches the base scan through the public entry points.

pattern

type string

returns

string | null

inferDeclarationKind
#

typescript-extract-shared.ts view source

(symbol: Symbol, node: Node): "function" | "type" | "variable" | "class" | "interface" | "enum" | "component" | "snippet" | "namespace" import {inferDeclarationKind} from 'svelte-docinfo/typescript-extract-shared.js';

Infer declaration kind from symbol and node.

Maps TypeScript constructs to DeclarationKind:

  • Classes → 'class'
  • Functions (declarations, expressions, arrows) → 'function'
  • Interfaces → 'interface'
  • Type aliases → 'type'
  • Enums (regular and const) → 'enum'
  • Variables → 'variable' (unless function-valued → 'function')

Note: namespace re-exports (export * as ns from './x') have no inline declaration form in TypeScript and are caught upstream in analyzeExports via classifyNamespaceReExport. They never reach this function. A direct call here on a ValueModule symbol would fall through to 'variable' and leak typeof import("/abs/path") into the output — keep the namespace dispatch in analyzeExports.

symbol

type Symbol

node

type Node

returns

"function" | "type" | "variable" | "class" | "interface" | "enum" | "component" | "snippet" | "namespace"

InterfaceDeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "interface"; extends: string[]; externalTypes: string[]; members: ({ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDes... import {InterfaceDeclarationJson} from 'svelte-docinfo/types.js';

An interface declaration. Has members, extends.

kind

type "interface"

extends

Extended interfaces.

Verbatim text of this declaration's own heritage clause, so entries are spelled as this module wrote them and resolve in its scope — a local rename (import type {Bag as B}) stays B. Unlike externalTypes, whose walk crosses modules and therefore resolves renames back to the exported name, this clause never leaves the declaring file.

type string[]

see also

  • ``ClassDeclarationJson.extends, ClassDeclarationJson.implements for the other verbatim heritage fields, externalTypes (this variant) for the resolved external reach.

externalTypes

External types the heritage composition reaches whose contributions members never enumerates.

Interface members are own-only, so nothing is *filtered* — inherited content simply isn't listed. This field names the external types behind that absence: interface Props extends HTMLButtonAttributes records the bag directly, and interface Props extends LocalBase (where LocalBase reaches a bag) records it transitively — the same answer the component annotated with this interface gets, where extends alone dead-ends at a possibly-unexported local name. Inherited *local* content is the extends field's business: the base is documented at its own declaration.

Entry normalization (rename resolution, type-parameter substitution, text-dedupe, source order) matches TypeDeclarationJson.externalTypes.

type string[]

members

Interface members: property signatures, method signatures, index signatures, call/construct signatures — own members only, inherited members excluded whatever their origin (call/construct signatures included: a base interface's (call) is not enumerated here).

type ({ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: nu...

mergedValue

The exported name also carries a value meaning — a merged value+type symbol (const Foo = ... + interface Foo {...}), where the interface wins the declaration slot and the value's own type goes undocumented. Tells consumers the name is importable as a runtime value: `import {Foo}, never import type {Foo} (see generateImport`).

type boolean

see also

  • ``TypeDeclarationJson.mergedValue``

alsoExportedFrom

Module paths (relative to sourceRoot) that re-export this declaration under the same name. The canonical declaration lives in this module's declarations array; these paths are additional import locations for the same thing.

The same edges appear from the re-exporting side as ModuleJson.reExports — use that when asking "what does this module re-export" instead of inverting these arrays. The two can disagree at the margins: a reExports entry whose canonical declaration is @nodocs (or whose module isn't in the analyzed set) has no back-link here.

Consumer note: To build a complete re-export map, scan two fields:

  1. alsoExportedFrom on each declaration — same-name re-exports
  2. aliasOf on declarations — renamed re-exports (separate declarations)

type string[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

aliasOf?

For renamed re-exports (export {foo as bar}), points to the original declaration. This declaration's name is the alias; aliasOf.name is the original name.

For renames out of the default slot (export {default as bar} from './x' where ./x is export default ...), aliasOf.name is 'default' — the canonical's actual symbol name. Consumers locate the canonical by (aliasOf.module, aliasOf.name).

Svelte component exception: when the source is a .svelte file (e.g., export {default as Foo} from './X.svelte'), the canonical's name is the component name (derived from the filename), so aliasOf.name is the component name ('X'), NOT 'default'. Consumers that branch on aliasOf.name === 'default' to detect default-rename should additionally check whether aliasOf.module ends with .svelte.

Different from alsoExportedFrom: aliases create new API surface names, while alsoExportedFrom tracks additional import paths for the same name.

type { module: string; name: string; }

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

isAbsolutePosixPath
#

paths.ts view source

(p: string): boolean import {isAbsolutePosixPath} from 'svelte-docinfo/paths.js';

Whether a POSIX-form path is absolute — rooted (/src/x.ts) or drive-qualified (C:/proj/x.ts).

Not node:path's isAbsolute, which is platform-flavored: on Linux it reads a posixified Windows path like C:/proj/x.ts as relative. Everything here is already in the internal POSIX form by contract, so the check has to cover both shapes regardless of host.

p

type string

returns

boolean

examples

isAbsolutePosixPath('/home/user/proj/foo.ts') // => true isAbsolutePosixPath('C:/proj/foo.ts') // => true isAbsolutePosixPath('src/lib/foo.ts') // => false isAbsolutePosixPath('../sibling/foo.ts') // => false

isAliasLostType
#

typescript-extract-type-json.ts view source

(type: Type): boolean import {isAliasLostType} from 'svelte-docinfo/typescript-extract-type-json.js';

Whether the checker kept no name for a type-alias declaration's resolved type: no alias symbol (the checker still prints type A = B as B), no nominal symbol (interfaces/classes/enums print their own name), and not an interned terminal (type A = string and type A = 'x' carry no alias symbol either but print fine). True exactly for the expansion-prone class the alias registry targets and the alias_lost diagnostic reports — indexed-access and conditional right-hand sides (z.infer<typeof S> et al.), whose resolution lands on a pre-existing interned type that TypeScript never retroactively stamps an alias symbol on.

type

type Type

returns

boolean

isBrandLikeIntersection
#

typescript-extract-type-json.ts view source

(type: Type): boolean import {isBrandLikeIntersection} from 'svelte-docinfo/typescript-extract-type-json.js';

Whether a type is an intersection carrying an intrinsic or literal member — the .brand() shape (string & BRAND<'x'>). Such aliases are lost but unrecoverable, readable, and author-unfixable, so the alias_lost diagnostic excludes them.

type

type Type

returns

boolean

isCss
#

source.ts view source

(path: string): boolean import {isCss} from 'svelte-docinfo/source.js';

Check if a path is a CSS file.

path

type string

returns

boolean

isDeclaredInFile
#

typescript-extract-shared.ts view source

(symbol: Symbol, fileName: string): boolean import {isDeclaredInFile} from 'svelte-docinfo/typescript-extract-shared.js';

Whether any of the symbol's declarations lives in fileName (virtual-suffix-normalized).

Merged symbols (module augmentation, declaration merging) can have declarations in several files — a symbol counts as declared in the file when at least one declaration is, so checking a single declaration node would drop locally-declared exports depending on bind order. Symbols without declarations are treated as declared in the file (permissive).

symbol

type Symbol

fileName

type string

returns

boolean

IsExternalFile
#

typescript-program.ts view source

IsExternalFile import type {IsExternalFile} from 'svelte-docinfo/typescript-program.js';

Predicate for determining whether a TypeScript source file is external to the project. Used by intersection type filtering to separate user-authored properties from library/framework properties.

Constructed from ModuleSourceOptions at analysis entry points — files under the source root (e.g., src/lib/) are internal, everything else is external.

(call)

type (sourceFile: SourceFile): boolean

sourceFile

type SourceFile
returns boolean

isExternalIndexInfo
#

typescript-extract-shared.ts view source

(info: IndexInfo, isExternalFile: IsExternalFile): boolean import {isExternalIndexInfo} from 'svelte-docinfo/typescript-extract-shared.js';

Check whether an index signature comes from an external file.

The checker synthesizes index infos for every mapped-type instantiation (Record<string, X>, Partial<Indexed>, hand-written {[K in string]: X}) with no declaration, so those read local under originIsExternal's fail-open, while a bare reference or an inherited info preserves the original index-signature declaration, external file included.

info

type IndexInfo

isExternalFile

returns

boolean

isExternalSignature
#

typescript-extract-shared.ts view source

(sig: Signature, isExternalFile: IsExternalFile): boolean import {isExternalSignature} from 'svelte-docinfo/typescript-extract-shared.js';

Check whether a call/construct signature comes from an external file. In practice a signature always carries its original declaration — through intersections, inheritance, and generic instantiation alike — so the fail-open arm is unreachable for the shapes that occur.

sig

type Signature

isExternalFile

returns

boolean

isJson
#

source.ts view source

(path: string): boolean import {isJson} from 'svelte-docinfo/source.js';

Check if a path is a JSON file.

path

type string

returns

boolean

isKind
#

declaration-helpers.ts view source

also exported from index.ts

<K extends DeclarationKind | MemberKind>(declaration: { kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: number | undefined; } | ... 10 more ... | { ...; }, kind: K): declaration is Extract<...> | ... 10 more ... | Extract<...> import {isKind} from 'svelte-docinfo/declaration-helpers.js';

Narrow a declaration by kind for type-safe field access.

Works with both DeclarationJson (top-level) and MemberJson (nested). Accepts DeclarationKind | MemberKind so isKind(member, 'constructor') compiles.

declaration

type { kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: num...

kind

type K

returns

boolean

generics

isKind<K extends DeclarationKind | MemberKind>
K
constraint DeclarationKind | MemberKind

examples

if (isKind(declaration, 'function')) { declaration.parameters; // FunctionDeclarationJson — has parameters declaration.returnType; // has returnType } if (isKind(member, 'constructor')) { member.parameters; // ConstructorMemberJson — has parameters }

isLiteralOnlyUnion
#

typescript-extract-type-json.ts view source

(type: Type): boolean import {isLiteralOnlyUnion} from 'svelte-docinfo/typescript-extract-type-json.js';

Whether a type is a union of literals only (z.enum outputs — a lost alias over one degrades mildly and readably, so the alias_lost diagnostic excludes it). Enum-member literals match too.

type

type Type

returns

boolean

isNodeBuiltin
#

dep-resolver.ts view source

(specifier: string): boolean import {isNodeBuiltin} from 'svelte-docinfo/dep-resolver.js';

Whether a lexed specifier names a Node builtin (fs, node:fs/promises, …).

Builtins can never be a project source file, so resolving them is pointless — and routing them through a host resolver (Vite/Rollup) makes that host emit "externalized for browser compatibility" warnings for browser-targeted configs. Callers skip resolution for these and treat them as unresolved (null), which the downstream isSource filter would do anyway.

specifier

type string

returns

boolean

isPrivateMemberDeclaration
#

typescript-extract-shared.ts view source

(decl: Declaration): boolean import {isPrivateMemberDeclaration} from 'svelte-docinfo/typescript-extract-shared.js';

Check whether a member declaration is private to the class that declares it — a # private identifier name, or a private modifier.

The one visibility rule, shared by the two ways a class's members reach output: extractClassInfo walking node.members at the class's own declaration, and filterDocumentedProperties projecting a class *type* at a structural container (type X = LocalClass, and since generic instantiations extract, type X = LocalGen<string>). Held in one place because the two paths disagreeing is what let # fields reach members through an alias while the class itself dropped them.

protected is deliberately not private: it is part of the extension API a subclass author documents against. Only classes can declare either form — interfaces and type literals have no private members — so this is a no-op on every other shape.

decl

type Declaration

returns

boolean

isSnippetReturnType
#

svelte.ts view source

(returnType: string): boolean import {isSnippetReturnType} from 'svelte-docinfo/svelte.js';

Check if a return type string matches svelte2tsx's snippet return type pattern.

svelte2tsx transforms exported snippets into arrow functions with ReturnType<import('svelte').Snippet> as the return type annotation. The resolved return type includes unique symbol (from Svelte's non-exported SnippetReturn unique symbol) intersected with the branded render message. We match on both parts to avoid false positives — the branded message alone could theoretically be crafted by user code, but the unique symbol intersection cannot since SnippetReturn is not exported from svelte.

returnType

type string

returns

boolean

isSnippetType
#

svelte.ts view source

(type: Type, checker: TypeChecker): boolean import {isSnippetType} from 'svelte-docinfo/svelte.js';

Whether a checker type is a Snippet instantiation, structurally: a named generic instantiation (referenceSymbolName) named Snippet that carries a call signature — by construction the same shape the TypeJson builder classifies as a Snippet reference.

Callers pass the bare type — a union wrapping the Snippet reference (optional widening, | null) doesn't match, and neither does an intersection (Snippet<[]> & {...}); strip or walk members first.

type

type Type

checker

type TypeChecker

returns

boolean

isSource
#

source-config.ts view source

(path: string, options: ModuleSourceOptions): boolean import {isSource} from 'svelte-docinfo/source-config.js';

Check if a path is an analyzable source file.

Combines all filtering: source directory paths, the always-on baseline (node_modules + dot-directories below the matched source path — see hasBaselineExcludedSegment), exclude globs, and analyzer availability. This is the single check for whether a file should be included in library analysis.

Uses proper path semantics with startsWith matching against projectRoot/sourcePath/. No heuristics needed — nested directories are correctly excluded by the prefix check.

Order is sourceDir-then-exclude: the prefix check guarantees the path lives under projectRoot before relativization, so relative() always produces a clean glob-shaped string for the matcher. Files outside projectRoot (rare; would require monorepo path mapping) short-circuit at the prefix check before reaching the matcher.

path

full absolute path to check

type string

options

module source options for filtering

returns

boolean

true if the path is an analyzable source file

examples

const options = createSourceOptions('/home/user/project'); isSource('/home/user/project/src/lib/foo.ts', options) // => true isSource('/home/user/project/src/lib/styles.css', options) // => true isSource('/home/user/project/src/lib/data.json', options) // => true isSource('/home/user/project/src/lib/foo.test.ts', options) // => false (excluded) isSource('/home/user/project/src/fixtures/mini/src/lib/bar.ts', options) // => false (wrong prefix)

isSvelte
#

source.ts view source

(path: string): boolean import {isSvelte} from 'svelte-docinfo/source.js';

Check if a path is a Svelte component file.

path

type string

returns

boolean

isSvelte2tsxGeneratedExport
#

source.ts view source

(name: string): boolean import {isSvelte2tsxGeneratedExport} from 'svelte-docinfo/source.js';

Whether an export name from a svelte2tsx virtual is generated machinery rather than an author declaration: the default slot (svelte2tsx's own component export — the component declaration is synthesized separately) plus every isSvelte2tsxInternal shape. The one rule shared by the Svelte export filter (analyzeSvelteModule), the alias-registry pre-pass skip, and warnAliasLost's virtual guard — only meaningful for names read off a virtual's export table (a plain TS module's default export is real).

name

type string

returns

boolean

isSvelte2tsxInternal
#

source.ts view source

(name: string): boolean import {isSvelte2tsxInternal} from 'svelte-docinfo/source.js';

Whether a symbol name is an internal svelte2tsx identifier — a generated name that must not appear in documentation output: $$ComponentProps, $$render, __sveltets_Render, and the synthesized component class/type alias <ComponentName>__SvelteComponent_. Building block for isSvelte2tsxGeneratedExport, which adds the default slot.

name

type string

returns

boolean

isSvelteVirtualPath
#

source.ts view source

(path: string): boolean import {isSvelteVirtualPath} from 'svelte-docinfo/source.js';

Whether a path names a svelte2tsx virtual file (carries SVELTE_VIRTUAL_SUFFIX).

path

type string

returns

boolean

isTypescript
#

source.ts view source

(path: string): boolean import {isTypescript} from 'svelte-docinfo/source.js';

Check if a path is a TypeScript or JS file.

Includes both .ts and .js files since JS files are valid in TS projects. Excludes .d.ts declaration files — use a custom getAnalyzerType to include them.

path

type string

returns

boolean

LegacyPropsDiagnostic
#

diagnostics.ts view source

{ componentName: string; propNames: string[]; file: string; message: string; severity: "error" | "warning"; kind: "legacy_props"; line?: number | undefined; column?: number | undefined; } import {LegacyPropsDiagnostic} from 'svelte-docinfo/diagnostics.js';

Legacy (runes-less) component props detected — not extracted.

export let components are still-legal Svelte 5 syntax, but prop extraction anchors on the $props() declaration, so their props yield no ComponentPropJson entries. Emitted once per component, listing the detected prop names — exported let/var statements plus export-clause renames of mutable bindings (export {a as b}) — with line pointing at the first legacy prop export in the original .svelte source.

componentName

Name of the component.

type string

propNames

Exported prop names, in source order.

type string[]

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "legacy_props"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

lexImports
#

dep-resolver.ts view source

(content: string, fileId: string): string[] import {lexImports} from 'svelte-docinfo/dep-resolver.js';

Lex import specifiers from prepared content.

Sync — caller must have awaited ensureLexerReady at least once before invoking. For .svelte files, pass the svelte2tsx-transformed virtual content, not the raw .svelte source (which isn't lex-able as JS/TS).

Dynamic imports (import(specifier) with non-literal arg) are omitted.

content

prepared file content (TS/JS, or svelte2tsx virtual)

type string

fileId

absolute file path (used for error messages)

type string

returns

string[]

specifiers in declaration order

throws

  • Error - if lexing fails (malformed source). Callers should catch and

loadFile
#

files.ts view source

(path: string, projectRoot: string): Promise<SourceFileInfo> import {loadFile} from 'svelte-docinfo/files.js';

Load a single source file from disk.

Accepts either relative or absolute paths. Relative paths are resolved against projectRoot.

path

file path (relative to projectRoot or absolute)

type string

projectRoot

absolute path to project root

type string

returns

Promise<SourceFileInfo>

source file info with content loaded

throws

  • Error - if the file cannot be read (e.g., missing or permission denied)

examples

const file = await loadFile('src/lib/math.ts', process.cwd()); // {id: '/abs/path/to/src/lib/math.ts', content: '...'}

loadTsconfig
#

typescript-program.ts view source

(options?: LoadTsconfigOptions | undefined, log?: AnalysisLog | undefined): { compilerOptions: CompilerOptions; rootFileNames: string[]; } import {loadTsconfig} from 'svelte-docinfo/typescript-program.js';

Load and parse tsconfig.json into compiler options + initial file list.

Shared by createAnalysisProgram and createAnalysisLanguageService so tsconfig-resolution behavior stays identical across the two paths. Also useful directly when a caller needs only CompilerOptions (e.g., import resolution via ts.resolveModuleName) without the cost of building a full ts.Program.

options?

optional

log?

optional

returns

{ compilerOptions: CompilerOptions; rootFileNames: string[]; }

throws

  • Error - if tsconfig.json (or the requested `tsconfigName`) is not found.

LoadTsconfigOptions
#

typescript-program.ts view source

LoadTsconfigOptions import type {LoadTsconfigOptions} from 'svelte-docinfo/typescript-program.js';

Base configuration shared by every entry point in this module.

projectRoot + tsconfig + compilerOptions together drive loadTsconfig, which is also exposed publicly. AnalysisProgramOptions and AnalysisLanguageServiceOptions extend this with their own fields.

projectRoot?

Absolute path to project root directory.

type string

default process.cwd()

tsconfig?

Path to tsconfig.json (relative to projectRoot).

type string

default 'tsconfig.json'

compilerOptions?

Compiler options merged on top of those parsed from tsconfig.json (per-key override; user-supplied keys win). Does not bypass the tsconfig.json file requirement — loadTsconfig still throws when no config file is found.

type CompilerOptions

logo_svelte_docinfo
#

logo.ts view source

{ label: string; fill: string; paths: { d: string; }[]; } import {logo_svelte_docinfo} from 'svelte-docinfo/logo.js';

map_concurrent
#

concurrency.ts view source

<T, R>(items: readonly T[], concurrency: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]> import {map_concurrent} from 'svelte-docinfo/concurrency.js';

Maps over items with a bounded number of in-flight promises, preserving input order.

Fail-fast: when fn rejects, the outer promise rejects with that error and idle workers stop pulling from the queue (already-in-flight fn calls run to completion — there's no AbortSignal plumbing). Subsequent rejections from in-flight calls are swallowed by Promise.all (only the first wins), so a misbehaving fn can't surface a second error after the function returns.

items

input array

type readonly T[]

concurrency

maximum number of concurrent operations

type number

fn

mapping function (receives item and index)

type (item: T, index: number) => Promise<R>

returns

Promise<R[]>

array of results in input order

generics

map_concurrent<T, R>
T
R

mapDistToSource
#

exports.ts view source

(distPath: string, condition: string, options: { distDir: string; sourceDir: string; }): string | null import {mapDistToSource} from 'svelte-docinfo/exports.js';

Map a dist file path to its source file path.

Replaces the dist directory prefix with the source directory and maps file extensions based on the export condition.

distPath

the dist path from exports (e.g., "./dist/index.js")

type string

condition

the export condition (e.g., "default", "svelte", "types")

type string

options

mapping configuration

type { distDir: string; sourceDir: string; }

returns

string | null

source path relative to project root, or null if not mappable

MAX_FILE_CONCURRENCY
#

MAX_RESOLVE_CONCURRENCY
#

MemberJson
#

types.ts view source

also exported from index.ts

{ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: num... import {MemberJson} from 'svelte-docinfo/types.js';

Metadata for a nested declaration within a class, interface, type, or enum.

Discriminated union on kind with 3 variants: FunctionMemberJson, VariableMemberJson, ConstructorMemberJson. Use isKind (in declaration-helpers.ts) to narrow, or check member.kind directly.

Does not include fields that exist on declarations but not on members (extends, externalTypes, implements, props, alsoExportedFrom, aliasOf).

Nesting is exactly one level deep — members never contain their own members.

MemberJsonBuild
#

declaration-build.ts view source

MemberJsonBuild import type {MemberJsonBuild} from 'svelte-docinfo/declaration-build.js';

Permissive type for constructing members incrementally before Zod validation.

Used by internal analysis functions in typescript-extract-*.ts that build members by mutating a plain object. The discriminated union schema (MemberJson) validates the final shape at the ModuleJson.parse() boundary.

Mirrors DeclarationJsonBuild for the same reason: construction sites determine kind at runtime, so TypeScript can't narrow the union during incremental field assignment.

name?

type string

kind

type "function" | "variable" | "constructor"

docComment?

type string

typeSignature?

type string

modifiers?

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

sourceLine?

type number

genericParams?

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

parameters?

type { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

returnType?

type string

returnTypeInfo?

type TypeJson

returnDescription?

type string

overloads?

type { typeSignature: string; parameters?: { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[] | undefined; ... 4 more ...; return...

examples?

type string[]

deprecatedMessage?

type string

internalMessage?

type string

seeAlso?

type string[]

throws?

type { type?: string | undefined; description: string; }[]

since?

type string

mutates?

type Record<string, string>

reactivity?

type "$state" | "$state.raw" | "$derived" | "$derived.by"

partial?

type boolean

optional?

Whether the member has a ? token in its declaration. Function and variable members only.

type boolean

defaultValue?

Default value documented via @default. Variable and function members only.

type string

typeInfo?

Structured type. Variable members only; see TypeJson.

type TypeJson

MemberJsonInput
#

types.ts view source

{ kind: "function"; name: string; optional?: boolean | undefined; defaultValue?: string | undefined; returnType?: string | undefined; returnTypeInfo?: TypeJson | undefined; ... 15 more ...; genericParams?: { ...; }[] | undefined; } | { ...; } | { ...; } import type {MemberJsonInput} from 'svelte-docinfo/types.js';

MemberKind
#

types.ts view source

also exported from index.ts

"function" | "variable" | "constructor" import {MemberKind} from 'svelte-docinfo/types.js';

The subset of declaration kinds that appear as nested members in classes, interfaces, and types.

Class members include constructors ('constructor'), methods ('function'), and properties/accessors ('variable'). Interface/type properties use the same kinds for property signatures, method signatures, index signatures, and call/construct signatures.

Top-level-only kinds ('class', 'interface', 'type', 'enum', 'component') never appear as members — nesting is exactly one level deep.

memberNameText
#

typescript-extract-shared.ts view source

(name: PropertyName): string | undefined import {memberNameText} from 'svelte-docinfo/typescript-extract-shared.js';

The output name for a member's property-name node: the unquoted text of an identifier or string/numeric literal (matching the symbol-based paths, where prop.getName() yields data-foo for a written 'data-foo'), or undefined for computed names (runtime-dependent; the symbol paths skip their __@-prefixed forms too).

name

type PropertyName

returns

string | undefined

mergeReExports
#

postprocess.ts view source

also exported from index.ts

(modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[]): { ...; }[] import {mergeReExports} from 'svelte-docinfo/postprocess.js';

Build alsoExportedFrom arrays from the modules' forward re-export edges.

Each module carries its same-name re-export edges as ModuleJson.reExports (collected in phase 1); this phase-2 pass inverts them onto the canonical declarations so both directions of the same fact are queryable. Edges whose canonical module or declaration is absent from modules are skipped — the forward entry remains without a back-link (see ReExportJson for the presence caveats).

Component-only fields on renamed component aliases (props, acceptsChildren, etc.) are populated separately by resolveComponentAliases — call it after this function. They split because they touch disjoint fields and have different inputs.

Pure: the input array and its objects are never mutated. Modules and declarations that gain no back-link flow through ===-equal (structural sharing), so a re-run over already-merged output returns the same object references. New re-exporters union with existing alsoExportedFrom entries (deduped + sorted), keeping repeated merges idempotent by content.

modules

the analyzed modules. Must be parsed ModuleJsons — wire JSON strips empty arrays, so run raw JSON through AnalyzeResultJson.parse first or reExports may be undefined

type { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

returns

{ path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

a new array; declarations with new back-links are copies with alsoExportedFrom unioned, everything else is the input object

examples

// helpers.ts exports: foo, bar // index.ts does: export {foo, bar} from './helpers.js' // (so index.ts's ModuleJson carries reExports: // [{name: 'foo', module: 'helpers.ts'}, {name: 'bar', module: 'helpers.ts'}]) // const merged = mergeReExports(modules); // - helpers.ts foo declaration gets: alsoExportedFrom: ['index.ts'] // - helpers.ts bar declaration gets: alsoExportedFrom: ['index.ts']

MisplacedTagDiagnostic
#

diagnostics.ts view source

{ tagName: "default" | "mutates" | "throws" | "since" | "example" | "deprecated" | "internal" | "see" | "nodocs"; file: string; message: string; severity: "error" | "warning"; kind: "misplaced_tag"; functionName?: string | undefined; line?: number | undefined; column?: number | undefined; } import {MisplacedTagDiagnostic} from 'svelte-docinfo/diagnostics.js';

A JSDoc tag found somewhere it has no effect.

Two contexts emit this:

  • Non-primary overload signature — symbol-scope tags (@example, @deprecated, @internal, @since, @see, @throws, @mutates, @default, @nodocs) describe the function as a whole, not individual signatures. The primary signature's JSDoc feeds the parent declaration's symbol-level extraction; tags on non-primary overload signatures are silently dropped from output. This diagnostic surfaces them so authors can move them to the primary signature. @default and @nodocs are included even though overloads never carry a defaultValue or per-overload exclusion: their presence on a non-primary signature is always a misplacement.
  • Module comment@nodocs has no module-level meaning (it applies to declarations and export statements); in a @module comment the tag does nothing except remain verbatim in moduleComment text. To omit a module from analysis, use exclude patterns instead.

tagName

The tag name without the @ prefix (e.g., 'example', 'deprecated').

type "default" | "mutates" | "throws" | "since" | "example" | "deprecated" | "internal" | "see" | "nodocs"

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "misplaced_tag"

functionName?

Name of the enclosing symbol: the function or method whose overload carries the misplaced tag. Absent for module-comment misplacements (no enclosing symbol).

type string

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

ModuleAnalysis
#

declaration-build.ts view source

ModuleAnalysis import type {ModuleAnalysis} from 'svelte-docinfo/declaration-build.js';

Result of analyzing a module (TypeScript or Svelte).

Produced by analyzeTypescriptModule and analyzeSvelteModule. Both analyzers return this same structure for uniform handling by analyzeModule in analyze-core.ts.

inheritance

path

Module path relative to source root.

type string

dependencies

Dependencies (other source modules this module imports). Empty if none.

type string[]

dependents

Dependents (other source modules that import this module). Empty if none.

type string[]

ModuleExportsAnalysis
#

declaration-build.ts view source

ModuleExportsAnalysis import type {ModuleExportsAnalysis} from 'svelte-docinfo/declaration-build.js';

Result of analyzing a module's exports.

Produced by analyzeExports in typescript-exports.ts.

moduleComment?

Module-level documentation comment. Always undefined for svelte2tsx virtual files — analyzeSvelteModule extracts Svelte module comments from the original source instead.

type string

declarations

All exported declarations with @nodocs flags — consumer filters based on policy.

type DeclarationAnalysis[]

reExports

Same-name re-exports. Published as ModuleJson.reExports and consumed by mergeReExports in phase 2 to build alsoExportedFrom arrays on canonical declarations. Unsorted here and may contain exact duplicates (Svelte default-slot re-keying) — ordering and dedup are applied at publication in analyze-core.ts.

type { name: string; module: string; typeOnly?: boolean | undefined; sourceLine?: number | undefined; }[]

starExports

Star exports (export * from './module') — module paths that are fully re-exported.

type string[]

externalReExports

Direct re-exports from external packages. Published as ModuleJson.externalReExports; unsorted here, sorted at publication.

type { name: string; specifier: string; originalName?: string | undefined; typeOnly?: boolean | undefined; sourceLine?: number | undefined; }[]

externalStarExports

External star exports (export * from 'pkg') — specifiers as written.

type string[]

ModuleJson
#

types.ts view source

also exported from index.ts

{ path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe... import {ModuleJson} from 'svelte-docinfo/types.js';

Metadata for a source module — the top-level container in the data model.

analyze and analyzeFromFiles return Array<ModuleJson> sorted alphabetically by path. Each module contains its exported declarations, dependency graph, and optional moduleComment.

path

Path relative to sourceRoot (e.g., helpers.ts for the default SvelteKit src/lib layout). sourceRoot is configurable via createSourceOptions / the CLI --source-root flag — consumers with a custom layout (e.g., sourcePaths: ['src/lib', 'src/routes'], sourceRoot: 'src') see prefixes like lib/foo.ts here.

type string

declarations

Exported declarations from this module.

type ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ...

dependencies

Modules this imports (paths relative to sourceRoot).

type string[]

dependents

Modules that import this (paths relative to sourceRoot).

type string[]

starExports

Modules fully re-exported via export * from './module'. Paths are relative to sourceRoot. Statement-level @nodocs suppresses the entry, like the other re-export encodings.

type string[]

reExports

Same-name re-exports in this module's source, sorted by name then module (names can collide — see ReExportJson). The forward view of alsoExportedFrom — see ReExportJson for the full contract (canonical resolution, Svelte default-slot naming, @nodocs suppression, presence caveats).

type { name: string; module: string; typeOnly: boolean; sourceLine?: number | undefined; }[]

externalReExports

Re-exports whose immediate target is an external package, sorted by name then specifier. See ExternalReExportJson for which forms are captured.

type { name: string; specifier: string; typeOnly: boolean; originalName?: string | undefined; sourceLine?: number | undefined; }[]

externalStarExports

External modules fully re-exported via export * from 'pkg', as written (statement order). The projected names are unknown — the package isn't analyzed. Statement-level @nodocs suppresses the entry; unresolvable specifiers are skipped.

type string[]

partial

Whether the module is a placeholder for a file that couldn't be analyzed.

Currently only set for Svelte files where svelte2tsx threw at ingest (the transform_failed diagnostic carries the error). Placeholder modules have declarations: [] and serve as a structural slot so the modules array reflects the full owned set; consumers render them as "broken" entries.

type boolean

moduleComment?

File-level JSDoc comment (from @module tag).

type string

ModuleJsonInput
#

types.ts view source

{ path: string; declarations?: ({ kind: "function"; name: string; returnType?: string | undefined; returnTypeInfo?: TypeJson | undefined; returnDescription?: string | undefined; ... 16 more ...; genericParams?: { ...; }[] | undefined; } | ... 7 more ... | { ...; })[] | undefined; ... 7 more ...; partial?: boolean | ... import type {ModuleJsonInput} from 'svelte-docinfo/types.js';

path

Path relative to sourceRoot (e.g., helpers.ts for the default SvelteKit src/lib layout). sourceRoot is configurable via createSourceOptions / the CLI --source-root flag — consumers with a custom layout (e.g., sourcePaths: ['src/lib', 'src/routes'], sourceRoot: 'src') see prefixes like lib/foo.ts here.

type string

declarations?

Exported declarations from this module.

type ({ kind: "function"; name: string; returnType?: string | undefined; returnTypeInfo?: TypeJson | undefined; returnDescription?: string | undefined; parameters?: { name: string; ... 6 more ...; propertyDescriptions?: Record<...> | undefined; }[] | undefined; ... 15 more ...; genericParams?: { ...; }[] | undefined; } |...

moduleComment?

File-level JSDoc comment (from @module tag).

type string

dependencies?

Modules this imports (paths relative to sourceRoot).

type string[]

dependents?

Modules that import this (paths relative to sourceRoot).

type string[]

starExports?

Modules fully re-exported via export * from './module'. Paths are relative to sourceRoot. Statement-level @nodocs suppresses the entry, like the other re-export encodings.

type string[]

reExports?

Same-name re-exports in this module's source, sorted by name then module (names can collide — see ReExportJson). The forward view of alsoExportedFrom — see ReExportJson for the full contract (canonical resolution, Svelte default-slot naming, @nodocs suppression, presence caveats).

type { name: string; module: string; typeOnly?: boolean | undefined; sourceLine?: number | undefined; }[]

externalReExports?

Re-exports whose immediate target is an external package, sorted by name then specifier. See ExternalReExportJson for which forms are captured.

type { name: string; specifier: string; originalName?: string | undefined; typeOnly?: boolean | undefined; sourceLine?: number | undefined; }[]

externalStarExports?

External modules fully re-exported via export * from 'pkg', as written (statement order). The projected names are unknown — the package isn't analyzed. Statement-level @nodocs suppresses the entry; unresolvable specifiers are skipped.

type string[]

partial?

Whether the module is a placeholder for a file that couldn't be analyzed.

Currently only set for Svelte files where svelte2tsx threw at ingest (the transform_failed diagnostic carries the error). Placeholder modules have declarations: [] and serve as a structural slot so the modules array reflects the full owned set; consumers render them as "broken" entries.

type boolean

ModuleSkippedDiagnostic
#

diagnostics.ts view source

{ reason: "not_in_program" | "no_analyzer" | "requires_program"; file: string; message: string; severity: "error" | "warning"; kind: "module_skipped"; line?: number | undefined; column?: number | undefined; } import {ModuleSkippedDiagnostic} from 'svelte-docinfo/diagnostics.js';

Module was skipped during the analysis pass.

Always warning severity — the rest of the analysis still runs and the module's absence in modules reflects the skip. Reasons:

  • not_in_program — the file wasn't in the ts.Program (race between session ingest and query, or virtual file missing for a .svelte)
  • no_analyzer — file extension didn't match any analyzer
  • requires_program — Svelte file reached the non-Svelte dispatcher (caller should use the session API instead of analyzeModule directly)

Discovery-time file-read failures are a separate kind: module_unreadable.

reason

Reason the module was skipped.

type "not_in_program" | "no_analyzer" | "requires_program"

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "module_skipped"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

ModuleSourceOptions
#

source-config.ts view source

also exported from index.ts

ModuleSourceOptions import type {ModuleSourceOptions} from 'svelte-docinfo/source-config.js';

Configuration for module source detection and path extraction.

Uses proper path semantics with projectRoot as the base for all path operations. Paths are matched using startsWith rather than substring search, which correctly handles nested directories without special heuristics.

examples

const options = createSourceOptions(process.cwd(), { sourcePaths: ['src/lib', 'src/routes'], sourceRoot: 'src', });

projectRoot

Path to the project root directory.

All sourcePaths are relative to this. Typically process.cwd(). Normalized (resolved to absolute, posixified to forward slashes, trailing slash stripped) by normalizeSourceOptions, which returns a new options object. Internal callers (isSource, extractPath) assume this is already POSIX form — construct via createSourceOptions / normalizeSourceOptions rather than building ModuleSourceOptions literals by hand on Windows.

type string

'/home/user/my-project'

sourcePaths

Source directory paths to include, relative to projectRoot.

Absolute entries are accepted when they resolve inside projectRoot and are stored root-relative; an entry resolving outside it throws (a root-anchored '/src/lib' is taken as filesystem-absolute, not shorthand — the error hints to drop the slash). Normalized (./.. segments collapsed, trailing slashes stripped) by normalizeSourceOptions, which returns a new options object.

type string[]

['src/lib'] // single source directory
['src/lib', 'src/routes'] // multiple directories

sourceRoot?

Source root for extracting relative module paths, relative to projectRoot.

Normalized like sourcePaths entries (absolute-inside-root accepted and stored root-relative, ./.. collapsed — so '.' becomes '', trailing slashes stripped, out-of-root throws) by normalizeSourceOptions, which returns a new options object.

When omitted:

  • Single sourcePath: defaults to that path
  • Multiple sourcePaths: auto-derived as the longest common directory prefix (or '' when paths share no common prefix — produces project-relative module paths)

type string

'src/lib' // module paths like 'foo.ts', 'utils/bar.ts'
'src' // module paths like 'lib/foo.ts', 'routes/page.svelte'
'' // or '.': module paths stay project-relative, e.g. 'src/lib/foo.ts'

exclude

Glob patterns to exclude from analysis, relative to projectRoot; an absolute pattern inside the root relativizes at normalizeSourceOptions, an out-of-root one throws.

Applied at both stages of the pipeline:

  • Discovery time by globFiles/discoverFromExports, preventing matched files from being loaded.
  • Analysis time by isSource() against relative(projectRoot, absolutePath), catching files that enter through TypeScript import resolution (e.g., a source file imports a test helper).

Beneath it, the always-on baseline (node_modules + dot-directories below a matched source path — see hasBaselineExcludedSegment) applies independently; overriding exclude can't strip it.

The defaults exclude tests and internal/ directories — the src/lib/internal/ convention: internal modules ship in the package for public modules to import (typically paired with an "./internal/*": null package.json exports entry blocking consumer imports), but aren't part of the documented surface. The override surfaces accept a (defaults) => patterns callback (see ExcludeOption) so extending the defaults doesn't require restating them; this normalized field is always a plain array.

analyzeFromFiles accepts a top-level exclude shortcut that merges into this field.

Compiled to a matcher once per options object via picomatch and cached by reference; mutating this array post-isSource-call has no effect — pass through normalizeSourceOptions (which returns a fresh object) or otherwise build a new options object to apply changes.

type string[]

default `['**\/*.test.ts', '**\/*.spec.ts', '**\/internal/**']`

getAnalyzerType

Determine which analyzer to use for a file path.

Called for files in source directories. Return an AnalyzerType or null to skip:

  • 'typescript' — TypeScript/JS files analyzed via TypeScript compiler API
  • 'svelte' — Svelte components analyzed via svelte2tsx + TypeScript compiler API
  • 'css' — CSS files included as modules with no declarations
  • 'json' — JSON files included as modules with no declarations
  • null — skip the file

type (path: string): AnalyzerType | null

path

type string
returns AnalyzerType | null
// Add MDsveX support getAnalyzerType: (path) => (path.endsWith('.svx') ? 'svelte' : getDefaultAnalyzer(path))
// Include .d.ts files (the default excludes them) getAnalyzerType: (path) => (path.endsWith('.d.ts') ? 'typescript' : getDefaultAnalyzer(path))

ModuleUnreadableDiagnostic
#

diagnostics.ts view source

{ file: string; message: string; severity: "error" | "warning"; kind: "module_unreadable"; line?: number | undefined; column?: number | undefined; } import {ModuleUnreadableDiagnostic} from 'svelte-docinfo/diagnostics.js';

File discovered via package.json exports exists but couldn't be read.

Always error severity — discovery-time, emitted by discoverFromExports when readFile fails (permission denied, FS error). Distinct from module_skipped so severity is a stable per-kind property and downstream consumers can route discovery failures separately from analysis-pass skips.

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "module_unreadable"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

namedSymbolName
#

typescript-extract-type-json.ts view source

(type: Type): string | undefined import {namedSymbolName} from 'svelte-docinfo/typescript-extract-type-json.js';

The type's non-anonymous symbol name (__type/__object/__function mark anonymous shapes). The one anonymity rule shared by the recovery gate here, the alias-lost predicate (isAliasLostType), and the registry's safety-gate walk (typescript-alias-registry.ts) — never ObjectFlags.Anonymous, which real inferred schema outputs (zod's are Mapped | Instantiated) don't carry.

type

type Type

returns

string | undefined

NamespaceDeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "namespace"; module: string; alsoExportedFrom: string[]; partial: boolean; examples: string[]; seeAlso: string[]; throws: { description: string; type?: string | undefined; }[]; name: string; modifiers: ("public" | ... 5 more ... | "setter")[]; ... 8 more ...; sourceLine?: number | undefined; } import {NamespaceDeclarationJson} from 'svelte-docinfo/types.js';

A namespace re-export binding: export * as ns from './x'.

Carries no inline members — module points to the source module whose declarations are projected under this name. Consumers that want to render ns.a can deref by reading the source module's declarations array.

kind

type "namespace"

module

Source module path (relative to sourceRoot) projected under this binding.

type string

alsoExportedFrom

Module paths (relative to sourceRoot) that re-export this declaration under the same name. The canonical declaration lives in this module's declarations array; these paths are additional import locations for the same thing.

The same edges appear from the re-exporting side as ModuleJson.reExports — use that when asking "what does this module re-export" instead of inverting these arrays. The two can disagree at the margins: a reExports entry whose canonical declaration is @nodocs (or whose module isn't in the analyzed set) has no back-link here.

Consumer note: To build a complete re-export map, scan two fields:

  1. alsoExportedFrom on each declaration — same-name re-exports
  2. aliasOf on declarations — renamed re-exports (separate declarations)

type string[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

aliasOf?

For renamed re-exports (export {foo as bar}), points to the original declaration. This declaration's name is the alias; aliasOf.name is the original name.

For renames out of the default slot (export {default as bar} from './x' where ./x is export default ...), aliasOf.name is 'default' — the canonical's actual symbol name. Consumers locate the canonical by (aliasOf.module, aliasOf.name).

Svelte component exception: when the source is a .svelte file (e.g., export {default as Foo} from './X.svelte'), the canonical's name is the component name (derived from the filename), so aliasOf.name is the component name ('X'), NOT 'default'. Consumers that branch on aliasOf.name === 'default' to detect default-rename should additionally check whether aliasOf.module ends with .svelte.

Different from alsoExportedFrom: aliases create new API surface names, while alsoExportedFrom tracks additional import paths for the same name.

type { module: string; name: string; }

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

noDepsResolver
#

dep-resolver.ts view source

ImportResolver import {noDepsResolver} from 'svelte-docinfo/dep-resolver.js';

Shared no-op ImportResolver for the "dependency resolution disabled" case.

Stable string identity ('no-deps') instead of a per-call symbol so that repeated ingests within a long-lived session cache-hit on identity. Each session still owns its own cache (entries live on the per-session owned map; sessions don't share state), but within one session every reference to noDepsResolver is === to every other — so a Vite re-save of byte-identical content with resolveDependencies: false exercises the cache-hit branch. The resolver always returns null, so any two calls with identical content under this identity produce identical resolution results — string identity correctly captures that. Used by both the one-shot analyzeFromFiles path and the long-lived Vite plugin (resolveDependencies: false).

normalizeDiagnosticPaths
#

analyze-core.ts view source

(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[], projectRoot: string): void import {normalizeDiagnosticPaths} from 'svelte-docinfo/analyze-core.js';

Normalize the paths a Diagnostic carries to project-root-relative form, in place.

Producers inside the analysis pipeline can write absolute paths or virtual paths (svelte2tsx output like Foo.svelte.__svelte2tsx__.ts). This pass collapses both to the public contract: a path relative to projectRoot with no leading slash and no ./ prefix. A file outside the root gets the ../ form, matching module paths in printed type text — and making the documented "rejoin with projectRoot to get an absolute path" actually hold for it, which dropping the leading slash did not.

message gets the same treatment as file, by textual substitution. A message is free-form, and not every path in one comes from a field this pass can see — import_parse_failed wraps an es-module-lexer error that embeds the file name itself. Scrubbing here means the contract holds for the whole record rather than one field, so a producer can't reintroduce an absolute path through prose.

Exposed for build-tool integrations that bypass the session and collect their own discovery/dep diagnostics — they need the same normalization to match the public contract. Hand it absolute paths. An already-relative file is left alone (relativizing it would resolve against cwd), so this pass can only correct the absolute form — a relative path on a base other than the project root passes through and ships as-is.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

projectRoot

type string

returns

void

mutates

  • diagnostics — — rewrites each diagnostic's `file` and `message`

see also

  • ``finalizeDiagnostics`` — when Svelte virtuals are in play, the position remap must run before this pass (it strips the suffix the remap matches on)

normalizeIncludePatterns
#

source-config.ts view source

(include: readonly string[], projectRoot: string): readonly string[] import {normalizeIncludePatterns} from 'svelte-docinfo/source-config.js';

Normalize discovery include patterns to projectRoot-relative form.

The include-pattern counterpart of normalizeSourceOptions' absolute-entry handling: in-root absolute patterns relativize, out-of-root ones throw, relative ones pass through (see normalizeGlobPattern; exclude gets the same treatment inside normalizeSourceOptions). Applied by the discovery seams (createSourceOptionsWithInclude, discoverSourceFiles) so widening, the anchored baseline ignores, and the glob itself all see canonical relative patterns; projectRoot must be normalized (absolute POSIX, no trailing slash) — pass ModuleSourceOptions.projectRoot.

include

type readonly string[]

projectRoot

type string

returns

readonly string[]

normalizeModulePathsInTypes
#

analyze-core.ts view source

(modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[], options: ModuleSourceOptions, program: Program): void import {normalizeModulePathsInTypes} from 'svelte-docinfo/analyze-core.js';

Normalize the absolute module paths TypeScript embeds in printed type text, in place.

The checker prints a module object as typeof import("<absolute path>"), which reaches output through every checker-printed field — typeSignature on declarations and members, returnType, and the text/name of a TypeJson node. Left alone it makes output machine-dependent (two checkouts of the same source produce different bytes), publishes local filesystem paths on any site that renders typeSignature, and exposes the svelte2tsx virtual suffix that stripVirtualSuffix exists to hide.

A path that resolves to a module in this output is rewritten to that module's ModuleJson.path, so the string doubles as a lookup key: a consumer linkifies with modules.find((m) => m.path === s) and reads a miss as "not a module here." See createModulePathNormalizer for the remaining tiers.

Runs as a whole-output pass rather than at the ~20 typeToString / signatureToString call sites, so a new printing site can't miss it.

modules

type { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

options

program

type Program

returns

void

mutates

  • modules — — rewrites printed type text on declarations and members

normalizeResolveImport
#

dep-resolver.ts view source

also exported from index.ts

(value: ResolveImport | undefined): ImportResolver | undefined import {normalizeResolveImport} from 'svelte-docinfo/dep-resolver.js';

Normalize the public ResolveImport union to an ImportResolver.

Wraps a bare function via wrapResolveImport (fresh synthesized identity); passes a token-paired resolver through unchanged. undefined in, undefined out — callers fall back to the session default. Call once per logical resolver scope: at session construction for the default, per call for an override.

value

type ResolveImport | undefined

returns

ImportResolver | undefined

normalizeSourceOptions
#

source-config.ts view source

(options: ModuleSourceOptions): ModuleSourceOptions import {normalizeSourceOptions} from 'svelte-docinfo/source-config.js';

Normalize and validate ModuleSourceOptions, returning a new options object.

Normalization:

  • projectRoot resolved to absolute via path.resolve (relative paths resolve against cwd)
  • Trailing slash stripped from projectRoot
  • sourcePaths entries and sourceRoot resolved against projectRoot and stored root-relative: ./.. segments collapse (src/../liblib, .''), trailing slashes drop, and absolute entries inside the root relativize (matching loadFile's treatment of path inputs)
  • exclude globs relativized when absolute inside the root (textual prefix strip, since glob metacharacters aren't path segments), so discovery's glob ignore and analysis-time isSource see the same relative pattern

Validation (after normalization):

  1. No sourcePaths entry, sourceRoot, or absolute exclude glob resolves outside projectRoot (out-of-root modules are unrepresentable — module paths and diagnostics are project-root-relative; widened include bases funnel through here too; absolute out-of-root entries get a drop-the-leading-slash hint)
  2. sourcePaths has at least one entry
  3. sourceRoot (if provided and non-empty) is a prefix of all sourcePaths

When sourceRoot is omitted and multiple sourcePaths are provided, sourceRoot is auto-derived as their longest common path prefix. If the paths share no common prefix, the derived root is '' and extractPath produces project-relative module paths.

Returns a fresh object — the input is not mutated. Re-normalization produces a fresh identity, which naturally invalidates the excludeMatcherCache (keyed by options-object identity) without a separate "rebuild a fresh object" rule.

options

returns

ModuleSourceOptions

a new ModuleSourceOptions with normalized fields

throws

  • Error - if validation fails

examples

// Normalization: trailing slash and dot segments collapse, relative projectRoot resolves const normalized = normalizeSourceOptions({projectRoot: '.', sourcePaths: ['src/../src/lib/'], ...}); // normalized.projectRoot is now absolute, normalized.sourcePaths is ['src/lib']

OnDuplicates
#

analyze-core.ts view source

also exported from index.ts

OnDuplicates import type {OnDuplicates} from 'svelte-docinfo/analyze-core.js';

Behavior selector for duplicate declaration names across modules.

  • 'throw' — throw an Error listing every duplicate (strict flat-namespace enforcement)
  • 'warn' — log to log.error and continue
  • OnDuplicatesCallback — custom handler

Omitted entirely: no dispatch runs, but a duplicate_declaration diagnostic is still emitted into the diagnostics array for every collision (the diagnostic is the data; this option is the action).

'throw' trade-off: the throw fires after diagnostics are emitted but before the result is returned, so 'throw' callers never reach the diagnostics array. Callers that want fail-fast *and* diagnostic access should omit onDuplicates and inspect themselves:

const result = await analyze({...}); if (hasErrors(result.diagnostics)) throw new Error('analysis errors');

Or use an OnDuplicatesCallback and stash the data before throwing.

OnDuplicatesCallback
#

analyze-core.ts view source

also exported from index.ts

OnDuplicatesCallback import type {OnDuplicatesCallback} from 'svelte-docinfo/analyze-core.js';

Custom callback for handling duplicate declaration names.

Use the 'throw' or 'warn' shortcuts on onDuplicates for the common cases. Pass a function to fully control reporting.

(call)

type (duplicates: Map<string, DuplicateDeclaration[]>, log: Pick<AnalysisLog, "error">): void

duplicates

type Map<string, DuplicateDeclaration[]>

log

type Pick<AnalysisLog, "error">
returns void

optionalWidened
#

typescript-extract-shared.ts view source

(ctx: ExtractContext, optional: boolean): boolean import {optionalWidened} from 'svelte-docinfo/typescript-extract-shared.js';

Whether the checker widened this optional *property* position with undefined — i.e. whether the optional-widening strip applies. Under exactOptionalPropertyTypes the checker doesn't widen optional properties at all, so every undefined in the type is author-written and stripping would corrupt it: x?: T | undefined trimmed to T, `x?: T | null | undefined to T | null`, and a null-free multi-member union rebuilt through getNonNullableType (x?: E | F printed as (E & {}) | (F & {})).

Property sites only — component props, type-alias and interface properties, class properties. Optional *parameters* and optional *tuple elements* widen under both modes (probed on TS 5.9), so their call sites pass optional unconditionally and never route through this gate. populatePropertyMember's callability query also bypasses it — an optional callable strips in both modes (see getNonOptionalType).

ctx

optional

type boolean

returns

boolean

optionalWideningTarget
#

typescript-extract-type-json.ts view source

(type: Type, checker: TypeChecker, optional: boolean): { target: Type; dropUndefined: boolean; } import {optionalWideningTarget} from 'svelte-docinfo/typescript-extract-type-json.js';

The single owner of the optional-widening strip, shared with getTypeSignature and getNonOptionalType (in typescript-extract-shared.ts) so the flat string, the tree, and the structural queries can't drift. Owns the optional gate too — a non-optional position passes through, so call sites hand over the flag rather than branching around the call. For a type at an optional-flagged position (a ?-marked declaration or tuple element):

  • a non-union carries no separate widening member to strip, so it passes through. Three shapes land here: x?: undefined (the written type and the widening coincide), and x?: unknown / x?: any (both absorb undefined). getNonNullableType must not run on any of them — it answers {} for unknown, which would report x?: unknown as "{}"
  • a null-bearing union keeps its shape and reports dropUndefined — the walk drops only the widening member (so the alias survives) and the printer trims the printed suffix
  • a union left with exactly one member after dropping undefined takes that member directly — it *is* the annotated type. Matters for a bare unconstrained type parameter (c?: E), where getNonNullableType can only answer NonNullable<E> and would print E & {}
  • every other union takes getNonNullableType, which rebuilds the union rather than picking a member (so a union of callables keeps its combined call signature) and preserves the alias symbol

Under exactOptionalPropertyTypes the checker widens optional *properties* not at all, so property sites gate optional off via optionalWidened (in typescript-extract-shared.ts) and never reach the strip; optional parameters and tuple elements widen under both modes and keep passing optional unconditionally.

type

type Type

checker

type TypeChecker

optional

type boolean

returns

{ target: Type; dropUndefined: boolean; }

OverloadJson
#

types.ts view source

also exported from index.ts

{ typeSignature: string; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 4 more ...; returnDescription?: string | undefined; } import {OverloadJson} from 'svelte-docinfo/types.js';

A single function overload signature.

When a function has multiple overload signatures, each public overload is captured here. The implementation signature is excluded.

typeSignature

Full TypeScript type signature for this overload.

type string

parameters

Parameters for this overload.

type { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

genericParams

Generic type parameters for this overload.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

returnType?

Return type for this overload.

type string

returnTypeInfo?

Structured return type; absent when returnType is the whole story (see TypeJson).

type TypeJson

docComment?

JSDoc/TSDoc comment specific to this overload.

type string

returnDescription?

Return value description from @returns tag on this overload.

type string

OverloadJsonInput
#

types.ts view source

{ typeSignature: string; parameters?: { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[] | undefined; ... 4 more ...; return... import type {OverloadJsonInput} from 'svelte-docinfo/types.js';

typeSignature

Full TypeScript type signature for this overload.

type string

parameters?

Parameters for this overload.

type { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

returnType?

Return type for this overload.

type string

returnTypeInfo?

Structured return type; absent when returnType is the whole story (see TypeJson).

type TypeJson

genericParams?

Generic type parameters for this overload.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

docComment?

JSDoc/TSDoc comment specific to this overload.

type string

returnDescription?

Return value description from @returns tag on this overload.

type string

OwnedDirIndex
#

typescript-program.ts view source

OwnedDirIndex import type {OwnedDirIndex} from 'svelte-docinfo/typescript-program.js';

Ancestor-directory index over a path set, maintained as the set mutates.

Module resolution probes directoryExists before trying file candidates inside it (directoryProbablyExists): a directory reported absent has every candidate recorded as a failed lookup with fileExists never consulted, so a directory that exists only as the prefix of served in-memory paths must report present. Refcounted per ancestor so removal is exact — O(path depth) per mutation, O(1) per query; a per-probe scan of the path set would multiply into resolution's hot path (bare-specifier resolution walks many nonexistent ancestor node_modules directories per import).

The index owns its path set, so add/remove are idempotent and a caller can't skew the refcounts by double-adding or by removing something it never added (which would drop an ancestor still holding live paths). Membership bookkeeping therefore stays here rather than in each caller's guard.

add

Count path's ancestor directories into the index. Idempotent.

type (path: string): void

path

type string
returns void

remove

Reverse of add; a path that isn't indexed is a no-op.

type (path: string): void

path

type string
returns void

has

Whether dir is an ancestor of any indexed path (trailing slash tolerated).

type (dir: string): boolean

dir

type string
returns boolean

clear

type (): void

returns void

ParameterJson
#

types.ts view source

also exported from index.ts

{ name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; } import {ParameterJson} from 'svelte-docinfo/types.js';

Parameter information for functions and methods.

Kept distinct from ComponentPropJson despite structural similarity. Function parameters form a tuple with positional semantics: calling order matters (fn(a, b) vs fn(b, a)), may include rest parameters and destructuring patterns.

name

Parameter name (e.g., options, ...args).

type string

type

Resolved TypeScript type string (e.g., string, Record<string, unknown>).

type string

optional

Whether the parameter has a ? token.

type boolean

rest

Whether the parameter uses rest syntax (...args).

type boolean

typeInfo?

Structured type; absent when type is the whole story (see TypeJson).

type TypeJson

description?

Description from @param tag.

type string

defaultValue?

Default value expression from the source (e.g., 'hello', 42).

type string

propertyDescriptions?

Descriptions for properties of a named object parameter, from dotted @param tags (@param obj.prop - ...).

Keyed by the sub-path relative to this parameter — @param obj.prop becomes {prop: '...'}, @param obj.a.b becomes {'a.b': '...'}. Keys are unvalidated against the parameter's actual type (matching the @mutates philosophy); absent when no dotted @param tags reference this parameter. Only populated for function/method/constructor signature parameters.

Matching is by the parameter's name, so destructured parameters (fn({a, b}: T)) are not covered — TypeScript names them __0, with no author-facing identifier for a @param key to reference.

type Record<string, string>

ParameterJsonInput
#

types.ts view source

{ name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; } import type {ParameterJsonInput} from 'svelte-docinfo/types.js';

name

Parameter name (e.g., options, ...args).

type string

type

Resolved TypeScript type string (e.g., string, Record<string, unknown>).

type string

typeInfo?

Structured type; absent when type is the whole story (see TypeJson).

type TypeJson

optional?

Whether the parameter has a ? token.

type boolean

rest?

Whether the parameter uses rest syntax (...args).

type boolean

description?

Description from @param tag.

type string

defaultValue?

Default value expression from the source (e.g., 'hello', 42).

type string

propertyDescriptions?

Descriptions for properties of a named object parameter, from dotted @param tags (@param obj.prop - ...).

Keyed by the sub-path relative to this parameter — @param obj.prop becomes {prop: '...'}, @param obj.a.b becomes {'a.b': '...'}. Keys are unvalidated against the parameter's actual type (matching the @mutates philosophy); absent when no dotted @param tags reference this parameter. Only populated for function/method/constructor signature parameters.

Matching is by the parameter's name, so destructured parameters (fn({a, b}: T)) are not covered — TypeScript names them __0, with no author-facing identifier for a @param key to reference.

type Record<string, string>

parseComment
#

tsdoc.ts view source

(node: Node, sourceFile?: SourceFile): TsdocParsedComment | undefined import {parseComment} from 'svelte-docinfo/tsdoc.js';

Parse JSDoc comment from a TypeScript node.

Extracts and parses all JSDoc tags including:

  • @param - parameter descriptions
  • @returns - return value description (@return accepted as a synonym)
  • @throws - error documentation
  • @example - code examples
  • @deprecated - deprecation warnings
  • @internal - internal-API marker (trailing prose kept)
  • @see - related references
  • @since - version information
  • @default - default value (@defaultValue/@defaultvalue accepted as synonyms)
  • @mutates - mutation documentation (non-standard)
  • @nodocs - exclusion flag (non-standard)

JSDoc blocks tagged @module are excluded entirely (text and tags): a module comment attaches to the file's first statement in the AST, and without the filter it would read as that statement's own docs. extractModuleComment (typescript-exports.ts) owns module comments.

node

the TypeScript node to extract JSDoc from

type Node

sourceFile

source file for full-text tag reads (@see); defaults to the node's own

type SourceFile
default node.getSourceFile()

returns

TsdocParsedComment | undefined

parsed comment with structured metadata, or undefined if no JSDoc found (or only @module blocks)

examples

const tsdoc = parseComment(declarationNode, sourceFile); if (tsdoc) { console.log(tsdoc.text); // main comment text console.log(tsdoc.params); // {paramName: 'description'} }

ParsedExports
#

exports.ts view source

ParsedExports import type {ParsedExports} from 'svelte-docinfo/exports.js';

Result of reading and parsing package.json exports.

entries

All parsed export entries.

type ExportEntry[]

blocked

Specifiers (exact or wildcard patterns) whose export target resolves nothing — a literal null, or a conditions object with no usable target. Node's explicit-exclusion form: "./internal/*": null blocks the subpaths a broader wildcard would otherwise expose. Discovery honors these with Node's best-match semantics: a subpath whose most-specific matching key is blocked is not exported, so its source file is not discovered.

Interpret via createBlockedSpecifierChecker — a naive membership check (blocked.includes(specifier)) is wrong for wildcard keys and ignores the positive keys that can out-match a blocked one.

type string[]

hasExports

Whether the package.json had an exports field.

type boolean

parseGenericParam
#

typescript-extract-shared.ts view source

(param: TypeParameterDeclaration): { name: string; constraint?: string | undefined; defaultType?: string | undefined; } import {parseGenericParam} from 'svelte-docinfo/typescript-extract-shared.js';

Parse a TypeScript generic type parameter declaration into structured info.

param

the TypeScript type parameter declaration node

type TypeParameterDeclaration

returns

{ name: string; constraint?: string | undefined; defaultType?: string | undefined; }

structured GenericParamJson with name, constraint, and default type

parsePackageExports
#

exports.ts view source

(projectRoot: string): Promise<ParsedExports> import {parsePackageExports} from 'svelte-docinfo/exports.js';

Read and parse the exports field from package.json.

Handles all Node.js export formats: strings, objects with conditions, nested conditions, fallback arrays (first usable element), null exclusions (surfaced on blocked for best-match blocking during discovery), and wildcard patterns.

projectRoot

absolute path to project root

type string

returns

Promise<ParsedExports>

parsed ParsedExports, or {entries: [], blocked: [], hasExports: false} if no exports field

populateCallableMember
#

typescript-extract-shared.ts view source

(target: MemberJsonBuild | DeclarationJsonBuild, signatures: readonly Signature[], ctx: ExtractContext, tsdoc: TsdocParsedComment | undefined, paramValidationNode: Node, name: string, includeReturn?: boolean): void import {populateCallableMember} from 'svelte-docinfo/typescript-extract-shared.js';

Populate the callable fields of a declaration or member from its call/construct signatures: typeSignature, parameters, overloads, and (unless includeReturn is false) returnType / returnTypeInfo / returnDescription.

The shared core of every named-callable extractor — standalone functions, interface methods, class methods/constructors, and type-alias function properties. Callers differ in how they obtain signatures (symbol type, constructor declarations, property call signatures) and in their own try/catch + diagnostic kind, so those stay at the callsite; this captures only the identical projection from a resolved signature list onto the build target. No-op when signatures is empty.

target

declaration or member build object (mutated)

type MemberJsonBuild | DeclarationJsonBuild

signatures

public call/construct signatures (signatures[0] is primary)

type readonly Signature[]

ctx

the extraction pass's context

tsdoc

parsed TSDoc for the target (supplies @param/@returns)

type TsdocParsedComment | undefined

paramValidationNode

node validateParamKeys reports unknown_param against

type Node

name

target name, for diagnostic messages

type string

includeReturn

set false for constructors (no return type/description)

type boolean
default true

returns

void

mutates

  • target — sets typeSignature, parameters, overloads, returnType, returnTypeInfo, returnDescription

populatePropertyMember
#

typescript-extract-shared.ts view source

(member: MemberJsonBuild, propType: Type, ctx: ExtractContext, optional: boolean, tsdoc: TsdocParsedComment | undefined, paramValidationNode: Node, name: string, annotation: TypeNode | undefined): void import {populatePropertyMember} from 'svelte-docinfo/typescript-extract-shared.js';

Populate a property-shaped member from its checker type: a callable property becomes kind: 'function' with the full signature field set (generic signatures carry genericParams like method signatures do), everything else gets the flat/structured pair (typeSignature + typeInfo) with the optional-widening strip paired to optional like every checker-backed site. Callability counts local call signatures only (isExternalSignature) — a property typed by an external function documents as the flat type text rather than enumerating the external package's overloads and docs. TSDoc applies here after the projection; members carry @defaultdefaultValue whatever kind the classification settles on (for a callable member it documents the behavior used when the callback is omitted).

The one projection shared by the structural property sites — type-alias properties and interface property signatures — so the same written shape can't extract differently across the two container kinds. Class fields deliberately don't route here: a field holding a function is still a field (kind: 'variable'), while on the structural containers callability is the member's classification.

member

propType

type Type

ctx

optional

type boolean

tsdoc

type TsdocParsedComment | undefined

paramValidationNode

type Node

name

type string

annotation

the written type annotation, when one exists (feeds typeInfo name recovery)

type TypeNode | undefined

returns

void

mutates

  • member — sets kind, doc fields, and either the callable field set or typeSignature/typeInfo

QueryOptions
#

session.ts view source

also exported from index.ts

QueryOptions import type {QueryOptions} from 'svelte-docinfo/session.js';

Per-call input to query.

onDuplicates?

Behavior when duplicate declaration names are found across modules.

type OnDuplicates

log?

Per-call logger override (defaults to the session-level logger).

type AnalysisLog

Reactivity
#

types.ts view source

also exported from index.ts

"$state" | "$state.raw" | "$derived" | "$derived.by" import {Reactivity} from 'svelte-docinfo/types.js';

Reactivity flavor for a variable declaration or class field, captured from the rune call at the initializer (e.g., let count = $state(0)).

Only the value-producing reactivity runes are represented here — $props and $bindable are modeled separately as ComponentPropJson.bindable (and prop-presence on the props array). A renderer wanting "all rune annotations across declarations and props" needs to read both this field and ComponentPropJson.bindable.

  • $state — deeply reactive proxy
  • $state.raw — reference-only reactive (no proxy)
  • $derived — recomputed from dependencies (re-assignable)
  • $derived.by — same as $derived, with a function argument

Detection is syntactic (AST-based) and runs on every analyzed file regardless of extension. Most reactive declarations live in .svelte, .svelte.ts, or .svelte.js, but the field will also surface on any .ts/.js file that uses the same rune call patterns — by design, so documentation pipelines can capture any rune-shaped declaration their conventions choose to expose.

ReExportJson
#

types.ts view source

also exported from index.ts

{ name: string; module: string; typeOnly: boolean; sourceLine?: number | undefined; } import {ReExportJson} from 'svelte-docinfo/types.js';

A same-name re-export edge, from the re-exporting module's side.

Each entry on ModuleJson.reExports records that the module's source contains export {name} from ... where the canonical declaration lives in module. This is the forward view of the same fact that alsoExportedFrom records on the canonical declaration — consumers resolve the canonical by (module, name), the same lookup contract as aliasOf.

Same-name re-exports of analyzed source only. Renamed re-exports appear as declarations with aliasOf in the re-exporting module; star exports live in ModuleJson.starExports; external re-exports in ModuleJson.externalReExports / externalStarExports. Use resolveExportSurface (in postprocess.ts) to combine all of these into a module's full export surface — it handles the name dedup (a documented same-name re-export appears both here and as a synthesized alias declaration) and the ES star semantics (explicit exports shadow star-projected ones, names ambiguous between stars are excluded, default doesn't project).

module points at the *canonical* module (multi-hop chains are resolved), not the immediate specifier in the export statement. For Svelte default-slot re-exports (export {default} from './X.svelte'), name is the component name derived from the filename ('X'), matching the canonical declaration's name — the same exception documented on aliasOf. Because of that re-keying, two entries in one module can share a name (a re-keyed component colliding with a same-name re-export from another module); (module, name) pairs remain unique (exact duplicates are deduped at construction).

@nodocs on the export statement suppresses the entry (and the alsoExportedFrom back-link). When the canonical declaration itself is @nodocs, or the canonical module isn't part of the analyzed set, the entry still exists but has no matching back-link — the same presence caveat as aliasOf.module and starExports.

name

Exported name — the canonical declaration's name in module.

type string

module

Module path (relative to sourceRoot) where the canonical declaration lives.

type string

typeOnly

Whether the statement (export type {A} from ...) or specifier (export {type A} from ...) is type-only — the name is erased at runtime and importable only via import type.

type boolean

sourceLine?

1-based line of the export specifier in this module's source. When identical (name, module) edges are deduped (Svelte default-slot re-keying), the smallest line is kept.

type number

ReExportJsonInput
#

types.ts view source

{ name: string; module: string; typeOnly?: boolean | undefined; sourceLine?: number | undefined; } import type {ReExportJsonInput} from 'svelte-docinfo/types.js';

name

Exported name — the canonical declaration's name in module.

type string

module

Module path (relative to sourceRoot) where the canonical declaration lives.

type string

typeOnly?

Whether the statement (export type {A} from ...) or specifier (export {type A} from ...) is type-only — the name is erased at runtime and importable only via import type.

type boolean

sourceLine?

1-based line of the export specifier in this module's source. When identical (name, module) edges are deduped (Svelte default-slot re-keying), the smallest line is kept.

type number

referenceSymbolName
#

typescript-extract-type-json.ts view source

(type: Type, checker: TypeChecker): string | undefined import {referenceSymbolName} from 'svelte-docinfo/typescript-extract-type-json.js';

The symbol name of a named generic instantiation (Snippet<[a: string]>, Map<string, B>) — checker Reference-flagged, non-anonymous symbol, carrying type arguments — or undefined for everything else. One predicate for the two decisions that must agree: the callable-classification exception (such a type is a reference node even when it has call signatures) and the object branch's reference emission. Tuples never match (their references carry no symbol); bare and aliased signatures are Anonymous-flagged; non-generic callable interfaces either aren't Reference-flagged (thisless) or carry no type arguments (the declared type of a this-referencing interface or a class is its own Reference with an empty argument list) — all of these stay function nodes.

type

type Type

checker

type TypeChecker

returns

string | undefined

remapVirtualDiagnosticPositions
#

svelte.ts view source

(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[], virtualFiles: Iterable<...>): void import {remapVirtualDiagnosticPositions} from 'svelte-docinfo/svelte.js';

Remap diagnostic positions emitted against svelte2tsx virtuals back to original .svelte positions, in place.

Extractors locate diagnostics via getNodeLocation, which reads whatever source file the node lives in — for a <script module> declaration that's the virtual. normalizeDiagnosticPaths later rewrites file to the .svelte path but has no position input, so without this pass the published combination is the original file with the virtual's line — actively misleading. Runs over the whole batch keyed by file, so a diagnostic emitted against *another* component's virtual (a rename re-export re-analyzes its canonical in the canonical's own source file) remaps through that virtual's map.

Must run before normalizeDiagnosticPaths, which strips the virtual suffix this pass matches on. An unmappable position (no source map, or a node svelte2tsx synthesized) drops line/column — absence over a virtual line.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

virtualFiles

type Iterable<SvelteVirtualFile>

returns

void

mutates

  • diagnostics — — rewrites `line`/`column` on virtual-file entries

resolveComponentAliases
#

postprocess.ts view source

also exported from index.ts

(modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[], contextModules?: readonly { ...; }[]): { ...; }[] import {resolveComponentAliases} from 'svelte-docinfo/postprocess.js';

Copy props/acceptsChildren/lang/etc. from canonical component declarations onto synthesized component-aliased declarations.

Renamed Svelte component re-exports (export {default as Foo} from './X.svelte') are emitted as kind: 'component' placeholders by analyzeExports, with aliasOf pointing at the canonical. The canonical's component-specific fields are only available after analyzeSvelteModule synthesizes the canonical declaration, so the copy happens here in phase 2 once all modules are analyzed.

Call this *after* mergeReExports — both walk the same modules array but read/write disjoint fields, so order between them only matters for clarity.

Pure: the input array and its objects are never mutated. Aliases with a resolvable canonical are replaced by filled copies (canonical field values are shared by reference, not cloned); everything else flows through ===-equal.

modules

the analyzed modules (parsed ModuleJsons)

type { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

contextModules

canonical-lookup-only modules that never appear in output — gated component canonicals (the internal/ convention) analyzed as fill context by analyzeCore. An alias whose aliasOf.module is gated fills from here; an emitted module with the same path (impossible by construction) would win the lookup

type readonly { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLin...
default []

returns

{ path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

a new array with component-only fields filled on aliased component declarations

resolveExportSurface
#

postprocess.ts view source

also exported from index.ts

(modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[], path: string): ExportSurface | null import {resolveExportSurface} from 'svelte-docinfo/postprocess.js';

Resolve a module's full export surface from the analyzed model, applying ES module semantics to star exports.

Combines the module's own declarations (including synthesized aliases), reExports edges, externalReExports, and transitively-resolved starExports into one deduped, name-sorted list. The ES rules applied to star projection:

  • explicit exports (declarations, edges, externals) shadow star-projected names
  • a name projected by two stars that resolve to *different* canonicals is ambiguous and excluded (same canonical through a diamond is included once)
  • default is never star-projected — including canonical Svelte component declarations, which represent their file's default export. (Caveat: a star-projected re-export edge whose canonical is a component is treated as a default-slot re-export and skipped; a <script module> const sharing the component's exact name would be skipped with it.)

A Position-3 alias and its reExports edge are the same fact — the declaration entry wins, inheriting the edge's typeOnly.

Cyclic star graphs terminate by contributing nothing along the back-edge (an approximation of ES fixpoint resolution — fine in practice). Surfaces resolved inside a cycle are path-relative and not memoized, so sibling star paths resolve independently rather than inheriting them. Star targets missing from modules are reported in unresolvedStarExports rather than guessed at; externalStarExports aggregates external star specifiers reachable from the module, whose names are unknowable.

modules

the analyzed modules (parsed ModuleJsons — run wire JSON through AnalyzeResultJson.parse first)

type { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

path

the module to resolve, as a ModuleJson.path value

type string

returns

ExportSurface | null

the resolved surface, or null when path isn't in modules

ResolveImport
#

dep-resolver.ts view source

also exported from index.ts

ResolveImport import type {ResolveImport} from 'svelte-docinfo/dep-resolver.js';

Public resolver shape accepted across the API — a bare ResolveImportFn or the token-paired ImportResolver.

Every entry point that accepts resolveImport (analyze, analyzeFromFiles, createAnalysisSession, and the session's setFile/setFiles per-call override) takes this union, so the same value copy-pastes between them. Pass:

  • a bare function for the common case — a fresh cache identity is synthesized at the boundary. Correct for one-shot use (analyze, analyzeFromFiles) and for a session default (wrapped once at construction, so identity is stable for the session's lifetime).
  • an ImportResolver with a stable identity when you need the session to reuse its resolve cache across calls where the same logical resolver is rebuilt as a fresh closure (Vite/Rollup plugins). A bare function handed to a *per-call* setFile/setFiles override is treated as a distinct resolver each call (fresh identity → touched files re-resolve), which is the expected behavior for a deliberate one-off override.

ResolveImportFn
#

dep-resolver.ts view source

also exported from index.ts

ResolveImportFn import type {ResolveImportFn} from 'svelte-docinfo/dep-resolver.js';

Bare import-resolver function — the convenience form.

Resolve an import specifier to an absolute file path, or null if the specifier is unresolvable (external package, missing file, etc.). May return synchronously or asynchronously; sync returns are awaited harmlessly in the session's parallel resolve phase.

(call)

type (specifier: string, fromFile: string): string | Promise<string | null> | null

specifier

type string

fromFile

type string
returns string | Promise<string | null> | null

ResolverFailedDiagnostic
#

diagnostics.ts view source

{ specifier: string; file: string; message: string; severity: "error" | "warning"; kind: "resolver_failed"; line?: number | undefined; column?: number | undefined; } import {ResolverFailedDiagnostic} from 'svelte-docinfo/diagnostics.js';

Import resolver threw while resolving a specifier.

Distinguishes a buggy resolver from a legitimately unresolvable specifier: resolvers that return null for unknown specifiers stay silent (the normal "external package" case); resolvers that *throw* surface here so consumers can fix the resolver. Recoverable — the session treats the throw as null and continues, so analysis still runs but with a missing dependency edge.

Emitted at ingest time by the session's resolve phase.

specifier

The import specifier the resolver failed on.

type string

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "resolver_failed"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

resolveTypeInfo
#

typescript-extract-type-json.ts view source

(type: Type, checker: TypeChecker, aliasRegistry: AliasRegistry | undefined, optional: boolean, options?: ResolveTypeInfoOptions | undefined): TypeJson | undefined import {resolveTypeInfo} from 'svelte-docinfo/typescript-extract-type-json.js';

The structured type for an output field, or undefined when the flat string is the whole story (the TypeJson absence contract).

Matches getTypeSignature's optional handling by construction — both select through optionalWideningTarget (see there for the case split); x?: undefined stays terminal. What's specific to the tree: union members walk the union's origin (see unionMemberTypes), so member order matches the printed string and a null-bearing optional alias survives: dropping the widening from the origin list leaves the alias-carrying union as the sole member, which the 1-member collapse promotes to the root (a?: A where A is nullable yields the A union, matching the flat string's printed-string surgery). When no usable origin exists both degrade together, bounded: checker- internal member order, alias lost.

Self-named alias roots relax the contract. checker.typeToString prints a type carrying an alias symbol as that alias's bare name, so a type alias's own typeSignature reads "StrArr", not "string[]" — there is no descriptive flat sibling for the tree to defer to, and the usual gate would leave type StrArr = string[] and type Pair = [string, number] with no type information at all. When the type reports ownAliasName as its alias the node is emitted regardless, except for the kinds members already covers (REDUNDANT_WITH_MEMBERS). Interned types (intrinsics, literals) never carry the alias symbol, so type Str = string still prints structurally and stays absent.

Recovered roots relax it too. When writtenNode or aliasRegistry names a nameless type, the tree emits {kind: 'reference', name} (see buildWrittenNameMap / recoveredReference) — and at the root that node is emitted even though a bare reference normally stays absent: a checker-named bare reference defers to a flat sibling printing the same name, while a recovered one stands against a flat sibling printing the anonymous expansion, so the name exists only in the tree.

type

the checker type the flat string was printed from

type Type

checker

TypeScript type checker

type TypeChecker

aliasRegistry

the analyzed set's alias registry, or undefined when no pre-pass ran; required so a call site can't silently opt out of registry recovery

type AliasRegistry | undefined

optional

whether the declaration site carries a ? token (pairs the widening strip, like getTypeSignature)

type boolean

options?

the declaration-site context: ownAliasName at a type-alias declaration (see BuildTypeJsonOptions.skipAliasName; also suppresses registry hits at the root — the self-skip), writtenNode wherever a written annotation exists (the name-recovery source for aliases TypeScript dropped)

optional

returns

TypeJson | undefined

ResolveTypeInfoOptions
#

typescript-extract-type-json.ts view source

ResolveTypeInfoOptions import type {ResolveTypeInfoOptions} from 'svelte-docinfo/typescript-extract-type-json.js';

Declaration-site context for resolveTypeInfo — see its param doc.

ownAliasName?

At a type-alias declaration site, the alias's own name.

type string

writtenNode?

The declaration's written type annotation, when one exists.

type TypeNode

restElementForms
#

typescript-extract-type-json.ts view source

(elementType: Type, checker: TypeChecker, aliasRegistry: AliasRegistry | undefined, writtenNode?: TypeNode | undefined): { ...; } import {restElementForms} from 'svelte-docinfo/typescript-extract-type-json.js';

Both output forms of a rest tuple element, which present it as the array it collects (...rest: B[] carries "B[]" and an array node) — the flat/structured counterpart of buildTuple's array rewrap, for extractSnippetParameters. Paired in one function so the two can't be half applied: a printed array beside a non-array tree would describe two different types.

The string prints through the checker's internal createArrayType so parenthesization is the printer's own — hand rules get the edges wrong (a readonly B[] element *must* parenthesize or readonly B[][] denotes a different type, a bare union needs parens, a unique symbol prints as a typeof query). If the internal factory disappears, the fallback parenthesizes everything but bare identifier paths — sometimes over-parenthesized, never a different type. The tree is presence-gated like any array node (present when the element is a reference or carries structure). writtenNode and aliasRegistry feed name recovery like resolveTypeInfo's — the caller passes the same annotation and registry it hands the sibling tree, so the two projections of one element can't disagree on a recovered name.

elementType

type Type

checker

type TypeChecker

aliasRegistry

type AliasRegistry | undefined

writtenNode?

type TypeNode
optional

returns

{ type: string; typeInfo: TypeJson | undefined; }

runCli
#

cli.ts view source

(argv?: string[]): Promise<number> import {runCli} from 'svelte-docinfo/cli.js';

Run the CLI with the given arguments.

argv

command line arguments (defaults to process.argv)

type string[]
default process.argv

returns

Promise<number>

exit code: 0 for success, 1 if errors in diagnostics, 2 for CLI errors

scrubVirtualSuffixes
#

source.ts view source

(text: string): string import {scrubVirtualSuffixes} from 'svelte-docinfo/source.js';

Remove every occurrence of the virtual suffix from free-form text.

The text twin of stripVirtualSuffix: that one strips a path's trailing suffix, this one scrubs a prose string (a diagnostic message) that may embed virtual paths anywhere. Both readings of the suffix live here so a suffix change has one home.

text

type string

returns

string

selectDeclarationNode
#

typescript-extract-shared.ts view source

(symbol: Symbol): Declaration | undefined import {selectDeclarationNode} from 'svelte-docinfo/typescript-extract-shared.js';

Select the declaration node that carries a symbol's documented meaning.

Mirrors inferDeclarationKind's flag priority. A symbol can merge value and type meanings — const Foo = ... + type Foo = ... (the schema/type pattern) or const Foo + interface Foo share one symbol with combined flags — and there valueDeclaration points at the value while the flags resolve a type-space kind, so value-first selection would document the value's type under the type's kind. When the flags resolve type-space (interface, type, enum), the first matching type-space declaration is selected instead; value-space kinds (and unmerged symbols) keep the valueDeclaration-first selection. The merged value meaning goes undocumented under the one-declaration-per-export-name model — the type is what consumers look up.

symbol

type Symbol

returns

Declaration | undefined

SetFileOptions
#

session.ts view source

also exported from index.ts

SetFileOptions import type {SetFileOptions} from 'svelte-docinfo/session.js';

Options for a per-file or per-batch resolver override.

Identity is required (not optional) — silently coalescing missing identities to a function reference would destroy cache reuse when the same logical resolver is wrapped in fresh closures across calls.

resolveImport?

Per-call override of the session-default resolver — a bare ResolveImportFn or a token-paired ImportResolver (see ResolveImport).

A bare function is normalized with a fresh identity on each call, so the files touched by this call re-resolve rather than cache-hitting — the expected behavior for a deliberate one-off override. To reuse the resolve cache across calls, pass an ImportResolver with a stable identity.

type ResolveImport

SetFileResult
#

session.ts view source

also exported from index.ts

SetFileResult import type {SetFileResult} from 'svelte-docinfo/session.js';

Result of setFile (single-file ingest).

changed is true when content or the mode-specific cache key (resolver identity for lex+resolve; dependency snapshot for pre-resolved) differed from the cached entry — the owned entry was rewritten. An LS push accompanies the entry write only when the file is TS/JS or has a successful Svelte virtual; CSS/JSON and transform-failed Svelte rewrite the entry without touching the LS. false indicates a cache-hit no-op: the cached ingestDiagnostics are returned but no work ran.

changed

Whether content or the mode-specific cache key differed from the cached entry.

type boolean

diagnostics

Ingest-time diagnostics for this file (durable on the entry).

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

SetFilesResult
#

session.ts view source

also exported from index.ts

SetFilesResult import type {SetFilesResult} from 'svelte-docinfo/session.js';

Result of setFiles (batch ingest).

Carries both aggregate views (changedIds, pre-flattened diagnostics) and a structured perFile map. HMR-style consumers want changedIds.size > 0 as the hot check; LSP-style consumers want per-file diagnostic association via perFile. Both are populated in the same single-pass walk over the batch — no extra cost.

changedIds

IDs whose content or mode-specific cache key differed from the cached entry — the subset of input file IDs that actually triggered work. Empty when every file was a cache-hit no-op.

type ReadonlySet<string>

diagnostics

Pre-flattened union of every file's ingestDiagnostics. Consumers can group by Diagnostic.file for per-file publish — already project-root-relative, normalized at rest before the entry was stored.

The array is fresh but its elements are the *stored* diagnostic objects, so mutating one (re-running normalizeDiagnosticPaths against a different root, say) corrupts the session's own state. Copy before mutating.

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

perFile

Per-file SetFileResult keyed by input file ID. Use this when the grouping Diagnostic.file would do isn't enough — e.g., LSP wanting to publish empty-diagnostic-list updates for files that ingested cleanly.

type ReadonlyMap<string, SetFileResult>

SignatureAnalysisDiagnostic
#

diagnostics.ts view source

{ functionName: string; file: string; message: string; severity: "error" | "warning"; kind: "signature_analysis_failed"; line?: number | undefined; column?: number | undefined; } import {SignatureAnalysisDiagnostic} from 'svelte-docinfo/diagnostics.js';

Function/method signature analysis failed.

functionName

Name of the function or method.

type string

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "signature_analysis_failed"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

SnippetDeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "snippet"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 15 more ...; sourceLine?: number | undefined; } import {SnippetDeclarationJson} from 'svelte-docinfo/types.js';

A Svelte snippet declaration exported from <script module>. Has parameters.

kind

type "snippet"

parameters

Snippet parameters.

type { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

alsoExportedFrom

Module paths (relative to sourceRoot) that re-export this declaration under the same name. The canonical declaration lives in this module's declarations array; these paths are additional import locations for the same thing.

The same edges appear from the re-exporting side as ModuleJson.reExports — use that when asking "what does this module re-export" instead of inverting these arrays. The two can disagree at the margins: a reExports entry whose canonical declaration is @nodocs (or whose module isn't in the analyzed set) has no back-link here.

Consumer note: To build a complete re-export map, scan two fields:

  1. alsoExportedFrom on each declaration — same-name re-exports
  2. aliasOf on declarations — renamed re-exports (separate declarations)

type string[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

aliasOf?

For renamed re-exports (export {foo as bar}), points to the original declaration. This declaration's name is the alias; aliasOf.name is the original name.

For renames out of the default slot (export {default as bar} from './x' where ./x is export default ...), aliasOf.name is 'default' — the canonical's actual symbol name. Consumers locate the canonical by (aliasOf.module, aliasOf.name).

Svelte component exception: when the source is a .svelte file (e.g., export {default as Foo} from './X.svelte'), the canonical's name is the component name (derived from the filename), so aliasOf.name is the component name ('X'), NOT 'default'. Consumers that branch on aliasOf.name === 'default' to detect default-rename should additionally check whether aliasOf.module ends with .svelte.

Different from alsoExportedFrom: aliases create new API surface names, while alsoExportedFrom tracks additional import paths for the same name.

type { module: string; name: string; }

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

sortModules
#

postprocess.ts view source

(modules: { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: number | undefined; } | ... 7 more ... | { ...; })[]; ... 7 more ...; moduleComment?: string | undefined; }[]): { ...; }[] import {sortModules} from 'svelte-docinfo/postprocess.js';

Sort modules alphabetically by path for deterministic output and cleaner diffs.

Case-insensitive order (compareStrings) so the output is environment-independent.

modules

the modules to sort

type { path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

returns

{ path: string; declarations: ({ kind: "function"; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 19 more ...; sourceLine?: numbe...

a new sorted array (does not mutate input)

SourceFileInfo
#

source.ts view source

also exported from index.ts

SourceFileInfo import type {SourceFileInfo} from 'svelte-docinfo/source.js';

File information for source analysis.

Provides file content to analysis functions from any source: file system, build pipeline, or in-memory.

Note: content is required to keep analysis functions pure (no hidden I/O). Callers are responsible for reading file content before analysis.

id

Absolute path to the file.

type string

content

File content (required - analysis functions don't read from disk).

type string

dependencies?

Pre-resolved absolute file paths of modules this file imports.

Opt-in optimization — when supplied, the session treats this as the authoritative dependency set for the file and skips its own lex+resolve pass for this entry. Build-tool integrations (e.g., Gro's filer) that already maintain a dependency graph can hand it over directly instead of paying the lex+resolve cost twice.

Omit (undefined) → default behavior — the session lexes import specifiers from content and resolves them via its ImportResolver. This is the right choice when the caller doesn't already have a graph.

Only include resolved local imports — node_modules paths are filtered out at storage time by the configured isSource predicate either way.

Trust contract — the session treats this array as authoritative and does not cross-check against the file's content. Edges declared here are accepted as-is, even if the source code doesn't actually import them; edges that *are* in content but missing from this array are silently omitted. The lex+resolve fallback path has no such hole — its edges are always grounded in syntactic imports. Build-tool integrations that supply this field own the correctness of the graph they hand over.

Type-only imports (import type {...}) are the most common asymmetry versus the lex+resolve path: the default lex (es-module-lexer) keeps them; pre-resolved callers backed by a Gro-style filer typically drop them. Both are intentional within their respective contracts.

Cache semantics: the session compares this array element-wise (shallow equality) against the snapshot stored from the prior call — a fresh array with identical contents cache-hits, while any length, element, or order difference invalidates. Callers that produce fresh arrays per call (e.g., Gro's [...filer.dependencies.keys()]) reuse the cache cleanly across persistent-session calls.

Order is significant. Reordering without a content change is treated as a real change — sort upstream if you want order-insensitive caching. Map-iteration-order callers (e.g., a Gro filer emitting [...filer.dependencies.keys()]) are naturally stable across calls for the same content, so no defensive sort is needed there.

type readonly string[]

SourceMapFailedDiagnostic
#

diagnostics.ts view source

{ file: string; message: string; severity: "error" | "warning"; kind: "source_map_failed"; line?: number | undefined; column?: number | undefined; } import {SourceMapFailedDiagnostic} from 'svelte-docinfo/diagnostics.js';

Source map parsing failed for a Svelte virtual file.

Analysis continues without position mapping: query-time diagnostics drop line/column rather than point into svelte2tsx-generated TS — those emitted against the virtual via remapVirtualDiagnosticPositions, svelte_prop_failed at its own emission site — while declaration sourceLines fall back to virtual positions. Rare; usually signals a malformed or incompatible svelte2tsx output.

Emitted at ingest time by transformSvelteSource (in svelte.ts); flows through setFile/setFiles ingest diagnostics rather than the analysis pass.

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "source_map_failed"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

SourceOptionsDefaults
#

source-config.ts view source

also exported from index.ts

SourceOptionsDefaults import type {SourceOptionsDefaults} from 'svelte-docinfo/source-config.js';

Default source options preset (without projectRoot).

Use with createSourceOptions to build complete options. Contains all ModuleSourceOptions fields except projectRoot, which is provided separately as the first argument to createSourceOptions.

sourcePaths

Source directory paths to include, relative to projectRoot.

Absolute entries are accepted when they resolve inside projectRoot and are stored root-relative; an entry resolving outside it throws (a root-anchored '/src/lib' is taken as filesystem-absolute, not shorthand — the error hints to drop the slash). Normalized (./.. segments collapsed, trailing slashes stripped) by normalizeSourceOptions, which returns a new options object.

type string[]

['src/lib'] // single source directory
['src/lib', 'src/routes'] // multiple directories

sourceRoot?

Source root for extracting relative module paths, relative to projectRoot.

Normalized like sourcePaths entries (absolute-inside-root accepted and stored root-relative, ./.. collapsed — so '.' becomes '', trailing slashes stripped, out-of-root throws) by normalizeSourceOptions, which returns a new options object.

When omitted:

  • Single sourcePath: defaults to that path
  • Multiple sourcePaths: auto-derived as the longest common directory prefix (or '' when paths share no common prefix — produces project-relative module paths)

type string

'src/lib' // module paths like 'foo.ts', 'utils/bar.ts'
'src' // module paths like 'lib/foo.ts', 'routes/page.svelte'
'' // or '.': module paths stay project-relative, e.g. 'src/lib/foo.ts'

exclude

Glob patterns to exclude from analysis, relative to projectRoot; an absolute pattern inside the root relativizes at normalizeSourceOptions, an out-of-root one throws.

Applied at both stages of the pipeline:

  • Discovery time by globFiles/discoverFromExports, preventing matched files from being loaded.
  • Analysis time by isSource() against relative(projectRoot, absolutePath), catching files that enter through TypeScript import resolution (e.g., a source file imports a test helper).

Beneath it, the always-on baseline (node_modules + dot-directories below a matched source path — see hasBaselineExcludedSegment) applies independently; overriding exclude can't strip it.

The defaults exclude tests and internal/ directories — the src/lib/internal/ convention: internal modules ship in the package for public modules to import (typically paired with an "./internal/*": null package.json exports entry blocking consumer imports), but aren't part of the documented surface. The override surfaces accept a (defaults) => patterns callback (see ExcludeOption) so extending the defaults doesn't require restating them; this normalized field is always a plain array.

analyzeFromFiles accepts a top-level exclude shortcut that merges into this field.

Compiled to a matcher once per options object via picomatch and cached by reference; mutating this array post-isSource-call has no effect — pass through normalizeSourceOptions (which returns a fresh object) or otherwise build a new options object to apply changes.

type string[]

default `['**\/*.test.ts', '**\/*.spec.ts', '**\/internal/**']`

getAnalyzerType

Determine which analyzer to use for a file path.

Called for files in source directories. Return an AnalyzerType or null to skip:

  • 'typescript' — TypeScript/JS files analyzed via TypeScript compiler API
  • 'svelte' — Svelte components analyzed via svelte2tsx + TypeScript compiler API
  • 'css' — CSS files included as modules with no declarations
  • 'json' — JSON files included as modules with no declarations
  • null — skip the file

type (path: string): AnalyzerType | null

path

type string
returns AnalyzerType | null
// Add MDsveX support getAnalyzerType: (path) => (path.endsWith('.svx') ? 'svelte' : getDefaultAnalyzer(path))
// Include .d.ts files (the default excludes them) getAnalyzerType: (path) => (path.endsWith('.d.ts') ? 'typescript' : getDefaultAnalyzer(path))

SourceOptionsOverrides
#

source-config.ts view source

also exported from index.ts

SourceOptionsOverrides import type {SourceOptionsOverrides} from 'svelte-docinfo/source-config.js';

Override surface for building ModuleSourceOptions: all fields optional, with exclude widened to ExcludeOption so callers can extend the default patterns instead of replacing them. Accepted by createSourceOptions / createSourceOptionsWithInclude and the option types layered on them (AnalyzeFromFilesOptions.sourceOptions, the Vite plugin's sourceOptions).

sourcePaths?

Source directory paths to include, relative to projectRoot.

Absolute entries are accepted when they resolve inside projectRoot and are stored root-relative; an entry resolving outside it throws (a root-anchored '/src/lib' is taken as filesystem-absolute, not shorthand — the error hints to drop the slash). Normalized (./.. segments collapsed, trailing slashes stripped) by normalizeSourceOptions, which returns a new options object.

type string[]

['src/lib'] // single source directory
['src/lib', 'src/routes'] // multiple directories

sourceRoot?

Source root for extracting relative module paths, relative to projectRoot.

Normalized like sourcePaths entries (absolute-inside-root accepted and stored root-relative, ./.. collapsed — so '.' becomes '', trailing slashes stripped, out-of-root throws) by normalizeSourceOptions, which returns a new options object.

When omitted:

  • Single sourcePath: defaults to that path
  • Multiple sourcePaths: auto-derived as the longest common directory prefix (or '' when paths share no common prefix — produces project-relative module paths)

type string

'src/lib' // module paths like 'foo.ts', 'utils/bar.ts'
'src' // module paths like 'lib/foo.ts', 'routes/page.svelte'
'' // or '.': module paths stay project-relative, e.g. 'src/lib/foo.ts'

getAnalyzerType?

Determine which analyzer to use for a file path.

Called for files in source directories. Return an AnalyzerType or null to skip:

  • 'typescript' — TypeScript/JS files analyzed via TypeScript compiler API
  • 'svelte' — Svelte components analyzed via svelte2tsx + TypeScript compiler API
  • 'css' — CSS files included as modules with no declarations
  • 'json' — JSON files included as modules with no declarations
  • null — skip the file

type (path: string): AnalyzerType | null

path

type string
returns AnalyzerType | null
// Add MDsveX support getAnalyzerType: (path) => (path.endsWith('.svx') ? 'svelte' : getDefaultAnalyzer(path))
// Include .d.ts files (the default excludes them) getAnalyzerType: (path) => (path.endsWith('.d.ts') ? 'typescript' : getDefaultAnalyzer(path))

exclude?

type ExcludeOption

specifierExportedName
#

typescript-extract-type-json.ts view source

(symbol: Symbol): string | undefined import {specifierExportedName} from 'svelte-docinfo/typescript-extract-type-json.js';

The name a module exports an aliased symbol under, or undefined when the alias names no export (a default or namespace import, a star re-export).

The one rule shared by both name-recovery channels — this file's written-name lookup and externalTypeRefText's textual substitution (typescript-extract-shared.ts). Both specifier kinds carry the name, on opposite sides of their own as: an ImportSpecifier takes the module's side, its propertyName (import type {Bag as B}Bag, B being this file's private spelling), while an ExportSpecifier *is* the module's side, so its name is what it publishes (export {Internal as Public}Public, Internal being the other module's). Unrenamed, both collapse to the one name written.

Stopping at a specifier rather than resolving the whole alias chain is what makes the result importable: the chain ends at the *declaration's* name, which a module renaming on the way out never exports — recovering Internal there names something no consumer of that module can reach.

symbol

type Symbol

returns

string | undefined

stripVirtualSuffix
#

source.ts view source

(path: string): string import {stripVirtualSuffix} from 'svelte-docinfo/source.js';

Strip the svelte2tsx virtual file suffix from a path, if present.

Maps Component.svelte.__svelte2tsx__.ts back to Component.svelte. Returns the path unchanged if the suffix is not present.

path

type string

returns

string

SVELTE_COMPONENT_ALIAS_SUFFIX
#

source.ts view source

"__SvelteComponent_" import {SVELTE_COMPONENT_ALIAS_SUFFIX} from 'svelte-docinfo/source.js';

Suffix svelte2tsx appends to the synthesized component const/type alias (<Name>__SvelteComponent_). One of the generated-identifier shapes isSvelte2tsxInternal filters.

SVELTE_VIRTUAL_SUFFIX
#

source.ts view source

".__svelte2tsx__.ts" import {SVELTE_VIRTUAL_SUFFIX} from 'svelte-docinfo/source.js';

Suffix appended to .svelte file paths to create virtual TypeScript file paths.

Used by svelte2tsx integration: Component.svelteComponent.svelte.__svelte2tsx__.ts.

SveltePropDiagnostic
#

diagnostics.ts view source

{ componentName: string; propName: string; file: string; message: string; severity: "error" | "warning"; kind: "svelte_prop_failed"; line?: number | undefined; column?: number | undefined; } import {SveltePropDiagnostic} from 'svelte-docinfo/diagnostics.js';

Svelte prop type resolution failed.

file is the original .svelte path, so line/column are present only when the prop's declaration lives in the component's own virtual *and* maps back to the original source — an imported props type or a node svelte2tsx synthesized leaves the position absent rather than publishing a virtual line, the rule remapVirtualDiagnosticPositions applies to extractor diagnostics.

componentName

Name of the component.

type string

propName

Name of the prop.

type string

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "svelte_prop_failed"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

SvelteVirtualFile
#

svelte.ts view source

SvelteVirtualFile import type {SvelteVirtualFile} from 'svelte-docinfo/svelte.js';

Pre-transformed Svelte virtual file data.

Produced by transformSvelteSource and consumed by analyzeSvelteModule to provide checker-backed analysis of Svelte components.

virtualPath

Path used for the virtual file in the TypeScript program.

type string

content

svelte2tsx transformed TypeScript content.

type string

sourceMap

Source map for position mapping back to the original .svelte file.

type TraceMap | null

scriptKind

Parser treatment for the virtual: ts.ScriptKind.JS for JS-only components (no lang="ts"), so the checker reads their JSDoc types — the parse tolerates the TS-only statements svelte2tsx emits (a grammar diagnostic, never surfaced) — else ts.ScriptKind.TS. The single encoding of the script language: ComponentDeclarationJson.lang is derived from it at output.

type ScriptKind

synthesizeSnippetTypeSignature
#

svelte.ts view source

(parameters: { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]): string import {synthesizeSnippetTypeSignature} from 'svelte-docinfo/svelte.js';

Synthesize a Snippet<[...]> type string from structured parameters.

Used for kind: 'snippet' declarations where the raw svelte2tsx type is implementation noise. Renders the normalized form — an optional parameter as b?: number, matching the structured parameter fields rather than the checker's widened b?: number | undefined, and a rest parameter with its ... marker (Svelte compile-errors rest parameters in {#snippet}, but analysis never runs that check — svelte2tsx passes them through, so the invalid-but-parseable case renders faithfully rather than dropping the marker).

parameters

type { name: string; type: string; typeInfo?: TypeJson | undefined; optional?: boolean | undefined; rest?: boolean | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]

returns

string

throwOnDuplicates
#

analyze-core.ts view source

also exported from index.ts

(duplicates: Map<string, DuplicateDeclaration[]>, log: Pick<AnalysisLog, "error">): void import {throwOnDuplicates} from 'svelte-docinfo/analyze-core.js';

Convenience OnDuplicatesCallback that throws on any duplicate.

duplicates

type Map<string, DuplicateDeclaration[]>

log

type Pick<AnalysisLog, "error">

returns

void

throws

  • Error - listing every duplicate name and module location

to_error_message
#

error.ts view source

(value: unknown, fallback?: string | undefined): string import {to_error_message} from 'svelte-docinfo/error.js';

Extract a human-readable message from an unknown thrown value.

value

type unknown

fallback?

type string
optional

returns

string

toPosixPath
#

paths.ts view source

(p: string): string import {toPosixPath} from 'svelte-docinfo/paths.js';

Normalize a path to POSIX form (forward slashes).

Replaces every backslash with a forward slash. Idempotent: forward-slash input returns unchanged. Empty string returns empty string.

p

type string

returns

string

examples

toPosixPath('C:\\proj\\src\\lib\\foo.ts') // => 'C:/proj/src/lib/foo.ts' toPosixPath('/home/user/proj/foo.ts') // => '/home/user/proj/foo.ts' (unchanged) toPosixPath('') // => ''

TransformFailedDiagnostic
#

diagnostics.ts view source

{ file: string; message: string; severity: "error" | "warning"; kind: "transform_failed"; line?: number | undefined; column?: number | undefined; } import {TransformFailedDiagnostic} from 'svelte-docinfo/diagnostics.js';

svelte2tsx transform threw for a .svelte file.

Unrecoverable at ingest — the file's owned-entry stays in the session (virtual: undefined, unfilteredDeps: [], transformFailed: true) so query() can synthesize a placeholder ModuleJson (partial: true, empty declarations). The originating error message lives in message; this diagnostic is the authoritative cause-of-failure signal.

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "transform_failed"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

TransformResult
#

svelte.ts view source

TransformResult import type {TransformResult} from 'svelte-docinfo/svelte.js';

Result of transformSvelteSource — a virtual file (when transform succeeded) plus any ingest-time diagnostics produced during the transform.

virtual is undefined when svelte2tsx threw; in that case diagnostics contains a transform_failed entry. When the transform succeeded but source map construction failed, virtual is populated and diagnostics contains a source_map_failed entry. The session's owned-entry stores both — the virtual (or transformFailed: true flag) and the ingest diagnostics.

virtual

type SvelteVirtualFile | undefined

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

transformSvelteSource
#

svelte.ts view source

(sourceFile: SourceFileInfo): TransformResult import {transformSvelteSource} from 'svelte-docinfo/svelte.js';

Pre-transform a Svelte source file via svelte2tsx.

Produces a SvelteVirtualFile containing the transformed TypeScript content and source map. The virtual file can be included in a TypeScript program (via createAnalysisProgram({ virtualFiles })) so that the checker can resolve imported types, <script module> exports, and re-exports.

Errors at ingest are returned via diagnostics rather than thrown:

  • svelte2tsx throws → transform_failed, virtual: undefined
  • source map construction fails → source_map_failed, virtual populated

Diagnostic file paths are the original .svelte source ID; downstream normalization rewrites them to project-root-relative form.

sourceFile

the Svelte source file with content loaded

returns

TransformResult

virtual file data (or undefined on transform failure) plus ingest diagnostics

throws

  • Error - if Svelte version is below 5 (checked once on first call)

TsdocParsedComment
#

tsdoc.ts view source

TsdocParsedComment import type {TsdocParsedComment} from 'svelte-docinfo/tsdoc.js';

Parsed JSDoc/TSDoc comment with structured metadata.

Returned by parseComment — consumers typically pass this to applyToDeclaration to populate DeclarationJsonBuild fields.

text

Comment text (excluding comment markers).

type string

params

Parameter descriptions mapped by parameter name.

type Record<string, string>

returns?

Return value description from @returns (or its JSDoc @return synonym).

type string

throws?

Thrown errors from @throws.

type { type?: string | undefined; description: string; }[]

examples?

Code examples from @example.

type string[]

deprecatedMessage?

Deprecation message from @deprecated.

type string

internalMessage?

Internal-API marker from @internal. Presence means the tag was written; an empty string is a bare tag with no trailing prose. Means "not stable public API" — the declaration is still documented (use @nodocs to exclude from output).

type string

seeAlso?

Related references from @see.

type string[]

since?

Version information from @since.

type string

defaultValue?

Default value from @default (or its @defaultValue/@defaultvalue spellings).

type string

mutates?

Mutation documentation from @mutates (non-standard), mapped by parameter name.

type Record<string, string>

nodocs?

Whether to exclude from documentation. From @nodocs tag.

type boolean

TupleElementJson
#

types.ts view source

also exported from index.ts

TupleElementJson import {TupleElementJson} from 'svelte-docinfo/types.js';

One element of a {kind: 'tuple'} node.

optional and rest are emitted only when true, matching the tree's meaningful-absence optionality (unlike ParameterJson's defaulted booleans, so the recursive schema keeps input = output).

name?

The written label of a named tuple member ([a: string]).

type string

type

The element's type. An optional element's type has the widening undefined stripped so optional carries it alone; a rest element's is the array it collects (...rest: boolean[] carries an array node over boolean, matching the written form), while a variadic spread of an unresolved type (...T) carries the spread type itself.

type TypeJson

optional?

The element's ? marker; emitted only when true.

type boolean

rest?

The element's ... marker; emitted only when true.

type boolean

tupleElementName
#

typescript-extract-type-json.ts view source

(el: TupleTypeElement): string | undefined import {tupleElementName} from 'svelte-docinfo/typescript-extract-type-json.js';

The written element label as an output name: a NamedTupleMember's identifier, or a parameter-derived label's (Parameters<F> tuples) — the identifier guard is defensive, since binding-pattern parameters produce no label declaration at all. The one naming rule for both tupleElements consumers, so parameters and the typeInfo tree can't disagree on names.

el

returns

string | undefined

tupleElements
#

typescript-extract-type-json.ts view source

(type: TypeReference, checker: TypeChecker): TupleTypeElement[] import {tupleElements} from 'svelte-docinfo/typescript-extract-type-json.js';

The per-index element metadata of a tuple reference — the one place the typeArguments/elementFlags/labeledElementDeclarations triple is read, consumed by buildTuple here and extractSnippetParameters in svelte.ts.

type

type TypeReference

checker

type TypeChecker

returns

TupleTypeElement[]

TupleTypeElement
#

typescript-extract-type-json.ts view source

TupleTypeElement import type {TupleTypeElement} from 'svelte-docinfo/typescript-extract-type-json.js';

Per-element checker metadata from tupleElements — one walk, projected per consumer.

type

The element's type argument; widened with undefined when optional.

type Type

label

The written label declaration, when the tuple has one for this slot.

type NamedTupleMember | ParameterDeclaration | undefined

optional

Whether the element carries a ? marker.

type boolean

rest

Whether the element is a rest element (...boolean[]; type is the array *element* type).

type boolean

variadic

Whether the element is an unresolved variadic spread (...T; type is the spread type).

type boolean

TypeDeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "type"; externalTypes: string[]; members: ({ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> ... import {TypeDeclarationJson} from 'svelte-docinfo/types.js';

A type alias declaration. Has members, externalTypes.

kind

type "type"

externalTypes

External types whose contributions are filtered out of members.

Filtering is by declaration origin at every granularity — named properties, index signatures, call/construct signatures — so a purely structural external branch (an index-signature-only or callable-only interface) is recorded here exactly like a named-property bag. A declaration-less contribution (the index signature the checker synthesizes for a mapped-type instantiation like Record<string, X> or Partial<Indexed>) is kept in members and records nothing here.

Covers every composition the written type reaches: an intersection or union branch, a bare or indexed-access reference, and a type composed behind a project-local name (type Base = Bag & {…}, a local interface's extends, a local container's accessed property LocalMap['a']). Entries carry the written form with two normalizations: an identifier bound by an import rename at the definition site (import type {Bag as B}) resolves back to the name its module exports, and a type parameter bound inside the descent substitutes its written argument (interface A<T> extends ExtG<T> reached via extends A<string> records ExtG<string>). Each distinct contributor appears once, in source order; a generic reference keeps its arguments. A local name is used only when it hides a definition the walk cannot traverse — a mapped or conditional type.

Names carry no module, so the dedupe is by name alone: two *distinct* external types sharing an exported name (one from each of two packages) collapse to a single entry.

type string[]

see also

  • ``ComponentDeclarationJson.externalTypes, InterfaceDeclarationJson.externalTypes, ClassDeclarationJson.externalTypes for the same field on the other kinds, and ClassDeclarationJson.extends, ClassDeclarationJson.implements, InterfaceDeclarationJson.extends for the verbatim own-clause heritage fields. Field shapes mirror TS syntax.

members

Type members: property signatures, method signatures, index signatures, call/construct signatures.

type ({ kind: "function"; name: string; optional: boolean; parameters: { name: string; type: string; optional: boolean; rest: boolean; typeInfo?: TypeJson | undefined; description?: string | undefined; defaultValue?: string | undefined; propertyDescriptions?: Record<...> | undefined; }[]; ... 17 more ...; sourceLine?: nu...

mergedValue

The exported name also carries a value meaning — a merged value+type symbol (const Foo = z.strictObject({...}) + `type Foo = z.infer<typeof Foo>`, the schema/type pattern), where the type alias wins the declaration slot and the value's own type goes undocumented. Tells consumers the name is importable as a runtime value: import {Foo}, never import type {Foo} (see generateImport).

type boolean

see also

  • ``InterfaceDeclarationJson.mergedValue``

alsoExportedFrom

Module paths (relative to sourceRoot) that re-export this declaration under the same name. The canonical declaration lives in this module's declarations array; these paths are additional import locations for the same thing.

The same edges appear from the re-exporting side as ModuleJson.reExports — use that when asking "what does this module re-export" instead of inverting these arrays. The two can disagree at the margins: a reExports entry whose canonical declaration is @nodocs (or whose module isn't in the analyzed set) has no back-link here.

Consumer note: To build a complete re-export map, scan two fields:

  1. alsoExportedFrom on each declaration — same-name re-exports
  2. aliasOf on declarations — renamed re-exports (separate declarations)

type string[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

typeInfo?

Structured type; absent when typeSignature is the whole story (see TypeJson). The headline case: a union alias's typeSignature prints as its own name (ColorScheme), and this field carries the enumerable members. Type aliases print as their own name for every non-interned type, so the tree is emitted there whatever its shape — the exception is object and function roots, whose content members already carries.

type TypeJson

aliasOf?

For renamed re-exports (export {foo as bar}), points to the original declaration. This declaration's name is the alias; aliasOf.name is the original name.

For renames out of the default slot (export {default as bar} from './x' where ./x is export default ...), aliasOf.name is 'default' — the canonical's actual symbol name. Consumers locate the canonical by (aliasOf.module, aliasOf.name).

Svelte component exception: when the source is a .svelte file (e.g., export {default as Foo} from './X.svelte'), the canonical's name is the component name (derived from the filename), so aliasOf.name is the component name ('X'), NOT 'default'. Consumers that branch on aliasOf.name === 'default' to detect default-rename should additionally check whether aliasOf.module ends with .svelte.

Different from alsoExportedFrom: aliases create new API surface names, while alsoExportedFrom tracks additional import paths for the same name.

type { module: string; name: string; }

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

TypeExtractionDiagnostic
#

diagnostics.ts view source

{ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } import {TypeExtractionDiagnostic} from 'svelte-docinfo/diagnostics.js';

Type extraction failed (e.g., complex or recursive types).

symbolName

Name of the symbol whose type couldn't be extracted.

type string

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "type_extraction_failed"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

TypeJson
#

types.ts view source

also exported from index.ts

TypeJson import {TypeJson} from 'svelte-docinfo/types.js';

Structured type information — the machine-readable counterpart to the flat type strings (ParameterJson.type, ComponentPropJson.type, and the typeSignature fields that carry a typeInfo sibling).

Absence contract: the field holding a TypeJson is absent when the flat string is the whole story — the type is terminal at the root (an intrinsic, a plain object literal, a function type, a bare named reference). Present only when the node carries structure the string can't: union/intersection members, reference type arguments, enumerable literals; an array or tuple qualifies when an element does (readonly alone doesn't — the flat string carries it, except at alias roots where the relaxation emits the tree regardless). A reference over the *empty* tuple is the one instantiation that doesn't qualify: Snippet<[]> prints itself in full, so the tree would wrap nothing (Snippet<[a: string]> still qualifies — its tuple has elements). Nested nodes inside a present tree are always populated (they have no flat-string sibling).

One exception, on TypeDeclarationJson for type aliases: the checker prints an aliased type as its bare alias name, so type StrArr = string[] has typeSignature: "StrArr" — no flat sibling to defer to. There the tree is emitted whatever its shape, except for object and function roots, whose content the declaration's own members already carries. Interned types (intrinsics, literals) don't carry an alias symbol and print structurally, so type Str = string is still absent.

Expansion policy: unions and intersections recurse into members; named references keep name plus recursive typeArgs; arrays carry their element; tuples carry elements (label, ?/... markers, recursive type); both mark readonly when written so (readonly Tome[], ReadonlyArray<Tome>, readonly [a, b]). Everything else is terminal: object literals, function types, and unclassified types (type parameters, conditional types, module objects) carry only text. Object property maps are deliberately not expanded. Recursion is depth-capped; nodes past the cap degrade to {kind: 'other', text}.

Alias policy: alias is emitted whenever the checker reports an alias symbol, root or nested — for a root node it may duplicate the flat string (type: "ColorScheme" beside alias: "ColorScheme"), which is accepted for uniformity: nested nodes have no flat sibling, and consumers get one lookup key (alias on composites, name on references) at any depth. This covers the composite kinds only. An aliased object type becomes a reference under its alias name.

Callable classification: callability is the load-bearing renderer signal, so anything with a call signature is a function node — with one narrow exception: a *named generic instantiation* (checker Reference-flagged, symbol-named, carrying type arguments) classifies as a reference even when callable, so Snippet<[a: string]> is a reference whose tuple typeArg carries real elements, and an alias over one, nested, references by the alias name (type MySnippet = Snippet<[string]> in a union is {kind: 'reference', name: 'MySnippet'}; at its own declaration root the self-alias skip applies and the Snippet reference shows through). Bare signatures (() => void), aliased function types, and anonymous or hybrid callables — non-generic callable interfaces included — stay function, so their name survives only inside text (type Handler = (e: Event) => void nested in a union is {kind: 'function', text: 'Handler'}, which a whole-string type-link lookup still resolves, but a structural walk can't distinguish from a printed signature).

Normalization: mirrors the flat strings — the optional-widening undefined member is dropped from a root union (optional: true carries it, and an optional tuple element strips the same widening from its type), and a true | false literal pair collapses to the boolean intrinsic (the checker expands boolean inside unions). A union reduced to one member by either rule becomes that member directly, never a 1-member union.

Terminal text fields are printed with NoTruncation up to a 1000-char budget, past which the checker's own elided rendering is used — so text is always a well-formed type string, and one node can't grow without bound the way the depth cap prevents for the tree. The flat strings keep the checker's default ~160-char truncation throughout (they are the checker's canonical rendering; see getTypeSignature). The budget bites only on types whose alias TypeScript dropped — an alias over an indexed access or conditional (z.infer<typeof S>, valibot's InferOutput) carries no alias symbol, so the checker expands its whole structure at every use.

Written-name recovery: where a written annotation exists (return types — per overload included — parameters, variables, type-alias declarations and their properties, index signatures, getter-backed accessors, component props, snippet parameters), each bare type reference in it is resolved by checker type identity, and a type the checker has no name for — the alias-dropped shapes above — emits {kind: 'reference', name} instead of expanding, alias-lost unions and intersections included. The name resolves through import aliases to the importable one (import {Original as Renamed} recovers Original); a name the checker has is never overridden; typeof queries, import types, inline type literals, and argument-carrying references (z.infer<typeof S> itself, Extract<D, {kind: K}> — whose bare symbol name would misrepresent the instantiation) never recover. A recovered bare reference is emitted even at the root, relaxing the absence contract the way alias roots do: a checker-named bare reference defers to a flat sibling printing the same name, while a recovered one stands against the anonymous expansion, so the name exists only in the tree.

Registry recovery: behind the written channel, unannotated positions recover through the analyzed set's alias registry — any exported, non-@nodocs, non-generic lost alias of an emitted module, matched by checker type identity. A registry-recovered reference additionally carries module, the declaring module's ModuleJson.path — provenance for collision-exact linking, and always an emitted module (gated modules never register), so a consumer lookup by (module, name) can't dangle. module is registry-only, deliberately: a written-channel recovery names whatever the author wrote at the site (which may not be the registry's winner), and checker-named references never carry it — consumers must handle absence.

Member order and nested aliases: union members follow the flat string's printed order — null/undefined sink last, and the checker's origin (the same internal field the flat strings are printed from) lists plain members before named sub-unions, so written ColorScheme | number reads number | ColorScheme in both — and a member written as a named sub-union survives as its own alias-carrying union node (ColorScheme stays nested, not flattened literals). When no usable origin exists the walk degrades, bounded, to the checker's normalized list: flattened members in checker-internal order (nullish still sunk last), written sub-aliases lost.

TypeJsonToken
#

declaration-helpers.ts view source

also exported from index.ts

TypeJsonToken import type {TypeJsonToken} from 'svelte-docinfo/declaration-helpers.js';

One rendered piece of a TypeJson tree, produced by typeJsonToTokens: name tokens are candidate references for a renderer to link (or print plainly) — reference names, alias names of alias-carrying unions/intersections — code tokens are terminal type text (intrinsics, literals, anonymous objects/functions, depth-capped nodes) for a renderer to syntax-highlight, and text tokens are structural punctuation (<, | , [], tuple labels). A name token carries module when its reference node does (registry-recovered references — the declaring ModuleJson.path), so a renderer can scope the link; alias-name tokens never carry it.

typeJsonToText
#

declaration-helpers.ts view source

also exported from index.ts

(node: TypeJson): string import {typeJsonToText} from 'svelte-docinfo/declaration-helpers.js';

The plain-text printed form of a TypeJson tree — typeJsonToTokens concatenated. For consumers with no linkification or highlighting surface (CLI output, markdown code spans, log lines) and for test assertions.

node

returns

string

examples

typeJsonToText({kind: 'union', members: [ {kind: 'reference', name: 'Tome'}, {kind: 'intrinsic', text: 'null'} ]}) // => 'Tome | null'

typeJsonToTokens
#

declaration-helpers.ts view source

also exported from index.ts

(node: TypeJson): TypeJsonToken[] import {typeJsonToTokens} from 'svelte-docinfo/declaration-helpers.js';

Flatten a TypeJson tree into a render-ready token list.

The semantic linearization for renderers: spacing, separators, parenthesization (((x) => void) | null, (A | B)[]), and tuple labels ([a: string, b?: number, ...rest: boolean[]]) are decided here — in lockstep with the TypeJson schema's projection rules — so a renderer maps tokens to output without re-deriving type syntax. What a token *looks like* stays the consumer's decision: fuz_ui links name tokens to API docs and syntax-highlights code tokens; a CLI might print them all plainly. Adjacent punctuation merges into single text tokens.

node

the TypeJson tree to flatten (a typeInfo/returnTypeInfo field)

returns

TypeJsonToken[]

tokens in source order; concatenating their text yields the printed type

examples

typeJsonToTokens({kind: 'reference', name: 'Map', typeArgs: [ {kind: 'intrinsic', text: 'string'}, {kind: 'reference', name: 'Tome'} ]}) // => [{kind: 'name', name: 'Map'}, {kind: 'text', text: '<'}, // {kind: 'code', text: 'string'}, {kind: 'text', text: ', '}, // {kind: 'name', name: 'Tome'}, {kind: 'text', text: '>'}]

unionMemberSetKey
#

typescript-extract-type-json.ts view source

(type: UnionType): string | undefined import {unionMemberSetKey} from 'svelte-docinfo/typescript-extract-type-json.js';

The member-set key of a union — sorted internal type ids, undefined filtered — or undefined when unusable (an internal-API id missing, or fewer than two non-undefined members, a set no widened-union lookup can produce). One function for both sides so registration and lookup can't drift. Identity safety carries over from the ids: two unions share a key only when they share their non-undefined members by object identity.

type

type UnionType

returns

string | undefined

UnknownParamDiagnostic
#

diagnostics.ts view source

{ paramName: string; functionName: string; file: string; message: string; severity: "error" | "warning"; kind: "unknown_param"; line?: number | undefined; column?: number | undefined; } import {UnknownParamDiagnostic} from 'svelte-docinfo/diagnostics.js';

@param tag references a name that doesn't match any actual parameter.

Usually a typo (@param argz for parameter args) or stale doc after a rename. The description is dropped; analysis continues.

paramName

The @param key that didn't match a real parameter.

type string

functionName

Name of the function or method.

type string

file

File path relative to project root (no leading slash, no ./ prefix).

Normalized at every public API boundary — session.setFile/setFiles (ingest-time), session.query (query-time, via analyzeCore), and the one-shot wrappers analyze / analyzeFromFiles. Producers inside the pipeline may write absolute or virtual paths (e.g., Foo.svelte.__svelte2tsx__.ts); normalization rewrites them to project-relative form before they reach consumers.

The exception is discoverydiscoverSourceFiles / discoverFromExports return their diagnostics unnormalized, since they run before any session exists. Their file is already project-root-relative, but message can embed an absolute path (an fs error names the file it failed on), so a consumer wiring discovery up itself owns the normalizeDiagnosticPaths call — analyzeFromFiles and the Vite plugin both make it before merging.

The absolute form is the one to write. Normalization deliberately leaves an already-relative path alone (relativizing it would resolve against cwd), so a producer writing a ModuleJson.path — relative to sourceRoot, a different base — passes through untouched and publishes the same file under a second name. Absolute is what the pass can actually correct.

type string

message

Human-readable description of the issue.

type string

severity

type "error" | "warning"

kind

type "unknown_param"

line?

Line number (1-based), absent if location unavailable.

type number

column?

Column number (1-based), absent if location unavailable.

type number

VariableDeclarationJson
#

types.ts view source

also exported from index.ts

{ kind: "variable"; alsoExportedFrom: string[]; partial: boolean; examples: string[]; seeAlso: string[]; throws: { description: string; type?: string | undefined; }[]; name: string; modifiers: ("public" | ... 5 more ... | "setter")[]; ... 11 more ...; sourceLine?: number | undefined; } import {VariableDeclarationJson} from 'svelte-docinfo/types.js';

A variable declaration. Has optional reactivity for top-level rune-module exports (e.g., export let count = $state(0) in .svelte.ts or <script module>).

kind

type "variable"

alsoExportedFrom

Module paths (relative to sourceRoot) that re-export this declaration under the same name. The canonical declaration lives in this module's declarations array; these paths are additional import locations for the same thing.

The same edges appear from the re-exporting side as ModuleJson.reExports — use that when asking "what does this module re-export" instead of inverting these arrays. The two can disagree at the margins: a reExports entry whose canonical declaration is @nodocs (or whose module isn't in the analyzed set) has no back-link here.

Consumer note: To build a complete re-export map, scan two fields:

  1. alsoExportedFrom on each declaration — same-name re-exports
  2. aliasOf on declarations — renamed re-exports (separate declarations)

type string[]

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

reactivity?

Rune flavor when this variable is initialized with a value-producing reactivity rune.

type "$state" | "$state.raw" | "$derived" | "$derived.by"

defaultValue?

Default value documented via @default. Useful when the AST initializer is opaque (a call expression, computed value) and the author wants to document the conceptual default.

type string

typeInfo?

Structured type; absent when typeSignature is the whole story (see TypeJson).

type TypeJson

aliasOf?

For renamed re-exports (export {foo as bar}), points to the original declaration. This declaration's name is the alias; aliasOf.name is the original name.

For renames out of the default slot (export {default as bar} from './x' where ./x is export default ...), aliasOf.name is 'default' — the canonical's actual symbol name. Consumers locate the canonical by (aliasOf.module, aliasOf.name).

Svelte component exception: when the source is a .svelte file (e.g., export {default as Foo} from './X.svelte'), the canonical's name is the component name (derived from the filename), so aliasOf.name is the component name ('X'), NOT 'default'. Consumers that branch on aliasOf.name === 'default' to detect default-rename should additionally check whether aliasOf.module ends with .svelte.

Different from alsoExportedFrom: aliases create new API surface names, while alsoExportedFrom tracks additional import paths for the same name.

type { module: string; name: string; }

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

VariableMemberJson
#

types.ts view source

also exported from index.ts

{ kind: "variable"; optional: boolean; partial: boolean; examples: string[]; seeAlso: string[]; throws: { description: string; type?: string | undefined; }[]; name: string; modifiers: ("public" | "protected" | ... 4 more ... | "setter")[]; ... 10 more ...; sourceLine?: number | undefined; } import {VariableMemberJson} from 'svelte-docinfo/types.js';

A variable member (property, accessor, index signature, enum value). Shared fields plus optional reactivity for class fields initialized with a Svelte rune ($state, $state.raw, $derived, $derived.by).

optional reflects a ? token on the declaration (e.g., x?: string). Always false for index signatures and enum values.

kind

type "variable"

optional

Whether the member has a ? token in its declaration.

type boolean

partial

Whether extraction failed partway through, leaving some fields missing (e.g., typeSignature, parameters).

type boolean

examples

Code examples from @example tags.

type string[]

seeAlso

Related items from @see tags, in raw TSDoc format.

type string[]

throws

Exceptions from @throws tags.

type { description: string; type?: string | undefined; }[]

name

The exported name. Always populated. The default-export slot is named 'default' — that's the symbol's actual name in JS (import {default as X} and ns.default both expose it directly), and import X from 'mod' is sugar for import {default as X}. Consumers branch on name === 'default' to render the sugar form when desired.

type string

modifiers

TypeScript modifiers like readonly, static, or protected.

type ("public" | "protected" | "readonly" | "static" | "abstract" | "getter" | "setter")[]

genericParams

Generic type parameters like <T, U>.

type { name: string; constraint?: string | undefined; defaultType?: string | undefined; }[]

reactivity?

Rune flavor when this field is initialized with a value-producing reactivity rune.

type "$state" | "$state.raw" | "$derived" | "$derived.by"

defaultValue?

Default value documented via @default. Authoritative initializer (when human-readable) is in typeSignature.

type string

typeInfo?

Structured type; absent when typeSignature is the whole story (see TypeJson). Member types are checker-backed everywhere — type-alias and interface properties and index signatures, class properties (annotated or inferred), and accessors (getter-backed or setter-only) all resolve through the checker, with written annotations feeding name recovery.

type TypeJson

internalMessage?

Internal-API marker from the @internal tag. Presence means the tag was written; an empty string is a bare tag with no trailing prose.

A marker, not an exclusion: @internal means "not stable public API" (TSDoc semantics) while the declaration stays documented — unlike @nodocs, which removes it from output entirely.

Deliberately here rather than in docFields: declarations and members only, not ComponentPropJson (widen to props as a separate additive change if demand appears).

type string

mutates?

Mutation documentation from @mutates tags (non-standard), mapping keys to descriptions.

Keys are intentionally unvalidated — typically a parameter name, but authors may also use compound paths (this.foo, obj.field) or external state references (globalCache). The schema accepts any string key so consumers can render whatever the author wrote.

type Record<string, string>

deprecatedMessage?

Deprecation message from @deprecated tag.

type string

since?

Version introduced, from @since tag.

type string

docComment?

JSDoc/TSDoc comment.

type string

typeSignature?

Full TypeScript type signature.

type string

sourceLine?

1-indexed line number in source file. Undefined for synthesized declarations (e.g., alias declarations from renamed re-exports).

type number

VirtualFileEntry
#

typescript-program.ts view source

VirtualFileEntry import type {VirtualFileEntry} from 'svelte-docinfo/typescript-program.js';

A host-served file entry: content plus optional parser treatment.

content

type string

scriptKind?

Overrides script-kind inference from the path's extension; undefined defers to the extension.

type ScriptKind

VitePluginSvelteDocinfoOptions
#

vite.ts view source

VitePluginSvelteDocinfoOptions import type {VitePluginSvelteDocinfoOptions} from 'svelte-docinfo/vite.js';

Options for the svelteDocinfo Vite plugin.

projectRoot?

Absolute path to project root directory. Defaults to Vite's resolved config.root.

type string

include?

Glob patterns to include (relative to projectRoot; an absolute pattern inside the root relativizes, an out-of-root one throws — see normalizeIncludePatterns).

When provided under the default discovery: 'auto', collapses the chain to glob (exports discovery is skipped). Combining include with discovery: 'exports' throws at config-resolve time — exports mode has no concept of include patterns.

Explicit patterns also widen the source scope: their static bases join sourceOptions.sourcePaths (see widenSourcePathsForInclude), so include-discovered files outside the configured source paths still emit modules — and the watcher tracks their changes. A pattern with no static base ('**\/*.ts', a literal root file) scopes the whole project root as source and logs an info line; an out-of-root base throws.

When omitted, the glob fallback derives an include from sourceOptions.sourcePaths via deriveIncludePatterns, so custom sourcePaths survive the fallback instead of silently defaulting to src/lib.

type string[]

exclude?

Glob patterns to exclude, applied at both discovery and analysis time.

Takes precedence over sourceOptions.exclude (no merge between the two). An array replaces the default patterns wholesale — the test, spec, and internal/ filters are dropped unless re-included — while the callback form extends them without restating them ((defaults) => [...defaults, '**\/*.gen.ts'] — see ExcludeOption). The callback always receives the built-in defaults, even when sourceOptions.exclude is also set (that value is superseded whole). The always-on baseline (node_modules + dot-directories below a matched source path) applies beneath it and is unaffected by overrides.

type ExcludeOption

resolveDependencies?

Whether to resolve import dependencies.

When false, the session's resolver returns null for every specifier, so module dependencies/dependents stay empty.

type boolean

default true

discovery?

Discovery strategy for source files.

type Discovery

default 'auto'

see also

distDir?

Dist directory name relative to project root, used for exports-based discovery.

type string

default 'dist'

sourceOptions?

Partial overrides for default source options (SvelteKit src/lib layout).

type SourceOptionsOverrides

onDuplicates?

Behavior when duplicate declaration names are found across modules.

type OnDuplicates

hmrDebounceMs?

HMR debounce delay in milliseconds. Coalesces rapid file changes during dev.

type number

default 100

warningsOf
#

diagnostics.ts view source

also exported from index.ts

(diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]): ({ ...; } | ... 14 more ... | { ...; })[] import {warningsOf} from 'svelte-docinfo/diagnostics.js';

Get all warning-severity diagnostics.

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

returns

({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

warnModuleCommentNodocs
#

typescript-exports.ts view source

(moduleComment: string | undefined, diagnosticFile: string, diagnostics: ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | ... 14 more ... | { ...; })[]): void import {warnModuleCommentNodocs} from 'svelte-docinfo/typescript-exports.js';

Warn when a module comment carries @nodocs.

The tag has no module-level meaning — it applies to declarations and export statements — so its presence in a @module comment is always author confusion: it does nothing except remain verbatim in moduleComment text. Same line-start detection as extractModuleComment's @module test, so a backticked or mid-prose mention doesn't trigger.

moduleComment

type string | undefined

diagnosticFile

absolute source id, the form normalizeDiagnosticPaths rewrites to the project-root-relative Diagnostic.file contract. Not a module path — those are relative to sourceRoot, and normalization passes an already-relative path through untouched, so a module path here ships as a second base for the same file.

type string

diagnostics

type ({ symbolName: string; file: string; message: string; severity: "error" | "warning"; kind: "type_extraction_failed"; line?: number | undefined; column?: number | undefined; } | { functionName: string; ... 5 more ...; column?: number | undefined; } | ... 13 more ... | { ...; })[]

returns

void

widenSourcePathsForInclude
#

source-config.ts view source

(sourcePaths: readonly string[], include: readonly string[]): readonly string[] import {widenSourcePathsForInclude} from 'svelte-docinfo/source-config.js';

Union sourcePaths with the static base directories of explicit include patterns, so include-discovered files count as source at analysis time.

Discovery include globs can reach outside sourcePaths (`--include 'src/other/' under the default ['src/lib']`); without widening, the query-time source gate would drop those modules, and extractPath would have no root to relativize their paths against (its fallback is the absolute path). Each pattern contributes its static base (see includePatternBase). A root-crossing pattern (`'\/*.ts'`) contributes '', which scopes the whole project root as source.

Pure path-set logic — callers re-run createSourceOptions on the widened list so sourceRoot derivation and validation see the final set (an *explicit* sourceRoot that doesn't prefix a widened path fails that validation loudly rather than emitting absolute module paths; an out-of-root base hits the projectRoot-escape throw). Returns the input array identity when nothing widens. createSourceOptionsWithInclude wraps both steps for the common call shape.

sourcePaths

type readonly string[]

include

type readonly string[]

returns

readonly string[]

wrapResolveImport
#

dep-resolver.ts view source

(resolveImport: ResolveImportFn, identity?: string | symbol): ImportResolver import {wrapResolveImport} from 'svelte-docinfo/dep-resolver.js';

Wrap a bare resolveImport function into an ImportResolver token.

identity is optional; when omitted, a fresh Symbol('wrapped') is synthesized per call. The synthesized default suits single-use scopes — normalizeResolveImport relies on it to wrap a bare function for a one-shot analyze call or for a session default (wrapped once at construction, so the identity stays stable for the session's lifetime).

For a long-lived session that re-wraps the *same* logical resolver across calls (Vite plugin, LSP), a throwaway identity cache-misses every time — the fresh Symbol('wrapped') never compares equal. Pass a stable identity here, or — simpler — construct an ImportResolver ({resolve, identity}) directly and pass it through the ResolveImport union.

resolveImport

identity

type string | symbol
default Symbol('wrapped')

returns

ImportResolver