@sdk-it/readme 0.27.0 → 0.28.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.js CHANGED
@@ -1,298 +1,5 @@
1
1
  // packages/readme/src/lib/readme.ts
2
- import { isEmpty } from "@sdk-it/core";
3
- import {
4
- forEachOperation,
5
- toSidebar
6
- } from "@sdk-it/spec";
7
-
8
- // packages/readme/src/lib/prop.emitter.ts
9
- import { followRef, isRef } from "@sdk-it/core";
10
- import { coerceTypes } from "@sdk-it/spec";
11
- var PropEmitter = class {
12
- #spec;
13
- constructor(spec) {
14
- this.#spec = spec;
15
- }
16
- /**
17
- * Handle objects (properties)
18
- */
19
- #object(schema) {
20
- const lines = [];
21
- const properties = schema.properties || {};
22
- if (Object.keys(properties).length > 0) {
23
- lines.push(`**Properties:**`);
24
- for (const [propName, propSchema] of Object.entries(properties)) {
25
- const isRequired = (schema.required ?? []).includes(propName);
26
- lines.push(...this.#property(propName, propSchema, isRequired));
27
- }
28
- }
29
- if (schema.additionalProperties) {
30
- lines.push(`**Additional Properties:**`);
31
- if (typeof schema.additionalProperties === "boolean") {
32
- lines.push(`- Allowed: ${schema.additionalProperties}`);
33
- } else {
34
- lines.push(
35
- ...this.handle(schema.additionalProperties).map((l) => ` ${l}`)
36
- );
37
- }
38
- }
39
- return lines;
40
- }
41
- /**
42
- * Format a property with its type and description
43
- */
44
- #property(name, schema, required) {
45
- const docs = this.handle(schema);
46
- const rawType = docs[0].replace("**Type:** ", "").replace(" (nullable)", "|null");
47
- const defaultVal = !isRef(schema) && schema.default !== void 0 ? ` default: ${JSON.stringify(schema.default)}` : "";
48
- const reqMark = required ? " required" : "";
49
- const summary = `- \`${name}\` ${rawType}${reqMark}${defaultVal}:`;
50
- const detailLines = docs.slice(1).filter((l) => !l.startsWith("**Default:**")).map((l) => ` ${l}`);
51
- return [summary, ...detailLines];
52
- }
53
- /**
54
- * Handle array schemas
55
- */
56
- #array(schema) {
57
- const lines = [];
58
- lines.push(`**Array items:**`);
59
- if (schema.items) {
60
- const itemDocs = this.handle(schema.items);
61
- lines.push(...itemDocs.map((line) => ` ${line}`));
62
- } else {
63
- lines.push(` **Type:** \`unknown\``);
64
- }
65
- if (schema.minItems !== void 0)
66
- lines.push(`- Minimum items: ${schema.minItems}`);
67
- if (schema.maxItems !== void 0)
68
- lines.push(`- Maximum items: ${schema.maxItems}`);
69
- if (schema.uniqueItems) lines.push(`- Items must be unique.`);
70
- return lines;
71
- }
72
- #ref($ref) {
73
- const schemaName = $ref.split("/").pop() || "object";
74
- const resolved = followRef(this.#spec, $ref);
75
- const lines = [
76
- `**Type:** [\`${schemaName}\`](#${schemaName.toLowerCase()})`
77
- ];
78
- if (resolved.description) {
79
- lines.push(resolved.description);
80
- }
81
- return lines;
82
- }
83
- #allOf(schemas) {
84
- const lines = ["**All of (Intersection):**"];
85
- schemas.forEach((subSchema, index) => {
86
- lines.push(`- **Constraint ${index + 1}:**`);
87
- const subLines = this.handle(subSchema);
88
- lines.push(...subLines.map((l) => ` ${l}`));
89
- });
90
- return lines;
91
- }
92
- #anyOf(schemas) {
93
- const lines = ["**Any of (Union):**"];
94
- schemas.forEach((subSchema, index) => {
95
- lines.push(`- **Option ${index + 1}:**`);
96
- const subLines = this.handle(subSchema);
97
- lines.push(...subLines.map((l) => ` ${l}`));
98
- });
99
- return lines;
100
- }
101
- #oneOf(schemas) {
102
- const lines = ["**One of (Exclusive Union):**"];
103
- schemas.forEach((subSchema, index) => {
104
- lines.push(`- **Option ${index + 1}:**`);
105
- const subLines = this.handle(subSchema);
106
- lines.push(...subLines.map((l) => ` ${l}`));
107
- });
108
- return lines;
109
- }
110
- #enum(schema) {
111
- const lines = [`**Type:** \`${schema.type || "unknown"}\` (enum)`];
112
- if (schema.description) lines.push(schema.description);
113
- lines.push("**Allowed values:**");
114
- lines.push(
115
- ...(schema.enum || []).map((val) => `- \`${JSON.stringify(val)}\``)
116
- );
117
- if (schema.default !== void 0) {
118
- lines.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
119
- }
120
- return lines;
121
- }
122
- #normal(type, schema, nullable) {
123
- const lines = [];
124
- const nullableSuffix = nullable ? " (nullable)" : "";
125
- const description = schema.description ? [schema.description] : [];
126
- switch (type) {
127
- case "string":
128
- lines.push(
129
- `**Type:** \`string\`${schema.format ? ` (format: ${schema.format})` : ""}${nullableSuffix}`
130
- );
131
- lines.push(...description);
132
- if (schema.minLength !== void 0)
133
- lines.push(`- Minimum length: ${schema.minLength}`);
134
- if (schema.maxLength !== void 0)
135
- lines.push(`- Maximum length: ${schema.maxLength}`);
136
- if (schema.pattern !== void 0)
137
- lines.push(`- Pattern: \`${schema.pattern}\``);
138
- break;
139
- case "number":
140
- case "integer":
141
- lines.push(
142
- `**Type:** \`${type}\`${schema.format ? ` (format: ${schema.format})` : ""}${nullableSuffix}`
143
- );
144
- lines.push(...description);
145
- if (schema.minimum !== void 0) {
146
- const exclusiveMin = typeof schema.exclusiveMinimum === "number";
147
- lines.push(
148
- `- Minimum: ${schema.minimum}${exclusiveMin ? " (exclusive)" : ""}`
149
- );
150
- if (exclusiveMin) {
151
- lines.push(
152
- `- Must be strictly greater than: ${schema.exclusiveMinimum}`
153
- );
154
- }
155
- } else if (typeof schema.exclusiveMinimum === "number") {
156
- lines.push(
157
- `- Must be strictly greater than: ${schema.exclusiveMinimum}`
158
- );
159
- }
160
- if (schema.maximum !== void 0) {
161
- const exclusiveMax = typeof schema.exclusiveMaximum === "number";
162
- lines.push(
163
- `- Maximum: ${schema.maximum}${exclusiveMax ? " (exclusive)" : ""}`
164
- );
165
- if (exclusiveMax) {
166
- lines.push(
167
- `- Must be strictly less than: ${schema.exclusiveMaximum}`
168
- );
169
- }
170
- } else if (typeof schema.exclusiveMaximum === "number") {
171
- lines.push(
172
- `- Must be strictly less than: ${schema.exclusiveMaximum}`
173
- );
174
- }
175
- if (schema.multipleOf !== void 0)
176
- lines.push(`- Must be a multiple of: ${schema.multipleOf}`);
177
- break;
178
- case "boolean":
179
- lines.push(`**Type:** \`boolean\`${nullableSuffix}`);
180
- lines.push(...description);
181
- break;
182
- case "object":
183
- lines.push(`**Type:** \`object\`${nullableSuffix}`);
184
- lines.push(...description);
185
- lines.push(...this.#object(schema));
186
- break;
187
- case "array":
188
- lines.push(`**Type:** \`array\`${nullableSuffix}`);
189
- lines.push(...description);
190
- lines.push(...this.#array(schema));
191
- break;
192
- case "null":
193
- lines.push(`**Type:** \`null\``);
194
- lines.push(...description);
195
- break;
196
- default:
197
- lines.push(`**Type:** \`${type}\`${nullableSuffix}`);
198
- lines.push(...description);
199
- }
200
- if (schema.default !== void 0) {
201
- lines.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
202
- }
203
- return lines.filter((l) => l);
204
- }
205
- /**
206
- * Handle schemas by resolving references and delegating to appropriate handler
207
- */
208
- handle(schemaOrRef) {
209
- if (isRef(schemaOrRef)) {
210
- return this.#ref(schemaOrRef.$ref);
211
- }
212
- const schema = schemaOrRef;
213
- if (schema.allOf && Array.isArray(schema.allOf)) {
214
- return this.#allOf(schema.allOf);
215
- }
216
- if (schema.anyOf && Array.isArray(schema.anyOf)) {
217
- return this.#anyOf(schema.anyOf);
218
- }
219
- if (schema.oneOf && Array.isArray(schema.oneOf)) {
220
- return this.#oneOf(schema.oneOf);
221
- }
222
- if (schema.enum && Array.isArray(schema.enum)) {
223
- return this.#enum(schema);
224
- }
225
- let types = coerceTypes(schema);
226
- let nullable = false;
227
- if (types.includes("null")) {
228
- nullable = true;
229
- types = types.filter((t) => t !== "null");
230
- }
231
- if (types.length === 0) {
232
- if (schema.properties || schema.additionalProperties) {
233
- types = ["object"];
234
- } else if (schema.items) {
235
- types = ["array"];
236
- }
237
- }
238
- if (types.length === 0) {
239
- const lines2 = ["**Type:** `unknown`"];
240
- if (schema.description) lines2.push(schema.description);
241
- if (schema.default !== void 0)
242
- lines2.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
243
- return lines2;
244
- }
245
- if (types.length === 1) {
246
- return this.#normal(types[0], schema, nullable);
247
- }
248
- const typeString = types.join(" | ");
249
- const nullableSuffix = nullable ? " (nullable)" : "";
250
- const lines = [`**Type:** \`${typeString}\`${nullableSuffix}`];
251
- if (schema.description) lines.push(schema.description);
252
- if (schema.default !== void 0)
253
- lines.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
254
- return lines;
255
- }
256
- /**
257
- * Process a request body and return markdown documentation
258
- */
259
- requestBody(requestBody) {
260
- if (!requestBody) return [];
261
- const lines = [];
262
- lines.push(`##### Request Body`);
263
- if (requestBody.description) {
264
- lines.push(requestBody.description);
265
- }
266
- if (requestBody.content) {
267
- const contentEntries = Object.entries(requestBody.content);
268
- if (contentEntries.length === 1) {
269
- const [contentType, mediaType] = contentEntries[0];
270
- lines.push(`**Content Type:** \`${contentType}\``);
271
- if (mediaType.schema) {
272
- const schemaDocs = this.handle(mediaType.schema);
273
- lines.push(...schemaDocs);
274
- }
275
- } else {
276
- for (const [contentType, mediaType] of contentEntries) {
277
- lines.push(`<details>`);
278
- lines.push(
279
- `<summary><b>Content Type:</b> \`${contentType}\`</summary>`
280
- );
281
- lines.push("");
282
- if (mediaType.schema) {
283
- const schemaDocs = this.handle(mediaType.schema);
284
- lines.push(...schemaDocs.map((l) => l));
285
- }
286
- lines.push("");
287
- lines.push(`</details>`);
288
- }
289
- }
290
- }
291
- return lines;
292
- }
293
- };
294
-
295
- // packages/readme/src/lib/readme.ts
2
+ import { toSidebar } from "@sdk-it/spec";
296
3
  function toTOC(spec) {
297
4
  const tocLines = [];
298
5
  const sidebar = toSidebar(spec);
@@ -323,8 +30,7 @@ function toTOC(spec) {
323
30
  }
324
31
  return { tocLines, contents };
325
32
  }
326
- function toReadme(spec, generators) {
327
- const propEmitter = new PropEmitter(spec);
33
+ function toReadme(spec) {
328
34
  const toc = toTOC(spec);
329
35
  const markdown = [];
330
36
  const generatedIntro = spec["x-docs"].flatMap((it) => it.items).find((doc) => doc.id === "generated-introduction");
@@ -338,68 +44,7 @@ function toReadme(spec, generators) {
338
44
  markdown.push(
339
45
  "This document provides an overview of the API endpoints available in this service. Each endpoint includes a brief description, example usage, and details about request and response formats."
340
46
  );
341
- markdown.push("");
342
- markdown.push("");
343
- markdown.push("```ts\n" + generators.client() + "\n```");
344
- markdown.push("");
345
47
  markdown.push(toc.contents.join("\n\n"));
346
- forEachOperation(spec, (entry, operation) => {
347
- const { method, path } = entry;
348
- markdown.push(
349
- `#### ${operation["x-fn-name"]} | ${`_${method.toUpperCase()} ${path}_`}`
350
- );
351
- markdown.push(operation.summary || "");
352
- const snippet = generators.snippet(entry, operation);
353
- markdown.push(`##### Example usage`);
354
- markdown.push(snippet);
355
- const requestBodyContent = propEmitter.requestBody(operation.requestBody);
356
- if (requestBodyContent.length > 1) {
357
- markdown.push(requestBodyContent.join("\n\n"));
358
- }
359
- markdown.push(`##### Responses`);
360
- for (const status in operation.responses) {
361
- const response = operation.responses[status];
362
- markdown.push(`<details>`);
363
- markdown.push(
364
- `<summary><b>${status}</b> <i>${response.description}</i></summary>`
365
- );
366
- if (!isEmpty(response.content)) {
367
- for (const [contentType, mediaType] of Object.entries(
368
- response.content
369
- )) {
370
- markdown.push(`
371
- **Content Type:** \`${contentType}\``);
372
- if (mediaType.schema) {
373
- const schemaDocs = propEmitter.handle(mediaType.schema);
374
- markdown.push(...schemaDocs.map((l) => `
375
- ${l}`));
376
- }
377
- }
378
- }
379
- markdown.push(`</details>`);
380
- }
381
- });
382
- if (spec.components?.schemas) {
383
- markdown.push("## Schemas");
384
- markdown.push("");
385
- for (const [schemaName, schema] of Object.entries(
386
- spec.components.schemas
387
- )) {
388
- if (schemaName === "ValidationError") {
389
- continue;
390
- }
391
- markdown.push(`<details>`);
392
- markdown.push(
393
- `<summary><h3 id="${schemaName.toLowerCase()}">${schemaName}</h3></summary>`
394
- );
395
- markdown.push("");
396
- const schemaDocs = propEmitter.handle(schema);
397
- markdown.push(...schemaDocs.map((line) => line.trim()));
398
- markdown.push("");
399
- markdown.push(`</details>`);
400
- markdown.push("");
401
- }
402
- }
403
48
  return markdown.join("\n\n");
404
49
  }
405
50
  export {
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/lib/readme.ts", "../src/lib/prop.emitter.ts"],
4
- "sourcesContent": ["import { isEmpty } from '@sdk-it/core';\nimport {\n type OurOpenAPIObject,\n forEachOperation,\n toSidebar,\n} from '@sdk-it/spec';\n\nimport type { Generator } from './generator.ts';\nimport { PropEmitter } from './prop.emitter.ts';\n\nfunction toTOC(spec: OurOpenAPIObject) {\n const tocLines: string[] = [];\n const sidebar = toSidebar(spec);\n const contents: string[] = [];\n\n for (const category of sidebar) {\n if (category.category) {\n tocLines.push(`### ${category.category}`);\n tocLines.push('');\n }\n\n for (const item of category.items) {\n if (item.id === 'generated-introduction') continue;\n\n contents.push(item.content || '');\n if (item.items && item.items.length > 0) {\n // This is a tag/group with operations\n tocLines.push(`- **${item.title}**`);\n\n // Add each operation in this tag\n for (const subItem of item.items) {\n // Create anchor that matches the markdown header format\n const anchor = `#${subItem.title\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-')}`;\n tocLines.push(` - [${subItem.title}](${anchor})`);\n }\n } else {\n // This might be a standalone item\n tocLines.push(`- **${item.title}**`);\n }\n }\n tocLines.push('');\n }\n\n if (spec.components?.schemas) {\n tocLines.push('- [Schemas](#schemas)');\n tocLines.push('');\n }\n\n return { tocLines, contents };\n}\n\nexport function toReadme(spec: OurOpenAPIObject, generators: Generator) {\n const propEmitter = new PropEmitter(spec);\n const toc = toTOC(spec);\n const markdown: string[] = [];\n\n const generatedIntro = spec['x-docs']\n .flatMap((it) => it.items)\n .find((doc) => doc.id === 'generated-introduction');\n\n if (generatedIntro && generatedIntro.content) {\n markdown.push(generatedIntro.content);\n }\n\n markdown.push('---');\n markdown.push('## Table of Contents');\n markdown.push(...toc.tocLines);\n markdown.push('---');\n\n markdown.push(\n 'This document provides an overview of the API endpoints available in this service. Each endpoint includes a brief description, example usage, and details about request and response formats.',\n );\n markdown.push('');\n markdown.push('');\n markdown.push('```ts\\n' + generators.client() + '\\n```');\n markdown.push('');\n\n markdown.push(toc.contents.join('\\n\\n'));\n\n forEachOperation(spec, (entry, operation) => {\n const { method, path } = entry;\n markdown.push(\n `#### ${operation['x-fn-name']} | ${`_${method.toUpperCase()} ${path}_`}`,\n );\n markdown.push(operation.summary || '');\n\n const snippet = generators.snippet(entry, operation);\n markdown.push(`##### Example usage`);\n markdown.push(snippet);\n\n // Process request body using the refactored emitter\n const requestBodyContent = propEmitter.requestBody(operation.requestBody);\n if (requestBodyContent.length > 1) {\n // Check if more than just the header was added\n markdown.push(requestBodyContent.join('\\n\\n'));\n }\n\n markdown.push(`##### Responses`);\n for (const status in operation.responses) {\n const response = operation.responses[status];\n // Wrap each response in its own toggle\n markdown.push(`<details>`);\n markdown.push(\n `<summary><b>${status}</b> <i>${response.description}</i></summary>`,\n );\n if (!isEmpty(response.content)) {\n for (const [contentType, mediaType] of Object.entries(\n response.content,\n )) {\n markdown.push(`\\n**Content Type:** \\`${contentType}\\``);\n if (mediaType.schema) {\n const schemaDocs = propEmitter.handle(mediaType.schema);\n // hide emitter output under the toggle\n markdown.push(...schemaDocs.map((l) => `\\n${l}`));\n }\n }\n }\n markdown.push(`</details>`);\n }\n }); // Add schemas section at the bottom\n if (spec.components?.schemas) {\n markdown.push('## Schemas');\n markdown.push('');\n\n for (const [schemaName, schema] of Object.entries(\n spec.components.schemas,\n )) {\n // Include all schemas except ValidationError which is internal\n if (schemaName === 'ValidationError') {\n continue;\n }\n\n markdown.push(`<details>`);\n markdown.push(\n `<summary><h3 id=\"${schemaName.toLowerCase()}\">${schemaName}</h3></summary>`,\n );\n markdown.push('');\n\n const schemaDocs = propEmitter.handle(schema);\n markdown.push(...schemaDocs.map((line) => line.trim()));\n\n markdown.push('');\n markdown.push(`</details>`);\n markdown.push('');\n }\n }\n\n // Generate Table of Contents\n\n return markdown.join('\\n\\n');\n}\n", "import type {\n OpenAPIObject,\n ReferenceObject,\n RequestBodyObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { followRef, isRef } from '@sdk-it/core';\nimport { coerceTypes } from '@sdk-it/spec';\n\n/**\n * PropEmitter handles converting OpenAPI schemas to Markdown documentation\n */\nexport class PropEmitter {\n #spec: OpenAPIObject;\n\n constructor(spec: OpenAPIObject) {\n this.#spec = spec;\n }\n\n /**\n * Handle objects (properties)\n */\n #object(schema: SchemaObject): string[] {\n const lines: string[] = [];\n const properties = schema.properties || {};\n\n if (Object.keys(properties).length > 0) {\n lines.push(`**Properties:**`);\n\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = (schema.required ?? []).includes(propName);\n lines.push(...this.#property(propName, propSchema, isRequired));\n }\n }\n\n // Handle additionalProperties\n if (schema.additionalProperties) {\n lines.push(`**Additional Properties:**`);\n if (typeof schema.additionalProperties === 'boolean') {\n lines.push(`- Allowed: ${schema.additionalProperties}`);\n } else {\n // Indent the schema documentation for additional properties\n lines.push(\n ...this.handle(schema.additionalProperties).map((l) => ` ${l}`),\n );\n }\n }\n\n return lines;\n }\n\n /**\n * Format a property with its type and description\n */\n #property(\n name: string,\n schema: SchemaObject | ReferenceObject,\n required: boolean,\n ): string[] {\n // get full docs and extract the type line\n const docs = this.handle(schema);\n const rawType = docs[0]\n .replace('**Type:** ', '')\n .replace(' (nullable)', '|null');\n\n // detect default if present on the schema\n const defaultVal =\n !isRef(schema) && (schema as SchemaObject).default !== undefined\n ? ` default: ${JSON.stringify((schema as SchemaObject).default)}`\n : '';\n\n // build summary line\n const reqMark = required ? ' required' : '';\n const summary = `- \\`${name}\\` ${rawType}${reqMark}${defaultVal}:`;\n\n // assemble final lines (skip the type and any default in details)\n const detailLines = docs\n .slice(1)\n .filter((l) => !l.startsWith('**Default:**'))\n .map((l) => ` ${l}`);\n\n return [summary, ...detailLines];\n }\n\n /**\n * Handle array schemas\n */\n #array(schema: SchemaObject): string[] {\n const lines: string[] = [];\n lines.push(`**Array items:**`);\n\n if (schema.items) {\n // Get documentation for the items schema\n const itemDocs = this.handle(schema.items);\n // Indent item documentation\n lines.push(...itemDocs.map((line) => ` ${line}`));\n } else {\n lines.push(` **Type:** \\`unknown\\``); // Array of unknown items\n }\n // Add array constraints\n if (schema.minItems !== undefined)\n lines.push(`- Minimum items: ${schema.minItems}`);\n if (schema.maxItems !== undefined)\n lines.push(`- Maximum items: ${schema.maxItems}`);\n if (schema.uniqueItems) lines.push(`- Items must be unique.`);\n\n return lines;\n }\n\n #ref($ref: string): string[] {\n const schemaName = $ref.split('/').pop() || 'object';\n const resolved = followRef<SchemaObject>(this.#spec, $ref);\n // Link to the schema definition (assuming heading anchors are generated elsewhere)\n const lines = [\n `**Type:** [\\`${schemaName}\\`](#${schemaName.toLowerCase()})`,\n ];\n if (resolved.description) {\n lines.push(resolved.description);\n }\n // Avoid deep recursion by default, just link and show description.\n // If more detail is needed, the linked definition should provide it.\n return lines;\n }\n\n #allOf(schemas: (SchemaObject | ReferenceObject)[]): string[] {\n const lines = ['**All of (Intersection):**'];\n schemas.forEach((subSchema, index) => {\n lines.push(`- **Constraint ${index + 1}:**`);\n const subLines = this.handle(subSchema);\n lines.push(...subLines.map((l) => ` ${l}`)); // Indent sub-schema docs\n });\n return lines;\n }\n\n #anyOf(schemas: (SchemaObject | ReferenceObject)[]): string[] {\n const lines = ['**Any of (Union):**'];\n schemas.forEach((subSchema, index) => {\n lines.push(`- **Option ${index + 1}:**`);\n const subLines = this.handle(subSchema);\n lines.push(...subLines.map((l) => ` ${l}`));\n });\n return lines;\n }\n\n #oneOf(schemas: (SchemaObject | ReferenceObject)[]): string[] {\n const lines = ['**One of (Exclusive Union):**'];\n schemas.forEach((subSchema, index) => {\n lines.push(`- **Option ${index + 1}:**`);\n const subLines = this.handle(subSchema);\n lines.push(...subLines.map((l) => ` ${l}`));\n });\n return lines;\n }\n\n #enum(schema: SchemaObject): string[] {\n const lines = [`**Type:** \\`${schema.type || 'unknown'}\\` (enum)`];\n if (schema.description) lines.push(schema.description);\n lines.push('**Allowed values:**');\n lines.push(\n ...(schema.enum || []).map((val) => `- \\`${JSON.stringify(val)}\\``),\n );\n if (schema.default !== undefined) {\n lines.push(`**Default:** \\`${JSON.stringify(schema.default)}\\``);\n }\n return lines;\n }\n\n #normal(type: string, schema: SchemaObject, nullable: boolean): string[] {\n const lines: string[] = [];\n const nullableSuffix = nullable ? ' (nullable)' : '';\n const description = schema.description ? [schema.description] : [];\n\n switch (type) {\n case 'string':\n lines.push(\n `**Type:** \\`string\\`${schema.format ? ` (format: ${schema.format})` : ''}${nullableSuffix}`,\n );\n lines.push(...description);\n if (schema.minLength !== undefined)\n lines.push(`- Minimum length: ${schema.minLength}`);\n if (schema.maxLength !== undefined)\n lines.push(`- Maximum length: ${schema.maxLength}`);\n if (schema.pattern !== undefined)\n lines.push(`- Pattern: \\`${schema.pattern}\\``);\n break;\n case 'number':\n case 'integer':\n lines.push(\n `**Type:** \\`${type}\\`${schema.format ? ` (format: ${schema.format})` : ''}${nullableSuffix}`,\n );\n lines.push(...description);\n // Add number constraints (OpenAPI 3.1)\n if (schema.minimum !== undefined) {\n // Check if exclusiveMinimum is a number (OAS 3.1)\n const exclusiveMin = typeof schema.exclusiveMinimum === 'number';\n lines.push(\n `- Minimum: ${schema.minimum}${exclusiveMin ? ' (exclusive)' : ''}`,\n );\n if (exclusiveMin) {\n lines.push(\n `- Must be strictly greater than: ${schema.exclusiveMinimum}`,\n );\n }\n } else if (typeof schema.exclusiveMinimum === 'number') {\n lines.push(\n `- Must be strictly greater than: ${schema.exclusiveMinimum}`,\n );\n }\n\n if (schema.maximum !== undefined) {\n // Check if exclusiveMaximum is a number (OAS 3.1)\n const exclusiveMax = typeof schema.exclusiveMaximum === 'number';\n lines.push(\n `- Maximum: ${schema.maximum}${exclusiveMax ? ' (exclusive)' : ''}`,\n );\n if (exclusiveMax) {\n lines.push(\n `- Must be strictly less than: ${schema.exclusiveMaximum}`,\n );\n }\n } else if (typeof schema.exclusiveMaximum === 'number') {\n lines.push(\n `- Must be strictly less than: ${schema.exclusiveMaximum}`,\n );\n }\n if (schema.multipleOf !== undefined)\n lines.push(`- Must be a multiple of: ${schema.multipleOf}`);\n break;\n case 'boolean':\n lines.push(`**Type:** \\`boolean\\`${nullableSuffix}`);\n lines.push(...description);\n break;\n case 'object':\n lines.push(`**Type:** \\`object\\`${nullableSuffix}`);\n lines.push(...description);\n lines.push(...this.#object(schema));\n break;\n case 'array':\n lines.push(`**Type:** \\`array\\`${nullableSuffix}`);\n lines.push(...description);\n lines.push(...this.#array(schema));\n break;\n case 'null':\n lines.push(`**Type:** \\`null\\``);\n lines.push(...description);\n break;\n default:\n lines.push(`**Type:** \\`${type}\\`${nullableSuffix}`);\n lines.push(...description);\n }\n if (schema.default !== undefined) {\n lines.push(`**Default:** \\`${JSON.stringify(schema.default)}\\``);\n }\n return lines.filter((l) => l); // Filter out empty description lines\n }\n\n /**\n * Handle schemas by resolving references and delegating to appropriate handler\n */\n public handle(schemaOrRef: SchemaObject | ReferenceObject): string[] {\n if (isRef(schemaOrRef)) {\n return this.#ref(schemaOrRef.$ref);\n }\n\n const schema = schemaOrRef;\n\n // Handle composition keywords first\n if (schema.allOf && Array.isArray(schema.allOf)) {\n return this.#allOf(schema.allOf);\n }\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n return this.#anyOf(schema.anyOf);\n }\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return this.#oneOf(schema.oneOf);\n }\n\n // Handle enums\n if (schema.enum && Array.isArray(schema.enum)) {\n return this.#enum(schema);\n }\n\n // Determine type(s) and nullability\n let types = coerceTypes(schema);\n let nullable = false; // Default to false\n\n if (types.includes('null')) {\n nullable = true;\n types = types.filter((t) => t !== 'null');\n }\n\n // Infer type if not explicitly set\n if (types.length === 0) {\n if (schema.properties || schema.additionalProperties) {\n types = ['object'];\n } else if (schema.items) {\n types = ['array'];\n }\n // Add other inferences if needed (e.g., based on format)\n }\n\n // If still no type, treat as unknown or any\n if (types.length === 0) {\n const lines = ['**Type:** `unknown`'];\n if (schema.description) lines.push(schema.description);\n if (schema.default !== undefined)\n lines.push(`**Default:** \\`${JSON.stringify(schema.default)}\\``);\n return lines;\n }\n\n // Handle single type (potentially nullable)\n if (types.length === 1) {\n return this.#normal(types[0], schema, nullable);\n }\n\n // Handle union of multiple non-null types (potentially nullable overall)\n const typeString = types.join(' | ');\n const nullableSuffix = nullable ? ' (nullable)' : '';\n const lines = [`**Type:** \\`${typeString}\\`${nullableSuffix}`];\n if (schema.description) lines.push(schema.description);\n if (schema.default !== undefined)\n lines.push(`**Default:** \\`${JSON.stringify(schema.default)}\\``);\n return lines;\n }\n\n /**\n * Process a request body and return markdown documentation\n */\n requestBody(requestBody?: RequestBodyObject): string[] {\n if (!requestBody) return [];\n\n const lines: string[] = [];\n lines.push(`##### Request Body`);\n\n if (requestBody.description) {\n lines.push(requestBody.description);\n }\n\n if (requestBody.content) {\n const contentEntries = Object.entries(requestBody.content);\n\n // If only one content type, show it directly without toggles\n if (contentEntries.length === 1) {\n const [contentType, mediaType] = contentEntries[0];\n lines.push(`**Content Type:** \\`${contentType}\\``);\n\n if (mediaType.schema) {\n const schemaDocs = this.handle(mediaType.schema);\n lines.push(...schemaDocs);\n }\n } else {\n // Multiple content types - use collapsible toggles\n for (const [contentType, mediaType] of contentEntries) {\n lines.push(`<details>`);\n lines.push(\n `<summary><b>Content Type:</b> \\`${contentType}\\`</summary>`,\n );\n lines.push('');\n\n if (mediaType.schema) {\n const schemaDocs = this.handle(mediaType.schema);\n lines.push(...schemaDocs.map((l) => l));\n }\n\n lines.push('');\n lines.push(`</details>`);\n }\n }\n }\n\n return lines;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["lines"]
3
+ "sources": ["../src/lib/readme.ts"],
4
+ "sourcesContent": ["import { type OurOpenAPIObject, toSidebar } from '@sdk-it/spec';\n\nfunction toTOC(spec: OurOpenAPIObject) {\n const tocLines: string[] = [];\n const sidebar = toSidebar(spec);\n const contents: string[] = [];\n\n for (const category of sidebar) {\n if (category.category) {\n tocLines.push(`### ${category.category}`);\n tocLines.push('');\n }\n\n for (const item of category.items) {\n if (item.id === 'generated-introduction') continue;\n\n contents.push(item.content || '');\n if (item.items && item.items.length > 0) {\n // This is a tag/group with operations\n tocLines.push(`- **${item.title}**`);\n\n // Add each operation in this tag\n for (const subItem of item.items) {\n // Create anchor that matches the markdown header format\n const anchor = `#${subItem.title\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-')}`;\n tocLines.push(` - [${subItem.title}](${anchor})`);\n }\n } else {\n // This might be a standalone item\n tocLines.push(`- **${item.title}**`);\n }\n }\n tocLines.push('');\n }\n\n if (spec.components?.schemas) {\n tocLines.push('- [Schemas](#schemas)');\n tocLines.push('');\n }\n\n return { tocLines, contents };\n}\n\nexport function toReadme(spec: OurOpenAPIObject) {\n const toc = toTOC(spec);\n const markdown: string[] = [];\n\n const generatedIntro = spec['x-docs']\n .flatMap((it) => it.items)\n .find((doc) => doc.id === 'generated-introduction');\n\n if (generatedIntro && generatedIntro.content) {\n markdown.push(generatedIntro.content);\n }\n\n markdown.push('---');\n markdown.push('## Table of Contents');\n markdown.push(...toc.tocLines);\n markdown.push('---');\n\n markdown.push(\n 'This document provides an overview of the API endpoints available in this service. Each endpoint includes a brief description, example usage, and details about request and response formats.',\n );\n\n markdown.push(toc.contents.join('\\n\\n'));\n\n return markdown.join('\\n\\n');\n}\n"],
5
+ "mappings": ";AAAA,SAAgC,iBAAiB;AAEjD,SAAS,MAAM,MAAwB;AACrC,QAAM,WAAqB,CAAC;AAC5B,QAAM,UAAU,UAAU,IAAI;AAC9B,QAAM,WAAqB,CAAC;AAE5B,aAAW,YAAY,SAAS;AAC9B,QAAI,SAAS,UAAU;AACrB,eAAS,KAAK,OAAO,SAAS,QAAQ,EAAE;AACxC,eAAS,KAAK,EAAE;AAAA,IAClB;AAEA,eAAW,QAAQ,SAAS,OAAO;AACjC,UAAI,KAAK,OAAO,yBAA0B;AAE1C,eAAS,KAAK,KAAK,WAAW,EAAE;AAChC,UAAI,KAAK,SAAS,KAAK,MAAM,SAAS,GAAG;AAEvC,iBAAS,KAAK,OAAO,KAAK,KAAK,IAAI;AAGnC,mBAAW,WAAW,KAAK,OAAO;AAEhC,gBAAM,SAAS,IAAI,QAAQ,MACxB,YAAY,EACZ,QAAQ,aAAa,EAAE,EACvB,QAAQ,QAAQ,GAAG,CAAC;AACvB,mBAAS,KAAK,QAAQ,QAAQ,KAAK,KAAK,MAAM,GAAG;AAAA,QACnD;AAAA,MACF,OAAO;AAEL,iBAAS,KAAK,OAAO,KAAK,KAAK,IAAI;AAAA,MACrC;AAAA,IACF;AACA,aAAS,KAAK,EAAE;AAAA,EAClB;AAEA,MAAI,KAAK,YAAY,SAAS;AAC5B,aAAS,KAAK,uBAAuB;AACrC,aAAS,KAAK,EAAE;AAAA,EAClB;AAEA,SAAO,EAAE,UAAU,SAAS;AAC9B;AAEO,SAAS,SAAS,MAAwB;AAC/C,QAAM,MAAM,MAAM,IAAI;AACtB,QAAM,WAAqB,CAAC;AAE5B,QAAM,iBAAiB,KAAK,QAAQ,EACjC,QAAQ,CAAC,OAAO,GAAG,KAAK,EACxB,KAAK,CAAC,QAAQ,IAAI,OAAO,wBAAwB;AAEpD,MAAI,kBAAkB,eAAe,SAAS;AAC5C,aAAS,KAAK,eAAe,OAAO;AAAA,EACtC;AAEA,WAAS,KAAK,KAAK;AACnB,WAAS,KAAK,sBAAsB;AACpC,WAAS,KAAK,GAAG,IAAI,QAAQ;AAC7B,WAAS,KAAK,KAAK;AAEnB,WAAS;AAAA,IACP;AAAA,EACF;AAEA,WAAS,KAAK,IAAI,SAAS,KAAK,MAAM,CAAC;AAEvC,SAAO,SAAS,KAAK,MAAM;AAC7B;",
6
+ "names": []
7
7
  }
@@ -1,4 +1,3 @@
1
1
  import { type OurOpenAPIObject } from '@sdk-it/spec';
2
- import type { Generator } from './generator.ts';
3
- export declare function toReadme(spec: OurOpenAPIObject, generators: Generator): string;
2
+ export declare function toReadme(spec: OurOpenAPIObject): string;
4
3
  //# sourceMappingURL=readme.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"readme.d.ts","sourceRoot":"","sources":["../../src/lib/readme.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA+ChD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,SAAS,UAmGrE"}
1
+ {"version":3,"file":"readme.d.ts","sourceRoot":"","sources":["../../src/lib/readme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAa,MAAM,cAAc,CAAC;AA8ChE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,UAwB9C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdk-it/readme",
3
- "version": "0.27.0",
3
+ "version": "0.28.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "!**/*.tsbuildinfo"
22
22
  ],
23
23
  "dependencies": {
24
- "@sdk-it/core": "0.27.0",
25
- "@sdk-it/spec": "0.27.0"
24
+ "@sdk-it/core": "0.28.0",
25
+ "@sdk-it/spec": "0.28.0"
26
26
  }
27
27
  }