@adhd/apigen-core-client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ export declare function apigenCore(): string;
@@ -0,0 +1,31 @@
1
+ import { GeneratedSchemas, ComposedSchemas } from './types';
2
+
3
+ interface SlimMiddleware {
4
+ id: string;
5
+ envelope?: Record<string, unknown>;
6
+ }
7
+ /**
8
+ * Merges domain schemas with middleware envelope fields.
9
+ *
10
+ * The `data: {}` wrapper **property** is always present, even for zero-param
11
+ * functions, so `{"data": {}}` still validates for callers who send it out of
12
+ * habit or symmetry. FEAT-APIGEN-023: the wrapper is only listed in the outer
13
+ * `required` array when the function actually has ≥1 required domain param
14
+ * (`domainRequired.length > 0`) — mirroring the exact same condition already
15
+ * used for the nested `data` schema's own `required`. A truly zero-parameter
16
+ * function's published schema therefore does not force callers to send an
17
+ * empty `data: {}` (or the whole envelope, if no middleware requires anything
18
+ * else). Override a middleware with `false` to suppress its envelope
19
+ * contribution for a specific function [inv:false-suppresses-middleware].
20
+ *
21
+ * BUG-APIGEN-017: both the top-level (envelope + data) object and the nested
22
+ * `data` object are generated with `additionalProperties: false` so MCP hosts
23
+ * (and any other JSON-Schema-validating consumer) reject unknown parameters
24
+ * instead of silently discarding them.
25
+ *
26
+ * BUG-APIGEN-020: the top-level schema also carries a `description` that
27
+ * documents the `data` envelope + any transport-envelope fields — see
28
+ * {@link buildEnvelopeDescription}.
29
+ */
30
+ export declare function composeSchemas(domainSchemas: GeneratedSchemas, middlewares: ReadonlyArray<SlimMiddleware>, overrides?: Record<string, Record<string, boolean>>): ComposedSchemas;
31
+ export {};
@@ -0,0 +1,220 @@
1
+ /**
2
+ * A JSON-Schema-2020-12 document fragment.
3
+ *
4
+ * The apigen type IR **is** JSON Schema 2020-12 with `$defs`/`$ref` — there is
5
+ * no separate or abstract type model and no new IR (SPEC §4, §16). Named types,
6
+ * discriminated unions / enum-with-data / `Result`/`Option` (`oneOf` + a `const`
7
+ * tag + `$ref`), nominal/branded types (a named `$def`), and recursion (`$ref`)
8
+ * are all represented here faithfully — exactly what `ts-json-schema-generator`
9
+ * and `schemars` already emit.
10
+ *
11
+ * Conventions baked into this IR:
12
+ * - **Big-int / decimal wire convention:** 64-bit integers and decimals exceed
13
+ * JSON's `f64`, so they are **string-encoded** as `{ type: 'string', format:
14
+ * 'int64' }` (a serialization convention, not a schema-expressiveness gap).
15
+ * - **Optional extractor-derived hints** live under `x-apigen-*` keys (see
16
+ * {@link ApigenSchemaHints}) and exist only so codegen can emit idiomatic
17
+ * (vs accurate-but-verbose) clients; they are never required for correctness
18
+ * and are never sourced from a source annotation (Tenet 1).
19
+ *
20
+ * Modeled as an open record because a JSON Schema is, structurally, an arbitrary
21
+ * keyword object. This mirrors how `input`/`output` are already typed in
22
+ * {@link GeneratedSchemas} / {@link ComposedSchemas} (`Record<string, unknown>`).
23
+ */
24
+ export type JSONSchema = Record<string, unknown> & {
25
+ /** Reusable type definitions referenced via `$ref` (`#/$defs/Name`). */
26
+ $defs?: Record<string, JSONSchema>;
27
+ /**
28
+ * Reusable type definitions under the draft-07 spelling, referenced via
29
+ * `$ref` (`#/definitions/Name`). `ts-json-schema-generator` — the only
30
+ * `$ref`/definitions producer in this codebase today — always emits this
31
+ * key, never `$defs`; both are recognized structurally by extract.ts's
32
+ * `hoistNestedDefs` / compose-schemas.ts (BUG-APIGEN-029) and by Ajv.
33
+ */
34
+ definitions?: Record<string, JSONSchema>;
35
+ /** Reference to a definition, e.g. `#/$defs/User` (enables recursion). */
36
+ $ref?: string;
37
+ } & ApigenSchemaHints;
38
+ /**
39
+ * Optional, **extractor-derived** codegen hints carried inline on a
40
+ * {@link JSONSchema} (SPEC §4). These are advisory: a plugin MAY use them to
41
+ * emit idiomatic clients (e.g. a real enum, a branded type) and a codegen MAY
42
+ * warn on an unresolved generic — but correctness never depends on them, and
43
+ * they are never required. They are computed by the extractor, never written by
44
+ * a human in source (Tenet 1).
45
+ */
46
+ export interface ApigenSchemaHints {
47
+ /**
48
+ * Marks a `$def` that originated from a nominal / branded type. Validation
49
+ * deliberately does NOT enforce nominality — on the wire a branded type *is*
50
+ * its base type — but codegen can re-introduce the brand for ergonomics.
51
+ */
52
+ 'x-apigen-nominal'?: boolean;
53
+ /**
54
+ * How an enum-like type should be represented in idiomatic codegen, e.g. a
55
+ * native enum vs a string-literal union. Advisory only.
56
+ */
57
+ 'x-apigen-enum-repr'?: 'enum' | 'union' | string;
58
+ /**
59
+ * Fidelity of this schema fragment relative to the source type:
60
+ * - `'full'` — the schema captures the source type without loss.
61
+ * - `'lossy'` — the source type could not be fully represented (the only
62
+ * true residual is generic *factoring*: an unconstrained generic operation
63
+ * isn't serializable, so it is out of scope by physics). Codegen MAY warn.
64
+ *
65
+ * Optional; absence means `'full'`.
66
+ */
67
+ fidelity?: 'full' | 'lossy';
68
+ }
69
+ /**
70
+ * A casing-neutral name segment (SPEC §4/§5).
71
+ *
72
+ * Identity is carried by the tokenized `words`; the original `raw` spelling is
73
+ * preserved so a same-host plugin can reproduce it, but every transport derives
74
+ * its own casing from `words` via `@adhd/apigen-naming` (kebab for HTTP/CLI,
75
+ * `_`-joined for MCP, Pascal for gRPC). Casing is therefore per-plugin, never
76
+ * baked into the descriptor.
77
+ */
78
+ export interface Segment {
79
+ /** Original spelling as it appeared in source, e.g. `'humanizeBytes'`. */
80
+ raw: string;
81
+ /** Tokenized, lower-cased words, e.g. `['humanize', 'bytes']`. */
82
+ words: string[];
83
+ }
84
+ /**
85
+ * Language-tagged textual rendering of a type — optional same-host *sugar*
86
+ * (SPEC §4). For a TypeScript host this is the literal TS source of the type;
87
+ * non-host targets ignore it and rely on {@link JSONSchema} (`input`/`output`)
88
+ * instead. `null` when no textual form is available/relevant.
89
+ */
90
+ export interface TypeText {
91
+ /** Language tag for `input`/`output` text, e.g. `'ts'`. */
92
+ lang: string;
93
+ /** Textual rendering of the input/params type. */
94
+ input: string;
95
+ /** Textual rendering of the output/return type (unwrapped). */
96
+ output: string;
97
+ }
98
+ /**
99
+ * Classification of an exported binding (SPEC §4).
100
+ *
101
+ * - `'action'` — a callable export (function declaration, or an
102
+ * arrow/const function). Served by invoking it.
103
+ * - `'query'` — a **serializable-data** const (primitive or plain
104
+ * serializable object/array — no functions / non-serializable values). Served
105
+ * **live**: the descriptor carries the const's *type* (schema), not its value,
106
+ * so env-/compute-dependent consts are never stale-at-extract.
107
+ * - `'constructor'` — a class constructor (class export; see SPEC §10).
108
+ * - `'instance-method'` — a method on an exported class instance (SPEC §10).
109
+ *
110
+ * A non-serializable, non-callable export is **skipped + warned**, never
111
+ * emitted as an operation.
112
+ */
113
+ export type OperationKind = 'action' | 'query' | 'constructor' | 'instance-method';
114
+ /**
115
+ * The canonical operation descriptor — the neutral contract every extractor
116
+ * emits and every plugin consumes (SPEC §4).
117
+ *
118
+ * One `Operation` corresponds to one selected export (an `action`, a live
119
+ * `query`, or a class member per §10). The descriptor is host-agnostic: a
120
+ * TypeScript extractor, a Python extractor, and a Rust extractor all emit the
121
+ * same shape, and a single plugin can project a merged set of `Operation`s into
122
+ * any transport.
123
+ *
124
+ * @remarks
125
+ * The type IR for `input`/`output`/`envelope` is JSON Schema 2020-12 with
126
+ * `$defs`/`$ref` (see {@link JSONSchema}) — there is no separate IR.
127
+ */
128
+ export interface Operation {
129
+ /**
130
+ * The canonical fully-qualified slug and cross-plugin reference key, derived
131
+ * purely from `namespace`/`path`, e.g. `'transform/humanize/humanize-bytes'`.
132
+ * Globally unique within a merged descriptor and never re-cased.
133
+ *
134
+ * **Deterministic, NOT refactor-stable.** Because `id` is a pure function of
135
+ * `namespace`/`path`, the same source always yields the same `id` — but moving
136
+ * or renaming a file/export re-mints it (and thus breaks any pinned
137
+ * `--exclude` id or generated client that referenced the old slug). This is
138
+ * accepted and documented; refactor-stability is an explicit **non-goal**. It
139
+ * is deliberately **not** papered over with a source `@id` annotation, which
140
+ * Tenet 1 forbids.
141
+ */
142
+ id: string;
143
+ /**
144
+ * The owning language runtime / host for this operation, e.g. `'ts'`,
145
+ * `'py'`, `'rust'`. Identifies which host's extractor produced it and which
146
+ * host can serve it same-process. Polyglot descriptors mix hosts.
147
+ */
148
+ host: string;
149
+ /**
150
+ * The package segment — sourced from `--namespace` or the tsconfig folder
151
+ * (SPEC §4/§5). Casing-neutral; transports derive their own casing from
152
+ * {@link Segment.words}.
153
+ */
154
+ namespace: Segment;
155
+ /**
156
+ * The hierarchical identity path: file → export… (SPEC §4/§5). For example a
157
+ * named export is `[file, name]`; a single default function is `[file]`; a
158
+ * default *object* is `[file, 'default', ...keys]` recursing into nested
159
+ * props. `index.*` drops its file segment. Each element is casing-neutral.
160
+ */
161
+ path: Segment[];
162
+ /** Classification of the underlying export — see {@link OperationKind}. */
163
+ kind: OperationKind;
164
+ /** True if the export is async (returns a `Promise`). */
165
+ async: boolean;
166
+ /**
167
+ * True if the export returns an `AsyncIterable` / `Generator` / `Stream`
168
+ * (streaming is implemented in v2, SPEC §11). The `output` schema describes
169
+ * the per-chunk element type with streaming unwrapped.
170
+ */
171
+ streaming: boolean;
172
+ /**
173
+ * Idempotent / no-side-effects hint (SPEC §4/§5).
174
+ *
175
+ * **Defaults from `kind`** (`query` → `true`, `action` → `false`) and is
176
+ * **overridable at projection time via config** (`--opt http.verb.<id>=GET`
177
+ * or `apigen.config`), never via a source annotation (Tenet 1). Drives the
178
+ * HTTP verb + cacheability (safe → GET, unsafe → POST) and gRPC
179
+ * idempotency-level (SPEC §5), decoupling the wire method from `kind`.
180
+ */
181
+ safe: boolean;
182
+ /**
183
+ * The params object as JSON Schema 2020-12 (see {@link JSONSchema}).
184
+ *
185
+ * This is the operation's input type directly: the `ctx` first param is
186
+ * excluded (by name match only, per the `ctx-name-only` invariant) and the
187
+ * middleware `data`-wrapper is **dissolved** — `input` is the bare domain
188
+ * params object, not the composed envelope. The request-side envelope lives
189
+ * separately in `envelope`.
190
+ */
191
+ input: JSONSchema;
192
+ /**
193
+ * The return type as JSON Schema 2020-12 (see {@link JSONSchema}), with
194
+ * `Promise<T>` and stream wrappers **unwrapped to `T`**. For a streaming
195
+ * operation this is the per-chunk element type.
196
+ */
197
+ output: JSONSchema;
198
+ /**
199
+ * The effective request-side envelope as JSON Schema 2020-12 — the
200
+ * middleware-contributed side-channel for this operation (e.g. a `session`
201
+ * field), merged across the active middleware with overrides applied. Empty
202
+ * (no envelope fields) when no middleware contributes to this operation.
203
+ */
204
+ envelope: JSONSchema;
205
+ /**
206
+ * Optional language-tagged textual type rendering (same-host sugar). `null`
207
+ * when unavailable; non-host targets ignore it. See {@link TypeText}.
208
+ */
209
+ typeText: TypeText | null;
210
+ /**
211
+ * True when the underlying export's first parameter is named `ctx`
212
+ * ([inv:ctx-name-only] — matched by name only, never by type). `ctx` is
213
+ * excluded from `input` like every other framework param, but this flag
214
+ * lets a runtime dispatcher re-inject it as the first call argument
215
+ * (BUG-APIGEN-001) — without it a caller with no session middleware would
216
+ * have its first REAL domain arg land in the `ctx` slot. Only meaningful
217
+ * for `kind: 'action'`; absent (`undefined`) for `query` and other kinds.
218
+ */
219
+ hasCtx?: boolean;
220
+ }
@@ -0,0 +1,37 @@
1
+ import { ExtractionSession } from './extraction-session';
2
+ import { Operation } from './descriptor';
3
+
4
+ export interface ExtractClassesOptions {
5
+ /** Absolute path to the TypeScript (or JavaScript) source file. */
6
+ sourceFile: string;
7
+ /**
8
+ * Namespace segment (from `--namespace` or tsconfig folder). Casing-neutral
9
+ * words are derived from the raw string. Defaults to `''`.
10
+ */
11
+ namespace?: string;
12
+ /** Absolute path to a tsconfig.json for type resolution. Optional. */
13
+ tsconfig?: string;
14
+ /**
15
+ * When true, extract constructor + instance-method ops in addition to static
16
+ * method ops. Off by default (opt-in per SPEC §10).
17
+ */
18
+ includeInstances?: boolean;
19
+ /**
20
+ * Optional per-run shared cache (see `createExtractionSession` in
21
+ * `@adhd/apigen-core-client). When absent, a private session is created and
22
+ * disposed before returning (previous behaviour, no retention).
23
+ */
24
+ session?: ExtractionSession;
25
+ }
26
+ /**
27
+ * Walks `opts.sourceFile` and emits canonical `Operation[]` descriptors for
28
+ * all exported class members per SPEC §10.
29
+ *
30
+ * Static methods are always extracted (they are stateless function-shaped ops).
31
+ * Constructor + instance methods require `opts.includeInstances = true`.
32
+ *
33
+ * @param opts - Extraction options.
34
+ * @returns Resolved array of canonical operations (static ops + optionally
35
+ * constructor + instance-method ops).
36
+ */
37
+ export declare function extractClasses(opts: ExtractClassesOptions): Promise<Operation[]>;
@@ -0,0 +1,43 @@
1
+ import { ExtractionSession } from './extraction-session';
2
+ import { Operation } from './descriptor';
3
+
4
+ export interface ExtractOptions {
5
+ /** Absolute path to the TypeScript (or JavaScript) source file. */
6
+ sourceFile: string;
7
+ /**
8
+ * Namespace segment (from `--namespace` or tsconfig folder). Casing-neutral
9
+ * words are derived from the raw string. Defaults to `''`.
10
+ */
11
+ namespace?: string;
12
+ /** Absolute path to a tsconfig.json for type resolution. Optional. */
13
+ tsconfig?: string;
14
+ /**
15
+ * Optional per-run shared cache (see {@link createExtractionSession}).
16
+ * When supplied, the ts-morph Project, built schema generators, and computed
17
+ * schemas are shared with every other extraction call in the same run — and
18
+ * released together by `session.dispose()`. When absent, a private session is
19
+ * created and disposed before returning (previous behaviour, no retention).
20
+ */
21
+ session?: ExtractionSession;
22
+ }
23
+ /**
24
+ * Walks `opts.sourceFile` and emits canonical `Operation[]` descriptors.
25
+ *
26
+ * Handles all six shapes in the export-shape matrix. Each operation is named
27
+ * by the **exported symbol** in source — never by position or internal name.
28
+ *
29
+ * @param opts - Extraction options.
30
+ * @returns Resolved array of canonical operations.
31
+ */
32
+ export declare function extract(opts: ExtractOptions): Promise<Operation[]>;
33
+ /**
34
+ * Tokenises a camelCase / PascalCase / kebab-case / snake_case identifier into
35
+ * lower-cased words. Used to build casing-neutral {@link Segment} records.
36
+ *
37
+ * Examples:
38
+ * 'humanizeBytes' → ['humanize', 'bytes']
39
+ * 'HTMLParser' → ['html', 'parser']
40
+ * 'my-util' → ['my', 'util']
41
+ * 'SOME_CONST' → ['some', 'const']
42
+ */
43
+ export declare function tokenize(raw: string): string[];
@@ -0,0 +1,97 @@
1
+ import { Project, SourceFile } from 'ts-morph';
2
+
3
+ /** Counters proving how much work a session actually did — used by perf regression tests. */
4
+ export interface ISessionStats {
5
+ /** ts-morph Projects constructed (one per distinct tsconfig per session). */
6
+ projectsBuilt: number;
7
+ /** ts-json-schema-generator generators (full TS programs) constructed. */
8
+ generatorsBuilt: number;
9
+ /**
10
+ * buildSchema calls answered from the session schema cache — includes both
11
+ * a call that found an already-RESOLVED entry and a call that joined an
12
+ * already-IN-FLIGHT promise for the same key (BUG-APIGEN-CORE-003:
13
+ * in-flight dedup — see `schemaCache`'s doc comment below).
14
+ */
15
+ schemaCacheHits: number;
16
+ /** buildSchema calls that had to start a new computation (cache miss). */
17
+ schemaCacheMisses: number;
18
+ }
19
+ /**
20
+ * A per-run cache shared across `extract()` / `extractClasses()` / the
21
+ * orchestrator. Create one per logical run with
22
+ * {@link createExtractionSession}, pass it to every extraction call in that
23
+ * run, and `dispose()` it when the run's outputs have been consumed.
24
+ *
25
+ * Passing a session is optional everywhere — calls without one create a
26
+ * private session internally and dispose it before returning, so existing
27
+ * consumers are unaffected.
28
+ */
29
+ export interface ExtractionSession {
30
+ /** Drop every cached Project / generator / schema so the run's memory is collectible. */
31
+ dispose(): void;
32
+ /** Live work counters (see {@link ISessionStats}). */
33
+ readonly stats: ISessionStats;
34
+ }
35
+ /** Cached built generator entry: `version` is the file's `mtimeMs:size` snapshot. */
36
+ export type BuiltGenerator = {
37
+ createSchema(type: string): unknown;
38
+ };
39
+ type GeneratorEntry = {
40
+ version: string;
41
+ gen: BuiltGenerator;
42
+ };
43
+ declare const INTERNAL: unique symbol;
44
+ /** Full internal surface — package-private (not exported from the index). */
45
+ export interface InternalExtractionSession extends ExtractionSession {
46
+ [INTERNAL]: true;
47
+ /** One ts-morph Project per distinct tsconfig path ('' for none). */
48
+ projectFor(tsconfig?: string): Project;
49
+ /** Add-or-reuse the SourceFile for `filePath` in the session's Project. */
50
+ sourceFileFor(filePath: string, tsconfig?: string): SourceFile;
51
+ /**
52
+ * Memoized buildSchema results, key = `${sfPath}\0${tsconfig ?? ''}\0${typeText}`.
53
+ *
54
+ * BUG-APIGEN-CORE-003: values are the in-flight/resolved `Promise`, not the
55
+ * resolved value itself, and are stored SYNCHRONOUSLY (before the underlying
56
+ * computation is awaited) — this is what makes concurrent identical requests
57
+ * (e.g. `morph-walk.ts`'s `Promise.all(members.map(...))` over union variants
58
+ * that share a nested type like `SharedArrayBuffer`) share one computation
59
+ * instead of each independently missing the cache and recomputing. See
60
+ * `buildSchema()` in `schema-builders/ts-json-schema.ts` for the write side.
61
+ */
62
+ readonly schemaCache: Map<string, Promise<Record<string, unknown>>>;
63
+ /** Memoized per-SourceFile import-alias maps (extractScalarAliases). */
64
+ readonly aliasCache: WeakMap<SourceFile, ReadonlyMap<string, string>>;
65
+ /** Memoized per-SourceFile zod-import check (sourceFileHasZodImport). */
66
+ readonly zodImportCache: WeakMap<SourceFile, boolean>;
67
+ /** One built generator per `${path}\0${tsconfig ?? ''}` — latest version only. */
68
+ readonly generatorCache: Map<string, GeneratorEntry>;
69
+ /** Memoized `mtimeMs:size` snapshot per file path (a run is a snapshot). */
70
+ statVersion(pathStr: string): string;
71
+ }
72
+ /** Compute a file's `mtimeMs:size` version string (uncached). */
73
+ export declare function fileVersion(pathStr: string): string;
74
+ /** Persistent-schema accessor for buildSchema (package-private).
75
+ *
76
+ * Computes a composite version stamp that includes the entry file's version
77
+ * AND the versions of all referenced files tracked by the persistent Project
78
+ * tier. Previously only the entry file's version was checked, so a type
79
+ * imported from another file that changed without the entry file changing was
80
+ * not detected (DEBT-APIGEN-CACHE-001).
81
+ */
82
+ export declare function persistentSchemasFor(sfPath: string, tsconfig: string | undefined, version: string): Map<string, Record<string, unknown>>;
83
+ /** Drop the process-lifetime Project + schema caches (tests / explicit memory reclaim). */
84
+ export declare function clearPersistentProjectCache(): void;
85
+ /**
86
+ * Create a fresh {@link ExtractionSession}.
87
+ *
88
+ * One session = one run = one snapshot of the source tree. Reusing a session
89
+ * across file edits is unsupported by design (invalidation is "new session").
90
+ */
91
+ export declare function createExtractionSession(): ExtractionSession;
92
+ /**
93
+ * Recover the internal surface from a public {@link ExtractionSession}.
94
+ * Package-private — deliberately NOT exported from the package index.
95
+ */
96
+ export declare function internalSession(session: ExtractionSession): InternalExtractionSession;
97
+ export {};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Structural check over a bare domain-input JSON Schema — the exact shape
3
+ * carried as `Operation.input` (and, unchanged, as `GeneratedSchemas.schemas
4
+ * [fn].input` — orchestrator.ts's Step 5 passes `op.input` straight through):
5
+ * `{ type: 'object', properties, required }`.
6
+ *
7
+ * Returns `true` iff every declared property is a "properly typed primitive"
8
+ * (`string`/`number`/`boolean`/`integer`, optionally unioned with `null`) —
9
+ * including the zero-property case (vacuously true). Absence of a
10
+ * `properties` key at all (as opposed to an explicit empty object) is NOT the
11
+ * same as zero params — it means the input shape was never populated, so this
12
+ * returns `false` rather than assume eligibility.
13
+ */
14
+ export declare function isPrimitiveOnlyInputSchema(input: Record<string, unknown> | undefined | null): boolean;
@@ -0,0 +1,36 @@
1
+ import { Node, ParameterDeclaration } from 'ts-morph';
2
+
3
+ /**
4
+ * Extracts the raw source text of a parameter's default value.
5
+ *
6
+ * @param paramDecl - The parameter's own declaration, when resolvable (may be
7
+ * `null`/`undefined` for parameters reached only through a `Signature`
8
+ * whose declaration could not be narrowed to a `ParameterDeclaration`).
9
+ * @param paramName - The parameter's name, used to match a JSDoc `@param` tag.
10
+ * @param jsDocSource - The enclosing function-like node (FunctionDeclaration,
11
+ * VariableStatement, ExportAssignment, …) whose leading JSDoc comment may
12
+ * carry a bracketed default for this parameter.
13
+ * @returns The raw default-value text (e.g. `"'auto'"`, `"0"`, `"false"`), or
14
+ * `undefined` when no default could be found.
15
+ */
16
+ export declare function extractParamDefault(paramDecl: ParameterDeclaration | null | undefined, paramName: string, jsDocSource?: Node | null): string | undefined;
17
+ /**
18
+ * Coerces a raw TS/JSDoc default-value literal into a properly-typed JSON
19
+ * value so it can be emitted verbatim as a JSON-Schema `default`.
20
+ *
21
+ * Handles quoted string literals (`'auto'`, `"auto"`, `` `auto` ``), the
22
+ * `true`/`false`/`null` keywords, numeric literals, and falls back to
23
+ * `JSON.parse` (array/object literals) before giving up and returning the
24
+ * trimmed raw text (e.g. an enum-member reference apigen can't evaluate
25
+ * statically).
26
+ */
27
+ export declare function coerceDefaultLiteral(raw: string): unknown;
28
+ /**
29
+ * Applies an extracted default onto a built parameter schema in place:
30
+ * sets the native JSON-Schema `default` keyword and appends a human-readable
31
+ * `(default: <value>)` note to `description` (preserving any existing text).
32
+ *
33
+ * A no-op when the coerced value is `undefined` (an explicit `= undefined`
34
+ * initializer carries no useful default to advertise).
35
+ */
36
+ export declare function applyParamDefault(schema: Record<string, unknown>, rawDefault: string): void;