@demokit-ai/schema 0.0.1 → 0.0.2

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.cjs CHANGED
@@ -1,10 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var SwaggerParser = require('@apidevtools/swagger-parser');
4
-
5
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
-
7
- var SwaggerParser__default = /*#__PURE__*/_interopDefault(SwaggerParser);
3
+ var openapiParser = require('@scalar/openapi-parser');
8
4
 
9
5
  // src/parser.ts
10
6
 
@@ -157,47 +153,52 @@ function getModelDependencyOrder(models, relationships) {
157
153
 
158
154
  // src/parser.ts
159
155
  async function parseOpenAPIFromPath(pathOrUrl, options = {}) {
160
- const { dereference = true } = options;
161
- let api;
162
- if (dereference) {
163
- api = await SwaggerParser__default.default.dereference(pathOrUrl);
164
- } else {
165
- api = await SwaggerParser__default.default.parse(pathOrUrl);
156
+ const response = await fetch(pathOrUrl);
157
+ if (!response.ok) {
158
+ throw new Error(`Failed to fetch OpenAPI spec from ${pathOrUrl}: ${response.statusText}`);
166
159
  }
167
- return parseOpenAPIDocument(api, options);
160
+ const content = await response.text();
161
+ return parseOpenAPIFromString(content, options);
168
162
  }
169
163
  async function parseOpenAPIFromString(spec, options = {}) {
170
- const { dereference = true } = options;
171
- let parsed;
172
- try {
173
- parsed = JSON.parse(spec);
174
- } catch {
175
- const api2 = await SwaggerParser__default.default.parse(spec);
176
- if (dereference) {
177
- return parseOpenAPIDocument(
178
- await SwaggerParser__default.default.dereference(api2),
179
- options
180
- );
181
- }
182
- return parseOpenAPIDocument(api2, options);
164
+ const { dereference: shouldDereference = true } = options;
165
+ const validationResult = await openapiParser.validate(spec);
166
+ if (!validationResult.valid) {
167
+ const errorMessages = validationResult.errors?.map((e) => e.message).join(", ") || "Unknown validation error";
168
+ throw new Error(`Invalid OpenAPI specification: ${errorMessages}`);
183
169
  }
184
- let api;
185
- if (dereference) {
186
- api = await SwaggerParser__default.default.dereference(parsed);
170
+ let schema;
171
+ if (shouldDereference) {
172
+ const derefResult = await openapiParser.dereference(spec);
173
+ if (derefResult.errors && derefResult.errors.length > 0) {
174
+ const errorMessages = derefResult.errors.map((e) => e.message).join(", ");
175
+ throw new Error(`Failed to dereference OpenAPI spec: ${errorMessages}`);
176
+ }
177
+ schema = derefResult.schema;
187
178
  } else {
188
- api = await SwaggerParser__default.default.validate(parsed);
179
+ schema = validationResult.specification;
189
180
  }
190
- return parseOpenAPIDocument(api, options);
181
+ return parseOpenAPIDocument(schema, options);
191
182
  }
192
183
  async function parseOpenAPIFromObject(spec, options = {}) {
193
- const { dereference = true } = options;
194
- let api;
195
- if (dereference) {
196
- api = await SwaggerParser__default.default.dereference(spec);
184
+ const { dereference: shouldDereference = true } = options;
185
+ const validationResult = await openapiParser.validate(spec);
186
+ if (!validationResult.valid) {
187
+ const errorMessages = validationResult.errors?.map((e) => e.message).join(", ") || "Unknown validation error";
188
+ throw new Error(`Invalid OpenAPI specification: ${errorMessages}`);
189
+ }
190
+ let schema;
191
+ if (shouldDereference) {
192
+ const derefResult = await openapiParser.dereference(spec);
193
+ if (derefResult.errors && derefResult.errors.length > 0) {
194
+ const errorMessages = derefResult.errors.map((e) => e.message).join(", ");
195
+ throw new Error(`Failed to dereference OpenAPI spec: ${errorMessages}`);
196
+ }
197
+ schema = derefResult.schema;
197
198
  } else {
198
- api = await SwaggerParser__default.default.validate(spec);
199
+ schema = validationResult.specification;
199
200
  }
200
- return parseOpenAPIDocument(api, options);
201
+ return parseOpenAPIDocument(schema, options);
201
202
  }
202
203
  function parseOpenAPIDocument(doc, options = {}) {
203
204
  const { detectRelationships: shouldDetect = true } = options;
@@ -213,24 +214,27 @@ function parseOpenAPIDocument(doc, options = {}) {
213
214
  };
214
215
  }
215
216
  function parseInfo(doc) {
217
+ const docInfo = doc.info || {};
216
218
  const info = {
217
- title: doc.info?.title ?? "Untitled API",
218
- version: doc.info?.version ?? "1.0.0",
219
- description: doc.info?.description
219
+ title: docInfo.title ?? "Untitled API",
220
+ version: docInfo.version ?? "1.0.0",
221
+ description: docInfo.description
220
222
  };
221
- if (doc.servers && doc.servers.length > 0 && doc.servers[0]) {
222
- info.baseUrl = doc.servers[0].url;
223
+ const servers = doc.servers;
224
+ if (servers && servers.length > 0 && servers[0]) {
225
+ info.baseUrl = servers[0].url;
223
226
  }
224
227
  return info;
225
228
  }
226
229
  function parseModels(doc) {
227
230
  const models = {};
228
- const schemas = doc.components?.schemas;
231
+ const components = doc.components;
232
+ const schemas = components?.schemas;
229
233
  if (!schemas) {
230
234
  return models;
231
235
  }
232
236
  for (const [name, schema] of Object.entries(schemas)) {
233
- if ("$ref" in schema) {
237
+ if (schema && typeof schema === "object" && "$ref" in schema) {
234
238
  continue;
235
239
  }
236
240
  models[name] = parseSchemaToModel(name, schema);
@@ -238,17 +242,21 @@ function parseModels(doc) {
238
242
  return models;
239
243
  }
240
244
  function parseSchemaToModel(name, schema) {
245
+ if (!schema || typeof schema !== "object") {
246
+ return { name, type: "object" };
247
+ }
248
+ const s = schema;
241
249
  const model = {
242
250
  name,
243
- type: schemaTypeToModelType(schema.type),
244
- description: schema.description
251
+ type: schemaTypeToModelType(s.type),
252
+ description: s.description
245
253
  };
246
- if (schema.type === "object" || schema.properties) {
254
+ if (s.type === "object" || s.properties) {
247
255
  model.type = "object";
248
256
  model.properties = {};
249
- model.required = schema.required || [];
250
- if (schema.properties) {
251
- for (const [propName, propSchema] of Object.entries(schema.properties)) {
257
+ model.required = s.required || [];
258
+ if (s.properties && typeof s.properties === "object") {
259
+ for (const [propName, propSchema] of Object.entries(s.properties)) {
252
260
  model.properties[propName] = parseProperty(
253
261
  propName,
254
262
  propSchema,
@@ -256,39 +264,41 @@ function parseSchemaToModel(name, schema) {
256
264
  );
257
265
  }
258
266
  }
259
- if (schema.additionalProperties !== void 0) {
260
- if (typeof schema.additionalProperties === "boolean") {
261
- model.additionalProperties = schema.additionalProperties;
262
- } else if ("$ref" in schema.additionalProperties) {
263
- model.additionalProperties = {
264
- $ref: schema.additionalProperties.$ref
265
- };
266
- } else {
267
- model.additionalProperties = parseSchemaToModel(
268
- `${name}AdditionalProps`,
269
- schema.additionalProperties
270
- );
267
+ if (s.additionalProperties !== void 0) {
268
+ if (typeof s.additionalProperties === "boolean") {
269
+ model.additionalProperties = s.additionalProperties;
270
+ } else if (s.additionalProperties && typeof s.additionalProperties === "object") {
271
+ if ("$ref" in s.additionalProperties) {
272
+ model.additionalProperties = {
273
+ $ref: s.additionalProperties.$ref
274
+ };
275
+ } else {
276
+ model.additionalProperties = parseSchemaToModel(
277
+ `${name}AdditionalProps`,
278
+ s.additionalProperties
279
+ );
280
+ }
271
281
  }
272
282
  }
273
283
  }
274
- if (schema.type === "array" && schema.items) {
284
+ if (s.type === "array" && s.items) {
275
285
  model.type = "array";
276
- if ("$ref" in schema.items) {
277
- model.items = { $ref: schema.items.$ref };
286
+ if (typeof s.items === "object" && "$ref" in s.items) {
287
+ model.items = { $ref: s.items.$ref };
278
288
  } else {
279
- model.items = parseSchemaToModel(`${name}Item`, schema.items);
289
+ model.items = parseSchemaToModel(`${name}Item`, s.items);
280
290
  }
281
291
  }
282
- if (schema.enum) {
283
- model.enum = schema.enum;
292
+ if (s.enum) {
293
+ model.enum = s.enum;
284
294
  }
285
- if (schema.example !== void 0) {
286
- model.example = schema.example;
295
+ if (s.example !== void 0) {
296
+ model.example = s.example;
287
297
  }
288
298
  return model;
289
299
  }
290
300
  function parseProperty(name, schema, required) {
291
- if ("$ref" in schema) {
301
+ if (schema && typeof schema === "object" && "$ref" in schema) {
292
302
  return {
293
303
  name,
294
304
  type: "object",
@@ -296,31 +306,32 @@ function parseProperty(name, schema, required) {
296
306
  $ref: schema.$ref
297
307
  };
298
308
  }
309
+ const s = schema;
299
310
  const prop = {
300
311
  name,
301
- type: schemaTypeToPropertyType(schema.type),
312
+ type: schemaTypeToPropertyType(s.type),
302
313
  required,
303
- nullable: schema.nullable,
304
- description: schema.description,
305
- format: schema.format,
306
- enum: schema.enum,
307
- example: schema.example,
308
- default: schema.default,
309
- minimum: schema.minimum,
310
- maximum: schema.maximum,
311
- minLength: schema.minLength,
312
- maxLength: schema.maxLength,
313
- pattern: schema.pattern
314
+ nullable: s.nullable,
315
+ description: s.description,
316
+ format: s.format,
317
+ enum: s.enum,
318
+ example: s.example,
319
+ default: s.default,
320
+ minimum: s.minimum,
321
+ maximum: s.maximum,
322
+ minLength: s.minLength,
323
+ maxLength: s.maxLength,
324
+ pattern: s.pattern
314
325
  };
315
- if (schema.type === "array" && schema.items) {
326
+ if (s.type === "array" && s.items) {
316
327
  prop.type = "array";
317
- if ("$ref" in schema.items) {
318
- prop.items = { $ref: schema.items.$ref };
328
+ if (typeof s.items === "object" && "$ref" in s.items) {
329
+ prop.items = { $ref: s.items.$ref };
319
330
  } else {
320
- prop.items = parseSchemaToModel(`${name}Item`, schema.items);
331
+ prop.items = parseSchemaToModel(`${name}Item`, s.items);
321
332
  }
322
333
  }
323
- const xRelationship = schema["x-demokit-relationship"];
334
+ const xRelationship = s["x-demokit-relationship"];
324
335
  if (xRelationship && typeof xRelationship === "object") {
325
336
  prop["x-demokit-relationship"] = xRelationship;
326
337
  }
@@ -328,28 +339,32 @@ function parseProperty(name, schema, required) {
328
339
  }
329
340
  function parseEndpoints(doc) {
330
341
  const endpoints = [];
331
- if (!doc.paths) {
342
+ const paths = doc.paths;
343
+ if (!paths) {
332
344
  return endpoints;
333
345
  }
334
346
  const methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
335
- for (const [path, pathItem] of Object.entries(doc.paths)) {
336
- if (!pathItem) continue;
347
+ for (const [path, pathItem] of Object.entries(paths)) {
348
+ if (!pathItem || typeof pathItem !== "object") continue;
337
349
  for (const method of methods) {
338
350
  const operation = pathItem[method.toLowerCase()];
339
- if (!operation) continue;
351
+ if (!operation || typeof operation !== "object") continue;
340
352
  endpoints.push(parseEndpoint(method, path, operation, pathItem));
341
353
  }
342
354
  }
343
355
  return endpoints;
344
356
  }
345
357
  function parseEndpoint(method, path, operation, pathItem) {
346
- const allParams = [...pathItem.parameters || [], ...operation.parameters || []];
347
358
  const pathParams = [];
348
359
  const queryParams = [];
360
+ const allParams = [
361
+ ...pathItem.parameters || [],
362
+ ...operation.parameters || []
363
+ ];
349
364
  for (const param of allParams) {
365
+ if (!param || typeof param !== "object") continue;
350
366
  if ("$ref" in param) continue;
351
- const paramObj = param;
352
- const parsed = parseParameter(paramObj);
367
+ const parsed = parseParameter(param);
353
368
  if (parsed.in === "path") {
354
369
  pathParams.push(parsed);
355
370
  } else if (parsed.in === "query") {
@@ -357,12 +372,15 @@ function parseEndpoint(method, path, operation, pathItem) {
357
372
  }
358
373
  }
359
374
  let requestBody;
360
- if (operation.requestBody && !("$ref" in operation.requestBody)) {
361
- requestBody = parseRequestBody(operation.requestBody);
375
+ const opRequestBody = operation.requestBody;
376
+ if (opRequestBody && typeof opRequestBody === "object" && !("$ref" in opRequestBody)) {
377
+ requestBody = parseRequestBody(opRequestBody);
362
378
  }
363
379
  const responses = {};
364
- if (operation.responses) {
365
- for (const [statusCode, response] of Object.entries(operation.responses)) {
380
+ const opResponses = operation.responses;
381
+ if (opResponses && typeof opResponses === "object") {
382
+ for (const [statusCode, response] of Object.entries(opResponses)) {
383
+ if (!response || typeof response !== "object") continue;
366
384
  if ("$ref" in response) continue;
367
385
  responses[statusCode] = parseResponse(statusCode, response);
368
386
  }
@@ -381,52 +399,64 @@ function parseEndpoint(method, path, operation, pathItem) {
381
399
  };
382
400
  }
383
401
  function parseParameter(param) {
384
- const schema = param.schema;
402
+ const p = param;
403
+ const schema = p.schema;
385
404
  return {
386
- name: param.name,
387
- in: param.in,
388
- required: param.required ?? false,
405
+ name: p.name,
406
+ in: p.in,
407
+ required: p.required ?? false,
389
408
  type: schema ? schemaTypeToPropertyType(schema.type) : "string",
390
409
  format: schema?.format,
391
- description: param.description,
392
- example: param.example ?? schema?.example
410
+ description: p.description,
411
+ example: p.example ?? schema?.example
393
412
  };
394
413
  }
395
414
  function parseRequestBody(body) {
396
- const contentType = Object.keys(body.content || {})[0] || "application/json";
397
- const mediaType = body.content?.[contentType];
415
+ const b = body;
416
+ const content = b.content;
417
+ const contentType = Object.keys(content || {})[0] || "application/json";
418
+ const mediaType = content?.[contentType];
398
419
  let schema = { name: "Unknown", type: "object" };
399
- if (mediaType?.schema) {
400
- if ("$ref" in mediaType.schema) {
401
- schema = { $ref: mediaType.schema.$ref };
402
- } else {
403
- schema = parseSchemaToModel("RequestBody", mediaType.schema);
420
+ if (mediaType) {
421
+ const m = mediaType;
422
+ const mediaSchema = m.schema;
423
+ if (mediaSchema && typeof mediaSchema === "object") {
424
+ if ("$ref" in mediaSchema) {
425
+ schema = { $ref: mediaSchema.$ref };
426
+ } else {
427
+ schema = parseSchemaToModel("RequestBody", mediaSchema);
428
+ }
404
429
  }
405
430
  }
406
431
  return {
407
432
  contentType,
408
433
  schema,
409
- required: body.required ?? false,
410
- description: body.description
434
+ required: b.required ?? false,
435
+ description: b.description
411
436
  };
412
437
  }
413
438
  function parseResponse(statusCode, response) {
439
+ const r = response;
414
440
  const responseDef = {
415
441
  statusCode,
416
- description: response.description
442
+ description: r.description
417
443
  };
418
- if (response.content) {
444
+ const content = r.content;
445
+ if (content) {
419
446
  responseDef.content = {};
420
- for (const [contentType, mediaType] of Object.entries(response.content)) {
421
- if (mediaType.schema) {
422
- if ("$ref" in mediaType.schema) {
447
+ for (const [contentType, mediaType] of Object.entries(content)) {
448
+ if (!mediaType || typeof mediaType !== "object") continue;
449
+ const m = mediaType;
450
+ const schema = m.schema;
451
+ if (schema && typeof schema === "object") {
452
+ if ("$ref" in schema) {
423
453
  responseDef.content[contentType] = {
424
- $ref: mediaType.schema.$ref
454
+ $ref: schema.$ref
425
455
  };
426
456
  } else {
427
457
  responseDef.content[contentType] = parseSchemaToModel(
428
458
  `Response${statusCode}`,
429
- mediaType.schema
459
+ schema
430
460
  );
431
461
  }
432
462
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/relationships.ts","../src/parser.ts"],"names":["SwaggerParser","api"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Core types for DemoKit schema representation\n *\n * These types represent a parsed API schema with relationship detection,\n * independent of the source format (OpenAPI, GraphQL, etc.)\n */\n\n/**\n * The main schema representation for DemoKit\n * Contains all information needed for fixture generation\n */\nexport interface DemokitSchema {\n /**\n * Metadata about the API\n */\n info: SchemaInfo\n\n /**\n * All API endpoints discovered from the spec\n */\n endpoints: Endpoint[]\n\n /**\n * All data models (schemas) from the spec\n */\n models: Record<string, DataModel>\n\n /**\n * Detected relationships between models\n */\n relationships: Relationship[]\n}\n\n/**\n * API metadata\n */\nexport interface SchemaInfo {\n /**\n * API title from the spec\n */\n title: string\n\n /**\n * API version\n */\n version: string\n\n /**\n * Optional description\n */\n description?: string\n\n /**\n * Base URL for the API (if specified)\n */\n baseUrl?: string\n}\n\n/**\n * An API endpoint\n */\nexport interface Endpoint {\n /**\n * HTTP method (GET, POST, PUT, PATCH, DELETE)\n */\n method: HttpMethod\n\n /**\n * URL path with parameter placeholders\n * @example \"/users/{id}\" or \"/orders/{orderId}/items\"\n */\n path: string\n\n /**\n * Operation ID from OpenAPI (if available)\n */\n operationId?: string\n\n /**\n * Human-readable summary\n */\n summary?: string\n\n /**\n * Detailed description\n */\n description?: string\n\n /**\n * Path parameters\n */\n pathParams: ParameterDef[]\n\n /**\n * Query parameters\n */\n queryParams: ParameterDef[]\n\n /**\n * Request body schema (for POST/PUT/PATCH)\n */\n requestBody?: RequestBody\n\n /**\n * Response schemas by status code\n */\n responses: Record<string, ResponseDef>\n\n /**\n * Tags for grouping endpoints\n */\n tags: string[]\n}\n\n/**\n * HTTP methods supported\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\n/**\n * A request or response body definition\n */\nexport interface RequestBody {\n /**\n * Content type (usually application/json)\n */\n contentType: string\n\n /**\n * Reference to the model name, or inline schema\n */\n schema: SchemaRef | DataModel\n\n /**\n * Whether the body is required\n */\n required: boolean\n\n /**\n * Description of the body\n */\n description?: string\n}\n\n/**\n * A response definition\n */\nexport interface ResponseDef {\n /**\n * HTTP status code\n */\n statusCode: string\n\n /**\n * Description of the response\n */\n description?: string\n\n /**\n * Content type to schema mapping\n */\n content?: Record<string, SchemaRef | DataModel>\n}\n\n/**\n * A parameter definition (path or query)\n */\nexport interface ParameterDef {\n /**\n * Parameter name\n */\n name: string\n\n /**\n * Where the parameter is located\n */\n in: 'path' | 'query' | 'header' | 'cookie'\n\n /**\n * Whether the parameter is required\n */\n required: boolean\n\n /**\n * Parameter type\n */\n type: PropertyType\n\n /**\n * Optional format hint\n */\n format?: string\n\n /**\n * Description\n */\n description?: string\n\n /**\n * Example value\n */\n example?: unknown\n}\n\n/**\n * Reference to another schema/model\n */\nexport interface SchemaRef {\n /**\n * The referenced model name\n */\n $ref: string\n}\n\n/**\n * A data model representing an object schema\n */\nexport interface DataModel {\n /**\n * Model name (from the schema component name)\n */\n name: string\n\n /**\n * The type of this model\n */\n type: ModelType\n\n /**\n * Description from the spec\n */\n description?: string\n\n /**\n * Properties for object types\n */\n properties?: Record<string, PropertyDef>\n\n /**\n * Required property names\n */\n required?: string[]\n\n /**\n * For array types, the item schema\n */\n items?: SchemaRef | DataModel\n\n /**\n * Enum values for enum types\n */\n enum?: unknown[]\n\n /**\n * Example value from the spec\n */\n example?: unknown\n\n /**\n * Additional properties schema (for dictionaries)\n */\n additionalProperties?: boolean | SchemaRef | DataModel\n}\n\n/**\n * Model types\n */\nexport type ModelType = 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null'\n\n/**\n * A property definition within a model\n */\nexport interface PropertyDef {\n /**\n * Property name\n */\n name: string\n\n /**\n * Property type\n */\n type: PropertyType\n\n /**\n * Format hint (uuid, email, date-time, etc.)\n */\n format?: string\n\n /**\n * Description\n */\n description?: string\n\n /**\n * Whether this property is required\n */\n required?: boolean\n\n /**\n * Whether this property is nullable\n */\n nullable?: boolean\n\n /**\n * Enum values for string enums\n */\n enum?: unknown[]\n\n /**\n * For array types, the item schema\n */\n items?: SchemaRef | DataModel\n\n /**\n * Reference to another model (for $ref properties)\n */\n $ref?: string\n\n /**\n * Example value\n */\n example?: unknown\n\n /**\n * Default value\n */\n default?: unknown\n\n /**\n * Minimum value (for numbers)\n */\n minimum?: number\n\n /**\n * Maximum value (for numbers)\n */\n maximum?: number\n\n /**\n * Min length (for strings)\n */\n minLength?: number\n\n /**\n * Max length (for strings)\n */\n maxLength?: number\n\n /**\n * Pattern (regex for strings)\n */\n pattern?: string\n\n /**\n * Detected relationship to another model\n * Set by relationship detection, not directly from spec\n */\n relationshipTo?: RelationshipTarget\n\n /**\n * Custom extension for explicit relationship hints\n * @example \"x-demokit-relationship\": { \"model\": \"User\", \"field\": \"id\" }\n */\n 'x-demokit-relationship'?: RelationshipTarget\n}\n\n/**\n * Property types\n */\nexport type PropertyType =\n | 'string'\n | 'number'\n | 'integer'\n | 'boolean'\n | 'array'\n | 'object'\n | 'null'\n\n/**\n * A detected relationship between two models\n */\nexport interface Relationship {\n /**\n * The source side of the relationship\n */\n from: RelationshipSide\n\n /**\n * The target side of the relationship\n */\n to: RelationshipSide\n\n /**\n * Type of relationship\n */\n type: RelationshipType\n\n /**\n * Whether the relationship is required (not nullable)\n */\n required: boolean\n\n /**\n * How this relationship was detected\n */\n detectedBy: RelationshipDetectionMethod\n}\n\n/**\n * One side of a relationship\n */\nexport interface RelationshipSide {\n /**\n * Model name\n */\n model: string\n\n /**\n * Field name\n */\n field: string\n}\n\n/**\n * Target for a relationship from a property\n */\nexport interface RelationshipTarget {\n /**\n * Target model name\n */\n model: string\n\n /**\n * Target field (usually \"id\")\n */\n field: string\n}\n\n/**\n * Types of relationships between models\n */\nexport type RelationshipType =\n | 'one-to-one'\n | 'one-to-many'\n | 'many-to-one'\n | 'many-to-many'\n\n/**\n * How a relationship was detected\n */\nexport type RelationshipDetectionMethod =\n | 'explicit-ref' // OpenAPI $ref\n | 'naming-convention' // userId -> User.id pattern\n | 'x-demokit-extension' // x-demokit-relationship extension\n | 'inferred' // AI or heuristic inference\n\n/**\n * Helper type to check if something is a schema reference\n */\nexport function isSchemaRef(value: unknown): value is SchemaRef {\n return (\n typeof value === 'object' &&\n value !== null &&\n '$ref' in value &&\n typeof (value as SchemaRef).$ref === 'string'\n )\n}\n\n/**\n * Extract the model name from a $ref string\n * @example \"#/components/schemas/User\" -> \"User\"\n */\nexport function extractRefName(ref: string): string {\n const parts = ref.split('/')\n return parts[parts.length - 1] ?? ref\n}\n","/**\n * Relationship detection for DemoKit schemas\n *\n * Detects relationships between models using:\n * 1. Explicit $ref references in OpenAPI\n * 2. Naming conventions (userId -> User.id)\n * 3. x-demokit-relationship extension\n */\n\nimport type {\n DataModel,\n PropertyDef,\n Relationship,\n RelationshipTarget,\n RelationshipDetectionMethod,\n RelationshipType,\n} from './types'\nimport { isSchemaRef, extractRefName } from './types'\n\n/**\n * Common ID field naming patterns\n * Maps suffix patterns to implied relationships\n */\nconst ID_FIELD_PATTERNS = [\n // Standard patterns: userId -> User, customerId -> Customer\n { pattern: /^(.+)Id$/, targetField: 'id' },\n { pattern: /^(.+)_id$/, targetField: 'id' },\n { pattern: /^(.+)ID$/, targetField: 'id' },\n\n // UUID patterns: userUuid -> User, customerUUID -> Customer\n { pattern: /^(.+)Uuid$/, targetField: 'uuid' },\n { pattern: /^(.+)UUID$/, targetField: 'uuid' },\n { pattern: /^(.+)_uuid$/, targetField: 'uuid' },\n]\n\n/**\n * Convert a field name prefix to a model name\n * @example \"user\" -> \"User\", \"orderItem\" -> \"OrderItem\"\n */\nfunction prefixToModelName(prefix: string): string {\n return prefix.charAt(0).toUpperCase() + prefix.slice(1)\n}\n\n/**\n * Check if a property looks like a foreign key based on naming conventions\n */\nexport function detectRelationshipFromNaming(\n property: PropertyDef,\n availableModels: Set<string>\n): RelationshipTarget | null {\n const fieldName = property.name\n\n for (const { pattern, targetField } of ID_FIELD_PATTERNS) {\n const match = fieldName.match(pattern)\n if (match && match[1]) {\n const prefix = match[1]\n const modelName = prefixToModelName(prefix)\n\n // Check if this model exists in the schema\n if (availableModels.has(modelName)) {\n return { model: modelName, field: targetField }\n }\n\n // Also check for plural forms\n const pluralModel = modelName + 's'\n if (availableModels.has(pluralModel)) {\n return { model: pluralModel, field: targetField }\n }\n }\n }\n\n return null\n}\n\n/**\n * Check if a property has an explicit x-demokit-relationship extension\n */\nexport function detectRelationshipFromExtension(\n property: PropertyDef\n): RelationshipTarget | null {\n const extension = property['x-demokit-relationship']\n if (extension && typeof extension === 'object') {\n return {\n model: extension.model,\n field: extension.field || 'id',\n }\n }\n return null\n}\n\n/**\n * Check if a property is a $ref to another model\n */\nexport function detectRelationshipFromRef(\n property: PropertyDef,\n availableModels: Set<string>\n): RelationshipTarget | null {\n if (property.$ref) {\n const modelName = extractRefName(property.$ref)\n if (availableModels.has(modelName)) {\n return { model: modelName, field: 'id' }\n }\n }\n\n // Check if items is a $ref (for arrays of references)\n if (property.items && isSchemaRef(property.items)) {\n const modelName = extractRefName(property.items.$ref)\n if (availableModels.has(modelName)) {\n return { model: modelName, field: 'id' }\n }\n }\n\n return null\n}\n\n/**\n * Detect the relationship type based on property and target\n */\nfunction determineRelationshipType(\n property: PropertyDef,\n _fromModel: DataModel\n): RelationshipType {\n // If the property is an array, it's one-to-many or many-to-many\n if (property.type === 'array') {\n // For simplicity, treat array references as one-to-many\n // (the \"one\" side has the array of references)\n return 'one-to-many'\n }\n\n // Single reference is many-to-one (many records can reference one target)\n return 'many-to-one'\n}\n\n/**\n * Detect all relationships in a set of models\n */\nexport function detectRelationships(\n models: Record<string, DataModel>\n): Relationship[] {\n const relationships: Relationship[] = []\n const availableModels = new Set(Object.keys(models))\n\n for (const [modelName, model] of Object.entries(models)) {\n if (!model.properties) continue\n\n for (const [propName, property] of Object.entries(model.properties)) {\n let target: RelationshipTarget | null = null\n let detectionMethod: RelationshipDetectionMethod = 'inferred'\n\n // Priority 1: Explicit x-demokit-relationship extension\n target = detectRelationshipFromExtension(property)\n if (target) {\n detectionMethod = 'x-demokit-extension'\n }\n\n // Priority 2: $ref references\n if (!target) {\n target = detectRelationshipFromRef(property, availableModels)\n if (target) {\n detectionMethod = 'explicit-ref'\n }\n }\n\n // Priority 3: Naming conventions\n if (!target) {\n target = detectRelationshipFromNaming(property, availableModels)\n if (target) {\n detectionMethod = 'naming-convention'\n }\n }\n\n if (target) {\n // Don't create self-referential relationships for simple IDs\n if (target.model === modelName && target.field === 'id' && propName === 'id') {\n continue\n }\n\n // Add the detected relationship info to the property\n property.relationshipTo = target\n\n relationships.push({\n from: { model: modelName, field: propName },\n to: target,\n type: determineRelationshipType(property, model),\n required: property.required ?? false,\n detectedBy: detectionMethod,\n })\n }\n }\n }\n\n return relationships\n}\n\n/**\n * Find all relationships for a specific model\n */\nexport function getRelationshipsForModel(\n modelName: string,\n relationships: Relationship[]\n): {\n outgoing: Relationship[]\n incoming: Relationship[]\n} {\n return {\n outgoing: relationships.filter(r => r.from.model === modelName),\n incoming: relationships.filter(r => r.to.model === modelName),\n }\n}\n\n/**\n * Check if a model is referenced by other models\n */\nexport function isModelReferenced(\n modelName: string,\n relationships: Relationship[]\n): boolean {\n return relationships.some(r => r.to.model === modelName)\n}\n\n/**\n * Get the dependency order for models based on relationships\n * Returns models in order such that dependencies come before dependents\n */\nexport function getModelDependencyOrder(\n models: Record<string, DataModel>,\n relationships: Relationship[]\n): string[] {\n const modelNames = Object.keys(models)\n const visited = new Set<string>()\n const order: string[] = []\n\n function visit(name: string, path: Set<string> = new Set()) {\n if (visited.has(name)) return\n if (path.has(name)) {\n // Circular dependency - skip to break the cycle\n return\n }\n\n path.add(name)\n\n // Visit all models that this model depends on first\n const deps = relationships\n .filter(r => r.from.model === name)\n .map(r => r.to.model)\n .filter(dep => modelNames.includes(dep))\n\n for (const dep of deps) {\n visit(dep, new Set(path))\n }\n\n if (!visited.has(name)) {\n visited.add(name)\n order.push(name)\n }\n }\n\n for (const name of modelNames) {\n visit(name)\n }\n\n return order\n}\n","/**\n * OpenAPI 3.x parser for DemoKit\n *\n * Parses OpenAPI specs into DemoKit's internal schema representation\n * with automatic relationship detection.\n */\n\nimport SwaggerParser from '@apidevtools/swagger-parser'\nimport type { OpenAPI, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types'\nimport type {\n DemokitSchema,\n SchemaInfo,\n Endpoint,\n DataModel,\n PropertyDef,\n HttpMethod,\n ParameterDef,\n RequestBody,\n ResponseDef,\n PropertyType,\n ModelType,\n} from './types'\n// extractRefName is used in relationships.ts, re-exported from index.ts\nimport { detectRelationships } from './relationships'\n\ntype OpenAPIDocument = OpenAPIV3.Document | OpenAPIV3_1.Document\ntype SchemaObject = OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject\ntype ReferenceObject = OpenAPIV3.ReferenceObject | OpenAPIV3_1.ReferenceObject\ntype ParameterObject = OpenAPIV3.ParameterObject | OpenAPIV3_1.ParameterObject\ntype RequestBodyObject = OpenAPIV3.RequestBodyObject | OpenAPIV3_1.RequestBodyObject\ntype ResponseObject = OpenAPIV3.ResponseObject | OpenAPIV3_1.ResponseObject\ntype MediaTypeObject = OpenAPIV3.MediaTypeObject | OpenAPIV3_1.MediaTypeObject\n\n/**\n * Options for parsing OpenAPI specs\n */\nexport interface ParseOptions {\n /**\n * Whether to dereference all $ref pointers\n * @default true\n */\n dereference?: boolean\n\n /**\n * Whether to detect relationships automatically\n * @default true\n */\n detectRelationships?: boolean\n\n /**\n * Whether to include response schemas in models\n * @default true\n */\n includeResponses?: boolean\n}\n\n/**\n * Parse an OpenAPI spec from a file path or URL\n */\nexport async function parseOpenAPIFromPath(\n pathOrUrl: string,\n options: ParseOptions = {}\n): Promise<DemokitSchema> {\n const { dereference = true } = options\n\n let api: OpenAPI.Document\n\n if (dereference) {\n api = await SwaggerParser.dereference(pathOrUrl)\n } else {\n api = await SwaggerParser.parse(pathOrUrl)\n }\n\n return parseOpenAPIDocument(api as OpenAPIDocument, options)\n}\n\n/**\n * Parse an OpenAPI spec from a string (JSON or YAML)\n */\nexport async function parseOpenAPIFromString(\n spec: string,\n options: ParseOptions = {}\n): Promise<DemokitSchema> {\n const { dereference = true } = options\n\n // Parse the string as JSON or YAML\n let parsed: unknown\n try {\n parsed = JSON.parse(spec)\n } catch {\n // If JSON parse fails, try YAML via SwaggerParser\n const api = await SwaggerParser.parse(spec as unknown as string)\n if (dereference) {\n return parseOpenAPIDocument(\n (await SwaggerParser.dereference(api)) as OpenAPIDocument,\n options\n )\n }\n return parseOpenAPIDocument(api as OpenAPIDocument, options)\n }\n\n let api: OpenAPI.Document\n if (dereference) {\n api = await SwaggerParser.dereference(parsed as OpenAPI.Document)\n } else {\n api = await SwaggerParser.validate(parsed as OpenAPI.Document)\n }\n\n return parseOpenAPIDocument(api as OpenAPIDocument, options)\n}\n\n/**\n * Parse an OpenAPI spec from an already-parsed object\n */\nexport async function parseOpenAPIFromObject(\n spec: Record<string, unknown>,\n options: ParseOptions = {}\n): Promise<DemokitSchema> {\n const { dereference = true } = options\n\n let api: OpenAPI.Document\n if (dereference) {\n api = await SwaggerParser.dereference(spec as OpenAPI.Document)\n } else {\n api = await SwaggerParser.validate(spec as OpenAPI.Document)\n }\n\n return parseOpenAPIDocument(api as OpenAPIDocument, options)\n}\n\n/**\n * Parse an OpenAPI document into DemokitSchema\n */\nfunction parseOpenAPIDocument(\n doc: OpenAPIDocument,\n options: ParseOptions = {}\n): DemokitSchema {\n const { detectRelationships: shouldDetect = true } = options\n\n // Parse info\n const info = parseInfo(doc)\n\n // Parse models from components/schemas\n const models = parseModels(doc)\n\n // Parse endpoints from paths\n const endpoints = parseEndpoints(doc)\n\n // Detect relationships\n const relationships = shouldDetect ? detectRelationships(models) : []\n\n return {\n info,\n endpoints,\n models,\n relationships,\n }\n}\n\n/**\n * Parse API info from the document\n */\nfunction parseInfo(doc: OpenAPIDocument): SchemaInfo {\n const info: SchemaInfo = {\n title: doc.info?.title ?? 'Untitled API',\n version: doc.info?.version ?? '1.0.0',\n description: doc.info?.description,\n }\n\n // Try to extract base URL from servers\n if (doc.servers && doc.servers.length > 0 && doc.servers[0]) {\n info.baseUrl = doc.servers[0].url\n }\n\n return info\n}\n\n/**\n * Parse all models from components/schemas\n */\nfunction parseModels(doc: OpenAPIDocument): Record<string, DataModel> {\n const models: Record<string, DataModel> = {}\n\n const schemas = doc.components?.schemas\n if (!schemas) {\n return models\n }\n\n for (const [name, schema] of Object.entries(schemas)) {\n // Skip reference objects (shouldn't happen after dereference)\n if ('$ref' in schema) {\n continue\n }\n\n models[name] = parseSchemaToModel(name, schema as SchemaObject)\n }\n\n return models\n}\n\n/**\n * Parse a schema object into a DataModel\n */\nfunction parseSchemaToModel(name: string, schema: SchemaObject): DataModel {\n const model: DataModel = {\n name,\n type: schemaTypeToModelType(schema.type),\n description: schema.description,\n }\n\n // Parse properties for object types\n if (schema.type === 'object' || schema.properties) {\n model.type = 'object'\n model.properties = {}\n model.required = schema.required || []\n\n if (schema.properties) {\n for (const [propName, propSchema] of Object.entries(schema.properties)) {\n model.properties[propName] = parseProperty(\n propName,\n propSchema as SchemaObject | ReferenceObject,\n model.required.includes(propName)\n )\n }\n }\n\n if (schema.additionalProperties !== undefined) {\n if (typeof schema.additionalProperties === 'boolean') {\n model.additionalProperties = schema.additionalProperties\n } else if ('$ref' in schema.additionalProperties) {\n model.additionalProperties = {\n $ref: (schema.additionalProperties as ReferenceObject).$ref,\n }\n } else {\n model.additionalProperties = parseSchemaToModel(\n `${name}AdditionalProps`,\n schema.additionalProperties as SchemaObject\n )\n }\n }\n }\n\n // Parse array items\n if (schema.type === 'array' && schema.items) {\n model.type = 'array'\n if ('$ref' in schema.items) {\n model.items = { $ref: (schema.items as ReferenceObject).$ref }\n } else {\n model.items = parseSchemaToModel(`${name}Item`, schema.items as SchemaObject)\n }\n }\n\n // Parse enum values\n if (schema.enum) {\n model.enum = schema.enum\n }\n\n // Parse example\n if (schema.example !== undefined) {\n model.example = schema.example\n }\n\n return model\n}\n\n/**\n * Parse a property schema into a PropertyDef\n */\nfunction parseProperty(\n name: string,\n schema: SchemaObject | ReferenceObject,\n required: boolean\n): PropertyDef {\n // Handle $ref\n if ('$ref' in schema) {\n return {\n name,\n type: 'object',\n required,\n $ref: schema.$ref,\n }\n }\n\n const prop: PropertyDef = {\n name,\n type: schemaTypeToPropertyType(schema.type),\n required,\n nullable: (schema as Record<string, unknown>).nullable as boolean | undefined,\n description: schema.description,\n format: schema.format,\n enum: schema.enum,\n example: schema.example,\n default: schema.default,\n minimum: schema.minimum,\n maximum: schema.maximum,\n minLength: schema.minLength,\n maxLength: schema.maxLength,\n pattern: schema.pattern,\n }\n\n // Parse array items\n if (schema.type === 'array' && schema.items) {\n prop.type = 'array'\n if ('$ref' in schema.items) {\n prop.items = { $ref: (schema.items as ReferenceObject).$ref }\n } else {\n prop.items = parseSchemaToModel(`${name}Item`, schema.items as SchemaObject)\n }\n }\n\n // Check for x-demokit-relationship extension\n const xRelationship = (schema as Record<string, unknown>)['x-demokit-relationship']\n if (xRelationship && typeof xRelationship === 'object') {\n prop['x-demokit-relationship'] = xRelationship as { model: string; field: string }\n }\n\n return prop\n}\n\n/**\n * Parse all endpoints from paths\n */\nfunction parseEndpoints(doc: OpenAPIDocument): Endpoint[] {\n const endpoints: Endpoint[] = []\n\n if (!doc.paths) {\n return endpoints\n }\n\n const methods: HttpMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']\n\n for (const [path, pathItem] of Object.entries(doc.paths)) {\n if (!pathItem) continue\n\n for (const method of methods) {\n const operation = pathItem[method.toLowerCase() as keyof typeof pathItem] as\n | OpenAPIV3.OperationObject\n | OpenAPIV3_1.OperationObject\n | undefined\n\n if (!operation) continue\n\n endpoints.push(parseEndpoint(method, path, operation, pathItem))\n }\n }\n\n return endpoints\n}\n\n/**\n * Parse a single endpoint\n */\nfunction parseEndpoint(\n method: HttpMethod,\n path: string,\n operation: OpenAPIV3.OperationObject | OpenAPIV3_1.OperationObject,\n pathItem: OpenAPIV3.PathItemObject | OpenAPIV3_1.PathItemObject\n): Endpoint {\n // Combine path-level and operation-level parameters\n const allParams = [...(pathItem.parameters || []), ...(operation.parameters || [])]\n\n const pathParams: ParameterDef[] = []\n const queryParams: ParameterDef[] = []\n\n for (const param of allParams) {\n if ('$ref' in param) continue // Skip refs\n const paramObj = param as ParameterObject\n const parsed = parseParameter(paramObj)\n\n if (parsed.in === 'path') {\n pathParams.push(parsed)\n } else if (parsed.in === 'query') {\n queryParams.push(parsed)\n }\n }\n\n // Parse request body\n let requestBody: RequestBody | undefined\n if (operation.requestBody && !('$ref' in operation.requestBody)) {\n requestBody = parseRequestBody(operation.requestBody as RequestBodyObject)\n }\n\n // Parse responses\n const responses: Record<string, ResponseDef> = {}\n if (operation.responses) {\n for (const [statusCode, response] of Object.entries(operation.responses)) {\n if ('$ref' in response) continue\n responses[statusCode] = parseResponse(statusCode, response as ResponseObject)\n }\n }\n\n return {\n method,\n path,\n operationId: operation.operationId,\n summary: operation.summary,\n description: operation.description,\n pathParams,\n queryParams,\n requestBody,\n responses,\n tags: operation.tags || [],\n }\n}\n\n/**\n * Parse a parameter object\n */\nfunction parseParameter(param: ParameterObject): ParameterDef {\n const schema = param.schema as SchemaObject | undefined\n\n return {\n name: param.name,\n in: param.in as 'path' | 'query' | 'header' | 'cookie',\n required: param.required ?? false,\n type: schema ? schemaTypeToPropertyType(schema.type) : 'string',\n format: schema?.format,\n description: param.description,\n example: param.example ?? schema?.example,\n }\n}\n\n/**\n * Parse a request body object\n */\nfunction parseRequestBody(body: RequestBodyObject): RequestBody {\n const contentType = Object.keys(body.content || {})[0] || 'application/json'\n const mediaType = body.content?.[contentType] as MediaTypeObject | undefined\n\n let schema: RequestBody['schema'] = { name: 'Unknown', type: 'object' }\n\n if (mediaType?.schema) {\n if ('$ref' in mediaType.schema) {\n schema = { $ref: (mediaType.schema as ReferenceObject).$ref }\n } else {\n schema = parseSchemaToModel('RequestBody', mediaType.schema as SchemaObject)\n }\n }\n\n return {\n contentType,\n schema,\n required: body.required ?? false,\n description: body.description,\n }\n}\n\n/**\n * Parse a response object\n */\nfunction parseResponse(statusCode: string, response: ResponseObject): ResponseDef {\n const responseDef: ResponseDef = {\n statusCode,\n description: response.description,\n }\n\n if (response.content) {\n responseDef.content = {}\n\n for (const [contentType, mediaType] of Object.entries(response.content)) {\n if (mediaType.schema) {\n if ('$ref' in mediaType.schema) {\n responseDef.content[contentType] = {\n $ref: (mediaType.schema as ReferenceObject).$ref,\n }\n } else {\n responseDef.content[contentType] = parseSchemaToModel(\n `Response${statusCode}`,\n mediaType.schema as SchemaObject\n )\n }\n }\n }\n }\n\n return responseDef\n}\n\n/**\n * Convert OpenAPI schema type to ModelType\n */\nfunction schemaTypeToModelType(\n type: string | string[] | undefined\n): ModelType {\n if (!type) return 'object'\n if (Array.isArray(type)) return type[0] as ModelType\n return type as ModelType\n}\n\n/**\n * Convert OpenAPI schema type to PropertyType\n */\nfunction schemaTypeToPropertyType(\n type: string | string[] | undefined\n): PropertyType {\n if (!type) return 'object'\n if (Array.isArray(type)) return type[0] as PropertyType\n return type as PropertyType\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/relationships.ts","../src/parser.ts"],"names":["validate","dereference"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Core types for DemoKit schema representation\n *\n * These types represent a parsed API schema with relationship detection,\n * independent of the source format (OpenAPI, GraphQL, etc.)\n */\n\n/**\n * The main schema representation for DemoKit\n * Contains all information needed for fixture generation\n */\nexport interface DemokitSchema {\n /**\n * Metadata about the API\n */\n info: SchemaInfo\n\n /**\n * All API endpoints discovered from the spec\n */\n endpoints: Endpoint[]\n\n /**\n * All data models (schemas) from the spec\n */\n models: Record<string, DataModel>\n\n /**\n * Detected relationships between models\n */\n relationships: Relationship[]\n}\n\n/**\n * API metadata\n */\nexport interface SchemaInfo {\n /**\n * API title from the spec\n */\n title: string\n\n /**\n * API version\n */\n version: string\n\n /**\n * Optional description\n */\n description?: string\n\n /**\n * Base URL for the API (if specified)\n */\n baseUrl?: string\n}\n\n/**\n * An API endpoint\n */\nexport interface Endpoint {\n /**\n * HTTP method (GET, POST, PUT, PATCH, DELETE)\n */\n method: HttpMethod\n\n /**\n * URL path with parameter placeholders\n * @example \"/users/{id}\" or \"/orders/{orderId}/items\"\n */\n path: string\n\n /**\n * Operation ID from OpenAPI (if available)\n */\n operationId?: string\n\n /**\n * Human-readable summary\n */\n summary?: string\n\n /**\n * Detailed description\n */\n description?: string\n\n /**\n * Path parameters\n */\n pathParams: ParameterDef[]\n\n /**\n * Query parameters\n */\n queryParams: ParameterDef[]\n\n /**\n * Request body schema (for POST/PUT/PATCH)\n */\n requestBody?: RequestBody\n\n /**\n * Response schemas by status code\n */\n responses: Record<string, ResponseDef>\n\n /**\n * Tags for grouping endpoints\n */\n tags: string[]\n}\n\n/**\n * HTTP methods supported\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\n/**\n * A request or response body definition\n */\nexport interface RequestBody {\n /**\n * Content type (usually application/json)\n */\n contentType: string\n\n /**\n * Reference to the model name, or inline schema\n */\n schema: SchemaRef | DataModel\n\n /**\n * Whether the body is required\n */\n required: boolean\n\n /**\n * Description of the body\n */\n description?: string\n}\n\n/**\n * A response definition\n */\nexport interface ResponseDef {\n /**\n * HTTP status code\n */\n statusCode: string\n\n /**\n * Description of the response\n */\n description?: string\n\n /**\n * Content type to schema mapping\n */\n content?: Record<string, SchemaRef | DataModel>\n}\n\n/**\n * A parameter definition (path or query)\n */\nexport interface ParameterDef {\n /**\n * Parameter name\n */\n name: string\n\n /**\n * Where the parameter is located\n */\n in: 'path' | 'query' | 'header' | 'cookie'\n\n /**\n * Whether the parameter is required\n */\n required: boolean\n\n /**\n * Parameter type\n */\n type: PropertyType\n\n /**\n * Optional format hint\n */\n format?: string\n\n /**\n * Description\n */\n description?: string\n\n /**\n * Example value\n */\n example?: unknown\n}\n\n/**\n * Reference to another schema/model\n */\nexport interface SchemaRef {\n /**\n * The referenced model name\n */\n $ref: string\n}\n\n/**\n * A data model representing an object schema\n */\nexport interface DataModel {\n /**\n * Model name (from the schema component name)\n */\n name: string\n\n /**\n * The type of this model\n */\n type: ModelType\n\n /**\n * Description from the spec\n */\n description?: string\n\n /**\n * Properties for object types\n */\n properties?: Record<string, PropertyDef>\n\n /**\n * Required property names\n */\n required?: string[]\n\n /**\n * For array types, the item schema\n */\n items?: SchemaRef | DataModel\n\n /**\n * Enum values for enum types\n */\n enum?: unknown[]\n\n /**\n * Example value from the spec\n */\n example?: unknown\n\n /**\n * Additional properties schema (for dictionaries)\n */\n additionalProperties?: boolean | SchemaRef | DataModel\n}\n\n/**\n * Model types\n */\nexport type ModelType = 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null'\n\n/**\n * A property definition within a model\n */\nexport interface PropertyDef {\n /**\n * Property name\n */\n name: string\n\n /**\n * Property type\n */\n type: PropertyType\n\n /**\n * Format hint (uuid, email, date-time, etc.)\n */\n format?: string\n\n /**\n * Description\n */\n description?: string\n\n /**\n * Whether this property is required\n */\n required?: boolean\n\n /**\n * Whether this property is nullable\n */\n nullable?: boolean\n\n /**\n * Enum values for string enums\n */\n enum?: unknown[]\n\n /**\n * For array types, the item schema\n */\n items?: SchemaRef | DataModel\n\n /**\n * Reference to another model (for $ref properties)\n */\n $ref?: string\n\n /**\n * Example value\n */\n example?: unknown\n\n /**\n * Default value\n */\n default?: unknown\n\n /**\n * Minimum value (for numbers)\n */\n minimum?: number\n\n /**\n * Maximum value (for numbers)\n */\n maximum?: number\n\n /**\n * Min length (for strings)\n */\n minLength?: number\n\n /**\n * Max length (for strings)\n */\n maxLength?: number\n\n /**\n * Pattern (regex for strings)\n */\n pattern?: string\n\n /**\n * Detected relationship to another model\n * Set by relationship detection, not directly from spec\n */\n relationshipTo?: RelationshipTarget\n\n /**\n * Custom extension for explicit relationship hints\n * @example \"x-demokit-relationship\": { \"model\": \"User\", \"field\": \"id\" }\n */\n 'x-demokit-relationship'?: RelationshipTarget\n}\n\n/**\n * Property types\n */\nexport type PropertyType =\n | 'string'\n | 'number'\n | 'integer'\n | 'boolean'\n | 'array'\n | 'object'\n | 'null'\n\n/**\n * A detected relationship between two models\n */\nexport interface Relationship {\n /**\n * The source side of the relationship\n */\n from: RelationshipSide\n\n /**\n * The target side of the relationship\n */\n to: RelationshipSide\n\n /**\n * Type of relationship\n */\n type: RelationshipType\n\n /**\n * Whether the relationship is required (not nullable)\n */\n required: boolean\n\n /**\n * How this relationship was detected\n */\n detectedBy: RelationshipDetectionMethod\n}\n\n/**\n * One side of a relationship\n */\nexport interface RelationshipSide {\n /**\n * Model name\n */\n model: string\n\n /**\n * Field name\n */\n field: string\n}\n\n/**\n * Target for a relationship from a property\n */\nexport interface RelationshipTarget {\n /**\n * Target model name\n */\n model: string\n\n /**\n * Target field (usually \"id\")\n */\n field: string\n}\n\n/**\n * Types of relationships between models\n */\nexport type RelationshipType =\n | 'one-to-one'\n | 'one-to-many'\n | 'many-to-one'\n | 'many-to-many'\n\n/**\n * How a relationship was detected\n */\nexport type RelationshipDetectionMethod =\n | 'explicit-ref' // OpenAPI $ref\n | 'naming-convention' // userId -> User.id pattern\n | 'x-demokit-extension' // x-demokit-relationship extension\n | 'inferred' // AI or heuristic inference\n\n/**\n * Helper type to check if something is a schema reference\n */\nexport function isSchemaRef(value: unknown): value is SchemaRef {\n return (\n typeof value === 'object' &&\n value !== null &&\n '$ref' in value &&\n typeof (value as SchemaRef).$ref === 'string'\n )\n}\n\n/**\n * Extract the model name from a $ref string\n * @example \"#/components/schemas/User\" -> \"User\"\n */\nexport function extractRefName(ref: string): string {\n const parts = ref.split('/')\n return parts[parts.length - 1] ?? ref\n}\n","/**\n * Relationship detection for DemoKit schemas\n *\n * Detects relationships between models using:\n * 1. Explicit $ref references in OpenAPI\n * 2. Naming conventions (userId -> User.id)\n * 3. x-demokit-relationship extension\n */\n\nimport type {\n DataModel,\n PropertyDef,\n Relationship,\n RelationshipTarget,\n RelationshipDetectionMethod,\n RelationshipType,\n} from './types'\nimport { isSchemaRef, extractRefName } from './types'\n\n/**\n * Common ID field naming patterns\n * Maps suffix patterns to implied relationships\n */\nconst ID_FIELD_PATTERNS = [\n // Standard patterns: userId -> User, customerId -> Customer\n { pattern: /^(.+)Id$/, targetField: 'id' },\n { pattern: /^(.+)_id$/, targetField: 'id' },\n { pattern: /^(.+)ID$/, targetField: 'id' },\n\n // UUID patterns: userUuid -> User, customerUUID -> Customer\n { pattern: /^(.+)Uuid$/, targetField: 'uuid' },\n { pattern: /^(.+)UUID$/, targetField: 'uuid' },\n { pattern: /^(.+)_uuid$/, targetField: 'uuid' },\n]\n\n/**\n * Convert a field name prefix to a model name\n * @example \"user\" -> \"User\", \"orderItem\" -> \"OrderItem\"\n */\nfunction prefixToModelName(prefix: string): string {\n return prefix.charAt(0).toUpperCase() + prefix.slice(1)\n}\n\n/**\n * Check if a property looks like a foreign key based on naming conventions\n */\nexport function detectRelationshipFromNaming(\n property: PropertyDef,\n availableModels: Set<string>\n): RelationshipTarget | null {\n const fieldName = property.name\n\n for (const { pattern, targetField } of ID_FIELD_PATTERNS) {\n const match = fieldName.match(pattern)\n if (match && match[1]) {\n const prefix = match[1]\n const modelName = prefixToModelName(prefix)\n\n // Check if this model exists in the schema\n if (availableModels.has(modelName)) {\n return { model: modelName, field: targetField }\n }\n\n // Also check for plural forms\n const pluralModel = modelName + 's'\n if (availableModels.has(pluralModel)) {\n return { model: pluralModel, field: targetField }\n }\n }\n }\n\n return null\n}\n\n/**\n * Check if a property has an explicit x-demokit-relationship extension\n */\nexport function detectRelationshipFromExtension(\n property: PropertyDef\n): RelationshipTarget | null {\n const extension = property['x-demokit-relationship']\n if (extension && typeof extension === 'object') {\n return {\n model: extension.model,\n field: extension.field || 'id',\n }\n }\n return null\n}\n\n/**\n * Check if a property is a $ref to another model\n */\nexport function detectRelationshipFromRef(\n property: PropertyDef,\n availableModels: Set<string>\n): RelationshipTarget | null {\n if (property.$ref) {\n const modelName = extractRefName(property.$ref)\n if (availableModels.has(modelName)) {\n return { model: modelName, field: 'id' }\n }\n }\n\n // Check if items is a $ref (for arrays of references)\n if (property.items && isSchemaRef(property.items)) {\n const modelName = extractRefName(property.items.$ref)\n if (availableModels.has(modelName)) {\n return { model: modelName, field: 'id' }\n }\n }\n\n return null\n}\n\n/**\n * Detect the relationship type based on property and target\n */\nfunction determineRelationshipType(\n property: PropertyDef,\n _fromModel: DataModel\n): RelationshipType {\n // If the property is an array, it's one-to-many or many-to-many\n if (property.type === 'array') {\n // For simplicity, treat array references as one-to-many\n // (the \"one\" side has the array of references)\n return 'one-to-many'\n }\n\n // Single reference is many-to-one (many records can reference one target)\n return 'many-to-one'\n}\n\n/**\n * Detect all relationships in a set of models\n */\nexport function detectRelationships(\n models: Record<string, DataModel>\n): Relationship[] {\n const relationships: Relationship[] = []\n const availableModels = new Set(Object.keys(models))\n\n for (const [modelName, model] of Object.entries(models)) {\n if (!model.properties) continue\n\n for (const [propName, property] of Object.entries(model.properties)) {\n let target: RelationshipTarget | null = null\n let detectionMethod: RelationshipDetectionMethod = 'inferred'\n\n // Priority 1: Explicit x-demokit-relationship extension\n target = detectRelationshipFromExtension(property)\n if (target) {\n detectionMethod = 'x-demokit-extension'\n }\n\n // Priority 2: $ref references\n if (!target) {\n target = detectRelationshipFromRef(property, availableModels)\n if (target) {\n detectionMethod = 'explicit-ref'\n }\n }\n\n // Priority 3: Naming conventions\n if (!target) {\n target = detectRelationshipFromNaming(property, availableModels)\n if (target) {\n detectionMethod = 'naming-convention'\n }\n }\n\n if (target) {\n // Don't create self-referential relationships for simple IDs\n if (target.model === modelName && target.field === 'id' && propName === 'id') {\n continue\n }\n\n // Add the detected relationship info to the property\n property.relationshipTo = target\n\n relationships.push({\n from: { model: modelName, field: propName },\n to: target,\n type: determineRelationshipType(property, model),\n required: property.required ?? false,\n detectedBy: detectionMethod,\n })\n }\n }\n }\n\n return relationships\n}\n\n/**\n * Find all relationships for a specific model\n */\nexport function getRelationshipsForModel(\n modelName: string,\n relationships: Relationship[]\n): {\n outgoing: Relationship[]\n incoming: Relationship[]\n} {\n return {\n outgoing: relationships.filter(r => r.from.model === modelName),\n incoming: relationships.filter(r => r.to.model === modelName),\n }\n}\n\n/**\n * Check if a model is referenced by other models\n */\nexport function isModelReferenced(\n modelName: string,\n relationships: Relationship[]\n): boolean {\n return relationships.some(r => r.to.model === modelName)\n}\n\n/**\n * Get the dependency order for models based on relationships\n * Returns models in order such that dependencies come before dependents\n */\nexport function getModelDependencyOrder(\n models: Record<string, DataModel>,\n relationships: Relationship[]\n): string[] {\n const modelNames = Object.keys(models)\n const visited = new Set<string>()\n const order: string[] = []\n\n function visit(name: string, path: Set<string> = new Set()) {\n if (visited.has(name)) return\n if (path.has(name)) {\n // Circular dependency - skip to break the cycle\n return\n }\n\n path.add(name)\n\n // Visit all models that this model depends on first\n const deps = relationships\n .filter(r => r.from.model === name)\n .map(r => r.to.model)\n .filter(dep => modelNames.includes(dep))\n\n for (const dep of deps) {\n visit(dep, new Set(path))\n }\n\n if (!visited.has(name)) {\n visited.add(name)\n order.push(name)\n }\n }\n\n for (const name of modelNames) {\n visit(name)\n }\n\n return order\n}\n","/**\n * OpenAPI 3.x parser for DemoKit\n *\n * Parses OpenAPI specs into DemoKit's internal schema representation\n * with automatic relationship detection.\n *\n * Uses @scalar/openapi-parser - a modern, webpack-compatible parser.\n */\n\nimport { dereference, validate } from '@scalar/openapi-parser'\nimport type { OpenAPI, OpenAPIV3_1 } from '@scalar/openapi-types'\nimport type {\n DemokitSchema,\n SchemaInfo,\n Endpoint,\n DataModel,\n PropertyDef,\n HttpMethod,\n ParameterDef,\n RequestBody,\n ResponseDef,\n PropertyType,\n ModelType,\n} from './types'\nimport { detectRelationships } from './relationships'\n\n// Type aliases for OpenAPI 3.x structures\ntype OpenAPIDocument = OpenAPI.Document\ntype SchemaObject = OpenAPIV3_1.SchemaObject\ntype ReferenceObject = OpenAPIV3_1.ReferenceObject\ntype ParameterObject = OpenAPIV3_1.ParameterObject\ntype RequestBodyObject = OpenAPIV3_1.RequestBodyObject\ntype ResponseObject = OpenAPIV3_1.ResponseObject\ntype MediaTypeObject = OpenAPIV3_1.MediaTypeObject\n\n/**\n * Options for parsing OpenAPI specs\n */\nexport interface ParseOptions {\n /**\n * Whether to dereference all $ref pointers\n * @default true\n */\n dereference?: boolean\n\n /**\n * Whether to detect relationships automatically\n * @default true\n */\n detectRelationships?: boolean\n\n /**\n * Whether to include response schemas in models\n * @default true\n */\n includeResponses?: boolean\n}\n\n/**\n * Parse an OpenAPI spec from a file path or URL\n */\nexport async function parseOpenAPIFromPath(\n pathOrUrl: string,\n options: ParseOptions = {}\n): Promise<DemokitSchema> {\n // Fetch the content\n const response = await fetch(pathOrUrl)\n if (!response.ok) {\n throw new Error(`Failed to fetch OpenAPI spec from ${pathOrUrl}: ${response.statusText}`)\n }\n\n const content = await response.text()\n return parseOpenAPIFromString(content, options)\n}\n\n/**\n * Parse an OpenAPI spec from a string (JSON or YAML)\n */\nexport async function parseOpenAPIFromString(\n spec: string,\n options: ParseOptions = {}\n): Promise<DemokitSchema> {\n const { dereference: shouldDereference = true } = options\n\n // First validate the spec\n const validationResult = await validate(spec)\n if (!validationResult.valid) {\n const errorMessages = validationResult.errors?.map(e => e.message).join(', ') || 'Unknown validation error'\n throw new Error(`Invalid OpenAPI specification: ${errorMessages}`)\n }\n\n // Get the dereferenced schema if requested\n let schema: OpenAPIDocument\n if (shouldDereference) {\n const derefResult = await dereference(spec)\n if (derefResult.errors && derefResult.errors.length > 0) {\n const errorMessages = derefResult.errors.map(e => e.message).join(', ')\n throw new Error(`Failed to dereference OpenAPI spec: ${errorMessages}`)\n }\n schema = derefResult.schema as OpenAPIDocument\n } else {\n // Parse without dereferencing - just use the validated result\n schema = validationResult.specification as OpenAPIDocument\n }\n\n return parseOpenAPIDocument(schema, options)\n}\n\n/**\n * Parse an OpenAPI spec from an already-parsed object\n */\nexport async function parseOpenAPIFromObject(\n spec: Record<string, unknown>,\n options: ParseOptions = {}\n): Promise<DemokitSchema> {\n const { dereference: shouldDereference = true } = options\n\n // Validate the object\n const validationResult = await validate(spec)\n if (!validationResult.valid) {\n const errorMessages = validationResult.errors?.map(e => e.message).join(', ') || 'Unknown validation error'\n throw new Error(`Invalid OpenAPI specification: ${errorMessages}`)\n }\n\n // Get the dereferenced schema if requested\n let schema: OpenAPIDocument\n if (shouldDereference) {\n const derefResult = await dereference(spec)\n if (derefResult.errors && derefResult.errors.length > 0) {\n const errorMessages = derefResult.errors.map(e => e.message).join(', ')\n throw new Error(`Failed to dereference OpenAPI spec: ${errorMessages}`)\n }\n schema = derefResult.schema as OpenAPIDocument\n } else {\n schema = validationResult.specification as OpenAPIDocument\n }\n\n return parseOpenAPIDocument(schema, options)\n}\n\n/**\n * Parse an OpenAPI document into DemokitSchema\n */\nfunction parseOpenAPIDocument(\n doc: OpenAPIDocument,\n options: ParseOptions = {}\n): DemokitSchema {\n const { detectRelationships: shouldDetect = true } = options\n\n // Parse info\n const info = parseInfo(doc)\n\n // Parse models from components/schemas\n const models = parseModels(doc)\n\n // Parse endpoints from paths\n const endpoints = parseEndpoints(doc)\n\n // Detect relationships\n const relationships = shouldDetect ? detectRelationships(models) : []\n\n return {\n info,\n endpoints,\n models,\n relationships,\n }\n}\n\n/**\n * Parse API info from the document\n */\nfunction parseInfo(doc: OpenAPIDocument): SchemaInfo {\n const docInfo = (doc as any).info || {}\n const info: SchemaInfo = {\n title: docInfo.title ?? 'Untitled API',\n version: docInfo.version ?? '1.0.0',\n description: docInfo.description,\n }\n\n // Try to extract base URL from servers\n const servers = (doc as any).servers\n if (servers && servers.length > 0 && servers[0]) {\n info.baseUrl = servers[0].url\n }\n\n return info\n}\n\n/**\n * Parse all models from components/schemas\n */\nfunction parseModels(doc: OpenAPIDocument): Record<string, DataModel> {\n const models: Record<string, DataModel> = {}\n\n const components = (doc as any).components\n const schemas = components?.schemas\n if (!schemas) {\n return models\n }\n\n for (const [name, schema] of Object.entries(schemas)) {\n // Skip reference objects (shouldn't happen after dereference)\n if (schema && typeof schema === 'object' && '$ref' in schema) {\n continue\n }\n\n models[name] = parseSchemaToModel(name, schema as SchemaObject)\n }\n\n return models\n}\n\n/**\n * Parse a schema object into a DataModel\n */\nfunction parseSchemaToModel(name: string, schema: SchemaObject): DataModel {\n if (!schema || typeof schema !== 'object') {\n return { name, type: 'object' }\n }\n\n const s = schema as Record<string, unknown>\n const model: DataModel = {\n name,\n type: schemaTypeToModelType(s.type as string | string[] | undefined),\n description: s.description as string | undefined,\n }\n\n // Parse properties for object types\n if (s.type === 'object' || s.properties) {\n model.type = 'object'\n model.properties = {}\n model.required = (s.required as string[]) || []\n\n if (s.properties && typeof s.properties === 'object') {\n for (const [propName, propSchema] of Object.entries(s.properties)) {\n model.properties[propName] = parseProperty(\n propName,\n propSchema as SchemaObject | ReferenceObject,\n model.required.includes(propName)\n )\n }\n }\n\n if (s.additionalProperties !== undefined) {\n if (typeof s.additionalProperties === 'boolean') {\n model.additionalProperties = s.additionalProperties\n } else if (s.additionalProperties && typeof s.additionalProperties === 'object') {\n if ('$ref' in s.additionalProperties) {\n model.additionalProperties = {\n $ref: (s.additionalProperties as ReferenceObject).$ref,\n }\n } else {\n model.additionalProperties = parseSchemaToModel(\n `${name}AdditionalProps`,\n s.additionalProperties as SchemaObject\n )\n }\n }\n }\n }\n\n // Parse array items\n if (s.type === 'array' && s.items) {\n model.type = 'array'\n if (typeof s.items === 'object' && '$ref' in s.items) {\n model.items = { $ref: (s.items as ReferenceObject).$ref }\n } else {\n model.items = parseSchemaToModel(`${name}Item`, s.items as SchemaObject)\n }\n }\n\n // Parse enum values\n if (s.enum) {\n model.enum = s.enum as unknown[]\n }\n\n // Parse example\n if (s.example !== undefined) {\n model.example = s.example\n }\n\n return model\n}\n\n/**\n * Parse a property schema into a PropertyDef\n */\nfunction parseProperty(\n name: string,\n schema: SchemaObject | ReferenceObject,\n required: boolean\n): PropertyDef {\n // Handle $ref\n if (schema && typeof schema === 'object' && '$ref' in schema) {\n return {\n name,\n type: 'object',\n required,\n $ref: schema.$ref,\n }\n }\n\n const s = schema as Record<string, unknown>\n\n const prop: PropertyDef = {\n name,\n type: schemaTypeToPropertyType(s.type as string | string[] | undefined),\n required,\n nullable: s.nullable as boolean | undefined,\n description: s.description as string | undefined,\n format: s.format as string | undefined,\n enum: s.enum as unknown[] | undefined,\n example: s.example,\n default: s.default,\n minimum: s.minimum as number | undefined,\n maximum: s.maximum as number | undefined,\n minLength: s.minLength as number | undefined,\n maxLength: s.maxLength as number | undefined,\n pattern: s.pattern as string | undefined,\n }\n\n // Parse array items\n if (s.type === 'array' && s.items) {\n prop.type = 'array'\n if (typeof s.items === 'object' && '$ref' in s.items) {\n prop.items = { $ref: (s.items as ReferenceObject).$ref }\n } else {\n prop.items = parseSchemaToModel(`${name}Item`, s.items as SchemaObject)\n }\n }\n\n // Check for x-demokit-relationship extension\n const xRelationship = s['x-demokit-relationship']\n if (xRelationship && typeof xRelationship === 'object') {\n prop['x-demokit-relationship'] = xRelationship as { model: string; field: string }\n }\n\n return prop\n}\n\n/**\n * Parse all endpoints from paths\n */\nfunction parseEndpoints(doc: OpenAPIDocument): Endpoint[] {\n const endpoints: Endpoint[] = []\n\n const paths = (doc as any).paths\n if (!paths) {\n return endpoints\n }\n\n const methods: HttpMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem || typeof pathItem !== 'object') continue\n\n for (const method of methods) {\n const operation = (pathItem as Record<string, unknown>)[method.toLowerCase()]\n\n if (!operation || typeof operation !== 'object') continue\n\n endpoints.push(parseEndpoint(method, path, operation as Record<string, unknown>, pathItem as Record<string, unknown>))\n }\n }\n\n return endpoints\n}\n\n/**\n * Parse a single endpoint\n */\nfunction parseEndpoint(\n method: HttpMethod,\n path: string,\n operation: Record<string, unknown>,\n pathItem: Record<string, unknown>\n): Endpoint {\n // Combine path-level and operation-level parameters\n const pathParams: ParameterDef[] = []\n const queryParams: ParameterDef[] = []\n\n const allParams = [\n ...((pathItem.parameters as unknown[]) || []),\n ...((operation.parameters as unknown[]) || []),\n ]\n\n for (const param of allParams) {\n if (!param || typeof param !== 'object') continue\n if ('$ref' in param) continue // Skip refs\n\n const parsed = parseParameter(param as ParameterObject)\n\n if (parsed.in === 'path') {\n pathParams.push(parsed)\n } else if (parsed.in === 'query') {\n queryParams.push(parsed)\n }\n }\n\n // Parse request body\n let requestBody: RequestBody | undefined\n const opRequestBody = operation.requestBody\n if (opRequestBody && typeof opRequestBody === 'object' && !('$ref' in opRequestBody)) {\n requestBody = parseRequestBody(opRequestBody as RequestBodyObject)\n }\n\n // Parse responses\n const responses: Record<string, ResponseDef> = {}\n const opResponses = operation.responses\n if (opResponses && typeof opResponses === 'object') {\n for (const [statusCode, response] of Object.entries(opResponses)) {\n if (!response || typeof response !== 'object') continue\n if ('$ref' in response) continue\n responses[statusCode] = parseResponse(statusCode, response as ResponseObject)\n }\n }\n\n return {\n method,\n path,\n operationId: operation.operationId as string | undefined,\n summary: operation.summary as string | undefined,\n description: operation.description as string | undefined,\n pathParams,\n queryParams,\n requestBody,\n responses,\n tags: (operation.tags as string[]) || [],\n }\n}\n\n/**\n * Parse a parameter object\n */\nfunction parseParameter(param: ParameterObject): ParameterDef {\n const p = param as Record<string, unknown>\n const schema = p.schema as Record<string, unknown> | undefined\n\n return {\n name: p.name as string,\n in: p.in as 'path' | 'query' | 'header' | 'cookie',\n required: (p.required as boolean) ?? false,\n type: schema ? schemaTypeToPropertyType(schema.type as string | string[] | undefined) : 'string',\n format: schema?.format as string | undefined,\n description: p.description as string | undefined,\n example: p.example ?? schema?.example,\n }\n}\n\n/**\n * Parse a request body object\n */\nfunction parseRequestBody(body: RequestBodyObject): RequestBody {\n const b = body as Record<string, unknown>\n const content = b.content as Record<string, unknown> | undefined\n const contentType = Object.keys(content || {})[0] || 'application/json'\n const mediaType = content?.[contentType] as MediaTypeObject | undefined\n\n let schema: RequestBody['schema'] = { name: 'Unknown', type: 'object' }\n\n if (mediaType) {\n const m = mediaType as Record<string, unknown>\n const mediaSchema = m.schema\n if (mediaSchema && typeof mediaSchema === 'object') {\n if ('$ref' in mediaSchema) {\n schema = { $ref: (mediaSchema as ReferenceObject).$ref }\n } else {\n schema = parseSchemaToModel('RequestBody', mediaSchema as SchemaObject)\n }\n }\n }\n\n return {\n contentType,\n schema,\n required: (b.required as boolean) ?? false,\n description: b.description as string | undefined,\n }\n}\n\n/**\n * Parse a response object\n */\nfunction parseResponse(statusCode: string, response: ResponseObject): ResponseDef {\n const r = response as Record<string, unknown>\n const responseDef: ResponseDef = {\n statusCode,\n description: r.description as string | undefined,\n }\n\n const content = r.content as Record<string, unknown> | undefined\n if (content) {\n responseDef.content = {}\n\n for (const [contentType, mediaType] of Object.entries(content)) {\n if (!mediaType || typeof mediaType !== 'object') continue\n\n const m = mediaType as Record<string, unknown>\n const schema = m.schema\n if (schema && typeof schema === 'object') {\n if ('$ref' in schema) {\n responseDef.content[contentType] = {\n $ref: (schema as ReferenceObject).$ref,\n }\n } else {\n responseDef.content[contentType] = parseSchemaToModel(\n `Response${statusCode}`,\n schema as SchemaObject\n )\n }\n }\n }\n }\n\n return responseDef\n}\n\n/**\n * Convert OpenAPI schema type to ModelType\n */\nfunction schemaTypeToModelType(\n type: string | string[] | undefined\n): ModelType {\n if (!type) return 'object'\n if (Array.isArray(type)) return type[0] as ModelType\n return type as ModelType\n}\n\n/**\n * Convert OpenAPI schema type to PropertyType\n */\nfunction schemaTypeToPropertyType(\n type: string | string[] | undefined\n): PropertyType {\n if (!type) return 'object'\n if (Array.isArray(type)) return type[0] as PropertyType\n return type as PropertyType\n}\n"]}