@lyku/lockstep-core 0.2.1 → 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 CHANGED
@@ -5,19 +5,23 @@ This document is a complete mechanical reference for the `@lyku/lockstep-core` l
5
5
  ## Pipeline overview
6
6
 
7
7
  ```
8
- pg-models (PostgresRecordModel)
9
- ↓ generateJsonModels
10
- json-models (JSON schemas + TypeScript types + Insertable types)
11
- ↓ generateDbTypes
12
- db-types (Kysely Database interface)
13
-
14
- mapi-models (TsonHandlerModel)
15
- ↓ generateApiTypes
16
- mapi-types (Request/Response TypeScript types)
17
- ↓ generateHandles
18
- handles (Handler factories with validators)
19
- generateClient
20
- monolith-ts-api (Type-safe HTTP + WebSocket client with MessagePack)
8
+ Table schemas (PostgresRecordModel)
9
+ ↓ generateJsonModels (this package)
10
+ JSON schemas + TypeScript types
11
+ ↓ generateDbTypes (this package)
12
+ Kysely Database interface
13
+
14
+ API definitions (TsonHandlerModel)
15
+ ↓ generateApiTypes (this package)
16
+ Request/Response TypeScript types
17
+ ↓ generateHandles (@lyku/lockstep-handles-ts)
18
+ Handler factories with validators
19
+ generateTsClient (@lyku/lockstep-client-ts)
20
+ Type-safe HTTP client
21
+
22
+ Table schemas
23
+ ↓ detectDrift / generateMigration (@lyku/lockstep-pg)
24
+ SQL migrations
21
25
  ```
22
26
 
23
27
  ---
package/README.md CHANGED
@@ -1,23 +1,76 @@
1
1
  # @lyku/lockstep-core
2
2
 
3
- Schema-driven code generation for TypeScript. Define your database tables and API endpoints once, generate everything else: TypeScript types, Kysely types, runtime validators, handler factories, and type-safe API clients.
3
+ Schema-driven code generation for TypeScript. Define your database tables and API endpoints once, generate everything else: TypeScript types, Kysely types, runtime validators, and more.
4
+
5
+ ## The lockstep ecosystem
6
+
7
+ <!-- Generated from libs/lockstep-core/diagrams/pipeline.mmd — do not edit manually -->
8
+
9
+ ```mermaid
10
+ graph TD
11
+ input-tables["Table Schemas<br/><small>PostgresRecordModel</small>"]
12
+ input-api["API Definitions<br/><small>TsonHandlerModel</small>"]
13
+
14
+ core-jsonmodels["generateJsonModels"]
15
+ core-dbtypes["generateDbTypes"]
16
+ core-apitypes["generateApiTypes"]
17
+ core-validators["buildValidator"]
18
+
19
+ handles-gen["generateHandles"]
20
+
21
+ client-gen["generateTsClient"]
22
+
23
+ pg-drift["detectDrift"]
24
+ pg-migrate["generateMigration"]
25
+
26
+ output-jsonschemas["JSON Schemas +<br/>TypeScript Types"]
27
+ output-kysely["Kysely Database<br/>Interface"]
28
+ output-reqres["Request / Response<br/>TypeScript Types"]
29
+ output-handlers["Handler Factories<br/>+ Validators"]
30
+ output-client["Type-safe<br/>HTTP Client"]
31
+ output-sql["SQL Migrations"]
32
+
33
+ input-tables --> core-jsonmodels
34
+ core-jsonmodels --> output-jsonschemas
35
+ output-jsonschemas --> core-dbtypes
36
+ core-dbtypes --> output-kysely
37
+
38
+ input-api --> core-apitypes
39
+ core-apitypes --> output-reqres
40
+ input-api --> core-validators
41
+
42
+ output-reqres --> handles-gen
43
+ input-api --> handles-gen
44
+ core-validators -.-> handles-gen
45
+ handles-gen --> output-handlers
46
+
47
+ output-reqres --> client-gen
48
+ input-api --> client-gen
49
+ client-gen --> output-client
50
+
51
+ input-tables --> pg-drift
52
+ pg-drift --> pg-migrate
53
+ pg-migrate --> output-sql
54
+
55
+ classDef highlight fill:#4f46e5,stroke:#3730a3,color:#fff,stroke-width:2px
56
+ classDef dimmed fill:#f1f5f9,stroke:#cbd5e1,color:#94a3b8,stroke-width:1px
57
+ classDef inputNode fill:#fef3c7,stroke:#f59e0b,color:#92400e,stroke-width:1px
58
+ classDef outputNode fill:#d1fae5,stroke:#10b981,color:#065f46,stroke-width:1px
59
+ classDef ownedOutput fill:#a5b4fc,stroke:#4f46e5,color:#1e1b4b,stroke-width:2px
60
+ classDef ownedInput fill:#fde68a,stroke:#4f46e5,color:#1e1b4b,stroke-width:2px
61
+ class core-jsonmodels,core-dbtypes,core-apitypes,core-validators highlight
62
+ class handles-gen,client-gen,pg-drift,pg-migrate dimmed
63
+ class output-handlers,output-client,output-sql outputNode
64
+ class input-tables,input-api ownedInput
65
+ class output-jsonschemas,output-kysely,output-reqres ownedOutput
66
+ ```
4
67
 
5
- ## What it generates
68
+ This package (`lockstep-core`) provides the schema type system, the first three generators, runtime validators, and BON serialization. Handler and client generation live in separate packages.
6
69
 
7
- ```
8
- pg-models (PostgreSQL schemas)
9
- ↓ generateJsonModels
10
- json-models (JSON schemas + TypeScript types)
11
- ↓ generateDbTypes
12
- db-types (Kysely Database interface)
13
-
14
- mapi-models (API endpoint contracts)
15
- ↓ generateApiTypes
16
- mapi-types (Request/Response TypeScript types)
17
- ↓ generateHandles
18
- handles (Handler factories + validators)
19
- ↓ generateClient
20
- monolith-ts-api (Type-safe HTTP + WebSocket client)
70
+ ## Installation
71
+
72
+ ```bash
73
+ npm install @lyku/lockstep-core
21
74
  ```
22
75
 
23
76
  ## Defining schemas
@@ -25,17 +78,17 @@ monolith-ts-api (Type-safe HTTP + WebSocket client)
25
78
  ### Database tables
26
79
 
27
80
  ```typescript
28
- // libs/pg-models/src/friendship.ts
29
81
  import type { PostgresRecordModel } from '@lyku/lockstep-core';
30
82
 
31
- export const friendship = {
83
+ export const users = {
32
84
  properties: {
33
85
  id: { type: 'bigserial' },
86
+ username: { type: 'varchar', maxLength: 32 },
34
87
  created: { type: 'timestamptz', default: { sql: 'CURRENT_TIMESTAMP' } },
35
- users: { type: 'array', items: { type: 'bigint' }, minItems: 2, maxItems: 2 },
36
- deleted: { type: 'timestamptz' },
88
+ email: { type: 'text' },
89
+ banned: { type: 'boolean' },
37
90
  },
38
- required: ['created', 'id', 'users'],
91
+ required: ['id', 'username', 'created', 'email'],
39
92
  } as const satisfies PostgresRecordModel;
40
93
  ```
41
94
 
@@ -44,24 +97,20 @@ Supported column types: `bigint`, `bigserial`, `serial`, `integer`, `smallint`,
44
97
  ### API endpoints
45
98
 
46
99
  ```typescript
47
- // libs/mapi-models/src/createFriendRequest.ts
48
100
  import type { TsonHandlerModel } from '@lyku/lockstep-core';
49
101
 
50
- export const createFriendRequest = {
102
+ export const getUser = {
51
103
  request: { type: 'bigint' },
52
104
  response: {
53
105
  type: 'object',
54
- properties: { id: { type: 'bigint' } },
55
- required: ['id'],
106
+ properties: {
107
+ id: { type: 'bigint' },
108
+ username: { type: 'string' },
109
+ },
110
+ required: ['id', 'username'],
56
111
  },
57
112
  authenticated: true,
58
- throws: [400, 401, 404, 409, 500],
59
-
60
- title: 'Create Friend Request',
61
- description: 'Sends a friend request to another user.',
62
- category: 'Friendship',
63
- tags: ['social', 'friends'],
64
- since: '1.0.0',
113
+ throws: [400, 401, 404],
65
114
  } as const satisfies TsonHandlerModel;
66
115
  ```
67
116
 
@@ -91,14 +140,14 @@ The type system used by API models:
91
140
 
92
141
  String formats: `email`, `uuid`, `uri`, `ipv4`, `ipv6`, `hostname`, `date-time`.
93
142
 
94
- ## Five generators
143
+ ## Generators
95
144
 
96
- ### 1. `generateJsonModels`
145
+ ### `generateJsonModels`
97
146
 
98
147
  Converts PostgreSQL column schemas to JSON schemas and TypeScript types.
99
148
 
100
149
  ```bash
101
- from-schema generate json-models --models ./pg-models --output ./json-models
150
+ lockstep generate json-models --models ./my-tables --output ./generated/json-models
102
151
  ```
103
152
 
104
153
  Produces two type variants per table:
@@ -106,12 +155,12 @@ Produces two type variants per table:
106
155
  - Full type (all fields, optionals included)
107
156
  - Insertable type (only required fields, auto-generated columns excluded)
108
157
 
109
- ### 2. `generateDbTypes`
158
+ ### `generateDbTypes`
110
159
 
111
160
  Generates a Kysely `Database` interface from PostgreSQL table definitions.
112
161
 
113
162
  ```bash
114
- from-schema generate db-types --models ./pg-models --output ./db-types --file kysely.d.ts
163
+ lockstep generate db-types --models ./my-tables --output ./generated/db-types --file kysely.d.ts
115
164
  ```
116
165
 
117
166
  Output:
@@ -129,88 +178,29 @@ export interface Database {
129
178
  }
130
179
  ```
131
180
 
132
- ### 3. `generateApiTypes`
181
+ ### `generateApiTypes`
133
182
 
134
183
  Generates TypeScript request/response types from API models.
135
184
 
136
185
  ```bash
137
- from-schema generate api-types --models ./mapi-models --output ./mapi-types
186
+ lockstep generate api-types --models ./my-endpoints --output ./generated/api-types
138
187
  ```
139
188
 
140
189
  Output:
141
190
 
142
191
  ```typescript
143
- export type CreateFriendRequestRequest = bigint;
144
- export type CreateFriendRequestResponse = { id: bigint };
192
+ export type GetUserRequest = bigint;
193
+ export type GetUserResponse = { id: bigint; username: string };
145
194
 
146
195
  export type ApiTypes = {
147
- createFriendRequest: {
148
- request: CreateFriendRequestRequest;
149
- response: CreateFriendRequestResponse;
196
+ getUser: {
197
+ request: GetUserRequest;
198
+ response: GetUserResponse;
150
199
  };
151
200
  // ...
152
201
  };
153
202
  ```
154
203
 
155
- ### 4. `generateHandles`
156
-
157
- Generates handler factory functions with built-in request validation.
158
-
159
- ```bash
160
- from-schema generate handles \
161
- --models ./mapi-models --output ./handles \
162
- --models-pkg @myapp/mapi-models \
163
- --types-pkg @myapp/mapi-types
164
- ```
165
-
166
- Each handler factory wraps your implementation with type safety:
167
-
168
- ```typescript
169
- // Generated
170
- export declare const handleCreateFriendRequest: (handler: (request: CreateFriendRequestRequest, context: SecureHttpContext<typeof createFriendRequest>) => CreateFriendRequestResponse | Promise<CreateFriendRequestResponse>) => {
171
- readonly execute: typeof handler;
172
- readonly validator: { validate; validateOrThrow; isValid };
173
- readonly model: typeof createFriendRequest;
174
- };
175
- ```
176
-
177
- Usage in route handlers:
178
-
179
- ```typescript
180
- import { handleCreateFriendRequest } from '@lyku/handles';
181
-
182
- export const createFriendRequest = handleCreateFriendRequest(async (targetUserId, { requester }) => {
183
- // fully typed: targetUserId is bigint, requester is bigint
184
- const bond = await createBond(requester, targetUserId);
185
- return { id: bond.id };
186
- });
187
- ```
188
-
189
- ### 5. `generateClient`
190
-
191
- Generates a type-safe API client using MessagePack serialization.
192
-
193
- ```bash
194
- from-schema generate client \
195
- --models ./mapi-models --output ./client \
196
- --types-pkg @myapp/mapi-types
197
- ```
198
-
199
- The generated client supports both HTTP and WebSocket endpoints:
200
-
201
- ```typescript
202
- import { createClient } from '@myapp/client';
203
-
204
- const api = createClient({ baseUrl: 'https://api.example.com' });
205
-
206
- // HTTP — returns Promise<Response>
207
- const result = await api.createFriendRequest(456n);
208
-
209
- // WebSocket — returns StreamSocket
210
- const socket = api.subscribeToPosts({ groupId: 1n });
211
- socket.listen((post) => console.log(post));
212
- ```
213
-
214
204
  ## Handler contexts
215
205
 
216
206
  Handlers receive a typed context object based on auth requirements:
@@ -244,19 +234,16 @@ Context fields:
244
234
 
245
235
  ## Runtime validation
246
236
 
247
- Each generated handler includes validators built from the schema:
237
+ Build validators from any schema:
248
238
 
249
239
  ```typescript
250
- const handle = handleCreateUser(myHandler);
251
-
252
- // Collect all validation errors
253
- const errors = handle.validator.validate(input);
240
+ import { buildValidator } from '@lyku/lockstep-core';
254
241
 
255
- // Throw on first error
256
- handle.validator.validateOrThrow(input);
242
+ const validator = buildValidator('input', { type: 'string', minLength: 1 });
257
243
 
258
- // Check validity (returns true or first error string)
259
- const result = handle.validator.isValid(input);
244
+ validator.validate(input); // returns string[] of errors
245
+ validator.validateOrThrow(input); // throws on invalid
246
+ validator.isValid(input); // returns true or first error string
260
247
  ```
261
248
 
262
249
  Validators check types, required fields, string lengths/patterns/formats, numeric ranges, enum membership, and array constraints.
@@ -283,29 +270,37 @@ API models support rich documentation metadata:
283
270
 
284
271
  ```typescript
285
272
  {
286
- title: 'Create Friend Request',
287
- description: 'Sends a friend request to another user.',
288
- category: 'Friendship',
289
- tags: ['social', 'friends'],
273
+ title: 'Get User',
274
+ description: 'Fetch a user by ID.',
275
+ category: 'Users',
276
+ tags: ['users'],
290
277
  since: '1.0.0',
291
- examples: [{ title: 'Basic', request: 456n, response: { id: 789n } }],
292
- notes: ['Cannot send to yourself', 'Cannot duplicate existing requests'],
293
- errors: [{ code: 409, title: 'Already Friends', description: '...' }],
294
- relatedEndpoints: ['acceptFriendRequest', 'deleteFriendship'],
295
- rateLimit: { requests: 10, period: '1 minute', scope: 'user' },
296
- deprecated: { since: '2.0.0', useInstead: 'createConnection', reason: '...' },
297
- requiredPermissions: ['social:write'],
278
+ examples: [{ title: 'Basic', request: 456n, response: { id: 456n, username: 'alice' } }],
279
+ notes: ['Returns 404 if user does not exist'],
280
+ errors: [{ code: 404, title: 'Not Found', description: '...' }],
281
+ relatedEndpoints: ['updateUser', 'deleteUser'],
282
+ rateLimit: { requests: 100, period: '1 minute', scope: 'user' },
283
+ deprecated: { since: '2.0.0', useInstead: 'getUserV2', reason: '...' },
284
+ requiredPermissions: ['users:read'],
298
285
  }
299
286
  ```
300
287
 
301
288
  ## Exports
302
289
 
303
290
  ```
304
- @lyku/lockstep-core # Schema types, BON, type converters, validators
305
- @lyku/lockstep-core/contexts # Handler context types
306
- @lyku/lockstep-core/generators # Code generators (json-models, db-types, api-types, handles, client)
291
+ @lyku/lockstep-core # Schema types, BON, type converters, validators
292
+ @lyku/lockstep-core/contexts # Handler context types
293
+ @lyku/lockstep-core/generators # Code generators (json-models, db-types, api-types)
307
294
  ```
308
295
 
296
+ ## Related packages
297
+
298
+ | Package | Purpose |
299
+ | --------------------------- | ------------------------------------------------ |
300
+ | `@lyku/lockstep-handles-ts` | Generate typed handler factories from API models |
301
+ | `@lyku/lockstep-client-ts` | Generate typed HTTP clients from API models |
302
+ | `@lyku/lockstep-pg` | PostgreSQL drift detection and migrations |
303
+
309
304
  ## License
310
305
 
311
306
  GPL-3.0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Generates per-package pipeline diagrams from the master pipeline.mmd.
3
+ *
4
+ * Each variant highlights the nodes belonging to that package and dims everything else.
5
+ * Output is a mermaid code block ready to paste into a README.
6
+ *
7
+ * Usage: bun libs/lockstep-core/diagrams/generate.ts
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../../libs/lockstep-core/diagrams/generate.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG"}
@@ -0,0 +1,149 @@
1
+ /* eslint-disable security/detect-non-literal-fs-filename, security/detect-object-injection */
2
+ /**
3
+ * Generates per-package pipeline diagrams from the master pipeline.mmd.
4
+ *
5
+ * Each variant highlights the nodes belonging to that package and dims everything else.
6
+ * Output is a mermaid code block ready to paste into a README.
7
+ *
8
+ * Usage: bun libs/lockstep-core/diagrams/generate.ts
9
+ */
10
+ import { readFileSync, writeFileSync, mkdirSync } from 'fs';
11
+ import { join, dirname } from 'path';
12
+ const DIAGRAMS_DIR = dirname(new URL(import.meta.url).pathname);
13
+ const master = readFileSync(join(DIAGRAMS_DIR, 'pipeline.mmd'), 'utf-8');
14
+ // Strip comment lines from master
15
+ const masterLines = master
16
+ .split('\n')
17
+ .filter((line) => !line.trim().startsWith('%%'));
18
+ const packages = {
19
+ 'lockstep-core': {
20
+ prefix: 'core-',
21
+ title: '@lyku/lockstep-core',
22
+ },
23
+ 'lockstep-handles-ts': {
24
+ prefix: 'handles-',
25
+ title: '@lyku/lockstep-handles-ts',
26
+ },
27
+ 'lockstep-client-ts': {
28
+ prefix: 'client-',
29
+ title: '@lyku/lockstep-client-ts',
30
+ },
31
+ 'lockstep-pg': {
32
+ prefix: 'pg-',
33
+ title: '@lyku/lockstep-pg',
34
+ },
35
+ };
36
+ // Find all node IDs in the diagram
37
+ const nodeIdRegex = /^\s{4}(\S+?)[[("]/m;
38
+ const allNodeIds = [];
39
+ for (const line of masterLines) {
40
+ const match = line.match(nodeIdRegex);
41
+ if (match) {
42
+ allNodeIds.push(match[1]);
43
+ }
44
+ }
45
+ function generateVariant(pkgKey) {
46
+ const pkg = packages[pkgKey];
47
+ const highlighted = allNodeIds.filter((id) => id.startsWith(pkg.prefix));
48
+ const dimmed = allNodeIds.filter((id) => !id.startsWith(pkg.prefix) && !id.startsWith('input-') && !id.startsWith('output-'));
49
+ const inputs = allNodeIds.filter((id) => id.startsWith('input-'));
50
+ const outputs = allNodeIds.filter((id) => id.startsWith('output-'));
51
+ // Find which outputs are directly produced by this package's nodes
52
+ // by scanning edges: highlighted-node --> output-node
53
+ const ownedOutputs = new Set();
54
+ for (const line of masterLines) {
55
+ const edgeMatch = line.match(/^\s{4}(\S+)\s+--.*?-->\s+(\S+)/);
56
+ const simpleEdge = line.match(/^\s{4}(\S+)\s+-->\s+(\S+)/);
57
+ const dottedEdge = line.match(/^\s{4}(\S+)\s+-\.\s*->\s+(\S+)/);
58
+ const dottedEdge2 = line.match(/^\s{4}(\S+)\s+-\.+->\s+(\S+)/);
59
+ const edge = edgeMatch || simpleEdge || dottedEdge || dottedEdge2;
60
+ if (edge) {
61
+ const [, from, to] = edge;
62
+ if (from.startsWith(pkg.prefix) && to.startsWith('output-')) {
63
+ ownedOutputs.add(to);
64
+ }
65
+ }
66
+ }
67
+ // Find which inputs feed directly into this package's nodes
68
+ const ownedInputs = new Set();
69
+ for (const line of masterLines) {
70
+ const edgeMatch = line.match(/^\s{4}(\S+)\s+--.*?-->\s+(\S+)/);
71
+ const simpleEdge = line.match(/^\s{4}(\S+)\s+-->\s+(\S+)/);
72
+ const dottedEdge = line.match(/^\s{4}(\S+)\s+-\.\s*->\s+(\S+)/);
73
+ const dottedEdge2 = line.match(/^\s{4}(\S+)\s+-\.+->\s+(\S+)/);
74
+ const edge = edgeMatch || simpleEdge || dottedEdge || dottedEdge2;
75
+ if (edge) {
76
+ const [, from, to] = edge;
77
+ if (from.startsWith('input-') && to.startsWith(pkg.prefix)) {
78
+ ownedInputs.add(from);
79
+ }
80
+ }
81
+ }
82
+ const classDefs = [
83
+ 'classDef highlight fill:#4f46e5,stroke:#3730a3,color:#fff,stroke-width:2px',
84
+ 'classDef dimmed fill:#f1f5f9,stroke:#cbd5e1,color:#94a3b8,stroke-width:1px',
85
+ 'classDef inputNode fill:#fef3c7,stroke:#f59e0b,color:#92400e,stroke-width:1px',
86
+ 'classDef outputNode fill:#d1fae5,stroke:#10b981,color:#065f46,stroke-width:1px',
87
+ 'classDef ownedOutput fill:#a5b4fc,stroke:#4f46e5,color:#1e1b4b,stroke-width:2px',
88
+ 'classDef ownedInput fill:#fde68a,stroke:#4f46e5,color:#1e1b4b,stroke-width:2px',
89
+ ];
90
+ const classAssignments = [];
91
+ if (highlighted.length > 0) {
92
+ classAssignments.push(`class ${highlighted.join(',')} highlight`);
93
+ }
94
+ if (dimmed.length > 0) {
95
+ classAssignments.push(`class ${dimmed.join(',')} dimmed`);
96
+ }
97
+ // Assign input/output classes, with owned variants taking precedence
98
+ const regularInputs = inputs.filter((id) => !ownedInputs.has(id));
99
+ const regularOutputs = outputs.filter((id) => !ownedOutputs.has(id));
100
+ if (regularInputs.length > 0) {
101
+ classAssignments.push(`class ${regularInputs.join(',')} inputNode`);
102
+ }
103
+ if (regularOutputs.length > 0) {
104
+ classAssignments.push(`class ${regularOutputs.join(',')} outputNode`);
105
+ }
106
+ if (ownedInputs.size > 0) {
107
+ classAssignments.push(`class ${[...ownedInputs].join(',')} ownedInput`);
108
+ }
109
+ if (ownedOutputs.size > 0) {
110
+ classAssignments.push(`class ${[...ownedOutputs].join(',')} ownedOutput`);
111
+ }
112
+ const lines = [
113
+ ...masterLines,
114
+ '',
115
+ ...classDefs,
116
+ ...classAssignments,
117
+ ];
118
+ return lines.join('\n').trim();
119
+ }
120
+ // Generate all variants
121
+ mkdirSync(join(DIAGRAMS_DIR, 'generated'), { recursive: true });
122
+ for (const [pkgKey, _pkg] of Object.entries(packages)) {
123
+ const variant = generateVariant(pkgKey);
124
+ const outPath = join(DIAGRAMS_DIR, 'generated', `${pkgKey}.mmd`);
125
+ writeFileSync(outPath, variant + '\n');
126
+ console.log(`Generated ${outPath}`);
127
+ }
128
+ // Also generate a "full" variant with no highlighting (all nodes normal)
129
+ const fullVariant = [
130
+ ...masterLines,
131
+ '',
132
+ `classDef inputNode fill:#fef3c7,stroke:#f59e0b,color:#92400e,stroke-width:1px`,
133
+ `classDef outputNode fill:#d1fae5,stroke:#10b981,color:#065f46,stroke-width:1px`,
134
+ `classDef coreNode fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f,stroke-width:1px`,
135
+ `classDef handlesNode fill:#e0e7ff,stroke:#6366f1,color:#312e81,stroke-width:1px`,
136
+ `classDef clientNode fill:#fce7f3,stroke:#ec4899,color:#831843,stroke-width:1px`,
137
+ `classDef pgNode fill:#fef9c3,stroke:#eab308,color:#713f12,stroke-width:1px`,
138
+ `class ${allNodeIds.filter((id) => id.startsWith('input-')).join(',')} inputNode`,
139
+ `class ${allNodeIds.filter((id) => id.startsWith('output-')).join(',')} outputNode`,
140
+ `class ${allNodeIds.filter((id) => id.startsWith('core-')).join(',')} coreNode`,
141
+ `class ${allNodeIds.filter((id) => id.startsWith('handles-')).join(',')} handlesNode`,
142
+ `class ${allNodeIds.filter((id) => id.startsWith('client-')).join(',')} clientNode`,
143
+ `class ${allNodeIds.filter((id) => id.startsWith('pg-')).join(',')} pgNode`,
144
+ ]
145
+ .join('\n')
146
+ .trim();
147
+ writeFileSync(join(DIAGRAMS_DIR, 'generated', 'full.mmd'), fullVariant + '\n');
148
+ console.log(`Generated ${join(DIAGRAMS_DIR, 'generated', 'full.mmd')}`);
149
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../../libs/lockstep-core/diagrams/generate.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lyku/lockstep-core",
3
- "version": "0.2.1",
3
+ "version": "1.3.1",
4
4
  "description": "Schema-driven code generation: PostgreSQL models → TypeScript types, Kysely types, API handlers, and typed clients",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",