@ir-kit/fn-schema-core 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.
- package/LICENSE.md +21 -0
- package/README.md +114 -0
- package/dist/defaults.d.ts +4 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +25 -0
- package/dist/defaults.js.map +1 -0
- package/dist/diagnostics.d.ts +15 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +31 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/emit/bundle.d.ts +22 -0
- package/dist/emit/bundle.d.ts.map +1 -0
- package/dist/emit/bundle.js +62 -0
- package/dist/emit/bundle.js.map +1 -0
- package/dist/emit/files.d.ts +16 -0
- package/dist/emit/files.d.ts.map +1 -0
- package/dist/emit/files.js +30 -0
- package/dist/emit/files.js.map +1 -0
- package/dist/emit/index.d.ts +4 -0
- package/dist/emit/index.d.ts.map +1 -0
- package/dist/emit/index.js +4 -0
- package/dist/emit/index.js.map +1 -0
- package/dist/emit/openapi.d.ts +31 -0
- package/dist/emit/openapi.d.ts.map +1 -0
- package/dist/emit/openapi.js +46 -0
- package/dist/emit/openapi.js.map +1 -0
- package/dist/filter.d.ts +4 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +67 -0
- package/dist/filter.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/naming.d.ts +3 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +31 -0
- package/dist/naming.js.map +1 -0
- package/dist/project.d.ts +3 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +335 -0
- package/dist/project.js.map +1 -0
- package/dist/targets.d.ts +12 -0
- package/dist/targets.d.ts.map +1 -0
- package/dist/targets.js +23 -0
- package/dist/targets.js.map +1 -0
- package/dist/types.d.ts +265 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +66 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ahmed Rowaihi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# @ir-kit/fn-schema-core
|
|
2
|
+
|
|
3
|
+
Language-agnostic IR + emitters for fn-schema. Defines the `Extractor` contract that language-specific packages implement, and ships the orchestration + output paths every extractor shares.
|
|
4
|
+
|
|
5
|
+
## When to use this directly
|
|
6
|
+
|
|
7
|
+
Most users don't import `core` — they use the [`cli`](../cli/README.md) or `@ir-kit/fn-schema-typescript` (which re-exports a pre-wired `extract`). Reach for `core` when you want to:
|
|
8
|
+
|
|
9
|
+
- register multiple extractors in the same run (e.g. TS + Python, when Python lands)
|
|
10
|
+
- keep a long-lived `Project` warm across many `extract()` calls
|
|
11
|
+
- build your own emitter on top of the orchestrator
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { createProject } from "@ir-kit/fn-schema-core"
|
|
17
|
+
import { typescript } from "@ir-kit/fn-schema-typescript"
|
|
18
|
+
|
|
19
|
+
const project = createProject({
|
|
20
|
+
cwd: process.cwd(),
|
|
21
|
+
tsConfigPath: "./tsconfig.json",
|
|
22
|
+
extractors: [typescript()],
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const result = await project.extract({
|
|
26
|
+
files: ["src/api/handlers.ts"],
|
|
27
|
+
schema: { identity: "x-fn-schema-ts", transport: "x-fn-schema-transport" },
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
project.dispose()
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Discovery without schemas
|
|
34
|
+
|
|
35
|
+
`Project.discover()` walks the same files but stops at function detection — no schema generation. Use it when you only need names, locations, JSDoc tags, and the like.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
const { signatures, stats } = await project.discover({
|
|
39
|
+
files: ["src/**/*.ts"],
|
|
40
|
+
include: { jsDocTag: "schema" },
|
|
41
|
+
})
|
|
42
|
+
for (const fn of signatures) console.log(fn.name, fn.file, fn.location)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Emitters
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { emit } from "@ir-kit/fn-schema-core"
|
|
49
|
+
|
|
50
|
+
emit.toFiles(result, { dir: "generated", format: "json-pretty" })
|
|
51
|
+
emit.toBundle(result, { pretty: true })
|
|
52
|
+
emit.toBundleTypesModule(result, { jsonImport: "./schemas.json" })
|
|
53
|
+
emit.toOpenAPI(result, { title: "my-api" })
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- `toFiles` — one JSON per signature
|
|
57
|
+
- `toBundle` — single JSON with all signatures + shared definitions
|
|
58
|
+
- `toBundleTypesModule` — TS wrapper exporting the bundle under literal-typed signature ids and definition names (pair with [`loader`](../loader/README.md))
|
|
59
|
+
- `toOpenAPI` — components-only OpenAPI 3.1 doc; tuples use `prefixItems`
|
|
60
|
+
|
|
61
|
+
## Schema knobs
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
schema: {
|
|
65
|
+
dialect: "draft-07" | "draft-2020-12" | "openapi-3.1",
|
|
66
|
+
expose: "all" | "export" | "none",
|
|
67
|
+
topRef: false,
|
|
68
|
+
additionalProperties: false,
|
|
69
|
+
|
|
70
|
+
// user overrides built-in mappings (Date, File, Buffer, …)
|
|
71
|
+
typeMappers: { MyType: { type: "string", format: "uuid" } },
|
|
72
|
+
|
|
73
|
+
// off-by-default vendor extensions
|
|
74
|
+
identity: "x-fn-schema-ts", // attach originating TS type name
|
|
75
|
+
transport: "x-fn-schema-transport", // attach multipart/base64 hint
|
|
76
|
+
sourceLocations: "x-fn-schema-source", // attach file:line:col
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Diagnostics
|
|
81
|
+
|
|
82
|
+
Every mapping decision is observable:
|
|
83
|
+
|
|
84
|
+
| Code | Severity | When |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `TYPE_MAPPED` | info | Well-known TS type rewritten to canonical JSON Schema |
|
|
87
|
+
| `LOSSY_MAPPING` | warning | Mapping lost information (e.g. `bigint` → `integer`) |
|
|
88
|
+
| `NOT_REPRESENTABLE` | error | Type can't be represented in JSON Schema (e.g. `symbol`) |
|
|
89
|
+
| `GENERIC_SKIPPED` | warning | Generic function skipped (set `signature.generics: "erase"` to override) |
|
|
90
|
+
| `DUPLICATE_ID` | warning | Definition emitted with conflicting shapes from two functions |
|
|
91
|
+
| `EXTRACTOR_FAILURE` | error | Extractor threw on a function |
|
|
92
|
+
| `EMPTY_RESULT` | info | No signatures matched the filter |
|
|
93
|
+
| `NO_EXTRACTOR` | warning | A file's extension isn't claimed by any registered extractor |
|
|
94
|
+
|
|
95
|
+
Subscribe via `extract({ onDiagnostic: (d) => ... })` or read `result.diagnostics` after.
|
|
96
|
+
|
|
97
|
+
## Extractor contract
|
|
98
|
+
|
|
99
|
+
Other languages plug in by implementing:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
interface Extractor {
|
|
103
|
+
readonly extensions: readonly string[]
|
|
104
|
+
readonly language: string
|
|
105
|
+
init(opts: ExtractorInitOptions): Promise<ExtractorInstance>
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
interface ExtractorInstance {
|
|
109
|
+
discover(files: readonly string[], filter: ResolvedFilter): Promise<FunctionInfo[]>
|
|
110
|
+
toSchemas(fn: FunctionInfo, opts: ResolvedSignatureOptions & ResolvedSchemaOptions): Promise<SignaturePair>
|
|
111
|
+
refresh(files: readonly string[]): void
|
|
112
|
+
dispose(): void
|
|
113
|
+
}
|
|
114
|
+
```
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ResolvedSchemaOptions, ResolvedSignatureOptions, SchemaOptions, SignatureOptions } from "./types.js";
|
|
2
|
+
export declare function resolveSignatureOptions(o?: SignatureOptions): ResolvedSignatureOptions;
|
|
3
|
+
export declare function resolveSchemaOptions(o?: SchemaOptions): ResolvedSchemaOptions;
|
|
4
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EACxB,aAAa,EACb,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,uBAAuB,CACrC,CAAC,CAAC,EAAE,gBAAgB,GACnB,wBAAwB,CAQ1B;AAED,wBAAgB,oBAAoB,CAAC,CAAC,CAAC,EAAE,aAAa,GAAG,qBAAqB,CAc7E"}
|
package/dist/defaults.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function resolveSignatureOptions(o) {
|
|
2
|
+
return {
|
|
3
|
+
parameters: o?.parameters ?? "array",
|
|
4
|
+
unwrapPromise: o?.unwrapPromise ?? true,
|
|
5
|
+
generics: o?.generics ?? "skip",
|
|
6
|
+
overloads: o?.overloads ?? "all",
|
|
7
|
+
skipParameter: o?.skipParameter ?? null,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function resolveSchemaOptions(o) {
|
|
11
|
+
return {
|
|
12
|
+
dialect: o?.dialect ?? "draft-07",
|
|
13
|
+
refStrategy: o?.refStrategy ?? "definitions",
|
|
14
|
+
definitionsPath: o?.definitionsPath ?? "#/definitions",
|
|
15
|
+
topRef: o?.topRef ?? false,
|
|
16
|
+
additionalProperties: o?.additionalProperties ?? false,
|
|
17
|
+
encodeRefs: o?.encodeRefs ?? true,
|
|
18
|
+
expose: o?.expose ?? "export",
|
|
19
|
+
typeMappers: o?.typeMappers ?? {},
|
|
20
|
+
identity: o?.identity ?? false,
|
|
21
|
+
transport: o?.transport ?? false,
|
|
22
|
+
sourceLocations: o?.sourceLocations ?? false,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,uBAAuB,CACrC,CAAoB;IAEpB,OAAO;QACL,UAAU,EAAE,CAAC,EAAE,UAAU,IAAI,OAAO;QACpC,aAAa,EAAE,CAAC,EAAE,aAAa,IAAI,IAAI;QACvC,QAAQ,EAAE,CAAC,EAAE,QAAQ,IAAI,MAAM;QAC/B,SAAS,EAAE,CAAC,EAAE,SAAS,IAAI,KAAK;QAChC,aAAa,EAAE,CAAC,EAAE,aAAa,IAAI,IAAI;KACxC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,CAAiB;IACpD,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,OAAO,IAAI,UAAU;QACjC,WAAW,EAAE,CAAC,EAAE,WAAW,IAAI,aAAa;QAC5C,eAAe,EAAE,CAAC,EAAE,eAAe,IAAI,eAAe;QACtD,MAAM,EAAE,CAAC,EAAE,MAAM,IAAI,KAAK;QAC1B,oBAAoB,EAAE,CAAC,EAAE,oBAAoB,IAAI,KAAK;QACtD,UAAU,EAAE,CAAC,EAAE,UAAU,IAAI,IAAI;QACjC,MAAM,EAAE,CAAC,EAAE,MAAM,IAAI,QAAQ;QAC7B,WAAW,EAAE,CAAC,EAAE,WAAW,IAAI,EAAE;QACjC,QAAQ,EAAE,CAAC,EAAE,QAAQ,IAAI,KAAK;QAC9B,SAAS,EAAE,CAAC,EAAE,SAAS,IAAI,KAAK;QAChC,eAAe,EAAE,CAAC,EAAE,eAAe,IAAI,KAAK;KAC7C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Diagnostic } from "./types.js";
|
|
2
|
+
export declare function diag(d: Diagnostic): Diagnostic;
|
|
3
|
+
export declare class DiagnosticSink {
|
|
4
|
+
private readonly onEach?;
|
|
5
|
+
private readonly failFast;
|
|
6
|
+
private readonly entries;
|
|
7
|
+
constructor(onEach?: ((d: Diagnostic) => void) | undefined, failFast?: boolean);
|
|
8
|
+
push(d: Diagnostic): void;
|
|
9
|
+
all(): Diagnostic[];
|
|
10
|
+
}
|
|
11
|
+
export declare class FailFastError extends Error {
|
|
12
|
+
readonly diagnostic: Diagnostic;
|
|
13
|
+
constructor(diagnostic: Diagnostic);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,wBAAgB,IAAI,CAAC,CAAC,EAAE,UAAU,GAAG,UAAU,CAE9C;AAED,qBAAa,cAAc;IAGvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAH3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;gBAEzB,MAAM,CAAC,GAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,aAAA,EAChC,QAAQ,UAAQ;IAGnC,IAAI,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI;IAQzB,GAAG,IAAI,UAAU,EAAE;CAGpB;AAED,qBAAa,aAAc,SAAQ,KAAK;aACV,UAAU,EAAE,UAAU;gBAAtB,UAAU,EAAE,UAAU;CAInD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function diag(d) {
|
|
2
|
+
return d;
|
|
3
|
+
}
|
|
4
|
+
export class DiagnosticSink {
|
|
5
|
+
onEach;
|
|
6
|
+
failFast;
|
|
7
|
+
entries = [];
|
|
8
|
+
constructor(onEach, failFast = false) {
|
|
9
|
+
this.onEach = onEach;
|
|
10
|
+
this.failFast = failFast;
|
|
11
|
+
}
|
|
12
|
+
push(d) {
|
|
13
|
+
this.entries.push(d);
|
|
14
|
+
this.onEach?.(d);
|
|
15
|
+
if (this.failFast && d.severity === "error") {
|
|
16
|
+
throw new FailFastError(d);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
all() {
|
|
20
|
+
return [...this.entries];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class FailFastError extends Error {
|
|
24
|
+
diagnostic;
|
|
25
|
+
constructor(diagnostic) {
|
|
26
|
+
super(`[${diagnostic.code}] ${diagnostic.message}`);
|
|
27
|
+
this.diagnostic = diagnostic;
|
|
28
|
+
this.name = "FailFastError";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,IAAI,CAAC,CAAa;IAChC,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,OAAO,cAAc;IAGN;IACA;IAHF,OAAO,GAAiB,EAAE,CAAC;IAC5C,YACmB,MAAgC,EAChC,WAAW,KAAK;QADhB,WAAM,GAAN,MAAM,CAA0B;QAChC,aAAQ,GAAR,QAAQ,CAAQ;IAChC,CAAC;IAEJ,IAAI,CAAC,CAAa;QAChB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;QACjB,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAC5C,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IACV;IAA5B,YAA4B,UAAsB;QAChD,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;QAD1B,eAAU,GAAV,UAAU,CAAY;QAEhD,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ExtractResult, SchemaDialect } from "../types.js";
|
|
2
|
+
export interface BundleEmitOptions {
|
|
3
|
+
pretty?: boolean;
|
|
4
|
+
/** Schema dialect URL stamped into the bundle's `$schema`. Default: draft-07. */
|
|
5
|
+
dialect?: SchemaDialect;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Emit a single JSON document containing every signature keyed by id, plus
|
|
9
|
+
* shared definitions. Useful for shipping one artifact instead of N files.
|
|
10
|
+
*/
|
|
11
|
+
export declare function toBundle(result: ExtractResult, opts?: BundleEmitOptions): string;
|
|
12
|
+
export interface BundleTypesOptions {
|
|
13
|
+
/** Module specifier the wrapper imports the JSON from. Default: `./schemas.json`. */
|
|
14
|
+
jsonImport?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Emit a TypeScript wrapper module that imports the bundle JSON and re-exports
|
|
18
|
+
* it under a literal-typed shape. Pair with `toBundle` to get autocomplete on
|
|
19
|
+
* signature ids and definition names + a typed `createReader<typeof schemas>()`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function toBundleTypesModule(result: ExtractResult, opts?: BundleTypesOptions): string;
|
|
22
|
+
//# sourceMappingURL=bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/emit/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAQD;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,aAAa,EACrB,IAAI,GAAE,iBAAsB,GAC3B,MAAM,CAkBR;AAED,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,IAAI,GAAE,kBAAuB,GAC5B,MAAM,CA+BR"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const DIALECT_URL = {
|
|
2
|
+
"draft-07": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"draft-2020-12": "https://json-schema.org/draft/2020-12/schema",
|
|
4
|
+
"openapi-3.1": "https://spec.openapis.org/oas/3.1/dialect/base",
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Emit a single JSON document containing every signature keyed by id, plus
|
|
8
|
+
* shared definitions. Useful for shipping one artifact instead of N files.
|
|
9
|
+
*/
|
|
10
|
+
export function toBundle(result, opts = {}) {
|
|
11
|
+
const dialect = opts.dialect ?? "draft-07";
|
|
12
|
+
const doc = {
|
|
13
|
+
$schema: DIALECT_URL[dialect],
|
|
14
|
+
definitions: result.definitions,
|
|
15
|
+
signatures: Object.fromEntries(result.signatures.map((s) => [
|
|
16
|
+
s.id,
|
|
17
|
+
{
|
|
18
|
+
name: s.name,
|
|
19
|
+
file: s.file,
|
|
20
|
+
input: s.input,
|
|
21
|
+
output: s.output,
|
|
22
|
+
},
|
|
23
|
+
])),
|
|
24
|
+
};
|
|
25
|
+
return opts.pretty ? JSON.stringify(doc, null, 2) : JSON.stringify(doc);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Emit a TypeScript wrapper module that imports the bundle JSON and re-exports
|
|
29
|
+
* it under a literal-typed shape. Pair with `toBundle` to get autocomplete on
|
|
30
|
+
* signature ids and definition names + a typed `createReader<typeof schemas>()`.
|
|
31
|
+
*/
|
|
32
|
+
export function toBundleTypesModule(result, opts = {}) {
|
|
33
|
+
const jsonImport = opts.jsonImport ?? "./schemas.json";
|
|
34
|
+
const sigKeys = result.signatures
|
|
35
|
+
.map((s) => ` readonly ${quoteKey(s.id)}: { input: ${Array.isArray(s.input) ? "readonly unknown[]" : "unknown"}; output: unknown };`)
|
|
36
|
+
.join("\n");
|
|
37
|
+
const defKeys = Object.keys(result.definitions)
|
|
38
|
+
.map((name) => ` readonly ${quoteKey(name)}: JSONSchema;`)
|
|
39
|
+
.join("\n");
|
|
40
|
+
return [
|
|
41
|
+
`import type { JSONSchema } from "@ir-kit/fn-schema-core";`,
|
|
42
|
+
`import raw from "${jsonImport}" with { type: "json" };`,
|
|
43
|
+
``,
|
|
44
|
+
`export interface Schemas {`,
|
|
45
|
+
` $schema?: string;`,
|
|
46
|
+
` signatures: {`,
|
|
47
|
+
sigKeys,
|
|
48
|
+
` };`,
|
|
49
|
+
` definitions: {`,
|
|
50
|
+
defKeys,
|
|
51
|
+
` };`,
|
|
52
|
+
`}`,
|
|
53
|
+
``,
|
|
54
|
+
`export const schemas: Schemas = raw as unknown as Schemas;`,
|
|
55
|
+
`export default schemas;`,
|
|
56
|
+
``,
|
|
57
|
+
].join("\n");
|
|
58
|
+
}
|
|
59
|
+
function quoteKey(name) {
|
|
60
|
+
return /^[A-Za-z_$][\w$]*$/.test(name) ? name : JSON.stringify(name);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/emit/bundle.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,GAAkC;IACjD,UAAU,EAAE,yCAAyC;IACrD,eAAe,EAAE,8CAA8C;IAC/D,aAAa,EAAE,gDAAgD;CAChE,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,QAAQ,CACtB,MAAqB,EACrB,OAA0B,EAAE;IAE5B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,UAAU,CAAC;IAC3C,MAAM,GAAG,GAAG;QACV,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC;QAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,WAAW,CAC5B,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC3B,CAAC,CAAC,EAAE;YACJ;gBACE,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,MAAM,EAAE,CAAC,CAAC,MAAM;aACjB;SACF,CAAC,CACH;KACF,CAAC;IACF,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAC1E,CAAC;AAOD;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAqB,EACrB,OAA2B,EAAE;IAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,gBAAgB,CAAC;IACvD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU;SAC9B,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,gBAAgB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,cAC5B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAClD,sBAAsB,CACzB;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;SAC5C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC;SAC5D,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO;QACL,2DAA2D;QAC3D,oBAAoB,UAAU,0BAA0B;QACxD,EAAE;QACF,4BAA4B;QAC5B,qBAAqB;QACrB,iBAAiB;QACjB,OAAO;QACP,MAAM;QACN,kBAAkB;QAClB,OAAO;QACP,MAAM;QACN,GAAG;QACH,EAAE;QACF,4DAA4D;QAC5D,yBAAyB;QACzB,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ExtractResult } from "../types.js";
|
|
2
|
+
export interface FileEmitOptions {
|
|
3
|
+
/** Output directory; created if missing. */
|
|
4
|
+
dir: string;
|
|
5
|
+
/** Output format. Default: "json". */
|
|
6
|
+
format?: "json" | "json-pretty";
|
|
7
|
+
/** Optional definitions filename. Default: "_definitions.json". */
|
|
8
|
+
definitionsFilename?: string;
|
|
9
|
+
/**
|
|
10
|
+
* How to compute the per-signature filename from the entry id.
|
|
11
|
+
* Default: replaces "/" with "__" and appends ".json".
|
|
12
|
+
*/
|
|
13
|
+
filename?: (id: string) => string;
|
|
14
|
+
}
|
|
15
|
+
export declare function toFiles(result: ExtractResult, opts: FileEmitOptions): Promise<string[]>;
|
|
16
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/emit/files.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,aAAa,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IAChC,mEAAmE;IACnE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;CACnC;AAED,wBAAsB,OAAO,CAC3B,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CAsCnB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export async function toFiles(result, opts) {
|
|
4
|
+
const dir = path.resolve(opts.dir);
|
|
5
|
+
await mkdir(dir, { recursive: true });
|
|
6
|
+
const written = [];
|
|
7
|
+
const fmt = opts.format ?? "json";
|
|
8
|
+
const stringify = (s) => fmt === "json-pretty" ? JSON.stringify(s, null, 2) : JSON.stringify(s);
|
|
9
|
+
const filename = opts.filename ?? defaultFilename;
|
|
10
|
+
for (const sig of result.signatures) {
|
|
11
|
+
const file = path.join(dir, filename(sig.id));
|
|
12
|
+
await writeFile(file, stringify({
|
|
13
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
14
|
+
title: sig.id,
|
|
15
|
+
input: sig.input,
|
|
16
|
+
output: sig.output,
|
|
17
|
+
}));
|
|
18
|
+
written.push(file);
|
|
19
|
+
}
|
|
20
|
+
if (Object.keys(result.definitions).length > 0) {
|
|
21
|
+
const file = path.join(dir, opts.definitionsFilename ?? "_definitions.json");
|
|
22
|
+
await writeFile(file, stringify(result.definitions));
|
|
23
|
+
written.push(file);
|
|
24
|
+
}
|
|
25
|
+
return written;
|
|
26
|
+
}
|
|
27
|
+
function defaultFilename(id) {
|
|
28
|
+
return `${id.replace(/[\\/]/g, "__")}.json`;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/emit/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAiB7B,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAqB,EACrB,IAAqB;IAErB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC;IAClC,MAAM,SAAS,GAAG,CAAC,CAAU,EAAE,EAAE,CAC/B,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAEzE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,eAAe,CAAC;IAElD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,MAAM,SAAS,CACb,IAAI,EACJ,SAAS,CAAC;YACR,OAAO,EAAE,yCAAyC;YAClD,KAAK,EAAE,GAAG,CAAC,EAAE;YACb,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB,CAAC,CACH,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,GAAG,EACH,IAAI,CAAC,mBAAmB,IAAI,mBAAmB,CAChD,CAAC;QACF,MAAM,SAAS,CACb,IAAI,EACJ,SAAS,CAAC,MAAM,CAAC,WAAgD,CAAC,CACnE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,eAAe,CAAC,EAAU;IACjC,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { type BundleEmitOptions, type BundleTypesOptions, toBundle, toBundleTypesModule, } from "./bundle.js";
|
|
2
|
+
export { type FileEmitOptions, toFiles } from "./files.js";
|
|
3
|
+
export { type OpenAPIEmitOptions, toOpenAPI } from "./openapi.js";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,QAAQ,EACR,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,eAAe,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,KAAK,kBAAkB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/emit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,EACR,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAwB,OAAO,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAA2B,SAAS,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ExtractResult, JSONSchema } from "../types.js";
|
|
2
|
+
export interface OpenAPIEmitOptions {
|
|
3
|
+
title?: string;
|
|
4
|
+
version?: string;
|
|
5
|
+
/**
|
|
6
|
+
* How to name the per-signature schemas. Defaults produce `<id>Input` and
|
|
7
|
+
* `<id>Output`. Override to avoid collisions with existing `definitions`.
|
|
8
|
+
*/
|
|
9
|
+
naming?: {
|
|
10
|
+
input?: (id: string) => string;
|
|
11
|
+
output?: (id: string) => string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Best-effort lift of fn-schema results into an OpenAPI 3.1 components-only
|
|
16
|
+
* document. Path mapping is left to the caller.
|
|
17
|
+
*
|
|
18
|
+
* Tuple inputs (when `parameters: "array"`) are rendered with `prefixItems`
|
|
19
|
+
* per the JSON Schema 2020-12 / OpenAPI 3.1 tuple convention.
|
|
20
|
+
*/
|
|
21
|
+
export declare function toOpenAPI(result: ExtractResult, opts?: OpenAPIEmitOptions): {
|
|
22
|
+
openapi: "3.1.0";
|
|
23
|
+
info: {
|
|
24
|
+
title: string;
|
|
25
|
+
version: string;
|
|
26
|
+
};
|
|
27
|
+
components: {
|
|
28
|
+
schemas: Record<string, JSONSchema>;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/emit/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;QAC/B,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;KACjC,CAAC;CACH;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,aAAa,EACrB,IAAI,GAAE,kBAAuB,GAC5B;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;KAAE,CAAC;CACrD,CA+BA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort lift of fn-schema results into an OpenAPI 3.1 components-only
|
|
3
|
+
* document. Path mapping is left to the caller.
|
|
4
|
+
*
|
|
5
|
+
* Tuple inputs (when `parameters: "array"`) are rendered with `prefixItems`
|
|
6
|
+
* per the JSON Schema 2020-12 / OpenAPI 3.1 tuple convention.
|
|
7
|
+
*/
|
|
8
|
+
export function toOpenAPI(result, opts = {}) {
|
|
9
|
+
const schemas = { ...result.definitions };
|
|
10
|
+
const inputName = opts.naming?.input ?? ((id) => `${id}Input`);
|
|
11
|
+
const outputName = opts.naming?.output ?? ((id) => `${id}Output`);
|
|
12
|
+
for (const sig of result.signatures) {
|
|
13
|
+
const iKey = pickFreeKey(inputName(sig.id), schemas);
|
|
14
|
+
const oKey = pickFreeKey(outputName(sig.id), schemas);
|
|
15
|
+
schemas[iKey] = Array.isArray(sig.input)
|
|
16
|
+
? // OpenAPI 3.1 / Draft 2020-12: tuples use `prefixItems`. Cast to
|
|
17
|
+
// JSONSchema7-compatible shape via index signature — `prefixItems`
|
|
18
|
+
// isn't in the JSONSchema7 type but is valid in the emitted JSON.
|
|
19
|
+
{
|
|
20
|
+
type: "array",
|
|
21
|
+
prefixItems: sig.input,
|
|
22
|
+
items: false,
|
|
23
|
+
minItems: sig.input.length,
|
|
24
|
+
maxItems: sig.input.length,
|
|
25
|
+
}
|
|
26
|
+
: sig.input;
|
|
27
|
+
schemas[oKey] = sig.output;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
openapi: "3.1.0",
|
|
31
|
+
info: {
|
|
32
|
+
title: opts.title ?? "fn-schema",
|
|
33
|
+
version: opts.version ?? "0.0.0",
|
|
34
|
+
},
|
|
35
|
+
components: { schemas },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function pickFreeKey(desired, schemas) {
|
|
39
|
+
if (!(desired in schemas))
|
|
40
|
+
return desired;
|
|
41
|
+
let n = 2;
|
|
42
|
+
while (`${desired}__${n}` in schemas)
|
|
43
|
+
n++;
|
|
44
|
+
return `${desired}__${n}`;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=openapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../src/emit/openapi.ts"],"names":[],"mappings":"AAeA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,MAAqB,EACrB,OAA2B,EAAE;IAM7B,MAAM,OAAO,GAA+B,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACtE,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAElE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YACtC,CAAC,CAAC,iEAAiE;gBACjE,mEAAmE;gBACnE,kEAAkE;gBACjE;oBACC,IAAI,EAAE,OAAO;oBACb,WAAW,EAAE,GAAG,CAAC,KAAK;oBACtB,KAAK,EAAE,KAAK;oBACZ,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM;oBAC1B,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM;iBACD;YAC7B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,OAAO;QACL,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE;YACJ,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,WAAW;YAChC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,OAAO;SACjC;QACD,UAAU,EAAE,EAAE,OAAO,EAAE;KACxB,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAClB,OAAe,EACf,OAAmC;IAEnC,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1C,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,GAAG,OAAO,KAAK,CAAC,EAAE,IAAI,OAAO;QAAE,CAAC,EAAE,CAAC;IAC1C,OAAO,GAAG,OAAO,KAAK,CAAC,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/filter.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ExcludeFilter, FunctionInfo, IncludeFilter, ResolvedFilter } from "./types.js";
|
|
2
|
+
export declare function resolveFilter(include?: IncludeFilter, exclude?: ExcludeFilter, custom?: (fn: FunctionInfo) => boolean): ResolvedFilter;
|
|
3
|
+
export declare function applyFilter(fn: FunctionInfo, filter: ResolvedFilter): boolean;
|
|
4
|
+
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EAEb,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,wBAAgB,aAAa,CAC3B,OAAO,CAAC,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,aAAa,EACvB,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,YAAY,KAAK,OAAO,GACrC,cAAc,CAehB;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAuB7E"}
|
package/dist/filter.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export function resolveFilter(include, exclude, custom) {
|
|
2
|
+
return {
|
|
3
|
+
exported: include?.exported ?? true,
|
|
4
|
+
name: toRegexList(include?.name),
|
|
5
|
+
jsDocTag: toStringList(include?.jsDocTag),
|
|
6
|
+
kind: include?.kind ?? null,
|
|
7
|
+
decorator: toRegex(include?.decorator),
|
|
8
|
+
exclude: {
|
|
9
|
+
name: toRegexList(exclude?.name),
|
|
10
|
+
jsDocTag: toStringList(exclude?.jsDocTag),
|
|
11
|
+
kind: exclude?.kind ?? null,
|
|
12
|
+
decorator: toRegex(exclude?.decorator),
|
|
13
|
+
},
|
|
14
|
+
custom: custom ?? null,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function applyFilter(fn, filter) {
|
|
18
|
+
if (filter.exported && !fn.exported)
|
|
19
|
+
return false;
|
|
20
|
+
if (filter.kind && !filter.kind.includes(fn.kind))
|
|
21
|
+
return false;
|
|
22
|
+
if (filter.name && !filter.name.some((r) => r.test(fn.name)))
|
|
23
|
+
return false;
|
|
24
|
+
if (filter.jsDocTag && !filter.jsDocTag.some((t) => fn.jsDoc?.tags?.[t]))
|
|
25
|
+
return false;
|
|
26
|
+
if (filter.decorator &&
|
|
27
|
+
!fn.decorators?.some((d) => filter.decorator.test(d)))
|
|
28
|
+
return false;
|
|
29
|
+
const ex = filter.exclude;
|
|
30
|
+
if (ex.kind && ex.kind.includes(fn.kind))
|
|
31
|
+
return false;
|
|
32
|
+
if (ex.name && ex.name.some((r) => r.test(fn.name)))
|
|
33
|
+
return false;
|
|
34
|
+
if (ex.jsDocTag && ex.jsDocTag.some((t) => fn.jsDoc?.tags?.[t]))
|
|
35
|
+
return false;
|
|
36
|
+
if (ex.decorator && fn.decorators?.some((d) => ex.decorator.test(d)))
|
|
37
|
+
return false;
|
|
38
|
+
if (filter.custom && !filter.custom(fn))
|
|
39
|
+
return false;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
function toRegexList(input) {
|
|
43
|
+
if (input == null)
|
|
44
|
+
return null;
|
|
45
|
+
const arr = Array.isArray(input) ? input : [input];
|
|
46
|
+
return arr.map(toRegexStrict);
|
|
47
|
+
}
|
|
48
|
+
function toRegex(input) {
|
|
49
|
+
if (input == null)
|
|
50
|
+
return null;
|
|
51
|
+
return toRegexStrict(input);
|
|
52
|
+
}
|
|
53
|
+
function toRegexStrict(p) {
|
|
54
|
+
if (p instanceof RegExp)
|
|
55
|
+
return p;
|
|
56
|
+
// Treat plain strings as literal substrings — simpler than glob, predictable.
|
|
57
|
+
return new RegExp(escapeRegExp(p));
|
|
58
|
+
}
|
|
59
|
+
function toStringList(input) {
|
|
60
|
+
if (input == null)
|
|
61
|
+
return null;
|
|
62
|
+
return Array.isArray(input) ? input : [input];
|
|
63
|
+
}
|
|
64
|
+
function escapeRegExp(s) {
|
|
65
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { resolveSchemaOptions, resolveSignatureOptions } from "./defaults.js";
|
|
2
|
+
export { DiagnosticSink, FailFastError } from "./diagnostics.js";
|
|
3
|
+
export * as emit from "./emit/index.js";
|
|
4
|
+
export { applyFilter, resolveFilter } from "./filter.js";
|
|
5
|
+
export { resolveNaming } from "./naming.js";
|
|
6
|
+
export { createProject } from "./project.js";
|
|
7
|
+
export { type ParsedTarget, parseTarget } from "./targets.js";
|
|
8
|
+
export type { CoverageEntry, CoverageOccurrence, CoverageReport, Diagnostic, DiagnosticCode, DiagnosticSeverity, DiscoverResult, ExcludeFilter, ExtractHooks, ExtractOptions, Extractor, ExtractorInitOptions, ExtractorInstance, ExtractResult, ExtractStats, FunctionInfo, FunctionKind, GenericsStrategy, IncludeFilter, InMemorySource, JSDocInfo, JSONSchema, LossyCoverageEntry, NamePattern, NamingStrategy, OverloadStrategy, ParameterInfo, ParametersStrategy, Project, ProjectOptions, RefStrategy, ResolvedFilter, ResolvedSchemaOptions, ResolvedSignatureOptions, SchemaContext, SchemaDialect, SchemaOptions, SignatureEntry, SignatureOptions, SignaturePair, SourceLocation, TargetRef, } from "./types.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,KAAK,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9D,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,OAAO,EACP,cAAc,EACd,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,SAAS,GACV,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { resolveSchemaOptions, resolveSignatureOptions } from "./defaults.js";
|
|
2
|
+
export { DiagnosticSink, FailFastError } from "./diagnostics.js";
|
|
3
|
+
export * as emit from "./emit/index.js";
|
|
4
|
+
export { applyFilter, resolveFilter } from "./filter.js";
|
|
5
|
+
export { resolveNaming } from "./naming.js";
|
|
6
|
+
export { createProject } from "./project.js";
|
|
7
|
+
export { parseTarget } from "./targets.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAqB,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/naming.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE/D,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,cAAc,GAAG,SAAS,EACpC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,MAAM,GACV,MAAM,CAoBR"}
|