@demokit-ai/core 0.2.0 → 0.4.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/dist/index.d.cts CHANGED
@@ -81,6 +81,43 @@ interface SessionState {
81
81
  */
82
82
  declare function createSessionState(): SessionState;
83
83
 
84
+ /**
85
+ * Configuration for automatic demo mode detection based on URL
86
+ */
87
+ interface DetectionConfig {
88
+ /**
89
+ * Hostnames that should auto-enable demo mode
90
+ * @example ['demo.myapp.com', 'demo.localhost']
91
+ */
92
+ subdomains?: string[];
93
+ /**
94
+ * Query parameters that trigger demo mode when present
95
+ * @default ['demo']
96
+ * @example With ['demo'], visiting ?demo=true enables demo mode
97
+ */
98
+ queryParams?: string[];
99
+ }
100
+ /**
101
+ * Context passed to the onMutationIntercepted callback
102
+ */
103
+ interface MutationInterceptedContext {
104
+ /**
105
+ * The full URL of the intercepted request
106
+ */
107
+ url: string;
108
+ /**
109
+ * HTTP method (POST, PUT, PATCH, DELETE)
110
+ */
111
+ method: string;
112
+ /**
113
+ * URL parameters extracted from the pattern
114
+ */
115
+ params: Record<string, string>;
116
+ /**
117
+ * The fixture pattern that matched
118
+ */
119
+ pattern: string;
120
+ }
84
121
  /**
85
122
  * Configuration for creating a demo interceptor
86
123
  */
@@ -120,6 +157,29 @@ interface DemoKitConfig {
120
157
  * @default 'http://localhost'
121
158
  */
122
159
  baseUrl?: string;
160
+ /**
161
+ * Auto-detection configuration for enabling demo mode based on URL
162
+ * When configured, demo mode is automatically enabled on matching subdomains
163
+ * or when specific query parameters are present
164
+ */
165
+ detection?: DetectionConfig;
166
+ /**
167
+ * Guard callback that controls whether demo mode can be disabled.
168
+ * Return `true` to allow disabling, `false` to prevent it,
169
+ * or a string to prevent it and provide a reason message.
170
+ *
171
+ * @example
172
+ * canDisable: () => {
173
+ * if (isPublicDemo) return 'Sign up to access your own data'
174
+ * return true
175
+ * }
176
+ */
177
+ canDisable?: () => boolean | string;
178
+ /**
179
+ * Callback fired when a non-GET request is intercepted by a fixture.
180
+ * Useful for showing "simulated in demo mode" toast notifications.
181
+ */
182
+ onMutationIntercepted?: (context: MutationInterceptedContext) => void;
123
183
  }
124
184
  /**
125
185
  * Map of URL patterns to fixture handlers
@@ -194,13 +254,19 @@ interface DemoInterceptor {
194
254
  */
195
255
  enable(): void;
196
256
  /**
197
- * Disable demo mode - fetches will pass through to the real API
257
+ * Disable demo mode - fetches will pass through to the real API.
258
+ * Returns `true` if disabled successfully, `false` or a string reason
259
+ * if prevented by the `canDisable` guard.
198
260
  */
199
- disable(): void;
261
+ disable(): boolean | string;
200
262
  /**
201
263
  * Check if demo mode is currently enabled
202
264
  */
203
265
  isEnabled(): boolean;
266
+ /**
267
+ * Check if this is a public demo (auto-detected via subdomain)
268
+ */
269
+ isPublicDemo(): boolean;
204
270
  /**
205
271
  * Toggle demo mode state and return the new state
206
272
  */
@@ -263,6 +329,140 @@ interface ParsedPattern {
263
329
  */
264
330
  paramNames: string[];
265
331
  }
332
+ /**
333
+ * Configuration for fetching fixtures from DemoKit Cloud
334
+ */
335
+ interface RemoteConfig {
336
+ /**
337
+ * DemoKit Cloud API key
338
+ * Format: dk_live_xxxx
339
+ */
340
+ apiKey: string;
341
+ /**
342
+ * DemoKit Cloud API URL (base URL)
343
+ * The SDK will append `/fixtures` to this URL.
344
+ * @example 'https://demokit-cloud.kasava.dev/api'
345
+ * @default 'https://api.demokit.cloud/api'
346
+ */
347
+ apiUrl?: string;
348
+ /**
349
+ * @deprecated Use apiUrl instead. This is kept for backwards compatibility.
350
+ */
351
+ cloudUrl?: string;
352
+ /**
353
+ * Error callback for remote fetch failures
354
+ */
355
+ onError?: (error: Error) => void;
356
+ /**
357
+ * Callback when fixtures are successfully loaded
358
+ */
359
+ onLoad?: (response: CloudFixtureResponse) => void;
360
+ /**
361
+ * Timeout for API requests in milliseconds
362
+ * @default 10000
363
+ */
364
+ timeout?: number;
365
+ /**
366
+ * Whether to retry on failure
367
+ * @default true
368
+ */
369
+ retry?: boolean;
370
+ /**
371
+ * Maximum number of retries
372
+ * @default 3
373
+ */
374
+ maxRetries?: number;
375
+ }
376
+ /**
377
+ * Response from DemoKit Cloud /api/v1/fixtures endpoint
378
+ */
379
+ interface CloudFixtureResponse {
380
+ /**
381
+ * The generated fixture data (keyed by model name)
382
+ * @example { users: [{ id: '1', name: 'Alice' }], products: [...] }
383
+ */
384
+ data: Record<string, unknown[]>;
385
+ /**
386
+ * Endpoint-to-data mappings for SDK auto-configuration
387
+ */
388
+ mappings: EndpointMapping[];
389
+ /**
390
+ * Version identifier (generation ID) for cache invalidation
391
+ */
392
+ version: string;
393
+ }
394
+ /**
395
+ * An endpoint mapping that describes how to route API calls to fixture data
396
+ */
397
+ interface EndpointMapping {
398
+ /**
399
+ * HTTP method (GET, POST, PUT, PATCH, DELETE)
400
+ */
401
+ method: string;
402
+ /**
403
+ * URL pattern with :param placeholders
404
+ * @example '/api/users/:id'
405
+ */
406
+ pattern: string;
407
+ /**
408
+ * Key in fixture data to use as source
409
+ * @example 'users'
410
+ */
411
+ sourceModel: string;
412
+ /**
413
+ * Response type:
414
+ * - 'collection': Returns all records (array)
415
+ * - 'single': Returns one record by lookup
416
+ * - 'custom': Uses custom transform (not yet supported in SDK)
417
+ */
418
+ responseType: 'collection' | 'single' | 'custom';
419
+ /**
420
+ * For 'single' type: field in data to match against
421
+ * @example 'id'
422
+ */
423
+ lookupField?: string | null;
424
+ /**
425
+ * For 'single' type: URL param name to use for lookup
426
+ * @example 'id' (from :id in pattern)
427
+ */
428
+ lookupParam?: string | null;
429
+ }
430
+ /**
431
+ * Combined configuration for DemoKit with optional remote support
432
+ */
433
+ interface DemoKitRemoteConfig extends Omit<DemoKitConfig, 'fixtures'> {
434
+ /**
435
+ * Remote configuration for fetching from DemoKit Cloud
436
+ * When provided, fixtures are fetched from the cloud
437
+ */
438
+ remote: RemoteConfig;
439
+ /**
440
+ * Local fixture overrides that take precedence over remote fixtures
441
+ * Useful for customizing specific endpoints while using cloud data for the rest
442
+ */
443
+ fixtures?: FixtureMap;
444
+ }
445
+ /**
446
+ * State of remote fixture loading
447
+ */
448
+ interface RemoteLoadingState {
449
+ /**
450
+ * Whether fixtures are currently being loaded
451
+ */
452
+ isLoading: boolean;
453
+ /**
454
+ * Error if loading failed
455
+ */
456
+ error: Error | null;
457
+ /**
458
+ * The loaded response (if successful)
459
+ */
460
+ response: CloudFixtureResponse | null;
461
+ /**
462
+ * Timestamp of last successful load
463
+ */
464
+ loadedAt: Date | null;
465
+ }
266
466
 
267
467
  /**
268
468
  * Create a demo interceptor that patches fetch to return mock data
@@ -562,4 +762,2193 @@ declare function saveDemoState(key: string | undefined, enabled: boolean): void;
562
762
  */
563
763
  declare function clearDemoState(key?: string): void;
564
764
 
565
- export { DEFAULT_STORAGE_KEY, type DemoInterceptor, type DemoKitConfig, type DemoState, type DemoStateStore, type DemoStateStoreOptions, type FixtureHandler, type FixtureMap, type MatchResult, type ParsedPattern, type QueryKey, type QueryKeyElement, type QueryKeyMatchResult, type RequestContext, type SessionState, clearDemoState, clearPatternCache, createDemoInterceptor, createDemoState, createDemoStateStore, createSessionState, findMatchingPattern, findMatchingQueryKeyPattern, loadDemoState, matchQueryKey, matchUrl, parseUrlPattern, saveDemoState };
765
+ /**
766
+ * Remote Configuration Support for DemoKit Cloud
767
+ *
768
+ * Provides functions to fetch fixture data and endpoint mappings from DemoKit Cloud
769
+ * and transform them into FixtureMap handlers that can be used with the demo interceptor.
770
+ *
771
+ * @example
772
+ * ```typescript
773
+ * import { fetchCloudFixtures, buildFixtureMap } from '@demokit-ai/core'
774
+ *
775
+ * const response = await fetchCloudFixtures({
776
+ * apiKey: 'dk_live_xxx',
777
+ * })
778
+ *
779
+ * const fixtureMap = buildFixtureMap(response.data, response.mappings)
780
+ * ```
781
+ */
782
+
783
+ /**
784
+ * Default DemoKit Cloud API URL
785
+ */
786
+ declare const DEFAULT_API_URL = "https://api.demokit.cloud/api";
787
+ /**
788
+ * @deprecated Use DEFAULT_API_URL instead
789
+ */
790
+ declare const DEFAULT_CLOUD_URL = "https://api.demokit.cloud/api";
791
+ /**
792
+ * Default request timeout in milliseconds
793
+ */
794
+ declare const DEFAULT_TIMEOUT = 10000;
795
+ /**
796
+ * Default maximum retries
797
+ */
798
+ declare const DEFAULT_MAX_RETRIES = 3;
799
+ /**
800
+ * Validate API key format
801
+ */
802
+ declare function isValidApiKey(apiKey: string): boolean;
803
+ /**
804
+ * Error thrown when remote fetch fails
805
+ */
806
+ declare class RemoteFetchError extends Error {
807
+ readonly statusCode?: number | undefined;
808
+ readonly retryable: boolean;
809
+ constructor(message: string, statusCode?: number | undefined, retryable?: boolean);
810
+ }
811
+ /**
812
+ * Fetch fixtures and mappings from DemoKit Cloud
813
+ *
814
+ * @param config - Remote configuration with API key and options
815
+ * @returns Promise resolving to cloud fixture response with data, mappings, and version
816
+ * @throws RemoteFetchError if the request fails
817
+ *
818
+ * @example
819
+ * ```typescript
820
+ * const response = await fetchCloudFixtures({
821
+ * apiKey: 'dk_live_xxx',
822
+ * onLoad: (data) => console.log('Loaded version:', data.version),
823
+ * onError: (error) => console.error('Failed to load:', error),
824
+ * })
825
+ * ```
826
+ */
827
+ declare function fetchCloudFixtures(config: RemoteConfig): Promise<CloudFixtureResponse>;
828
+ /**
829
+ * Build a FixtureMap from cloud data and endpoint mappings
830
+ *
831
+ * Transforms endpoint mappings into fixture handlers that can be used
832
+ * with the demo interceptor. Each mapping becomes a pattern-matched
833
+ * handler that returns the appropriate data.
834
+ *
835
+ * @param data - Fixture data keyed by model name (e.g., { users: [...], products: [...] })
836
+ * @param mappings - Endpoint mappings from DemoKit Cloud
837
+ * @returns FixtureMap that can be passed to createDemoInterceptor
838
+ *
839
+ * @example
840
+ * ```typescript
841
+ * const fixtureMap = buildFixtureMap(
842
+ * { users: [{ id: '1', name: 'Alice' }] },
843
+ * [
844
+ * { method: 'GET', pattern: '/api/users', sourceModel: 'users', responseType: 'collection' },
845
+ * { method: 'GET', pattern: '/api/users/:id', sourceModel: 'users', responseType: 'single', lookupField: 'id', lookupParam: 'id' },
846
+ * ]
847
+ * )
848
+ *
849
+ * // Result:
850
+ * // {
851
+ * // 'GET /api/users': () => [{ id: '1', name: 'Alice' }],
852
+ * // 'GET /api/users/:id': ({ params }) => users.find(u => u.id === params.id),
853
+ * // }
854
+ * ```
855
+ */
856
+ declare function buildFixtureMap(data: Record<string, unknown[]>, mappings: EndpointMapping[]): FixtureMap;
857
+ /**
858
+ * Create a fixture handler for a single endpoint mapping
859
+ *
860
+ * @param mapping - The endpoint mapping configuration
861
+ * @param sourceData - The source data array for this mapping
862
+ * @returns A fixture handler function or undefined if mapping is invalid
863
+ */
864
+ declare function createHandlerForMapping(mapping: EndpointMapping, sourceData: unknown[]): FixtureHandler | undefined;
865
+ /**
866
+ * Merge remote fixtures with local overrides
867
+ *
868
+ * Creates a combined FixtureMap where local fixtures take precedence
869
+ * over remote fixtures for the same patterns.
870
+ *
871
+ * @param remoteFixtures - Fixtures built from cloud mappings
872
+ * @param localOverrides - Local fixtures that override remote ones
873
+ * @returns Merged FixtureMap
874
+ *
875
+ * @example
876
+ * ```typescript
877
+ * const merged = mergeFixtures(remoteFixtures, {
878
+ * // Override specific endpoint with custom logic
879
+ * 'POST /api/users': ({ body }) => ({ id: 'custom', ...body }),
880
+ * })
881
+ * ```
882
+ */
883
+ declare function mergeFixtures(remoteFixtures: FixtureMap, localOverrides?: FixtureMap): FixtureMap;
884
+ /**
885
+ * Create a complete fixture setup from cloud response and optional overrides
886
+ *
887
+ * Convenience function that combines buildFixtureMap and mergeFixtures.
888
+ *
889
+ * @param response - Cloud fixture response
890
+ * @param localOverrides - Optional local fixtures to merge
891
+ * @returns Complete FixtureMap ready for use with createDemoInterceptor
892
+ */
893
+ declare function createRemoteFixtures(response: CloudFixtureResponse, localOverrides?: FixtureMap): FixtureMap;
894
+
895
+ /**
896
+ * Core types for DemoKit schema representation
897
+ *
898
+ * These types represent a parsed API schema with relationship detection,
899
+ * independent of the source format (OpenAPI, GraphQL, etc.)
900
+ */
901
+ /**
902
+ * The main schema representation for DemoKit
903
+ * Contains all information needed for fixture generation
904
+ */
905
+ interface DemokitSchema {
906
+ /**
907
+ * Metadata about the API
908
+ */
909
+ info: SchemaInfo;
910
+ /**
911
+ * All API endpoints discovered from the spec
912
+ */
913
+ endpoints: Endpoint[];
914
+ /**
915
+ * All data models (schemas) from the spec
916
+ */
917
+ models: Record<string, DataModel>;
918
+ /**
919
+ * Detected relationships between models
920
+ */
921
+ relationships: Relationship[];
922
+ }
923
+ /**
924
+ * API metadata
925
+ */
926
+ interface SchemaInfo {
927
+ /**
928
+ * API title from the spec
929
+ */
930
+ title: string;
931
+ /**
932
+ * API version
933
+ */
934
+ version: string;
935
+ /**
936
+ * Optional description
937
+ */
938
+ description?: string;
939
+ /**
940
+ * Base URL for the API (if specified)
941
+ */
942
+ baseUrl?: string;
943
+ }
944
+ /**
945
+ * An API endpoint
946
+ */
947
+ interface Endpoint {
948
+ /**
949
+ * HTTP method (GET, POST, PUT, PATCH, DELETE)
950
+ */
951
+ method: HttpMethod;
952
+ /**
953
+ * URL path with parameter placeholders
954
+ * @example "/users/{id}" or "/orders/{orderId}/items"
955
+ */
956
+ path: string;
957
+ /**
958
+ * Operation ID from OpenAPI (if available)
959
+ */
960
+ operationId?: string;
961
+ /**
962
+ * Human-readable summary
963
+ */
964
+ summary?: string;
965
+ /**
966
+ * Detailed description
967
+ */
968
+ description?: string;
969
+ /**
970
+ * Path parameters
971
+ */
972
+ pathParams: ParameterDef[];
973
+ /**
974
+ * Query parameters
975
+ */
976
+ queryParams: ParameterDef[];
977
+ /**
978
+ * Request body schema (for POST/PUT/PATCH)
979
+ */
980
+ requestBody?: RequestBody;
981
+ /**
982
+ * Response schemas by status code
983
+ */
984
+ responses: Record<string, ResponseDef>;
985
+ /**
986
+ * Tags for grouping endpoints
987
+ */
988
+ tags: string[];
989
+ }
990
+ /**
991
+ * HTTP methods supported
992
+ */
993
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
994
+ /**
995
+ * A request or response body definition
996
+ */
997
+ interface RequestBody {
998
+ /**
999
+ * Content type (usually application/json)
1000
+ */
1001
+ contentType: string;
1002
+ /**
1003
+ * Reference to the model name, or inline schema
1004
+ */
1005
+ schema: SchemaRef | DataModel;
1006
+ /**
1007
+ * Whether the body is required
1008
+ */
1009
+ required: boolean;
1010
+ /**
1011
+ * Description of the body
1012
+ */
1013
+ description?: string;
1014
+ }
1015
+ /**
1016
+ * A response definition
1017
+ */
1018
+ interface ResponseDef {
1019
+ /**
1020
+ * HTTP status code
1021
+ */
1022
+ statusCode: string;
1023
+ /**
1024
+ * Description of the response
1025
+ */
1026
+ description?: string;
1027
+ /**
1028
+ * Content type to schema mapping
1029
+ */
1030
+ content?: Record<string, SchemaRef | DataModel>;
1031
+ }
1032
+ /**
1033
+ * A parameter definition (path or query)
1034
+ */
1035
+ interface ParameterDef {
1036
+ /**
1037
+ * Parameter name
1038
+ */
1039
+ name: string;
1040
+ /**
1041
+ * Where the parameter is located
1042
+ */
1043
+ in: 'path' | 'query' | 'header' | 'cookie';
1044
+ /**
1045
+ * Whether the parameter is required
1046
+ */
1047
+ required: boolean;
1048
+ /**
1049
+ * Parameter type
1050
+ */
1051
+ type: PropertyType;
1052
+ /**
1053
+ * Optional format hint
1054
+ */
1055
+ format?: string;
1056
+ /**
1057
+ * Description
1058
+ */
1059
+ description?: string;
1060
+ /**
1061
+ * Example value
1062
+ */
1063
+ example?: unknown;
1064
+ }
1065
+ /**
1066
+ * Reference to another schema/model
1067
+ */
1068
+ interface SchemaRef {
1069
+ /**
1070
+ * The referenced model name
1071
+ */
1072
+ $ref: string;
1073
+ }
1074
+ /**
1075
+ * A data model representing an object schema
1076
+ */
1077
+ interface DataModel {
1078
+ /**
1079
+ * Model name (from the schema component name)
1080
+ */
1081
+ name: string;
1082
+ /**
1083
+ * The type of this model
1084
+ */
1085
+ type: ModelType;
1086
+ /**
1087
+ * Description from the spec
1088
+ */
1089
+ description?: string;
1090
+ /**
1091
+ * Properties for object types
1092
+ */
1093
+ properties?: Record<string, PropertyDef>;
1094
+ /**
1095
+ * Required property names
1096
+ */
1097
+ required?: string[];
1098
+ /**
1099
+ * For array types, the item schema
1100
+ */
1101
+ items?: SchemaRef | DataModel;
1102
+ /**
1103
+ * Enum values for enum types
1104
+ */
1105
+ enum?: unknown[];
1106
+ /**
1107
+ * Example value from the spec
1108
+ */
1109
+ example?: unknown;
1110
+ /**
1111
+ * Additional properties schema (for dictionaries)
1112
+ */
1113
+ additionalProperties?: boolean | SchemaRef | DataModel;
1114
+ }
1115
+ /**
1116
+ * Model types
1117
+ */
1118
+ type ModelType = 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
1119
+ /**
1120
+ * A property definition within a model
1121
+ */
1122
+ interface PropertyDef {
1123
+ /**
1124
+ * Property name
1125
+ */
1126
+ name: string;
1127
+ /**
1128
+ * Property type
1129
+ */
1130
+ type: PropertyType;
1131
+ /**
1132
+ * Format hint (uuid, email, date-time, etc.)
1133
+ */
1134
+ format?: string;
1135
+ /**
1136
+ * Description
1137
+ */
1138
+ description?: string;
1139
+ /**
1140
+ * Whether this property is required
1141
+ */
1142
+ required?: boolean;
1143
+ /**
1144
+ * Whether this property is nullable
1145
+ */
1146
+ nullable?: boolean;
1147
+ /**
1148
+ * Enum values for string enums
1149
+ */
1150
+ enum?: unknown[];
1151
+ /**
1152
+ * For array types, the item schema
1153
+ */
1154
+ items?: SchemaRef | DataModel;
1155
+ /**
1156
+ * Reference to another model (for $ref properties)
1157
+ */
1158
+ $ref?: string;
1159
+ /**
1160
+ * Example value
1161
+ */
1162
+ example?: unknown;
1163
+ /**
1164
+ * Default value
1165
+ */
1166
+ default?: unknown;
1167
+ /**
1168
+ * Minimum value (for numbers)
1169
+ */
1170
+ minimum?: number;
1171
+ /**
1172
+ * Maximum value (for numbers)
1173
+ */
1174
+ maximum?: number;
1175
+ /**
1176
+ * Min length (for strings)
1177
+ */
1178
+ minLength?: number;
1179
+ /**
1180
+ * Max length (for strings)
1181
+ */
1182
+ maxLength?: number;
1183
+ /**
1184
+ * Pattern (regex for strings)
1185
+ */
1186
+ pattern?: string;
1187
+ /**
1188
+ * Detected relationship to another model
1189
+ * Set by relationship detection, not directly from spec
1190
+ */
1191
+ relationshipTo?: RelationshipTarget;
1192
+ /**
1193
+ * Custom extension for explicit relationship hints
1194
+ * @example "x-demokit-relationship": { "model": "User", "field": "id" }
1195
+ */
1196
+ 'x-demokit-relationship'?: RelationshipTarget;
1197
+ }
1198
+ /**
1199
+ * Property types
1200
+ */
1201
+ type PropertyType = 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'null';
1202
+ /**
1203
+ * A detected relationship between two models
1204
+ */
1205
+ interface Relationship {
1206
+ /**
1207
+ * The source side of the relationship
1208
+ */
1209
+ from: RelationshipSide;
1210
+ /**
1211
+ * The target side of the relationship
1212
+ */
1213
+ to: RelationshipSide;
1214
+ /**
1215
+ * Type of relationship
1216
+ */
1217
+ type: RelationshipType;
1218
+ /**
1219
+ * Whether the relationship is required (not nullable)
1220
+ */
1221
+ required: boolean;
1222
+ /**
1223
+ * How this relationship was detected
1224
+ */
1225
+ detectedBy: RelationshipDetectionMethod;
1226
+ }
1227
+ /**
1228
+ * One side of a relationship
1229
+ */
1230
+ interface RelationshipSide {
1231
+ /**
1232
+ * Model name
1233
+ */
1234
+ model: string;
1235
+ /**
1236
+ * Field name
1237
+ */
1238
+ field: string;
1239
+ }
1240
+ /**
1241
+ * Target for a relationship from a property
1242
+ */
1243
+ interface RelationshipTarget {
1244
+ /**
1245
+ * Target model name
1246
+ */
1247
+ model: string;
1248
+ /**
1249
+ * Target field (usually "id")
1250
+ */
1251
+ field: string;
1252
+ }
1253
+ /**
1254
+ * Types of relationships between models
1255
+ */
1256
+ type RelationshipType = 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';
1257
+ /**
1258
+ * How a relationship was detected
1259
+ */
1260
+ type RelationshipDetectionMethod = 'explicit-ref' | 'naming-convention' | 'x-demokit-extension' | 'inferred';
1261
+ /**
1262
+ * Helper type to check if something is a schema reference
1263
+ */
1264
+ declare function isSchemaRef(value: unknown): value is SchemaRef;
1265
+ /**
1266
+ * Extract the model name from a $ref string
1267
+ * @example "#/components/schemas/User" -> "User"
1268
+ */
1269
+ declare function extractRefName(ref: string): string;
1270
+
1271
+ /**
1272
+ * OpenAPI 3.x parser for DemoKit
1273
+ *
1274
+ * Parses OpenAPI specs into DemoKit's internal schema representation
1275
+ * with automatic relationship detection.
1276
+ *
1277
+ * Uses @scalar/openapi-parser - a modern, webpack-compatible parser.
1278
+ */
1279
+
1280
+ /**
1281
+ * Options for parsing OpenAPI specs
1282
+ */
1283
+ interface ParseOptions {
1284
+ /**
1285
+ * Whether to dereference all $ref pointers
1286
+ * @default true
1287
+ */
1288
+ dereference?: boolean;
1289
+ /**
1290
+ * Whether to detect relationships automatically
1291
+ * @default true
1292
+ */
1293
+ detectRelationships?: boolean;
1294
+ /**
1295
+ * Whether to include response schemas in models
1296
+ * @default true
1297
+ */
1298
+ includeResponses?: boolean;
1299
+ }
1300
+ /**
1301
+ * Parse an OpenAPI spec from a file path or URL
1302
+ */
1303
+ declare function parseOpenAPIFromPath(pathOrUrl: string, options?: ParseOptions): Promise<DemokitSchema>;
1304
+ /**
1305
+ * Parse an OpenAPI spec from a string (JSON or YAML)
1306
+ */
1307
+ declare function parseOpenAPIFromString(spec: string, options?: ParseOptions): Promise<DemokitSchema>;
1308
+ /**
1309
+ * Parse an OpenAPI spec from an already-parsed object
1310
+ */
1311
+ declare function parseOpenAPIFromObject(spec: Record<string, unknown>, options?: ParseOptions): Promise<DemokitSchema>;
1312
+
1313
+ /**
1314
+ * Types for codebase schema parsers.
1315
+ * These types define the interface for parsing various schema formats
1316
+ * (TypeScript, Zod, Drizzle, Prisma, etc.) into DemokitSchema.
1317
+ */
1318
+
1319
+ /**
1320
+ * Supported schema formats that can be parsed from codebases.
1321
+ */
1322
+ type SchemaFormat = 'typescript' | 'zod' | 'drizzle' | 'prisma' | 'graphql' | 'supabase' | 'trpc' | 'nextjs' | 'openapi' | 'auto';
1323
+ /**
1324
+ * A file to be parsed, with path and content.
1325
+ */
1326
+ interface CodebaseFile {
1327
+ /**
1328
+ * Relative or absolute file path.
1329
+ */
1330
+ path: string;
1331
+ /**
1332
+ * File content as a string.
1333
+ */
1334
+ content: string;
1335
+ }
1336
+ /**
1337
+ * Options for parsing codebase schemas.
1338
+ */
1339
+ interface ParseSchemaOptions {
1340
+ /**
1341
+ * The format to parse as. Use 'auto' to detect.
1342
+ * @default 'auto'
1343
+ */
1344
+ format?: SchemaFormat;
1345
+ /**
1346
+ * Schema/API name for the output.
1347
+ * @default 'Codebase Schema'
1348
+ */
1349
+ name?: string;
1350
+ /**
1351
+ * Schema version.
1352
+ * @default '1.0.0'
1353
+ */
1354
+ version?: string;
1355
+ /**
1356
+ * Whether to detect relationships between models.
1357
+ * @default true
1358
+ */
1359
+ detectRelationships?: boolean;
1360
+ /**
1361
+ * Whether to include inferred relationships from naming conventions.
1362
+ * @default true
1363
+ */
1364
+ inferRelationships?: boolean;
1365
+ }
1366
+ /**
1367
+ * Result of parsing with additional metadata.
1368
+ */
1369
+ interface ParseResult {
1370
+ /**
1371
+ * The parsed schema.
1372
+ */
1373
+ schema: DemokitSchema;
1374
+ /**
1375
+ * The format that was detected/used.
1376
+ */
1377
+ format: SchemaFormat;
1378
+ /**
1379
+ * Any warnings encountered during parsing.
1380
+ */
1381
+ warnings: ParseWarning[];
1382
+ /**
1383
+ * Files that were parsed.
1384
+ */
1385
+ parsedFiles: string[];
1386
+ }
1387
+ /**
1388
+ * A warning encountered during parsing.
1389
+ */
1390
+ interface ParseWarning {
1391
+ /**
1392
+ * Warning code for programmatic handling.
1393
+ */
1394
+ code: string;
1395
+ /**
1396
+ * Human-readable message.
1397
+ */
1398
+ message: string;
1399
+ /**
1400
+ * File where the warning occurred.
1401
+ */
1402
+ file?: string;
1403
+ /**
1404
+ * Line number where the warning occurred.
1405
+ */
1406
+ line?: number;
1407
+ }
1408
+ /**
1409
+ * Detection result for schema format.
1410
+ */
1411
+ interface FormatDetectionResult {
1412
+ /**
1413
+ * The detected format, or null if unknown.
1414
+ */
1415
+ format: SchemaFormat | null;
1416
+ /**
1417
+ * Confidence score from 0-1.
1418
+ */
1419
+ confidence: number;
1420
+ /**
1421
+ * Evidence that led to this detection.
1422
+ */
1423
+ evidence: string[];
1424
+ }
1425
+ /**
1426
+ * Patterns for detecting schema formats from file content.
1427
+ */
1428
+ interface FormatDetectionPatterns {
1429
+ /**
1430
+ * File path patterns (globs).
1431
+ */
1432
+ pathPatterns: string[];
1433
+ /**
1434
+ * Keywords/patterns to search for in content.
1435
+ */
1436
+ contentPatterns: string[];
1437
+ /**
1438
+ * File extensions to match.
1439
+ */
1440
+ extensions: string[];
1441
+ }
1442
+
1443
+ /**
1444
+ * Format detection utilities for codebase schema files.
1445
+ * Detects which schema format (TypeScript, Zod, Drizzle, Prisma, etc.)
1446
+ * a given file or content is written in.
1447
+ */
1448
+
1449
+ /**
1450
+ * Detection patterns for each schema format.
1451
+ */
1452
+ declare const FORMAT_PATTERNS: Record<Exclude<SchemaFormat, 'auto'>, FormatDetectionPatterns>;
1453
+ /**
1454
+ * Priority order when multiple formats are detected.
1455
+ * Formats earlier in the list take precedence.
1456
+ */
1457
+ declare const FORMAT_PRIORITY: SchemaFormat[];
1458
+ /**
1459
+ * Detect the schema format of a single file.
1460
+ */
1461
+ declare function detectFormat(file: CodebaseFile): FormatDetectionResult;
1462
+ /**
1463
+ * Detect the primary schema format from multiple files.
1464
+ * Returns the format with highest total confidence.
1465
+ */
1466
+ declare function detectFormatFromFiles(files: CodebaseFile[]): FormatDetectionResult;
1467
+ /**
1468
+ * Group files by their detected format.
1469
+ */
1470
+ declare function groupFilesByFormat(files: CodebaseFile[]): Map<SchemaFormat, CodebaseFile[]>;
1471
+
1472
+ /**
1473
+ * TypeScript interface/type parser.
1474
+ * Parses TypeScript interface and type declarations into DemokitSchema.
1475
+ *
1476
+ * Supports:
1477
+ * - interface declarations
1478
+ * - type aliases (object types)
1479
+ * - enum declarations
1480
+ * - Generic types (partial support)
1481
+ * - Union/intersection types (partial support)
1482
+ * - Array types
1483
+ * - Optional properties
1484
+ * - JSDoc comments for descriptions
1485
+ */
1486
+
1487
+ /**
1488
+ * Parse TypeScript files containing interface/type definitions.
1489
+ */
1490
+ declare function parseTypeScript(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1491
+
1492
+ /**
1493
+ * Zod schema parser.
1494
+ * Parses Zod validation schemas into DemokitSchema.
1495
+ *
1496
+ * Supports:
1497
+ * - z.object() schemas
1498
+ * - z.string(), z.number(), z.boolean() primitives
1499
+ * - z.array() and z.tuple()
1500
+ * - z.enum() and z.nativeEnum()
1501
+ * - z.optional(), z.nullable()
1502
+ * - z.union(), z.intersection()
1503
+ * - z.lazy() for recursive types
1504
+ * - .describe() for descriptions
1505
+ * - .default() values
1506
+ * - String validations (.email(), .uuid(), .url(), etc.)
1507
+ * - Number validations (.min(), .max(), .int())
1508
+ */
1509
+
1510
+ /**
1511
+ * Parse Zod schema files into DemokitSchema.
1512
+ */
1513
+ declare function parseZod(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1514
+
1515
+ /**
1516
+ * Drizzle ORM schema parser.
1517
+ * Parses Drizzle table definitions and relations into DemokitSchema.
1518
+ *
1519
+ * Supports:
1520
+ * - pgTable(), mysqlTable(), sqliteTable() definitions
1521
+ * - Column types (text, integer, boolean, uuid, timestamp, etc.)
1522
+ * - Primary keys, foreign keys, unique constraints
1523
+ * - relations() function for explicit relationships
1524
+ * - Default values
1525
+ * - Nullable columns
1526
+ *
1527
+ * This parser extracts high-fidelity relationship information
1528
+ * since Drizzle uses explicit relations() declarations.
1529
+ */
1530
+
1531
+ /**
1532
+ * Parse Drizzle schema files into DemokitSchema.
1533
+ */
1534
+ declare function parseDrizzle(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1535
+
1536
+ /**
1537
+ * Prisma schema parser.
1538
+ * Parses Prisma schema files (.prisma) into DemokitSchema.
1539
+ *
1540
+ * Supports:
1541
+ * - model definitions with fields
1542
+ * - Field types (String, Int, Float, Boolean, DateTime, etc.)
1543
+ * - @id, @unique, @default attributes
1544
+ * - @relation for relationships
1545
+ * - Optional fields (?)
1546
+ * - Array fields ([])
1547
+ * - Enums
1548
+ * - @map and @@map for custom names
1549
+ *
1550
+ * Prisma schemas have explicit relationship definitions,
1551
+ * providing high-fidelity relationship detection.
1552
+ */
1553
+
1554
+ /**
1555
+ * Parse Prisma schema files into DemokitSchema.
1556
+ */
1557
+ declare function parsePrisma(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1558
+
1559
+ /**
1560
+ * GraphQL SDL parser.
1561
+ * Parses GraphQL schema files (.graphql, .gql) into DemokitSchema.
1562
+ *
1563
+ * Supports:
1564
+ * - type definitions (type, interface, input, enum)
1565
+ * - Field types (String, Int, Float, Boolean, ID, custom types)
1566
+ * - Non-null (!) and list ([]) modifiers
1567
+ * - Field relationships based on type references
1568
+ * - Query, Mutation, and Subscription types
1569
+ *
1570
+ * GraphQL schemas have explicit type references,
1571
+ * providing high-fidelity relationship detection.
1572
+ */
1573
+
1574
+ /**
1575
+ * Parse GraphQL schema files into DemokitSchema.
1576
+ */
1577
+ declare function parseGraphQL(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1578
+
1579
+ /**
1580
+ * Supabase generated types parser.
1581
+ * Parses Supabase database.types.ts files into DemokitSchema.
1582
+ *
1583
+ * Supports:
1584
+ * - Database interface with Tables property
1585
+ * - Tables.*.Row type for each table
1586
+ * - Column types mapped from PostgreSQL types
1587
+ * - Foreign key relationships from Insert/Update types
1588
+ * - Views and Enums
1589
+ *
1590
+ * Supabase generates types from the database schema,
1591
+ * providing accurate type information and relationships.
1592
+ */
1593
+
1594
+ /**
1595
+ * Parse Supabase types files into DemokitSchema.
1596
+ */
1597
+ declare function parseSupabase(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1598
+
1599
+ /**
1600
+ * tRPC router parser.
1601
+ * Parses tRPC router definitions into DemokitSchema.
1602
+ *
1603
+ * Supports:
1604
+ * - router() definitions with procedure chains
1605
+ * - .input() and .output() Zod schemas
1606
+ * - publicProcedure and protectedProcedure
1607
+ * - Nested routers (appRouter structure)
1608
+ *
1609
+ * tRPC uses Zod for validation, so this parser extracts
1610
+ * Zod schemas and delegates to the Zod parser for details.
1611
+ */
1612
+
1613
+ /**
1614
+ * Parse tRPC router files into DemokitSchema.
1615
+ */
1616
+ declare function parseTRPC(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1617
+
1618
+ /**
1619
+ * Next.js parser.
1620
+ * Parses Next.js API routes and Server Actions into DemokitSchema.
1621
+ *
1622
+ * Supports:
1623
+ * - App Router: app/api/[...]/route.ts (GET, POST, PUT, PATCH, DELETE)
1624
+ * - Pages Router: pages/api/[...].ts (handler function)
1625
+ * - Server Actions: 'use server' directive
1626
+ * - TypeScript types for request/response bodies
1627
+ * - Zod validation schemas in API routes
1628
+ *
1629
+ * Extracts endpoint and schema information from Next.js conventions.
1630
+ */
1631
+
1632
+ /**
1633
+ * Parse Next.js files into DemokitSchema.
1634
+ */
1635
+ declare function parseNextJS(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1636
+
1637
+ /**
1638
+ * Unified schema parser entry point.
1639
+ *
1640
+ * Provides a single `parseSchema()` function that can parse
1641
+ * multiple schema formats and automatically detect the format.
1642
+ *
1643
+ * @example
1644
+ * // Parse with auto-detection
1645
+ * const result = await parseSchema(files)
1646
+ *
1647
+ * // Parse specific format
1648
+ * const result = await parseSchema(files, { format: 'drizzle' })
1649
+ *
1650
+ * // Parse from strings
1651
+ * const result = await parseSchemaFromStrings([
1652
+ * { path: 'schema.ts', content: 'export const users = pgTable(...)' }
1653
+ * ])
1654
+ */
1655
+
1656
+ /**
1657
+ * Parse schema files from a codebase.
1658
+ *
1659
+ * Supports TypeScript, Zod, Drizzle, and Prisma formats.
1660
+ * Can auto-detect the format or use a specified format.
1661
+ *
1662
+ * @param files - Array of files with path and content
1663
+ * @param options - Parsing options
1664
+ * @returns Parsed schema with metadata
1665
+ */
1666
+ declare function parseSchema(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1667
+ /**
1668
+ * Parse multiple formats from a codebase and merge the results.
1669
+ *
1670
+ * This is useful when a codebase uses multiple schema sources
1671
+ * (e.g., Drizzle for database + Zod for validation).
1672
+ *
1673
+ * @param files - Array of files with path and content
1674
+ * @param options - Parsing options
1675
+ * @returns Merged schema from all detected formats
1676
+ */
1677
+ declare function parseSchemaMultiFormat(files: CodebaseFile[], options?: ParseSchemaOptions): ParseResult;
1678
+
1679
+ /**
1680
+ * Relationship detection for DemoKit schemas
1681
+ *
1682
+ * Detects relationships between models using:
1683
+ * 1. Explicit $ref references in OpenAPI
1684
+ * 2. Naming conventions (userId -> User.id)
1685
+ * 3. x-demokit-relationship extension
1686
+ */
1687
+
1688
+ /**
1689
+ * Check if a property looks like a foreign key based on naming conventions
1690
+ */
1691
+ declare function detectRelationshipFromNaming(property: PropertyDef, availableModels: Set<string>): RelationshipTarget | null;
1692
+ /**
1693
+ * Check if a property has an explicit x-demokit-relationship extension
1694
+ */
1695
+ declare function detectRelationshipFromExtension(property: PropertyDef): RelationshipTarget | null;
1696
+ /**
1697
+ * Check if a property is a $ref to another model
1698
+ */
1699
+ declare function detectRelationshipFromRef(property: PropertyDef, availableModels: Set<string>): RelationshipTarget | null;
1700
+ /**
1701
+ * Detect all relationships in a set of models
1702
+ */
1703
+ declare function detectRelationships(models: Record<string, DataModel>): Relationship[];
1704
+ /**
1705
+ * Find all relationships for a specific model
1706
+ */
1707
+ declare function getRelationshipsForModel(modelName: string, relationships: Relationship[]): {
1708
+ outgoing: Relationship[];
1709
+ incoming: Relationship[];
1710
+ };
1711
+ /**
1712
+ * Check if a model is referenced by other models
1713
+ */
1714
+ declare function isModelReferenced(modelName: string, relationships: Relationship[]): boolean;
1715
+ /**
1716
+ * Get the dependency order for models based on relationships
1717
+ * Returns models in order such that dependencies come before dependents
1718
+ */
1719
+ declare function getModelDependencyOrder(models: Record<string, DataModel>, relationships: Relationship[]): string[];
1720
+
1721
+ /**
1722
+ * Schema Merger.
1723
+ * Merges multiple DemokitSchemas from different sources into a unified schema.
1724
+ *
1725
+ * Features:
1726
+ * - Case-insensitive model name matching
1727
+ * - Property merge with source tracking
1728
+ * - Relationship priority (explicit > inferred)
1729
+ * - Conflict detection and resolution
1730
+ * - Endpoint merging from multiple sources
1731
+ */
1732
+
1733
+ /**
1734
+ * Options for schema merging.
1735
+ */
1736
+ interface MergeOptions {
1737
+ /**
1738
+ * How to resolve property conflicts when the same model appears in multiple sources.
1739
+ * - 'prefer-explicit': Prefer properties from more explicit sources (e.g., Drizzle over TypeScript)
1740
+ * - 'prefer-first': Keep the first value encountered
1741
+ * - 'union': Combine all properties, with first taking precedence for conflicts
1742
+ */
1743
+ conflictResolution?: 'prefer-explicit' | 'prefer-first' | 'union';
1744
+ /**
1745
+ * Order of precedence for relationships.
1746
+ * Earlier formats have higher priority.
1747
+ * Default: ['drizzle', 'prisma', 'graphql', 'supabase', 'zod', 'trpc', 'typescript', 'nextjs']
1748
+ */
1749
+ relationshipPriority?: SchemaFormat[];
1750
+ /**
1751
+ * Whether to track the source of each field for debugging.
1752
+ */
1753
+ trackSources?: boolean;
1754
+ /**
1755
+ * Name for the merged schema.
1756
+ */
1757
+ name?: string;
1758
+ /**
1759
+ * Version for the merged schema.
1760
+ */
1761
+ version?: string;
1762
+ }
1763
+ /**
1764
+ * A source schema with its format identifier.
1765
+ */
1766
+ interface SchemaSource {
1767
+ format: SchemaFormat;
1768
+ schema: DemokitSchema;
1769
+ }
1770
+ /**
1771
+ * Result of a merge operation.
1772
+ */
1773
+ interface MergeResult {
1774
+ /**
1775
+ * The merged schema.
1776
+ */
1777
+ schema: DemokitSchema;
1778
+ /**
1779
+ * Conflicts detected during merge.
1780
+ */
1781
+ conflicts: MergeConflict[];
1782
+ /**
1783
+ * Source tracking for each model (if enabled).
1784
+ */
1785
+ sources?: ModelSourceMap;
1786
+ /**
1787
+ * Formats that were merged.
1788
+ */
1789
+ mergedFormats: SchemaFormat[];
1790
+ }
1791
+ /**
1792
+ * Describes a merge conflict.
1793
+ */
1794
+ interface MergeConflict {
1795
+ type: 'model' | 'property' | 'relationship';
1796
+ modelName: string;
1797
+ propertyName?: string;
1798
+ sources: SchemaFormat[];
1799
+ resolution: 'kept-first' | 'merged' | 'overwritten';
1800
+ details?: string;
1801
+ }
1802
+ /**
1803
+ * Tracks which source provided each model/property.
1804
+ */
1805
+ interface ModelSourceMap {
1806
+ [modelName: string]: {
1807
+ primarySource: SchemaFormat;
1808
+ properties: {
1809
+ [propertyName: string]: SchemaFormat;
1810
+ };
1811
+ };
1812
+ }
1813
+ /**
1814
+ * Merge multiple schemas into a unified schema.
1815
+ *
1816
+ * @param sources - Array of schemas with their format identifiers
1817
+ * @param options - Merge options
1818
+ * @returns Merged schema with conflict information
1819
+ */
1820
+ declare function mergeSchemas(sources: SchemaSource[], options?: MergeOptions): MergeResult;
1821
+ /**
1822
+ * Compare two schemas and return the differences.
1823
+ */
1824
+ declare function diffSchemas(base: DemokitSchema, updated: DemokitSchema): SchemaDiff;
1825
+ /**
1826
+ * Schema diff result.
1827
+ */
1828
+ interface SchemaDiff {
1829
+ added: SchemaDiffItem[];
1830
+ removed: SchemaDiffItem[];
1831
+ modified: SchemaDiffItem[];
1832
+ }
1833
+ /**
1834
+ * A single diff item.
1835
+ */
1836
+ interface SchemaDiffItem {
1837
+ type: 'model' | 'relationship' | 'endpoint';
1838
+ name: string;
1839
+ details: unknown;
1840
+ }
1841
+ /**
1842
+ * Property diff.
1843
+ */
1844
+ interface PropertyDiff {
1845
+ name: string;
1846
+ change: 'added' | 'removed' | 'modified';
1847
+ oldValue?: PropertyDef;
1848
+ newValue?: PropertyDef;
1849
+ }
1850
+
1851
+ /**
1852
+ * Error handling utilities for schema parsing.
1853
+ *
1854
+ * Provides custom error types and safe parsing utilities
1855
+ * for graceful error recovery during schema parsing.
1856
+ */
1857
+
1858
+ /**
1859
+ * Base error class for schema parsing errors.
1860
+ */
1861
+ declare class SchemaParseError extends Error {
1862
+ readonly code: string;
1863
+ readonly filePath?: string | undefined;
1864
+ readonly line?: number | undefined;
1865
+ constructor(message: string, code: string, filePath?: string | undefined, line?: number | undefined);
1866
+ }
1867
+ /**
1868
+ * Error thrown when a format cannot be detected.
1869
+ */
1870
+ declare class FormatDetectionError extends SchemaParseError {
1871
+ constructor(message: string, filePath?: string);
1872
+ }
1873
+ /**
1874
+ * Error thrown when a file cannot be parsed.
1875
+ */
1876
+ declare class FileParseError extends SchemaParseError {
1877
+ constructor(message: string, filePath: string, line?: number);
1878
+ }
1879
+ /**
1880
+ * Error thrown when schema validation fails.
1881
+ */
1882
+ declare class SchemaValidationError extends SchemaParseError {
1883
+ readonly validationErrors: string[];
1884
+ constructor(message: string, validationErrors: string[]);
1885
+ }
1886
+ /**
1887
+ * Error thrown when merging schemas fails.
1888
+ */
1889
+ declare class SchemaMergeError extends SchemaParseError {
1890
+ readonly modelName?: string | undefined;
1891
+ constructor(message: string, modelName?: string | undefined);
1892
+ }
1893
+ /**
1894
+ * Result of a safe operation that may fail.
1895
+ */
1896
+ type SafeResult<T> = {
1897
+ success: true;
1898
+ value: T;
1899
+ warnings: ParseWarning[];
1900
+ } | {
1901
+ success: false;
1902
+ error: Error;
1903
+ warnings: ParseWarning[];
1904
+ };
1905
+ /**
1906
+ * Safely execute a parsing function and capture errors as warnings.
1907
+ *
1908
+ * @param fn - The function to execute
1909
+ * @param fallback - Fallback value if the function fails
1910
+ * @param errorCode - Warning code to use if the function fails
1911
+ * @returns Result with value or error
1912
+ */
1913
+ declare function safeExecute<T>(fn: () => T, fallback: T, errorCode: string): {
1914
+ value: T;
1915
+ warning?: ParseWarning;
1916
+ };
1917
+ /**
1918
+ * Safely parse content with error recovery.
1919
+ * Returns partial results with warnings instead of failing completely.
1920
+ *
1921
+ * @param items - Array of items to process
1922
+ * @param processor - Function to process each item
1923
+ * @param errorCode - Warning code prefix for errors
1924
+ * @returns Processed results and accumulated warnings
1925
+ */
1926
+ declare function safeProcessMany<T, R>(items: T[], processor: (item: T) => R, errorCode: string): {
1927
+ results: R[];
1928
+ warnings: ParseWarning[];
1929
+ };
1930
+ /**
1931
+ * Create a warning from an error.
1932
+ */
1933
+ declare function errorToWarning(error: unknown, code: string, file?: string): ParseWarning;
1934
+ /**
1935
+ * Aggregate multiple warnings into a summary warning.
1936
+ */
1937
+ declare function aggregateWarnings(warnings: ParseWarning[], summaryCode: string, summaryPrefix: string): ParseWarning[];
1938
+ /**
1939
+ * Check if an error is recoverable (should result in warning, not failure).
1940
+ */
1941
+ declare function isRecoverableError(error: unknown): boolean;
1942
+
1943
+ /**
1944
+ * Types for @demokit-ai/codegen
1945
+ *
1946
+ * Includes validation types, generation options, and output formats.
1947
+ */
1948
+
1949
+ /**
1950
+ * Result of validating demo data against a schema
1951
+ */
1952
+ interface ValidationResult {
1953
+ /** Whether all validations passed */
1954
+ valid: boolean;
1955
+ /** Critical errors that must be fixed */
1956
+ errors: ValidationError[];
1957
+ /** Non-critical issues that should be reviewed */
1958
+ warnings: ValidationWarning[];
1959
+ /** Summary statistics */
1960
+ stats: ValidationStats;
1961
+ }
1962
+ /**
1963
+ * A validation error - data that violates schema constraints
1964
+ */
1965
+ interface ValidationError {
1966
+ /** Type of validation failure */
1967
+ type: ValidationErrorType;
1968
+ /** Model where the error occurred */
1969
+ model: string;
1970
+ /** Field where the error occurred */
1971
+ field: string;
1972
+ /** Human-readable error message */
1973
+ message: string;
1974
+ /** The invalid value (for debugging) */
1975
+ value?: unknown;
1976
+ /** Expected value or constraint */
1977
+ expected?: string;
1978
+ /** Record ID if applicable */
1979
+ recordId?: string;
1980
+ }
1981
+ /**
1982
+ * Types of validation errors
1983
+ */
1984
+ type ValidationErrorType = 'missing_reference' | 'type_mismatch' | 'format_invalid' | 'constraint_violation' | 'required_missing' | 'enum_invalid' | 'timestamp_order' | 'array_empty' | 'duplicate_id';
1985
+ /**
1986
+ * A validation warning - issues that may be intentional
1987
+ */
1988
+ interface ValidationWarning {
1989
+ /** Type of warning */
1990
+ type: ValidationWarningType;
1991
+ /** Model where the warning occurred */
1992
+ model: string;
1993
+ /** Field where the warning occurred */
1994
+ field: string;
1995
+ /** Human-readable warning message */
1996
+ message: string;
1997
+ /** The suspicious value */
1998
+ value?: unknown;
1999
+ }
2000
+ /**
2001
+ * Types of validation warnings
2002
+ */
2003
+ type ValidationWarningType = 'orphaned_record' | 'suspicious_value' | 'missing_optional' | 'empty_string';
2004
+ /**
2005
+ * Statistics about the validation run
2006
+ */
2007
+ interface ValidationStats {
2008
+ /** Total number of records validated */
2009
+ totalRecords: number;
2010
+ /** Records per model */
2011
+ recordsByModel: Record<string, number>;
2012
+ /** Number of relationships validated */
2013
+ relationshipsChecked: number;
2014
+ /** Number of type checks performed */
2015
+ typeChecks: number;
2016
+ /** Duration of validation in ms */
2017
+ durationMs: number;
2018
+ }
2019
+ /**
2020
+ * A validation rule that can be applied to data
2021
+ */
2022
+ interface ValidationRule {
2023
+ /** Unique identifier for this rule */
2024
+ id: string;
2025
+ /** Model this rule applies to */
2026
+ model: string;
2027
+ /** Field this rule applies to */
2028
+ field: string;
2029
+ /** Type of check to perform */
2030
+ check: ValidationCheck;
2031
+ /** Target field or value for comparison checks */
2032
+ target?: string;
2033
+ /** Whether this is a required field */
2034
+ required?: boolean;
2035
+ /** Custom error message */
2036
+ message?: string;
2037
+ }
2038
+ /**
2039
+ * Types of validation checks
2040
+ */
2041
+ type ValidationCheck = 'isString' | 'isNumber' | 'isInteger' | 'isBoolean' | 'isArray' | 'isObject' | 'isNull' | 'isUUID' | 'isEmail' | 'isURL' | 'isISO8601' | 'isDate' | 'isDateTime' | 'minLength' | 'maxLength' | 'minimum' | 'maximum' | 'pattern' | 'existsIn' | 'isUnique' | 'equals' | 'beforeOrEqual' | 'afterOrEqual' | 'arrayNotEmpty' | 'arrayMinLength' | 'arrayMaxLength' | 'inEnum';
2042
+ /**
2043
+ * Configuration for the rule generator
2044
+ */
2045
+ interface RuleGeneratorConfig {
2046
+ /** Whether to generate rules for optional fields */
2047
+ includeOptional?: boolean;
2048
+ /** Whether to generate relationship rules */
2049
+ includeRelationships?: boolean;
2050
+ /** Whether to generate format validation rules */
2051
+ includeFormats?: boolean;
2052
+ /** Custom rules to add */
2053
+ customRules?: ValidationRule[];
2054
+ }
2055
+ /**
2056
+ * Demo data for a single model
2057
+ */
2058
+ type ModelData = Record<string, unknown>[];
2059
+ /**
2060
+ * Complete demo data set
2061
+ */
2062
+ type DemoData = Record<string, ModelData>;
2063
+ /**
2064
+ * Options for the validator
2065
+ */
2066
+ interface ValidatorOptions {
2067
+ /** Schema to validate against */
2068
+ schema: DemokitSchema;
2069
+ /** Whether to collect warnings (slower) */
2070
+ collectWarnings?: boolean;
2071
+ /** Whether to stop on first error */
2072
+ failFast?: boolean;
2073
+ /** Maximum errors to collect before stopping */
2074
+ maxErrors?: number;
2075
+ /** Custom validation rules to add */
2076
+ customRules?: ValidationRule[];
2077
+ }
2078
+ /**
2079
+ * Level of data generation
2080
+ */
2081
+ type GenerationLevel = 'schema-valid' | 'relationship-valid' | 'narrative-driven';
2082
+ /**
2083
+ * Options for data generation
2084
+ */
2085
+ interface GenerationOptions {
2086
+ /** Level of generation */
2087
+ level: GenerationLevel;
2088
+ /** Number of records per model */
2089
+ counts?: Record<string, number>;
2090
+ /** Base timestamp for reproducible data */
2091
+ baseTimestamp?: number;
2092
+ /** Seed for random generation - different seed produces different data */
2093
+ seed?: number;
2094
+ /** Output format */
2095
+ format?: 'typescript' | 'json';
2096
+ /** Whether to include validation */
2097
+ validate?: boolean;
2098
+ /** Custom generation rules from project settings */
2099
+ customRules?: GenerationRulesConfig;
2100
+ }
2101
+ /**
2102
+ * Configuration for custom field generation rules
2103
+ * Stored in projects.settings.generationRules
2104
+ */
2105
+ interface GenerationRulesConfig {
2106
+ /** Schema version for migration support */
2107
+ version: 1;
2108
+ /** Per-field rules, keyed by "ModelName.fieldName" */
2109
+ fieldRules: Record<string, FieldRule>;
2110
+ /** Uploaded datasets for correlated value generation, keyed by dataset ID */
2111
+ datasets?: Record<string, Dataset>;
2112
+ }
2113
+ /**
2114
+ * A rule for generating values for a specific field
2115
+ */
2116
+ type FieldRule = StringFieldRule | NumberFieldRule | IntegerFieldRule | BooleanFieldRule | EnumFieldRule | DatasetFieldRule;
2117
+ /**
2118
+ * Rule for generating string field values
2119
+ */
2120
+ interface StringFieldRule {
2121
+ type: 'string';
2122
+ strategy: 'oneOf' | 'pattern';
2123
+ /** For 'oneOf' strategy - pick randomly from this list */
2124
+ values?: string[];
2125
+ /** For 'pattern' strategy - template like "SKU-{0000}" where {0000} is replaced with zero-padded number */
2126
+ pattern?: string;
2127
+ }
2128
+ /**
2129
+ * Rule for generating number field values
2130
+ */
2131
+ interface NumberFieldRule {
2132
+ type: 'number';
2133
+ strategy: 'range' | 'fixed';
2134
+ /** For 'range' strategy */
2135
+ min?: number;
2136
+ max?: number;
2137
+ /** Number of decimal places (default: 2) */
2138
+ precision?: number;
2139
+ /** For 'fixed' strategy - always use this value */
2140
+ value?: number;
2141
+ }
2142
+ /**
2143
+ * Rule for generating integer field values
2144
+ */
2145
+ interface IntegerFieldRule {
2146
+ type: 'integer';
2147
+ strategy: 'range' | 'fixed';
2148
+ min?: number;
2149
+ max?: number;
2150
+ value?: number;
2151
+ }
2152
+ /**
2153
+ * Rule for generating boolean field values
2154
+ */
2155
+ interface BooleanFieldRule {
2156
+ type: 'boolean';
2157
+ strategy: 'fixed' | 'weighted';
2158
+ /** For 'fixed' strategy - always this value */
2159
+ value?: boolean;
2160
+ /** For 'weighted' strategy - probability of true (0-1) */
2161
+ trueProbability?: number;
2162
+ }
2163
+ /**
2164
+ * Rule for generating enum field values
2165
+ */
2166
+ interface EnumFieldRule {
2167
+ type: 'enum';
2168
+ strategy: 'subset' | 'weighted';
2169
+ /** For 'subset' strategy - only use these values */
2170
+ allowedValues?: string[];
2171
+ /** For 'weighted' strategy - value -> weight mapping */
2172
+ weights?: Record<string, number>;
2173
+ }
2174
+ /**
2175
+ * Rule for generating values from a linked dataset column
2176
+ * Enables row-based correlation - multiple fields linked to the same dataset
2177
+ * will use values from the same row within a record
2178
+ */
2179
+ interface DatasetFieldRule {
2180
+ type: 'fromDataset';
2181
+ /** ID of the dataset to pull values from */
2182
+ datasetId: string;
2183
+ /** Column name to use for this field's values */
2184
+ column: string;
2185
+ }
2186
+ /**
2187
+ * A dataset containing rows of correlated values
2188
+ * Limited to ~1000 rows for in-memory storage in project settings
2189
+ */
2190
+ interface Dataset {
2191
+ /** Unique identifier for the dataset */
2192
+ id: string;
2193
+ /** Human-readable name for display */
2194
+ name: string;
2195
+ /** Column headers from CSV */
2196
+ columns: string[];
2197
+ /** Row data - array of arrays matching column order */
2198
+ rows: string[][];
2199
+ /** When the dataset was created/uploaded */
2200
+ createdAt: string;
2201
+ /** Optional description of the dataset contents */
2202
+ description?: string;
2203
+ }
2204
+ /**
2205
+ * Result of parsing CSV content
2206
+ */
2207
+ interface ParseCSVResult {
2208
+ /** Whether parsing succeeded */
2209
+ success: boolean;
2210
+ /** Column headers (if successful) */
2211
+ columns?: string[];
2212
+ /** Row data (if successful) */
2213
+ rows?: string[][];
2214
+ /** Error message (if failed) */
2215
+ error?: string;
2216
+ /** Whether rows were truncated to meet limit */
2217
+ truncated?: boolean;
2218
+ /** Original row count before truncation */
2219
+ originalRowCount?: number;
2220
+ }
2221
+ /**
2222
+ * Result of data generation
2223
+ */
2224
+ interface GenerationResult {
2225
+ /** The generated data */
2226
+ data: DemoData;
2227
+ /** Generated fixture code (if format is typescript) */
2228
+ fixtures?: string;
2229
+ /** Validation results */
2230
+ validation: ValidationResult;
2231
+ /** Generation metadata */
2232
+ metadata: GenerationMetadata;
2233
+ }
2234
+ /**
2235
+ * Metadata about the generation process
2236
+ */
2237
+ interface GenerationMetadata {
2238
+ /** Generation level used */
2239
+ level: GenerationLevel;
2240
+ /** Timestamp when generated */
2241
+ generatedAt: string;
2242
+ /** Total records generated */
2243
+ totalRecords: number;
2244
+ /** Records per model */
2245
+ recordsByModel: Record<string, number>;
2246
+ /** IDs used in generation */
2247
+ usedIds: Record<string, string[]>;
2248
+ /** Duration of generation in ms */
2249
+ durationMs: number;
2250
+ }
2251
+ /**
2252
+ * Context about the application being demoed
2253
+ */
2254
+ interface AppContext {
2255
+ /** Application name */
2256
+ name: string;
2257
+ /** What the app does */
2258
+ description: string;
2259
+ /** Domain (e-commerce, b2b-saas, etc.) */
2260
+ domain: string;
2261
+ /** Key entities and their purposes */
2262
+ keyEntities: EntityContext[];
2263
+ /** Main features/capabilities */
2264
+ features: string[];
2265
+ }
2266
+ /**
2267
+ * Context about a specific entity
2268
+ */
2269
+ interface EntityContext {
2270
+ /** Entity/model name */
2271
+ name: string;
2272
+ /** What this entity represents */
2273
+ purpose: string;
2274
+ /** Key fields to focus on */
2275
+ keyFields: string[];
2276
+ /** Business rules that apply */
2277
+ businessRules?: string[];
2278
+ }
2279
+ /**
2280
+ * Narrative for generating story-driven data
2281
+ */
2282
+ interface DemoNarrative {
2283
+ /** Overall scenario */
2284
+ scenario: string;
2285
+ /** Key story points to hit */
2286
+ keyPoints: string[];
2287
+ /** Named characters/personas */
2288
+ characters?: Character[];
2289
+ /** Timeline of events */
2290
+ timeline?: TimelineEvent[];
2291
+ /** Metric targets */
2292
+ metrics?: MetricTarget[];
2293
+ }
2294
+ /**
2295
+ * A character/persona in the demo
2296
+ */
2297
+ interface Character {
2298
+ /** Character name */
2299
+ name: string;
2300
+ /** Role (customer, admin, etc.) */
2301
+ role: string;
2302
+ /** Character description */
2303
+ description?: string;
2304
+ }
2305
+ /**
2306
+ * A timeline event in the narrative
2307
+ */
2308
+ interface TimelineEvent {
2309
+ /** When this happens (relative or absolute) */
2310
+ when: string;
2311
+ /** What happens */
2312
+ event: string;
2313
+ /** Which characters are involved */
2314
+ characters?: string[];
2315
+ }
2316
+ /**
2317
+ * A metric target for the narrative
2318
+ */
2319
+ interface MetricTarget {
2320
+ /** Metric name */
2321
+ name: string;
2322
+ /** Target value or description */
2323
+ value?: string;
2324
+ /** Trend (increasing, declining, stable) */
2325
+ trend?: 'increasing' | 'declining' | 'stable';
2326
+ /** Percentage change */
2327
+ amount?: string;
2328
+ }
2329
+
2330
+ /**
2331
+ * Main generator orchestrator for demo data generation
2332
+ *
2333
+ * Supports two levels:
2334
+ * - Level 1 (schema-valid): Generate data that matches types
2335
+ * - Level 2 (relationship-valid): Generate data with valid references
2336
+ */
2337
+
2338
+ /**
2339
+ * Generate demo data from a schema
2340
+ */
2341
+ declare function generateDemoData(schema: DemokitSchema, options?: GenerationOptions): GenerationResult;
2342
+
2343
+ /**
2344
+ * ID generation utilities for demo data
2345
+ *
2346
+ * Generates consistent, deterministic IDs for reproducible fixtures.
2347
+ */
2348
+ /**
2349
+ * Generate a UUID v4 (random)
2350
+ * Uses a simple implementation for portability
2351
+ */
2352
+ declare function generateUUID(): string;
2353
+ /**
2354
+ * Generate a deterministic UUID from a seed
2355
+ * Useful for reproducible fixtures
2356
+ */
2357
+ declare function generateSeededUUID(seed: number): string;
2358
+ /**
2359
+ * Generate a model-specific ID
2360
+ * Format: {prefix}_{index} or UUID based on format hint
2361
+ */
2362
+ declare function generateIdForModel(modelName: string, index: number, format?: string): string;
2363
+ /**
2364
+ * Generate an ID based on a property definition
2365
+ */
2366
+ declare function generateId(format?: string, index?: number): string;
2367
+ /**
2368
+ * Generate a prefixed ID
2369
+ * @example generatePrefixedId('user', 1) => 'user_001'
2370
+ */
2371
+ declare function generatePrefixedId(prefix: string, index: number): string;
2372
+ /**
2373
+ * Generate a CUID-like ID
2374
+ * Format: c + timestamp + random
2375
+ */
2376
+ declare function generateCuid(): string;
2377
+ /**
2378
+ * Generate a ULID-like ID
2379
+ * Format: timestamp (10 chars) + random (16 chars)
2380
+ */
2381
+ declare function generateUlid(): string;
2382
+
2383
+ interface GeneratedAddress {
2384
+ line1: string;
2385
+ line2?: string;
2386
+ city: string;
2387
+ state: string;
2388
+ stateFull: string;
2389
+ country: string;
2390
+ countryCode: string;
2391
+ postalCode: string;
2392
+ formatted: string;
2393
+ }
2394
+
2395
+ /**
2396
+ * Value generators for different property types
2397
+ *
2398
+ * Generates realistic demo data based on property type, format, and constraints.
2399
+ */
2400
+
2401
+ /**
2402
+ * Context for generating correlated values within a single record.
2403
+ * This allows related fields (like city, state, zip) to be consistent,
2404
+ * and ensures fields linked to the same dataset use the same row.
2405
+ */
2406
+ interface RecordContext {
2407
+ /** Pre-generated correlated address for this record */
2408
+ address?: GeneratedAddress;
2409
+ /** Country code preference (US, CA, GB, AU, DE) */
2410
+ countryCode?: string;
2411
+ /**
2412
+ * Pre-selected row indices for each dataset (Phase 2).
2413
+ * Key is dataset ID, value is the row index to use.
2414
+ * This ensures multiple fields linked to the same dataset use the same row.
2415
+ */
2416
+ datasetRowIndices?: Map<string, number>;
2417
+ }
2418
+ /**
2419
+ * Generate a value for a property definition
2420
+ *
2421
+ * @param propDef - The property definition from the schema
2422
+ * @param index - The record index (0-based)
2423
+ * @param baseTimestamp - Optional base timestamp for date generation
2424
+ * @param seed - Random seed for deterministic generation
2425
+ * @param recordContext - Optional context for correlated field generation
2426
+ * @param customRule - Optional custom generation rule for this field
2427
+ * @param datasets - Optional datasets for fromDataset rules (Phase 2)
2428
+ */
2429
+ declare function generateValue(propDef: PropertyDef, index: number, baseTimestamp?: number, seed?: number, recordContext?: RecordContext, customRule?: FieldRule, datasets?: Record<string, Dataset>): unknown;
2430
+
2431
+ /**
2432
+ * CSV Parser for Linked Datasets
2433
+ *
2434
+ * Parses CSV content into structured data for use in generation rules.
2435
+ * Supports:
2436
+ * - Quoted fields with commas and newlines
2437
+ * - Header row detection
2438
+ * - Row limit enforcement (1000 rows max)
2439
+ * - Validation of consistent column counts
2440
+ */
2441
+
2442
+ /**
2443
+ * Parse CSV content into columns and rows
2444
+ *
2445
+ * @param content - Raw CSV content as a string
2446
+ * @returns ParseCSVResult with columns, rows, or error
2447
+ */
2448
+ declare function parseCSV(content: string): ParseCSVResult;
2449
+ /**
2450
+ * Generate a unique dataset ID
2451
+ */
2452
+ declare function generateDatasetId(): string;
2453
+ /**
2454
+ * Validate that a dataset name is valid
2455
+ */
2456
+ declare function validateDatasetName(name: string): string | null;
2457
+
2458
+ /**
2459
+ * App Context Inference
2460
+ *
2461
+ * Analyzes a DemokitSchema to infer what the application does,
2462
+ * its domain, key entities, and features. This provides context
2463
+ * for narrative-driven data generation.
2464
+ *
2465
+ * The inference process works in several stages:
2466
+ * 1. Domain detection - What type of application is this?
2467
+ * 2. Entity analysis - What are the key data objects?
2468
+ * 3. Feature inference - What can users do with the app?
2469
+ * 4. Business rule extraction - What constraints apply?
2470
+ *
2471
+ * @example
2472
+ * ```typescript
2473
+ * const schema = await importFromOpenAPI('api.yaml')
2474
+ * const context = inferAppContext(schema)
2475
+ * // context.domain === 'e-commerce'
2476
+ * // context.keyEntities includes Product, Order, Customer
2477
+ * ```
2478
+ */
2479
+
2480
+ /**
2481
+ * Infer application context from a schema.
2482
+ *
2483
+ * This is the main entry point for context inference. It analyzes the schema
2484
+ * structure to understand what the application does and how its data relates.
2485
+ *
2486
+ * @param schema - The parsed DemokitSchema from an OpenAPI spec
2487
+ * @returns AppContext with inferred domain, entities, and features
2488
+ *
2489
+ * @example
2490
+ * ```typescript
2491
+ * const context = inferAppContext(schema)
2492
+ * console.log(context.domain) // 'e-commerce'
2493
+ * console.log(context.keyEntities.length) // 5
2494
+ * ```
2495
+ */
2496
+ declare function inferAppContext(schema: DemokitSchema): AppContext;
2497
+ /**
2498
+ * Create a custom app context with explicit values.
2499
+ *
2500
+ * Use this when the user wants to provide their own context rather than
2501
+ * relying on inference. Useful for demos where the inferred context
2502
+ * doesn't match the intended story.
2503
+ *
2504
+ * @param name - Application name
2505
+ * @param description - What the app does
2506
+ * @param domain - Application domain
2507
+ * @param entities - Key entities with their purposes
2508
+ * @param features - Main features/capabilities
2509
+ * @returns Complete AppContext object
2510
+ *
2511
+ * @example
2512
+ * ```typescript
2513
+ * const context = createAppContext(
2514
+ * 'ShopFlow',
2515
+ * 'Enterprise e-commerce platform',
2516
+ * 'e-commerce',
2517
+ * [{ name: 'Product', purpose: 'Items for sale', keyFields: ['id', 'price'] }],
2518
+ * ['Checkout', 'Inventory Management']
2519
+ * )
2520
+ * ```
2521
+ */
2522
+ declare function createAppContext(name: string, description: string, domain: string, entities: EntityContext[], features: string[]): AppContext;
2523
+ /**
2524
+ * Merge inferred context with user-provided overrides.
2525
+ *
2526
+ * Allows users to customize specific parts of the inferred context
2527
+ * while keeping the rest. Useful for fine-tuning without starting
2528
+ * from scratch.
2529
+ *
2530
+ * @param inferred - The automatically inferred context
2531
+ * @param overrides - User-provided values to override
2532
+ * @returns Merged context with overrides taking precedence
2533
+ *
2534
+ * @example
2535
+ * ```typescript
2536
+ * const inferred = inferAppContext(schema)
2537
+ * const custom = mergeAppContext(inferred, {
2538
+ * name: 'My Custom App Name',
2539
+ * domain: 'b2b-saas', // Override the detected domain
2540
+ * })
2541
+ * ```
2542
+ */
2543
+ declare function mergeAppContext(inferred: AppContext, overrides: Partial<AppContext>): AppContext;
2544
+
2545
+ /**
2546
+ * Output Formatters
2547
+ *
2548
+ * Convert generated demo data into various output formats for different use cases:
2549
+ *
2550
+ * - **TypeScript**: Type-safe fixture files with const assertions
2551
+ * - **JSON**: Standard data interchange format with optional metadata
2552
+ * - **SQL**: INSERT statements for database seeding
2553
+ * - **CSV**: Spreadsheet-compatible format for individual models
2554
+ *
2555
+ * Each formatter handles:
2556
+ * - Proper escaping for the target format
2557
+ * - Optional headers/metadata
2558
+ * - Null and special value handling
2559
+ * - Nested objects and arrays
2560
+ *
2561
+ * @example
2562
+ * ```typescript
2563
+ * // Generate TypeScript fixtures
2564
+ * const tsCode = formatAsTypeScript(data, { asConst: true })
2565
+ *
2566
+ * // Generate JSON with metadata
2567
+ * const json = formatAsJSON(data, { includeMetadata: true })
2568
+ *
2569
+ * // Generate SQL INSERT statements
2570
+ * const sql = formatAsSQL(data, { tableName: name => `tbl_${name}` })
2571
+ *
2572
+ * // Generate CSV for a specific model
2573
+ * const csv = formatAsCSV(data, 'Customer')
2574
+ * ```
2575
+ *
2576
+ * @module
2577
+ */
2578
+
2579
+ /**
2580
+ * Output format options for TypeScript generation
2581
+ *
2582
+ * Controls the generated TypeScript code structure and styling.
2583
+ *
2584
+ * @example
2585
+ * ```typescript
2586
+ * const options: OutputOptions = {
2587
+ * asConst: true, // Add 'as const' for type safety
2588
+ * indent: 2, // 2-space indentation
2589
+ * includeHeader: true, // Add generation comment
2590
+ * narrative: myNarrative, // Include narrative in header
2591
+ * }
2592
+ * ```
2593
+ */
2594
+ interface OutputOptions {
2595
+ /** Whether to include TypeScript 'as const' assertions. Defaults to true. */
2596
+ asConst?: boolean;
2597
+ /** Whether to include type annotations (future use). */
2598
+ includeTypes?: boolean;
2599
+ /** Indentation in spaces. Defaults to 2. */
2600
+ indent?: number;
2601
+ /** Whether to add a comment header with generation info. Defaults to true. */
2602
+ includeHeader?: boolean;
2603
+ /** Narrative for header comments (scenario, key points). */
2604
+ narrative?: DemoNarrative;
2605
+ }
2606
+ /**
2607
+ * Format demo data as TypeScript code
2608
+ *
2609
+ * Generates a TypeScript module with:
2610
+ * - Header comment with generation timestamp
2611
+ * - Optional narrative info (scenario, key points)
2612
+ * - Individual exports per model (DEMO_USER, DEMO_ORDER, etc.)
2613
+ * - Combined DEMO_DATA export with all models
2614
+ * - 'as const' assertions for full type inference
2615
+ *
2616
+ * Model names are converted to CONSTANT_CASE for variable names.
2617
+ *
2618
+ * @param data - Demo data object (model names → record arrays)
2619
+ * @param options - Formatting options (asConst, indent, header, narrative)
2620
+ * @returns TypeScript source code as string
2621
+ *
2622
+ * @example
2623
+ * ```typescript
2624
+ * const data = {
2625
+ * User: [{ id: '1', name: 'Alice' }],
2626
+ * Order: [{ id: '1', userId: '1', total: 100 }],
2627
+ * }
2628
+ *
2629
+ * const code = formatAsTypeScript(data, {
2630
+ * asConst: true,
2631
+ * narrative: { scenario: 'Demo', keyPoints: ['Show users'] },
2632
+ * })
2633
+ *
2634
+ * // Output:
2635
+ * // /**
2636
+ * // * Auto-generated demo fixtures
2637
+ * // * Scenario: Demo
2638
+ * // * Key points:
2639
+ * // * - Show users
2640
+ * // *‍/
2641
+ * // export const DEMO_USER = [...] as const
2642
+ * // export const DEMO_ORDER = [...] as const
2643
+ * // export const DEMO_DATA = { User: DEMO_USER, Order: DEMO_ORDER } as const
2644
+ * ```
2645
+ */
2646
+ declare function formatAsTypeScript(data: DemoData, options?: OutputOptions): string;
2647
+ /**
2648
+ * Format demo data as JSON
2649
+ *
2650
+ * Generates standard JSON output with optional metadata wrapper.
2651
+ *
2652
+ * Without metadata:
2653
+ * ```json
2654
+ * { "User": [...], "Order": [...] }
2655
+ * ```
2656
+ *
2657
+ * With metadata:
2658
+ * ```json
2659
+ * {
2660
+ * "_metadata": { "generatedAt": "...", "modelCount": 2, "recordCount": 10 },
2661
+ * "data": { "User": [...], "Order": [...] }
2662
+ * }
2663
+ * ```
2664
+ *
2665
+ * @param data - Demo data object (model names → record arrays)
2666
+ * @param options - Formatting options (indent, includeMetadata)
2667
+ * @returns JSON string
2668
+ *
2669
+ * @example
2670
+ * ```typescript
2671
+ * // Simple JSON output
2672
+ * const json = formatAsJSON(data)
2673
+ *
2674
+ * // JSON with metadata
2675
+ * const jsonWithMeta = formatAsJSON(data, { includeMetadata: true })
2676
+ * ```
2677
+ */
2678
+ declare function formatAsJSON(data: DemoData, options?: {
2679
+ indent?: number;
2680
+ includeMetadata?: boolean;
2681
+ }): string;
2682
+ /**
2683
+ * Format demo data as SQL INSERT statements
2684
+ *
2685
+ * Generates INSERT statements for database seeding. Handles:
2686
+ * - Automatic table name conversion (snake_case by default)
2687
+ * - Proper value escaping (strings, nulls, numbers, booleans)
2688
+ * - JSON serialization for arrays and objects
2689
+ * - Comment headers with record counts
2690
+ *
2691
+ * @param data - Demo data object (model names → record arrays)
2692
+ * @param options - Formatting options (tableName function)
2693
+ * @returns SQL INSERT statements as string
2694
+ *
2695
+ * @example
2696
+ * ```typescript
2697
+ * const sql = formatAsSQL(data)
2698
+ * // Output:
2699
+ * // -- Auto-generated demo data
2700
+ * // -- User (5 records)
2701
+ * // INSERT INTO user (id, name, email) VALUES ('1', 'Alice', 'alice@example.com');
2702
+ *
2703
+ * // Custom table names
2704
+ * const sql = formatAsSQL(data, {
2705
+ * tableName: name => `demo_${name.toLowerCase()}`
2706
+ * })
2707
+ * ```
2708
+ */
2709
+ declare function formatAsSQL(data: DemoData, options?: {
2710
+ tableName?: (modelName: string) => string;
2711
+ }): string;
2712
+ /**
2713
+ * Format demo data as CSV (one model at a time)
2714
+ *
2715
+ * Generates RFC 4180-compliant CSV with:
2716
+ * - Header row with all column names
2717
+ * - Proper escaping (commas, quotes, newlines)
2718
+ * - Unified columns from all records (handles sparse data)
2719
+ * - JSON serialization for complex values
2720
+ *
2721
+ * Note: CSV format only supports a single model at a time.
2722
+ * For multiple models, call this function once per model.
2723
+ *
2724
+ * @param data - Demo data object (model names → record arrays)
2725
+ * @param modelName - Name of the model to export
2726
+ * @returns CSV string (empty string if model not found or empty)
2727
+ *
2728
+ * @example
2729
+ * ```typescript
2730
+ * const userCsv = formatAsCSV(data, 'User')
2731
+ * // Output:
2732
+ * // id,name,email
2733
+ * // 1,Alice,alice@example.com
2734
+ * // 2,Bob,bob@example.com
2735
+ *
2736
+ * // Export each model to separate files
2737
+ * for (const model of Object.keys(data)) {
2738
+ * const csv = formatAsCSV(data, model)
2739
+ * writeFileSync(`${model}.csv`, csv)
2740
+ * }
2741
+ * ```
2742
+ */
2743
+ declare function formatAsCSV(data: DemoData, modelName: string): string;
2744
+
2745
+ /**
2746
+ * Main validator for demo data
2747
+ *
2748
+ * Validates data against a DemokitSchema, checking:
2749
+ * - Type correctness
2750
+ * - Format validity
2751
+ * - Referential integrity
2752
+ * - Custom constraints
2753
+ */
2754
+
2755
+ /**
2756
+ * Validate demo data against a schema
2757
+ */
2758
+ declare function validateData(data: DemoData, options: ValidatorOptions): ValidationResult;
2759
+ /**
2760
+ * Validate timestamp ordering (e.g., createdAt <= updatedAt)
2761
+ */
2762
+ declare function validateTimestampOrder(data: DemoData, rules: Array<{
2763
+ model: string;
2764
+ before: string;
2765
+ after: string;
2766
+ }>): ValidationError[];
2767
+
2768
+ /**
2769
+ * Validation rule generation from DemokitSchema
2770
+ *
2771
+ * Automatically generates validation rules based on:
2772
+ * - Property types and formats
2773
+ * - Required fields
2774
+ * - Constraints (min/max, patterns)
2775
+ * - Relationships
2776
+ */
2777
+
2778
+ /**
2779
+ * Generate all validation rules from a schema
2780
+ */
2781
+ declare function generateRulesFromSchema(schema: DemokitSchema, config?: RuleGeneratorConfig): ValidationRule[];
2782
+ /**
2783
+ * Get a human-readable description of a rule
2784
+ */
2785
+ declare function describeRule(rule: ValidationRule): string;
2786
+ /**
2787
+ * Group rules by model for easier inspection
2788
+ */
2789
+ declare function groupRulesByModel(rules: ValidationRule[]): Record<string, ValidationRule[]>;
2790
+ /**
2791
+ * Filter rules to get only relationship rules
2792
+ */
2793
+ declare function getRelationshipRules(rules: ValidationRule[]): ValidationRule[];
2794
+ /**
2795
+ * Filter rules to get only required field rules
2796
+ */
2797
+ declare function getRequiredFieldRules(rules: ValidationRule[]): ValidationRule[];
2798
+
2799
+ /**
2800
+ * Individual validation check functions
2801
+ *
2802
+ * Each function returns true if the value passes the check.
2803
+ */
2804
+ /**
2805
+ * Check if value is a string
2806
+ */
2807
+ declare function isString(value: unknown): boolean;
2808
+ /**
2809
+ * Check if value is a number (not NaN)
2810
+ */
2811
+ declare function isNumber(value: unknown): boolean;
2812
+ /**
2813
+ * Check if value is an integer
2814
+ */
2815
+ declare function isInteger(value: unknown): boolean;
2816
+ /**
2817
+ * Check if value is a boolean
2818
+ */
2819
+ declare function isBoolean(value: unknown): boolean;
2820
+ /**
2821
+ * Check if value is an array
2822
+ */
2823
+ declare function isArray(value: unknown): boolean;
2824
+ /**
2825
+ * Check if value is a plain object
2826
+ */
2827
+ declare function isObject(value: unknown): boolean;
2828
+ /**
2829
+ * Check if value is null
2830
+ */
2831
+ declare function isNull(value: unknown): boolean;
2832
+ /**
2833
+ * Check if value is undefined
2834
+ */
2835
+ declare function isUndefined(value: unknown): boolean;
2836
+ /**
2837
+ * Check if value is null or undefined
2838
+ */
2839
+ declare function isNullish(value: unknown): boolean;
2840
+ /**
2841
+ * Check if value is a valid UUID
2842
+ */
2843
+ declare function isUUID(value: unknown, strict?: boolean): boolean;
2844
+ /**
2845
+ * Check if value is a valid email format
2846
+ */
2847
+ declare function isEmail(value: unknown): boolean;
2848
+ /**
2849
+ * Check if value is a valid URL
2850
+ */
2851
+ declare function isURL(value: unknown): boolean;
2852
+ /**
2853
+ * Check if value is a valid ISO 8601 date (YYYY-MM-DD)
2854
+ */
2855
+ declare function isDate(value: unknown): boolean;
2856
+ /**
2857
+ * Check if value is a valid ISO 8601 datetime
2858
+ */
2859
+ declare function isDateTime(value: unknown): boolean;
2860
+ /**
2861
+ * Alias for isDateTime - checks ISO 8601 format
2862
+ */
2863
+ declare function isISO8601(value: unknown): boolean;
2864
+ /**
2865
+ * Check if string length is at least minLength
2866
+ */
2867
+ declare function hasMinLength(value: unknown, minLength: number): boolean;
2868
+ /**
2869
+ * Check if string length is at most maxLength
2870
+ */
2871
+ declare function hasMaxLength(value: unknown, maxLength: number): boolean;
2872
+ /**
2873
+ * Check if number is at least minimum
2874
+ */
2875
+ declare function hasMinimum(value: unknown, minimum: number): boolean;
2876
+ /**
2877
+ * Check if number is at most maximum
2878
+ */
2879
+ declare function hasMaximum(value: unknown, maximum: number): boolean;
2880
+ /**
2881
+ * Check if string matches a regex pattern
2882
+ */
2883
+ declare function matchesPattern(value: unknown, pattern: string | RegExp): boolean;
2884
+ /**
2885
+ * Check if value is in an enum array
2886
+ */
2887
+ declare function isInEnum(value: unknown, enumValues: unknown[]): boolean;
2888
+ /**
2889
+ * Check if two values are equal
2890
+ */
2891
+ declare function equals(value: unknown, expected: unknown): boolean;
2892
+ /**
2893
+ * Check if a date/datetime is before or equal to another
2894
+ */
2895
+ declare function isBeforeOrEqual(value: unknown, other: unknown): boolean;
2896
+ /**
2897
+ * Check if a date/datetime is after or equal to another
2898
+ */
2899
+ declare function isAfterOrEqual(value: unknown, other: unknown): boolean;
2900
+ /**
2901
+ * Check if array is not empty
2902
+ */
2903
+ declare function isArrayNotEmpty(value: unknown): boolean;
2904
+ /**
2905
+ * Check if array has at least minLength items
2906
+ */
2907
+ declare function hasArrayMinLength(value: unknown, minLength: number): boolean;
2908
+ /**
2909
+ * Check if array has at most maxLength items
2910
+ */
2911
+ declare function hasArrayMaxLength(value: unknown, maxLength: number): boolean;
2912
+ /**
2913
+ * Check if a string is empty or only whitespace
2914
+ */
2915
+ declare function isEmptyString(value: unknown): boolean;
2916
+ /**
2917
+ * Get the type name of a value (for error messages)
2918
+ */
2919
+ declare function getTypeName(value: unknown): string;
2920
+
2921
+ declare const checks_equals: typeof equals;
2922
+ declare const checks_getTypeName: typeof getTypeName;
2923
+ declare const checks_hasArrayMaxLength: typeof hasArrayMaxLength;
2924
+ declare const checks_hasArrayMinLength: typeof hasArrayMinLength;
2925
+ declare const checks_hasMaxLength: typeof hasMaxLength;
2926
+ declare const checks_hasMaximum: typeof hasMaximum;
2927
+ declare const checks_hasMinLength: typeof hasMinLength;
2928
+ declare const checks_hasMinimum: typeof hasMinimum;
2929
+ declare const checks_isAfterOrEqual: typeof isAfterOrEqual;
2930
+ declare const checks_isArray: typeof isArray;
2931
+ declare const checks_isArrayNotEmpty: typeof isArrayNotEmpty;
2932
+ declare const checks_isBeforeOrEqual: typeof isBeforeOrEqual;
2933
+ declare const checks_isBoolean: typeof isBoolean;
2934
+ declare const checks_isDate: typeof isDate;
2935
+ declare const checks_isDateTime: typeof isDateTime;
2936
+ declare const checks_isEmail: typeof isEmail;
2937
+ declare const checks_isEmptyString: typeof isEmptyString;
2938
+ declare const checks_isISO8601: typeof isISO8601;
2939
+ declare const checks_isInEnum: typeof isInEnum;
2940
+ declare const checks_isInteger: typeof isInteger;
2941
+ declare const checks_isNull: typeof isNull;
2942
+ declare const checks_isNullish: typeof isNullish;
2943
+ declare const checks_isNumber: typeof isNumber;
2944
+ declare const checks_isObject: typeof isObject;
2945
+ declare const checks_isString: typeof isString;
2946
+ declare const checks_isURL: typeof isURL;
2947
+ declare const checks_isUUID: typeof isUUID;
2948
+ declare const checks_isUndefined: typeof isUndefined;
2949
+ declare const checks_matchesPattern: typeof matchesPattern;
2950
+ declare namespace checks {
2951
+ export { checks_equals as equals, checks_getTypeName as getTypeName, checks_hasArrayMaxLength as hasArrayMaxLength, checks_hasArrayMinLength as hasArrayMinLength, checks_hasMaxLength as hasMaxLength, checks_hasMaximum as hasMaximum, checks_hasMinLength as hasMinLength, checks_hasMinimum as hasMinimum, checks_isAfterOrEqual as isAfterOrEqual, checks_isArray as isArray, checks_isArrayNotEmpty as isArrayNotEmpty, checks_isBeforeOrEqual as isBeforeOrEqual, checks_isBoolean as isBoolean, checks_isDate as isDate, checks_isDateTime as isDateTime, checks_isEmail as isEmail, checks_isEmptyString as isEmptyString, checks_isISO8601 as isISO8601, checks_isInEnum as isInEnum, checks_isInteger as isInteger, checks_isNull as isNull, checks_isNullish as isNullish, checks_isNumber as isNumber, checks_isObject as isObject, checks_isString as isString, checks_isURL as isURL, checks_isUUID as isUUID, checks_isUndefined as isUndefined, checks_matchesPattern as matchesPattern };
2952
+ }
2953
+
2954
+ export { type AppContext, type BooleanFieldRule, type Character, type CloudFixtureResponse, type CodebaseFile, DEFAULT_API_URL, DEFAULT_CLOUD_URL, DEFAULT_MAX_RETRIES, DEFAULT_STORAGE_KEY, DEFAULT_TIMEOUT, type DataModel, type Dataset, type DatasetFieldRule, type DemoData, type DemoInterceptor, type DemoKitConfig, type DemoKitRemoteConfig, type DemoNarrative, type DemoState, type DemoStateStore, type DemoStateStoreOptions, type DemokitSchema, type DetectionConfig, type Endpoint, type EndpointMapping, type EntityContext, type EnumFieldRule, FORMAT_PATTERNS, FORMAT_PRIORITY, type FieldRule, FileParseError, type FixtureHandler, type FixtureMap, FormatDetectionError, type FormatDetectionPatterns, type FormatDetectionResult, type GenerationLevel, type GenerationMetadata, type GenerationOptions, type GenerationResult, type GenerationRulesConfig, type HttpMethod, type IntegerFieldRule, type MatchResult, type MergeConflict, type MergeOptions, type MergeResult, type MetricTarget, type ModelData, type ModelSourceMap, type ModelType, type MutationInterceptedContext, type NumberFieldRule, type OutputOptions, type ParameterDef, type ParseCSVResult, type ParseOptions, type ParseResult, type ParseSchemaOptions, type ParseWarning, type ParsedPattern, type PropertyDef, type PropertyDiff, type PropertyType, type QueryKey, type QueryKeyElement, type QueryKeyMatchResult, type Relationship, type RelationshipDetectionMethod, type RelationshipSide, type RelationshipTarget, type RelationshipType, type RemoteConfig, RemoteFetchError, type RemoteLoadingState, type RequestBody, type RequestContext, type ResponseDef, type RuleGeneratorConfig, type SafeResult, type SchemaDiff, type SchemaDiffItem, type SchemaFormat, type SchemaInfo, SchemaMergeError, SchemaParseError, type SchemaRef, type SchemaSource, SchemaValidationError, type SessionState, type StringFieldRule, type TimelineEvent, type ValidationCheck, type ValidationError, type ValidationErrorType, type ValidationResult, type ValidationRule, type ValidationStats, type ValidationWarning, type ValidationWarningType, type ValidatorOptions, aggregateWarnings, buildFixtureMap, checks, clearDemoState, clearPatternCache, createAppContext, createDemoInterceptor, createDemoState, createDemoStateStore, createHandlerForMapping, createRemoteFixtures, createSessionState, describeRule, detectFormat, detectFormatFromFiles, detectRelationshipFromExtension, detectRelationshipFromNaming, detectRelationshipFromRef, detectRelationships, diffSchemas, errorToWarning, extractRefName, fetchCloudFixtures, findMatchingPattern, findMatchingQueryKeyPattern, formatAsCSV, formatAsJSON, formatAsSQL, formatAsTypeScript, generateCuid, generateDatasetId, generateDemoData, generateId, generateIdForModel, generatePrefixedId, generateRulesFromSchema, generateSeededUUID, generateUUID, generateUlid, generateValue, getModelDependencyOrder, getRelationshipRules, getRelationshipsForModel, getRequiredFieldRules, groupFilesByFormat, groupRulesByModel, inferAppContext, isModelReferenced, isRecoverableError, isSchemaRef, isValidApiKey, loadDemoState, matchQueryKey, matchUrl, mergeAppContext, mergeFixtures, mergeSchemas, parseCSV, parseDrizzle, parseGraphQL, parseNextJS, parseOpenAPIFromObject, parseOpenAPIFromPath, parseOpenAPIFromString, parsePrisma, parseSchema, parseSchemaMultiFormat, parseSupabase, parseTRPC, parseTypeScript, parseUrlPattern, parseZod, safeExecute, safeProcessMany, saveDemoState, validateData, validateDatasetName, validateTimestampOrder };