@lyku/lockstep-client-ts 1.0.0 → 1.3.1
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/LLMs.md +85 -0
- package/README.md +71 -9
- package/package.json +5 -2
package/LLMs.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @lyku/lockstep-client-ts -- LLM Context
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
A code generation library that converts `ExternalApiModel` definitions (TsonSchema-based) into fully-typed, self-contained TypeScript HTTP client files. It bridges the gap between Lyku's custom schema system (`@lyku/lockstep-core`) and external third-party APIs.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
External API model definitions (e.g., @lyku/valhalla-models)
|
|
11
|
+
|
|
|
12
|
+
v
|
|
13
|
+
lockstep-client-ts (this package)
|
|
14
|
+
-- reads ExternalApiSpec
|
|
15
|
+
-- calls tsonToType() from @lyku/lockstep-core to convert schemas to TS types
|
|
16
|
+
-- generates index.ts with types + client factory
|
|
17
|
+
|
|
|
18
|
+
v
|
|
19
|
+
Generated client library (e.g., @lyku/valhalla-handles-ts)
|
|
20
|
+
-- consumed by route handlers at runtime
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The generation is run as a build step, typically from a `build.ts` script like:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { generateTsClient } from '@lyku/lockstep-client-ts';
|
|
27
|
+
import { valhallaModels } from '@lyku/valhalla-models';
|
|
28
|
+
|
|
29
|
+
await generateTsClient({
|
|
30
|
+
models: valhallaModels,
|
|
31
|
+
name: 'Valhalla',
|
|
32
|
+
outputDir: '../../dist/libs/valhalla-handles-ts',
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## File Structure
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
src/
|
|
40
|
+
index.ts -- entire implementation in a single file
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The package is intentionally minimal: one file containing the generator function, validation helper, and all type definitions.
|
|
44
|
+
|
|
45
|
+
## Key Patterns and Conventions
|
|
46
|
+
|
|
47
|
+
- **Single-file codegen**: All logic lives in `src/index.ts`. The generator builds a large string template of TypeScript code and writes it to disk.
|
|
48
|
+
- **Schema conversion**: Uses `tsonToType()` from `@lyku/lockstep-core` to convert TsonSchema definitions into TypeScript type strings at generation time.
|
|
49
|
+
- **GET vs POST routing**: GET endpoints use query parameter serialization; POST/PUT/PATCH/DELETE endpoints use JSON request bodies.
|
|
50
|
+
- **Path parameter interpolation**: Endpoints with `pathParams` get template literal paths (e.g., `/stops/${encodeURIComponent(stopId)}`).
|
|
51
|
+
- **Parameter mapping**: The `paramMapping` option supports APIs that use non-standard param formats (e.g., Pelias uses dotted params like `focus.point.lat`).
|
|
52
|
+
- **API key injection**: The `apiKeyParam` option automatically injects an API key into all requests as a query parameter.
|
|
53
|
+
- **Custom methods**: For endpoints with complex signatures (e.g., overloaded path params), `customMethods` allows injecting raw TypeScript code.
|
|
54
|
+
|
|
55
|
+
## Important Types
|
|
56
|
+
|
|
57
|
+
- `ExternalApiModel` -- defines a single API endpoint (method, path, request/response schemas, path params)
|
|
58
|
+
- `ExternalApiSpec` -- `Record<string, ExternalApiModel>`, the full API surface
|
|
59
|
+
- `GenerateTsClientOptions` -- configuration for the generator
|
|
60
|
+
|
|
61
|
+
## Generated Code Structure
|
|
62
|
+
|
|
63
|
+
For a client named `Foo`, the output contains:
|
|
64
|
+
|
|
65
|
+
1. Per-endpoint request/response types (`FooBarRequest`, `FooBarResponse`)
|
|
66
|
+
2. A type map (`FooTypes`) for generic method dispatch
|
|
67
|
+
3. Query string builder (with optional parameter mapping)
|
|
68
|
+
4. `FooClientOptions` type for client configuration
|
|
69
|
+
5. `FooError` class extending `Error`
|
|
70
|
+
6. HTTP `request()` helper using `fetch` + `AbortController`
|
|
71
|
+
7. `createFooClient()` factory returning typed methods
|
|
72
|
+
8. `FooClient` type alias
|
|
73
|
+
|
|
74
|
+
## Common Pitfalls
|
|
75
|
+
|
|
76
|
+
- **The generated file should never be edited manually** -- it is overwritten on each build. The `DO NOT EDIT MANUALLY` comment is included in the output.
|
|
77
|
+
- **Peer dependency**: `@lyku/lockstep-core` must be available; without it, `tsonToType()` calls will fail.
|
|
78
|
+
- **Prettier failures are non-fatal**: If Prettier formatting fails, the unformatted output is written with a console warning.
|
|
79
|
+
- **GET requests with body schemas**: The validator will flag GET endpoints that use `request` instead of `queryParams`, but the generator will still work (it checks both).
|
|
80
|
+
|
|
81
|
+
## Monorepo Connections
|
|
82
|
+
|
|
83
|
+
- **Peer dependency**: `@lyku/lockstep-core` (schema framework)
|
|
84
|
+
- **Consumers**: `@lyku/valhalla-handles-ts`, `@lyku/pelias-handles-ts`, `@lyku/tomtom-handles-ts`, `@lyku/otp-handles-ts` -- each has a `build.ts` that calls `generateTsClient()`
|
|
85
|
+
- **Not used for internal Lyku APIs** -- internal APIs use `@lyku/mapi-models` and the `handles` system instead
|
package/README.md
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
# ts
|
|
1
|
+
# @lyku/lockstep-client-ts
|
|
2
2
|
|
|
3
3
|
Generate fully-typed TypeScript HTTP clients from TsonSchema-based API definitions.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
This package takes a set of external API model definitions (request/response schemas, HTTP methods, path patterns) and produces a complete, self-contained TypeScript HTTP client file. It is used within the Lyku monorepo to generate typed clients for third-party APIs such as Valhalla (routing), Pelias (geocoding), TomTom (maps), and OTP (transit).
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install ts
|
|
13
|
-
# or as a workspace dependency
|
|
14
|
-
pnpm add ts-codegen
|
|
12
|
+
npm install @lyku/lockstep-client-ts
|
|
15
13
|
```
|
|
16
14
|
|
|
17
15
|
Requires `@lyku/lockstep-core` as a peer dependency for schema-to-type conversion.
|
|
@@ -23,13 +21,13 @@ Requires `@lyku/lockstep-core` as a peer dependency for schema-to-type conversio
|
|
|
23
21
|
Generates a TypeScript client file in the specified output directory.
|
|
24
22
|
|
|
25
23
|
```typescript
|
|
26
|
-
import { generateTsClient } from 'ts
|
|
27
|
-
import { valhallaModels } from '@
|
|
24
|
+
import { generateTsClient } from '@lyku/lockstep-client-ts';
|
|
25
|
+
import { valhallaModels } from '@myapp/api-models';
|
|
28
26
|
|
|
29
27
|
await generateTsClient({
|
|
30
28
|
models: valhallaModels,
|
|
31
29
|
name: 'Valhalla',
|
|
32
|
-
outputDir: './dist/libs/valhalla-
|
|
30
|
+
outputDir: './dist/libs/valhalla-client',
|
|
33
31
|
});
|
|
34
32
|
```
|
|
35
33
|
|
|
@@ -53,7 +51,7 @@ await generateTsClient({
|
|
|
53
51
|
Validates an API specification and returns an array of error messages (empty if valid).
|
|
54
52
|
|
|
55
53
|
```typescript
|
|
56
|
-
import { validateApiSpec } from 'ts
|
|
54
|
+
import { validateApiSpec } from '@lyku/lockstep-client-ts';
|
|
57
55
|
|
|
58
56
|
const errors = validateApiSpec(myModels);
|
|
59
57
|
if (errors.length > 0) {
|
|
@@ -90,6 +88,70 @@ For a client named `Valhalla`, the generated `index.ts` contains:
|
|
|
90
88
|
|
|
91
89
|
The generated client uses `fetch` with `AbortController` for timeout support and handles JSON serialization/deserialization automatically.
|
|
92
90
|
|
|
91
|
+
## Where it fits
|
|
92
|
+
|
|
93
|
+
<!-- Generated from libs/lockstep-core/diagrams/pipeline.mmd — do not edit manually -->
|
|
94
|
+
|
|
95
|
+
```mermaid
|
|
96
|
+
graph TD
|
|
97
|
+
input-tables["Table Schemas<br/><small>PostgresRecordModel</small>"]
|
|
98
|
+
input-api["API Definitions<br/><small>TsonHandlerModel</small>"]
|
|
99
|
+
|
|
100
|
+
core-jsonmodels["generateJsonModels"]
|
|
101
|
+
core-dbtypes["generateDbTypes"]
|
|
102
|
+
core-apitypes["generateApiTypes"]
|
|
103
|
+
core-validators["buildValidator"]
|
|
104
|
+
|
|
105
|
+
handles-gen["generateHandles"]
|
|
106
|
+
|
|
107
|
+
client-gen["generateTsClient"]
|
|
108
|
+
|
|
109
|
+
pg-drift["detectDrift"]
|
|
110
|
+
pg-migrate["generateMigration"]
|
|
111
|
+
|
|
112
|
+
output-jsonschemas["JSON Schemas +<br/>TypeScript Types"]
|
|
113
|
+
output-kysely["Kysely Database<br/>Interface"]
|
|
114
|
+
output-reqres["Request / Response<br/>TypeScript Types"]
|
|
115
|
+
output-handlers["Handler Factories<br/>+ Validators"]
|
|
116
|
+
output-client["Type-safe<br/>HTTP Client"]
|
|
117
|
+
output-sql["SQL Migrations"]
|
|
118
|
+
|
|
119
|
+
input-tables --> core-jsonmodels
|
|
120
|
+
core-jsonmodels --> output-jsonschemas
|
|
121
|
+
output-jsonschemas --> core-dbtypes
|
|
122
|
+
core-dbtypes --> output-kysely
|
|
123
|
+
|
|
124
|
+
input-api --> core-apitypes
|
|
125
|
+
core-apitypes --> output-reqres
|
|
126
|
+
input-api --> core-validators
|
|
127
|
+
|
|
128
|
+
output-reqres --> handles-gen
|
|
129
|
+
input-api --> handles-gen
|
|
130
|
+
core-validators -.-> handles-gen
|
|
131
|
+
handles-gen --> output-handlers
|
|
132
|
+
|
|
133
|
+
output-reqres --> client-gen
|
|
134
|
+
input-api --> client-gen
|
|
135
|
+
client-gen --> output-client
|
|
136
|
+
|
|
137
|
+
input-tables --> pg-drift
|
|
138
|
+
pg-drift --> pg-migrate
|
|
139
|
+
pg-migrate --> output-sql
|
|
140
|
+
|
|
141
|
+
classDef highlight fill:#4f46e5,stroke:#3730a3,color:#fff,stroke-width:2px
|
|
142
|
+
classDef dimmed fill:#f1f5f9,stroke:#cbd5e1,color:#94a3b8,stroke-width:1px
|
|
143
|
+
classDef inputNode fill:#fef3c7,stroke:#f59e0b,color:#92400e,stroke-width:1px
|
|
144
|
+
classDef outputNode fill:#d1fae5,stroke:#10b981,color:#065f46,stroke-width:1px
|
|
145
|
+
classDef ownedOutput fill:#a5b4fc,stroke:#4f46e5,color:#1e1b4b,stroke-width:2px
|
|
146
|
+
classDef ownedInput fill:#fde68a,stroke:#4f46e5,color:#1e1b4b,stroke-width:2px
|
|
147
|
+
class client-gen highlight
|
|
148
|
+
class core-jsonmodels,core-dbtypes,core-apitypes,core-validators,handles-gen,pg-drift,pg-migrate dimmed
|
|
149
|
+
class input-tables inputNode
|
|
150
|
+
class output-jsonschemas,output-kysely,output-reqres,output-handlers,output-sql outputNode
|
|
151
|
+
class input-api ownedInput
|
|
152
|
+
class output-client ownedOutput
|
|
153
|
+
```
|
|
154
|
+
|
|
93
155
|
## Dependencies
|
|
94
156
|
|
|
95
157
|
- `@lyku/lockstep-core` (peer) -- schema-to-TypeScript-type conversion via `tsonToType`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lyku/lockstep-client-ts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Generate fully-typed TypeScript HTTP clients from TsonSchema-based API definitions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
"files": [
|
|
16
16
|
"index.js",
|
|
17
17
|
"index.cjs",
|
|
18
|
-
"index.d.ts"
|
|
18
|
+
"index.d.ts",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LLMs.md"
|
|
19
21
|
],
|
|
20
22
|
"keywords": [
|
|
21
23
|
"typescript",
|
|
@@ -33,6 +35,7 @@
|
|
|
33
35
|
"prettier": "^3.0.0"
|
|
34
36
|
},
|
|
35
37
|
"devDependencies": {
|
|
38
|
+
"@lyku/lockstep-core": "1.3.1",
|
|
36
39
|
"typescript": "^5.0.0"
|
|
37
40
|
},
|
|
38
41
|
"module": "./src/index.js"
|