@apollo-deploy/tesseract 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 +21 -0
- package/README.md +235 -0
- package/dist/adapters/types.d.ts +15 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +6 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/typescript/index.d.ts +11 -0
- package/dist/adapters/typescript/index.d.ts.map +1 -0
- package/dist/adapters/typescript/index.js +112 -0
- package/dist/adapters/typescript/index.js.map +1 -0
- package/dist/adapters/typescript/model-emitter.d.ts +13 -0
- package/dist/adapters/typescript/model-emitter.d.ts.map +1 -0
- package/dist/adapters/typescript/model-emitter.js +415 -0
- package/dist/adapters/typescript/model-emitter.js.map +1 -0
- package/dist/adapters/typescript/shared.d.ts +26 -0
- package/dist/adapters/typescript/shared.d.ts.map +1 -0
- package/dist/adapters/typescript/shared.js +65 -0
- package/dist/adapters/typescript/shared.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +53 -0
- package/dist/cli.js.map +1 -0
- package/dist/helpers/handlebars.d.ts +15 -0
- package/dist/helpers/handlebars.d.ts.map +1 -0
- package/dist/helpers/handlebars.js +172 -0
- package/dist/helpers/handlebars.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/enrich.d.ts +7 -0
- package/dist/pipeline/enrich.d.ts.map +1 -0
- package/dist/pipeline/enrich.js +277 -0
- package/dist/pipeline/enrich.js.map +1 -0
- package/dist/pipeline/intake.d.ts +11 -0
- package/dist/pipeline/intake.d.ts.map +1 -0
- package/dist/pipeline/intake.js +508 -0
- package/dist/pipeline/intake.js.map +1 -0
- package/dist/pipeline/write.d.ts +15 -0
- package/dist/pipeline/write.d.ts.map +1 -0
- package/dist/pipeline/write.js +33 -0
- package/dist/pipeline/write.js.map +1 -0
- package/dist/types/config.d.ts +47 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +24 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/ir.d.ts +172 -0
- package/dist/types/ir.d.ts.map +1 -0
- package/dist/types/ir.js +7 -0
- package/dist/types/ir.js.map +1 -0
- package/dist/types/manifest.d.ts +112 -0
- package/dist/types/manifest.d.ts.map +1 -0
- package/dist/types/manifest.js +32 -0
- package/dist/types/manifest.js.map +1 -0
- package/dist/utils/format.d.ts +5 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +21 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/naming.d.ts +26 -0
- package/dist/utils/naming.d.ts.map +1 -0
- package/dist/utils/naming.js +270 -0
- package/dist/utils/naming.js.map +1 -0
- package/package.json +58 -0
- package/templates/typescript/client.hbs +145 -0
- package/templates/typescript/domain-index.hbs +10 -0
- package/templates/typescript/domain.hbs +127 -0
- package/templates/typescript/index.hbs +64 -0
- package/templates/typescript/package-json.hbs +29 -0
- package/templates/typescript/readme.hbs +78 -0
- package/templates/typescript/transport-sse.hbs +377 -0
- package/templates/typescript/transport.hbs +662 -0
- package/templates/typescript/tsconfig.hbs +18 -0
- package/templates/typescript/types-common.hbs +98 -0
- package/templates/typescript/types-errors.hbs +191 -0
- package/templates/typescript/types.hbs +33 -0
- package/templates/typescript/utils-index.hbs +7 -0
- package/templates/typescript/utils-query.hbs +29 -0
- package/templates/typescript/webhook-handler.hbs +447 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tihan-Nico
|
|
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,235 @@
|
|
|
1
|
+
# Tesseract
|
|
2
|
+
|
|
3
|
+
Manifest-first SDK generator — turns `sdk-manifold/v1` manifests into production-ready TypeScript SDKs.
|
|
4
|
+
|
|
5
|
+
Tesseract is **not** an OpenAPI parser. It consumes a purpose-built manifest format designed specifically for SDK generation, producing fully typed, batteries-included TypeScript packages.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @apollo-deploy/tesseract
|
|
11
|
+
# or
|
|
12
|
+
bun add -g @apollo-deploy/tesseract
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
tesseract generate -i manifest.json -o ./sdk
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This reads your manifest and produces a complete npm-ready SDK in `./sdk/`.
|
|
22
|
+
|
|
23
|
+
## CLI
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
tesseract generate [options]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| Flag | Required | Description |
|
|
30
|
+
|------|----------|-------------|
|
|
31
|
+
| `-i, --input <path>` | Yes | Path to the `sdk-manifold/v1` manifest JSON file |
|
|
32
|
+
| `-o, --output <dir>` | Yes | Output directory for the generated SDK |
|
|
33
|
+
| `-n, --name <name>` | No | Override the npm package name |
|
|
34
|
+
| `--client-name <name>` | No | Override the generated client class name |
|
|
35
|
+
| `--base-url <url>` | No | Override the default base URL |
|
|
36
|
+
|
|
37
|
+
## Input: The Manifest
|
|
38
|
+
|
|
39
|
+
Tesseract consumes a `BackendManifest` JSON file with schema `"sdk-manifold/v1"`:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"schema": "sdk-manifold/v1",
|
|
44
|
+
"info": {
|
|
45
|
+
"title": "My API",
|
|
46
|
+
"version": "1.0.0",
|
|
47
|
+
"description": "An example API",
|
|
48
|
+
"baseUrl": "https://api.example.com"
|
|
49
|
+
},
|
|
50
|
+
"domains": [
|
|
51
|
+
{
|
|
52
|
+
"name": "users",
|
|
53
|
+
"prefix": "/users",
|
|
54
|
+
"stability": "stable",
|
|
55
|
+
"routes": [
|
|
56
|
+
{
|
|
57
|
+
"method": "GET",
|
|
58
|
+
"url": "/:id",
|
|
59
|
+
"schema": {
|
|
60
|
+
"params": { "id": { "type": "string" } },
|
|
61
|
+
"response": { "200": { "$ref": "#/definitions/User" } }
|
|
62
|
+
},
|
|
63
|
+
"sdk": { "methodName": "get" }
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"definitions": {
|
|
69
|
+
"User": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"properties": {
|
|
72
|
+
"id": { "type": "string" },
|
|
73
|
+
"name": { "type": "string" }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Key Manifest Fields
|
|
81
|
+
|
|
82
|
+
- **`info`** — Title, version, description, and base URL for the API
|
|
83
|
+
- **`domains`** — Groups of routes organized by domain, each with a prefix, stability level (`stable` / `experimental` / `internal`), and route definitions
|
|
84
|
+
- **`definitions`** — JSON Schema definitions for shared types
|
|
85
|
+
- **`schemaPackage`** _(optional)_ — An external npm package to import types from instead of generating them
|
|
86
|
+
|
|
87
|
+
### Route Configuration
|
|
88
|
+
|
|
89
|
+
Each route in a domain can specify:
|
|
90
|
+
|
|
91
|
+
- **`method`** / **`url`** — HTTP method and Fastify-style URL pattern (`:param`)
|
|
92
|
+
- **`schema`** — JSON Schemas for params, query, body, headers, and response
|
|
93
|
+
- **`sdk`** — SDK-specific config: method name override, transport type (`json` | `multipart` | `binary` | `stream`), exclusion flags
|
|
94
|
+
- **`sse: true`** — Marks the route as a Server-Sent Events stream
|
|
95
|
+
|
|
96
|
+
## Output
|
|
97
|
+
|
|
98
|
+
Tesseract generates a complete, publishable npm package:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
sdk/
|
|
102
|
+
├── package.json
|
|
103
|
+
├── tsconfig.json
|
|
104
|
+
├── README.md
|
|
105
|
+
├── index.ts
|
|
106
|
+
└── src/
|
|
107
|
+
├── client.ts # Main client with config, auth, plugins
|
|
108
|
+
├── transport/
|
|
109
|
+
│ ├── axios.ts # HTTP transport with retries, telemetry
|
|
110
|
+
│ └── sse.ts # SSE streaming transport (if needed)
|
|
111
|
+
├── domain/
|
|
112
|
+
│ ├── users.ts # Domain-grouped API methods
|
|
113
|
+
│ └── ...
|
|
114
|
+
├── types/
|
|
115
|
+
│ ├── models.ts # Interfaces, type aliases, enums
|
|
116
|
+
│ ├── common.ts # Pagination, error envelope
|
|
117
|
+
│ ├── errors.ts # SDKError class
|
|
118
|
+
│ └── index.ts # Barrel export
|
|
119
|
+
├── utils/
|
|
120
|
+
│ └── query.ts # Query parameter utilities
|
|
121
|
+
└── webhooks/
|
|
122
|
+
└── handler.ts # Typed webhook registry (if needed)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Generated SDK Features
|
|
126
|
+
|
|
127
|
+
- **Typed client** with grouped domain methods
|
|
128
|
+
- **Automatic retries** with exponential backoff, jitter, and customizable retry logic
|
|
129
|
+
- **Configurable timeouts** at both transport and per-request level
|
|
130
|
+
- **Security scheme support** — API key, Bearer, OAuth2, OpenID Connect
|
|
131
|
+
- **Plugin system** — `SDKPlugin` hooks for request/response/error interception
|
|
132
|
+
- **Telemetry hooks** — `onRequest`, `onResponse`, `onError` with timing data
|
|
133
|
+
- **Idempotency keys** on mutating requests
|
|
134
|
+
- **SSE streaming** — Typed `AsyncIterable<SSEEvent<T>>` with automatic reconnection, heartbeat detection, and buffer overflow protection
|
|
135
|
+
- **Webhook handlers** — Typed event registry with HMAC verification, replay protection, handler timeouts, and one-time handlers
|
|
136
|
+
- **AbortSignal support** for request cancellation
|
|
137
|
+
- **Per-request overrides** — timeout, headers, retry config
|
|
138
|
+
|
|
139
|
+
### Example Usage of Generated SDK
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { createMyApiClient } from './sdk';
|
|
143
|
+
|
|
144
|
+
const client = createMyApiClient({
|
|
145
|
+
baseUrl: 'https://api.example.com',
|
|
146
|
+
apiKey: 'sk_...',
|
|
147
|
+
timeoutMs: 10000,
|
|
148
|
+
retries: { attempts: 3, backoffMs: 500, jitter: true },
|
|
149
|
+
plugins: [{
|
|
150
|
+
name: 'logger',
|
|
151
|
+
beforeRequest(config) {
|
|
152
|
+
console.log('→', config.method, config.url);
|
|
153
|
+
},
|
|
154
|
+
}],
|
|
155
|
+
onError({ method, url, error, attempt, willRetry }) {
|
|
156
|
+
console.error(`${method} ${url} failed (attempt ${attempt}, retry: ${willRetry})`);
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Typed domain methods
|
|
161
|
+
const user = await client.users.get('user_123');
|
|
162
|
+
|
|
163
|
+
// Per-request overrides
|
|
164
|
+
const result = await client.orders.list(
|
|
165
|
+
{ page: 1, limit: 20 },
|
|
166
|
+
{ timeoutMs: 30000, retries: { attempts: 5 } },
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
// SSE streaming
|
|
170
|
+
for await (const event of client.events.stream({ signal: controller.signal })) {
|
|
171
|
+
console.log(event.type, event.data);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Webhooks
|
|
175
|
+
client.webhooks.on('orderCreated', async (payload, meta) => {
|
|
176
|
+
console.log('New order:', payload.id);
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Pipeline
|
|
181
|
+
|
|
182
|
+
Tesseract processes manifests through three stages:
|
|
183
|
+
|
|
184
|
+
1. **Intake** — Reads and validates the manifest, converts it to an intermediate representation (SDKIR). Handles JSON Schema → TypeScript type conversion, parameter extraction, and domain grouping. Internal-stability domains are filtered out.
|
|
185
|
+
|
|
186
|
+
2. **Enrich** — Augments the SDKIR with a symbol table, import graph, topologically sorted schemas (with cycle detection), render decisions (interface / type alias / enum / union), method signatures, and doc blocks.
|
|
187
|
+
|
|
188
|
+
3. **Write** — Diff-aware file writer. Only overwrites files whose content has actually changed, making it safe for CI/CD regeneration.
|
|
189
|
+
|
|
190
|
+
### Code Generation Approach
|
|
191
|
+
|
|
192
|
+
Tesseract uses a dual strategy:
|
|
193
|
+
|
|
194
|
+
- **[ts-morph](https://ts-morph.com/)** (AST-based) for type definitions — interfaces, enums, type aliases
|
|
195
|
+
- **[Handlebars](https://handlebarsjs.com/)** templates for everything else — client, transport, domain methods, utilities
|
|
196
|
+
|
|
197
|
+
All output is formatted with Prettier.
|
|
198
|
+
|
|
199
|
+
## Programmatic API
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { generate } from '@apollo-deploy/tesseract';
|
|
203
|
+
|
|
204
|
+
await generate({
|
|
205
|
+
input: './manifest.json',
|
|
206
|
+
output: './sdk',
|
|
207
|
+
language: 'typescript',
|
|
208
|
+
packageName: '@my-org/api-sdk',
|
|
209
|
+
clientName: 'MyApi',
|
|
210
|
+
baseUrl: 'https://api.example.com',
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Configuration
|
|
215
|
+
|
|
216
|
+
| Option | Type | Description |
|
|
217
|
+
|--------|------|-------------|
|
|
218
|
+
| `input` | `string` | Path to the manifest file |
|
|
219
|
+
| `output` | `string` | Output directory |
|
|
220
|
+
| `language` | `'typescript'` | Target language |
|
|
221
|
+
| `packageName` | `string?` | Override npm package name |
|
|
222
|
+
| `clientName` | `string?` | Override client class name |
|
|
223
|
+
| `baseUrl` | `string?` | Override default base URL |
|
|
224
|
+
| `environments` | `{ name: string; baseUrl: string }[]?` | Named environment presets |
|
|
225
|
+
| `dryRun` | `boolean?` | Transform only, no file I/O |
|
|
226
|
+
| `check` | `boolean?` | Compare output without writing |
|
|
227
|
+
| `prettier` | `boolean?` | Toggle formatting (default: `true`) |
|
|
228
|
+
|
|
229
|
+
## Requirements
|
|
230
|
+
|
|
231
|
+
- Node.js ≥ 18 or Bun ≥ 1.0
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
MIT
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language adapter interface.
|
|
3
|
+
* Each supported language implements this contract.
|
|
4
|
+
*/
|
|
5
|
+
import type { EnrichedSDKIR } from '../types/ir.js';
|
|
6
|
+
import type { EmittedFile } from '../pipeline/write.js';
|
|
7
|
+
export interface EmitResult {
|
|
8
|
+
files: EmittedFile[];
|
|
9
|
+
warnings: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface LanguageAdapter {
|
|
12
|
+
readonly language: string;
|
|
13
|
+
emit(enriched: EnrichedSDKIR, outputDir: string): Promise<EmitResult>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACvE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript language adapter.
|
|
3
|
+
* Orchestrates model emission (ts-morph) and template rendering (Handlebars).
|
|
4
|
+
*/
|
|
5
|
+
import type { EnrichedSDKIR } from '../../types/ir.js';
|
|
6
|
+
import type { LanguageAdapter, EmitResult } from '../types.js';
|
|
7
|
+
export declare class TypeScriptAdapter implements LanguageAdapter {
|
|
8
|
+
readonly language = "typescript";
|
|
9
|
+
emit(enriched: EnrichedSDKIR, outputDir: string): Promise<EmitResult>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/typescript/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO/D,qBAAa,iBAAkB,YAAW,eAAe;IACvD,QAAQ,CAAC,QAAQ,gBAAgB;IAE3B,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAkH5E"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript language adapter.
|
|
3
|
+
* Orchestrates model emission (ts-morph) and template rendering (Handlebars).
|
|
4
|
+
*/
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { emitTypeScriptModels } from './model-emitter.js';
|
|
7
|
+
import { splitSchemasByOwnership, buildExternalImportGroups, collectExternalPackages, COMMON_TYPE_NAMES } from './shared.js';
|
|
8
|
+
import { getTemplate, registerHelpers, collectImports } from '../../helpers/handlebars.js';
|
|
9
|
+
import { formatTypeScript } from '../../utils/format.js';
|
|
10
|
+
export class TypeScriptAdapter {
|
|
11
|
+
language = 'typescript';
|
|
12
|
+
async emit(enriched, outputDir) {
|
|
13
|
+
registerHelpers();
|
|
14
|
+
const files = [];
|
|
15
|
+
const warnings = [];
|
|
16
|
+
const { generatedSchemas, externalSchemas } = splitSchemasByOwnership(enriched.schemas);
|
|
17
|
+
const schemaNames = new Set(enriched.schemas.map((s) => s.name));
|
|
18
|
+
const externalImports = buildExternalImportGroups(externalSchemas);
|
|
19
|
+
const externalTypeNames = new Set(externalSchemas.map((s) => s.name));
|
|
20
|
+
const commonTypeExports = COMMON_TYPE_NAMES.filter((name) => !externalTypeNames.has(name));
|
|
21
|
+
const externalPackages = collectExternalPackages(enriched.schemas, enriched.meta.schemaPackage);
|
|
22
|
+
const hasSSE = enriched.groups.some((g) => g.operations.some((op) => op.isEventStream));
|
|
23
|
+
// ── ts-morph: model type files ───────────────────────────────────────────
|
|
24
|
+
let domainTypeFiles = [];
|
|
25
|
+
try {
|
|
26
|
+
const { files: modelFiles, domainTypeFiles: dtf } = emitTypeScriptModels(enriched, outputDir);
|
|
27
|
+
files.push(...modelFiles);
|
|
28
|
+
domainTypeFiles = dtf;
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
warnings.push(`ts-morph model emission failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
32
|
+
}
|
|
33
|
+
// ── Handlebars: all other TypeScript files ───────────────────────────────
|
|
34
|
+
// Domain files
|
|
35
|
+
const domainTemplate = getTemplate('typescript', 'domain');
|
|
36
|
+
for (const group of enriched.groups) {
|
|
37
|
+
try {
|
|
38
|
+
const imports = collectImports(group.operations, schemaNames);
|
|
39
|
+
const groupHasSSE = group.operations.some((op) => op.isEventStream);
|
|
40
|
+
files.push({
|
|
41
|
+
relativePath: join('src', 'domain', `${group.fileName}.ts`),
|
|
42
|
+
content: domainTemplate({ ...group, imports, hasSSE: groupHasSSE }),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
warnings.push(`domain/${group.fileName}.ts: ${err instanceof Error ? err.message : String(err)}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Domain index barrel
|
|
50
|
+
tryEmit(files, warnings, join('src', 'domain', 'index.ts'), () => getTemplate('typescript', 'domain-index')({ groups: enriched.groups }));
|
|
51
|
+
// Types
|
|
52
|
+
tryEmit(files, warnings, join('src', 'types', 'common.ts'), () => getTemplate('typescript', 'types-common')({}));
|
|
53
|
+
tryEmit(files, warnings, join('src', 'types', 'errors.ts'), () => getTemplate('typescript', 'types-errors')({}));
|
|
54
|
+
tryEmit(files, warnings, join('src', 'types', 'index.ts'), () => getTemplate('typescript', 'types')({
|
|
55
|
+
schemas: generatedSchemas,
|
|
56
|
+
externalImports,
|
|
57
|
+
domainTypeFiles,
|
|
58
|
+
commonTypeExports,
|
|
59
|
+
}));
|
|
60
|
+
// Transport
|
|
61
|
+
tryEmit(files, warnings, join('src', 'transport', 'axios.ts'), () => getTemplate('typescript', 'transport')({ securitySchemes: enriched.securitySchemes }));
|
|
62
|
+
// SSE transport
|
|
63
|
+
if (hasSSE) {
|
|
64
|
+
tryEmit(files, warnings, join('src', 'transport', 'sse.ts'), () => getTemplate('typescript', 'transport-sse')({}));
|
|
65
|
+
}
|
|
66
|
+
// Utils
|
|
67
|
+
tryEmit(files, warnings, join('src', 'utils', 'query.ts'), () => getTemplate('typescript', 'utils-query')({}));
|
|
68
|
+
tryEmit(files, warnings, join('src', 'utils', 'index.ts'), () => getTemplate('typescript', 'utils-index')({}));
|
|
69
|
+
// Client, index, package.json, tsconfig, README
|
|
70
|
+
tryEmit(files, warnings, join('src', 'client.ts'), () => getTemplate('typescript', 'client')({
|
|
71
|
+
meta: enriched.meta,
|
|
72
|
+
groups: enriched.groups,
|
|
73
|
+
securitySchemes: enriched.securitySchemes,
|
|
74
|
+
hasSSE,
|
|
75
|
+
}));
|
|
76
|
+
tryEmit(files, warnings, 'index.ts', () => getTemplate('typescript', 'index')({
|
|
77
|
+
meta: enriched.meta,
|
|
78
|
+
groups: enriched.groups,
|
|
79
|
+
schemas: enriched.schemas,
|
|
80
|
+
hasSSE,
|
|
81
|
+
}));
|
|
82
|
+
tryEmit(files, warnings, 'package.json', () => getTemplate('typescript', 'package-json')({ ...enriched.meta, externalPackages }));
|
|
83
|
+
tryEmit(files, warnings, 'tsconfig.json', () => getTemplate('typescript', 'tsconfig')({}));
|
|
84
|
+
tryEmit(files, warnings, 'README.md', () => getTemplate('typescript', 'readme')({
|
|
85
|
+
...enriched.meta,
|
|
86
|
+
groups: enriched.groups,
|
|
87
|
+
schemas: enriched.schemas,
|
|
88
|
+
securitySchemes: enriched.securitySchemes,
|
|
89
|
+
hasSSE,
|
|
90
|
+
}));
|
|
91
|
+
// Format TypeScript files
|
|
92
|
+
const formatted = [];
|
|
93
|
+
for (const file of files) {
|
|
94
|
+
if (file.relativePath.endsWith('.ts')) {
|
|
95
|
+
formatted.push({ ...file, content: await formatTypeScript(file.content) });
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
formatted.push(file);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return { files: formatted, warnings };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function tryEmit(files, warnings, relativePath, render) {
|
|
105
|
+
try {
|
|
106
|
+
files.push({ relativePath, content: render() });
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
warnings.push(`${relativePath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/typescript/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript model emitter (ts-morph based).
|
|
3
|
+
*
|
|
4
|
+
* Emits schema definitions as TypeScript interfaces, type aliases,
|
|
5
|
+
* and enums using ts-morph AST construction.
|
|
6
|
+
*/
|
|
7
|
+
import type { EnrichedSDKIR } from '../../types/ir.js';
|
|
8
|
+
import type { EmittedFile } from '../../pipeline/write.js';
|
|
9
|
+
export declare function emitTypeScriptModels(enriched: EnrichedSDKIR, outputDir: string): {
|
|
10
|
+
files: EmittedFile[];
|
|
11
|
+
domainTypeFiles: string[];
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=model-emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-emitter.d.ts","sourceRoot":"","sources":["../../../src/adapters/typescript/model-emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,aAAa,EAAoC,MAAM,mBAAmB,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAA;CAAE,CAmErD"}
|