@sdk-it/typescript 0.26.0 → 0.27.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
@@ -10,7 +10,6 @@ import {
10
10
  getFolderExports,
11
11
  writeFiles
12
12
  } from "@sdk-it/core/file-system.js";
13
- import { toReadme } from "@sdk-it/readme";
14
13
  import {
15
14
  augmentSpec,
16
15
  cleanFiles,
@@ -159,10 +158,10 @@ var ZodEmitter = class {
159
158
  switch (schema.format) {
160
159
  case "date-time":
161
160
  case "datetime":
162
- base = "z.coerce.date()";
161
+ base = "z.string().datetime()";
163
162
  break;
164
163
  case "date":
165
- base = "z.coerce.date() /* or z.string() if you want raw date strings */";
164
+ base = "z.coerce.date()";
166
165
  break;
167
166
  case "time":
168
167
  base = "z.string() /* optionally add .regex(...) for HH:MM:SS format */";
@@ -1594,17 +1593,397 @@ var offset_pagination_default = "type OffsetPaginationParams = {\n offset: numb
1594
1593
  // packages/typescript/src/lib/paginations/page-pagination.txt
1595
1594
  var page_pagination_default = "type InferPage<T> = T extends Page<infer U> ? U : never;\ntype PaginationParams<P extends number | bigint, S extends number | bigint> = {\n page?: P;\n pageSize?: S;\n};\n\ninterface Metadata {\n hasMore?: boolean;\n}\n\ntype PaginationResult<T, M extends Metadata> = {\n data: T[];\n meta: M;\n};\n\ntype FetchFn<\n T,\n M extends Metadata,\n P extends number | bigint,\n S extends number | bigint,\n> = (input: Partial<PaginationParams<P, S>>) => Promise<PaginationResult<T, M>>;\n\n/**\n * @experimental\n */\nexport class Pagination<\n T,\n M extends Metadata,\n P extends number | bigint,\n S extends number | bigint,\n> {\n #meta: PaginationResult<T, M>['meta'] | null = null;\n #params: PaginationParams<P, S>;\n #currentPage: Page<T> | null = null;\n readonly #fetchFn: FetchFn<T, M, P, S>;\n\n constructor(\n initialParams: Partial<PaginationParams<P, S>>,\n fetchFn: FetchFn<T, M, P, S>,\n ) {\n this.#fetchFn = fetchFn;\n this.#params = { ...initialParams, page: initialParams.page };\n }\n\n async getNextPage() {\n const result = await this.#fetchFn(this.#params);\n this.#currentPage = new Page(result.data);\n this.#meta = result.meta;\n this.#params = {\n ...this.#params,\n page: ((this.#params.page as number) || 0 + 1) as never,\n };\n return this;\n }\n\n getCurrentPage() {\n if (!this.#currentPage) {\n throw new Error(\n 'No page data available. Please call getNextPage() first.',\n );\n }\n return this.#currentPage;\n }\n\n get hasMore() {\n if (!this.#meta) {\n throw new Error(\n 'No meta data available. Please call getNextPage() first.',\n );\n }\n return this.#meta.hasMore;\n }\n\n async *[Symbol.asyncIterator]() {\n for await (const page of this.iter()) {\n yield page.getCurrentPage();\n }\n }\n\n async *iter() {\n if (!this.#currentPage) {\n yield await this.getNextPage();\n }\n\n while (this.hasMore) {\n yield await this.getNextPage();\n }\n }\n\n get metadata() {\n if (!this.#meta) {\n throw new Error(\n 'No meta data available. Please call getNextPage() first.',\n );\n }\n return this.#meta;\n }\n}\n\nclass Page<T> {\n data: T[];\n constructor(data: T[]) {\n this.data = data;\n }\n}\n";
1596
1595
 
1596
+ // packages/typescript/src/lib/readme/readme.ts
1597
+ import { isEmpty as isEmpty3 } from "@sdk-it/core";
1598
+ import { forEachOperation as forEachOperation2 } from "@sdk-it/spec";
1599
+
1600
+ // packages/typescript/src/lib/readme/prop.emitter.ts
1601
+ import { followRef as followRef4, isRef as isRef4 } from "@sdk-it/core";
1602
+ import { coerceTypes } from "@sdk-it/spec";
1603
+ var PropEmitter = class {
1604
+ #spec;
1605
+ constructor(spec) {
1606
+ this.#spec = spec;
1607
+ }
1608
+ /**
1609
+ * Handle objects (properties)
1610
+ */
1611
+ #object(schema) {
1612
+ const lines = [];
1613
+ const properties = schema.properties || {};
1614
+ if (Object.keys(properties).length > 0) {
1615
+ lines.push(`**Properties:**`);
1616
+ for (const [propName, propSchema] of Object.entries(properties)) {
1617
+ const isRequired = (schema.required ?? []).includes(propName);
1618
+ lines.push(...this.#property(propName, propSchema, isRequired));
1619
+ }
1620
+ }
1621
+ if (schema.additionalProperties) {
1622
+ lines.push(`**Additional Properties:**`);
1623
+ if (typeof schema.additionalProperties === "boolean") {
1624
+ lines.push(`- Allowed: ${schema.additionalProperties}`);
1625
+ } else {
1626
+ lines.push(
1627
+ ...this.handle(schema.additionalProperties).map((l) => ` ${l}`)
1628
+ );
1629
+ }
1630
+ }
1631
+ return lines;
1632
+ }
1633
+ /**
1634
+ * Format a property with its type and description
1635
+ */
1636
+ #property(name, schema, required) {
1637
+ const docs = this.handle(schema);
1638
+ const rawType = docs[0].replace("**Type:** ", "").replace(" (nullable)", "|null");
1639
+ const defaultVal = !isRef4(schema) && schema.default !== void 0 ? ` default: ${JSON.stringify(schema.default)}` : "";
1640
+ const reqMark = required ? " required" : "";
1641
+ const summary = `- \`${name}\` ${rawType}${reqMark}${defaultVal}:`;
1642
+ const detailLines = docs.slice(1).filter((l) => !l.startsWith("**Default:**")).map((l) => ` ${l}`);
1643
+ return [summary, ...detailLines];
1644
+ }
1645
+ /**
1646
+ * Handle array schemas
1647
+ */
1648
+ #array(schema) {
1649
+ const lines = [];
1650
+ lines.push(`**Array items:**`);
1651
+ if (schema.items) {
1652
+ const itemDocs = this.handle(schema.items);
1653
+ lines.push(...itemDocs.map((line) => ` ${line}`));
1654
+ } else {
1655
+ lines.push(` **Type:** \`unknown\``);
1656
+ }
1657
+ if (schema.minItems !== void 0)
1658
+ lines.push(`- Minimum items: ${schema.minItems}`);
1659
+ if (schema.maxItems !== void 0)
1660
+ lines.push(`- Maximum items: ${schema.maxItems}`);
1661
+ if (schema.uniqueItems) lines.push(`- Items must be unique.`);
1662
+ return lines;
1663
+ }
1664
+ #ref($ref) {
1665
+ const schemaName = $ref.split("/").pop() || "object";
1666
+ const resolved = followRef4(this.#spec, $ref);
1667
+ const lines = [
1668
+ `**Type:** [\`${schemaName}\`](#${schemaName.toLowerCase()})`
1669
+ ];
1670
+ if (resolved.description) {
1671
+ lines.push(resolved.description);
1672
+ }
1673
+ return lines;
1674
+ }
1675
+ #allOf(schemas) {
1676
+ const lines = ["**All of (Intersection):**"];
1677
+ schemas.forEach((subSchema, index) => {
1678
+ lines.push(`- **Constraint ${index + 1}:**`);
1679
+ const subLines = this.handle(subSchema);
1680
+ lines.push(...subLines.map((l) => ` ${l}`));
1681
+ });
1682
+ return lines;
1683
+ }
1684
+ #anyOf(schemas) {
1685
+ const lines = ["**Any of (Union):**"];
1686
+ schemas.forEach((subSchema, index) => {
1687
+ lines.push(`- **Option ${index + 1}:**`);
1688
+ const subLines = this.handle(subSchema);
1689
+ lines.push(...subLines.map((l) => ` ${l}`));
1690
+ });
1691
+ return lines;
1692
+ }
1693
+ #oneOf(schemas) {
1694
+ const lines = ["**One of (Exclusive Union):**"];
1695
+ schemas.forEach((subSchema, index) => {
1696
+ lines.push(`- **Option ${index + 1}:**`);
1697
+ const subLines = this.handle(subSchema);
1698
+ lines.push(...subLines.map((l) => ` ${l}`));
1699
+ });
1700
+ return lines;
1701
+ }
1702
+ #enum(schema) {
1703
+ const lines = [`**Type:** \`${schema.type || "unknown"}\` (enum)`];
1704
+ if (schema.description) lines.push(schema.description);
1705
+ lines.push("**Allowed values:**");
1706
+ lines.push(
1707
+ ...(schema.enum || []).map((val) => `- \`${JSON.stringify(val)}\``)
1708
+ );
1709
+ if (schema.default !== void 0) {
1710
+ lines.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
1711
+ }
1712
+ return lines;
1713
+ }
1714
+ #normal(type, schema, nullable) {
1715
+ const lines = [];
1716
+ const nullableSuffix = nullable ? " (nullable)" : "";
1717
+ const description = schema.description ? [schema.description] : [];
1718
+ switch (type) {
1719
+ case "string":
1720
+ lines.push(
1721
+ `**Type:** \`string\`${schema.format ? ` (format: ${schema.format})` : ""}${nullableSuffix}`
1722
+ );
1723
+ lines.push(...description);
1724
+ if (schema.minLength !== void 0)
1725
+ lines.push(`- Minimum length: ${schema.minLength}`);
1726
+ if (schema.maxLength !== void 0)
1727
+ lines.push(`- Maximum length: ${schema.maxLength}`);
1728
+ if (schema.pattern !== void 0)
1729
+ lines.push(`- Pattern: \`${schema.pattern}\``);
1730
+ break;
1731
+ case "number":
1732
+ case "integer":
1733
+ lines.push(
1734
+ `**Type:** \`${type}\`${schema.format ? ` (format: ${schema.format})` : ""}${nullableSuffix}`
1735
+ );
1736
+ lines.push(...description);
1737
+ if (schema.minimum !== void 0) {
1738
+ const exclusiveMin = typeof schema.exclusiveMinimum === "number";
1739
+ lines.push(
1740
+ `- Minimum: ${schema.minimum}${exclusiveMin ? " (exclusive)" : ""}`
1741
+ );
1742
+ if (exclusiveMin) {
1743
+ lines.push(
1744
+ `- Must be strictly greater than: ${schema.exclusiveMinimum}`
1745
+ );
1746
+ }
1747
+ } else if (typeof schema.exclusiveMinimum === "number") {
1748
+ lines.push(
1749
+ `- Must be strictly greater than: ${schema.exclusiveMinimum}`
1750
+ );
1751
+ }
1752
+ if (schema.maximum !== void 0) {
1753
+ const exclusiveMax = typeof schema.exclusiveMaximum === "number";
1754
+ lines.push(
1755
+ `- Maximum: ${schema.maximum}${exclusiveMax ? " (exclusive)" : ""}`
1756
+ );
1757
+ if (exclusiveMax) {
1758
+ lines.push(
1759
+ `- Must be strictly less than: ${schema.exclusiveMaximum}`
1760
+ );
1761
+ }
1762
+ } else if (typeof schema.exclusiveMaximum === "number") {
1763
+ lines.push(
1764
+ `- Must be strictly less than: ${schema.exclusiveMaximum}`
1765
+ );
1766
+ }
1767
+ if (schema.multipleOf !== void 0)
1768
+ lines.push(`- Must be a multiple of: ${schema.multipleOf}`);
1769
+ break;
1770
+ case "boolean":
1771
+ lines.push(`**Type:** \`boolean\`${nullableSuffix}`);
1772
+ lines.push(...description);
1773
+ break;
1774
+ case "object":
1775
+ lines.push(`**Type:** \`object\`${nullableSuffix}`);
1776
+ lines.push(...description);
1777
+ lines.push(...this.#object(schema));
1778
+ break;
1779
+ case "array":
1780
+ lines.push(`**Type:** \`array\`${nullableSuffix}`);
1781
+ lines.push(...description);
1782
+ lines.push(...this.#array(schema));
1783
+ break;
1784
+ case "null":
1785
+ lines.push(`**Type:** \`null\``);
1786
+ lines.push(...description);
1787
+ break;
1788
+ default:
1789
+ lines.push(`**Type:** \`${type}\`${nullableSuffix}`);
1790
+ lines.push(...description);
1791
+ }
1792
+ if (schema.default !== void 0) {
1793
+ lines.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
1794
+ }
1795
+ return lines.filter((l) => l);
1796
+ }
1797
+ /**
1798
+ * Handle schemas by resolving references and delegating to appropriate handler
1799
+ */
1800
+ handle(schemaOrRef) {
1801
+ if (isRef4(schemaOrRef)) {
1802
+ return this.#ref(schemaOrRef.$ref);
1803
+ }
1804
+ const schema = schemaOrRef;
1805
+ if (schema.allOf && Array.isArray(schema.allOf)) {
1806
+ return this.#allOf(schema.allOf);
1807
+ }
1808
+ if (schema.anyOf && Array.isArray(schema.anyOf)) {
1809
+ return this.#anyOf(schema.anyOf);
1810
+ }
1811
+ if (schema.oneOf && Array.isArray(schema.oneOf)) {
1812
+ return this.#oneOf(schema.oneOf);
1813
+ }
1814
+ if (schema.enum && Array.isArray(schema.enum)) {
1815
+ return this.#enum(schema);
1816
+ }
1817
+ let types = coerceTypes(schema);
1818
+ let nullable = false;
1819
+ if (types.includes("null")) {
1820
+ nullable = true;
1821
+ types = types.filter((t) => t !== "null");
1822
+ }
1823
+ if (types.length === 0) {
1824
+ if (schema.properties || schema.additionalProperties) {
1825
+ types = ["object"];
1826
+ } else if (schema.items) {
1827
+ types = ["array"];
1828
+ }
1829
+ }
1830
+ if (types.length === 0) {
1831
+ const lines2 = ["**Type:** `unknown`"];
1832
+ if (schema.description) lines2.push(schema.description);
1833
+ if (schema.default !== void 0)
1834
+ lines2.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
1835
+ return lines2;
1836
+ }
1837
+ if (types.length === 1) {
1838
+ return this.#normal(types[0], schema, nullable);
1839
+ }
1840
+ const typeString = types.join(" | ");
1841
+ const nullableSuffix = nullable ? " (nullable)" : "";
1842
+ const lines = [`**Type:** \`${typeString}\`${nullableSuffix}`];
1843
+ if (schema.description) lines.push(schema.description);
1844
+ if (schema.default !== void 0)
1845
+ lines.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
1846
+ return lines;
1847
+ }
1848
+ /**
1849
+ * Process a request body and return markdown documentation
1850
+ */
1851
+ requestBody(requestBody) {
1852
+ if (!requestBody) return [];
1853
+ const lines = [];
1854
+ lines.push(`##### Request Body`);
1855
+ if (requestBody.description) {
1856
+ lines.push(requestBody.description);
1857
+ }
1858
+ if (requestBody.content) {
1859
+ const contentEntries = Object.entries(requestBody.content);
1860
+ if (contentEntries.length === 1) {
1861
+ const [contentType, mediaType] = contentEntries[0];
1862
+ lines.push(`**Content Type:** \`${contentType}\``);
1863
+ if (mediaType.schema) {
1864
+ const schemaDocs = this.handle(mediaType.schema);
1865
+ lines.push(...schemaDocs);
1866
+ }
1867
+ } else {
1868
+ for (const [contentType, mediaType] of contentEntries) {
1869
+ lines.push(`<details>`);
1870
+ lines.push(
1871
+ `<summary><b>Content Type:</b> \`${contentType}\`</summary>`
1872
+ );
1873
+ lines.push("");
1874
+ if (mediaType.schema) {
1875
+ const schemaDocs = this.handle(mediaType.schema);
1876
+ lines.push(...schemaDocs.map((l) => l));
1877
+ }
1878
+ lines.push("");
1879
+ lines.push(`</details>`);
1880
+ }
1881
+ }
1882
+ }
1883
+ return lines;
1884
+ }
1885
+ };
1886
+
1887
+ // packages/typescript/src/lib/readme/readme.ts
1888
+ function toReadme(spec, generator) {
1889
+ const propEmitter = new PropEmitter(spec);
1890
+ const markdown = [];
1891
+ markdown.push(`# ${spec.info.title} TypeScript SDK`);
1892
+ markdown.push("");
1893
+ markdown.push(
1894
+ "A fully-typed TypeScript SDK with comprehensive IntelliSense support, automatic request/response validation, and modern async/await patterns. Built for seamless integration with TypeScript and JavaScript projects."
1895
+ );
1896
+ markdown.push("");
1897
+ markdown.push(generator.clientSetupDocs());
1898
+ markdown.push("");
1899
+ const securitySchemes = spec.components?.securitySchemes || {};
1900
+ if (Object.keys(securitySchemes).length > 0) {
1901
+ markdown.push(generator.authenticationDocs());
1902
+ markdown.push("");
1903
+ }
1904
+ const paginationDocs = generator.paginationDocs();
1905
+ if (paginationDocs) {
1906
+ markdown.push(paginationDocs);
1907
+ markdown.push("");
1908
+ }
1909
+ markdown.push(generator.errorHandlingDocs());
1910
+ markdown.push("");
1911
+ markdown.push(generator.generalUsageDocs());
1912
+ markdown.push("");
1913
+ markdown.push("## API Reference");
1914
+ markdown.push("");
1915
+ forEachOperation2(spec, (entry, operation) => {
1916
+ const { method, path } = entry;
1917
+ markdown.push(
1918
+ `#### ${operation["x-fn-name"]} | ${`_${method.toUpperCase()} ${path}_`}`
1919
+ );
1920
+ markdown.push(operation.summary || "");
1921
+ const snippet = generator.snippet(entry, operation);
1922
+ markdown.push(`##### Example usage`);
1923
+ markdown.push(snippet);
1924
+ const requestBodyContent = propEmitter.requestBody(operation.requestBody);
1925
+ if (requestBodyContent.length > 1) {
1926
+ markdown.push(requestBodyContent.join("\n\n"));
1927
+ }
1928
+ markdown.push(`##### Responses`);
1929
+ for (const status in operation.responses) {
1930
+ const response = operation.responses[status];
1931
+ markdown.push(`<details>`);
1932
+ markdown.push(
1933
+ `<summary><b>${status}</b> <i>${response.description}</i></summary>`
1934
+ );
1935
+ if (!isEmpty3(response.content)) {
1936
+ for (const [contentType, mediaType] of Object.entries(
1937
+ response.content
1938
+ )) {
1939
+ markdown.push(`
1940
+ **Content Type:** \`${contentType}\``);
1941
+ if (mediaType.schema) {
1942
+ const schemaDocs = propEmitter.handle(mediaType.schema);
1943
+ markdown.push(...schemaDocs.map((l) => `
1944
+ ${l}`));
1945
+ }
1946
+ }
1947
+ }
1948
+ markdown.push(`</details>`);
1949
+ }
1950
+ });
1951
+ if (spec.components?.schemas) {
1952
+ markdown.push("## Schemas");
1953
+ markdown.push("");
1954
+ for (const [schemaName, schema] of Object.entries(
1955
+ spec.components.schemas
1956
+ )) {
1957
+ if (schemaName === "ValidationError") {
1958
+ continue;
1959
+ }
1960
+ markdown.push(`<details>`);
1961
+ markdown.push(
1962
+ `<summary><h3 id="${schemaName.toLowerCase()}">${schemaName}</h3></summary>`
1963
+ );
1964
+ markdown.push("");
1965
+ const schemaDocs = propEmitter.handle(schema);
1966
+ markdown.push(...schemaDocs.map((line) => line.trim()));
1967
+ markdown.push("");
1968
+ markdown.push(`</details>`);
1969
+ markdown.push("");
1970
+ }
1971
+ }
1972
+ return markdown.join("\n\n");
1973
+ }
1974
+
1597
1975
  // packages/typescript/src/lib/typescript-snippet.ts
1598
1976
  import { camelcase as camelcase3, spinalcase as spinalcase2 } from "stringcase";
1599
- import { isEmpty as isEmpty3, pascalcase as pascalcase4, resolveRef as resolveRef2 } from "@sdk-it/core";
1977
+ import { isEmpty as isEmpty4, pascalcase as pascalcase4, resolveRef as resolveRef3 } from "@sdk-it/core";
1600
1978
  import "@sdk-it/readme";
1601
1979
  import {
1980
+ forEachOperation as forEachOperation3,
1602
1981
  patchParameters,
1603
1982
  securityToOptions
1604
1983
  } from "@sdk-it/spec";
1605
1984
 
1606
1985
  // packages/typescript/src/lib/emitters/snippet.ts
1607
- import { followRef as followRef4, isRef as isRef4 } from "@sdk-it/core";
1986
+ import { followRef as followRef5, isRef as isRef5, resolveRef as resolveRef2 } from "@sdk-it/core";
1608
1987
  var SnippetEmitter = class {
1609
1988
  spec;
1610
1989
  generatedRefs = /* @__PURE__ */ new Set();
@@ -1613,12 +1992,12 @@ var SnippetEmitter = class {
1613
1992
  this.spec = spec;
1614
1993
  }
1615
1994
  object(schema) {
1616
- const schemaObj = isRef4(schema) ? followRef4(this.spec, schema.$ref) : schema;
1995
+ const schemaObj = resolveRef2(this.spec, schema);
1617
1996
  const result = {};
1618
1997
  const properties = schemaObj.properties || {};
1619
1998
  for (const [propName, propSchema] of Object.entries(properties)) {
1620
1999
  const isRequired = (schemaObj.required ?? []).includes(propName);
1621
- const resolvedProp = isRef4(propSchema) ? followRef4(this.spec, propSchema.$ref) : propSchema;
2000
+ const resolvedProp = resolveRef2(this.spec, propSchema);
1622
2001
  if (isRequired || resolvedProp.example !== void 0 || resolvedProp.default !== void 0 || Math.random() > 0.5) {
1623
2002
  result[propName] = this.handle(propSchema);
1624
2003
  }
@@ -1631,7 +2010,7 @@ var SnippetEmitter = class {
1631
2010
  return result;
1632
2011
  }
1633
2012
  array(schema) {
1634
- const schemaObj = isRef4(schema) ? followRef4(this.spec, schema.$ref) : schema;
2013
+ const schemaObj = resolveRef2(this.spec, schema);
1635
2014
  const itemsSchema = schemaObj.items;
1636
2015
  if (!itemsSchema) {
1637
2016
  return [];
@@ -1713,7 +2092,7 @@ var SnippetEmitter = class {
1713
2092
  return this.cache.get($ref);
1714
2093
  }
1715
2094
  this.cache.set($ref, { _ref: refKey });
1716
- const resolved = followRef4(this.spec, $ref);
2095
+ const resolved = followRef5(this.spec, $ref);
1717
2096
  const result = this.handle(resolved);
1718
2097
  this.cache.set($ref, result);
1719
2098
  return result;
@@ -1740,10 +2119,10 @@ var SnippetEmitter = class {
1740
2119
  return Array.isArray(schema.enum) && schema.enum.length > 0 ? schema.enum[0] : void 0;
1741
2120
  }
1742
2121
  handle(schemaOrRef) {
1743
- if (isRef4(schemaOrRef)) {
2122
+ if (isRef5(schemaOrRef)) {
1744
2123
  return this.ref(schemaOrRef.$ref);
1745
2124
  }
1746
- const schema = isRef4(schemaOrRef) ? followRef4(this.spec, schemaOrRef.$ref) : schemaOrRef;
2125
+ const schema = resolveRef2(this.spec, schemaOrRef);
1747
2126
  if (schema.example !== void 0) {
1748
2127
  return schema.example;
1749
2128
  }
@@ -1808,9 +2187,9 @@ var TypeScriptGenerator = class {
1808
2187
  }
1809
2188
  succinct(entry, operation, values) {
1810
2189
  let payload = "{}";
1811
- if (!isEmpty3(operation.requestBody)) {
2190
+ if (!isEmpty4(operation.requestBody)) {
1812
2191
  const contentTypes = Object.keys(operation.requestBody.content || {});
1813
- const schema = resolveRef2(
2192
+ const schema = resolveRef3(
1814
2193
  this.#spec,
1815
2194
  operation.requestBody.content[contentTypes[0]].schema
1816
2195
  );
@@ -1870,31 +2249,31 @@ var TypeScriptGenerator = class {
1870
2249
  return this.#streamDownload(entry, payload);
1871
2250
  }
1872
2251
  }
1873
- if (!isEmpty3(operation["x-pagination"])) {
2252
+ if (!isEmpty4(operation["x-pagination"])) {
1874
2253
  return this.#pagination(operation, entry, payload);
1875
2254
  }
1876
2255
  return this.#normal(entry, payload);
1877
2256
  }
1878
- #pagination(opeartion, entry, payload) {
1879
- const pagination = opeartion["x-pagination"];
2257
+ #pagination(operation, entry, payload) {
2258
+ const pagination = operation["x-pagination"];
1880
2259
  switch (pagination.type) {
1881
2260
  case "page":
1882
2261
  return {
1883
- content: `const result = ${this.#ddd(entry, payload)}`,
2262
+ content: `const result = ${this.#toRequest(entry, payload)}`,
1884
2263
  footer: `for await (const page of result) {
1885
2264
  console.log(page);
1886
2265
  }`
1887
2266
  };
1888
2267
  case "offset":
1889
2268
  return {
1890
- content: `const result = ${this.#ddd(entry, payload)}`,
2269
+ content: `const result = ${this.#toRequest(entry, payload)}`,
1891
2270
  footer: `for await (const page of result) {
1892
2271
  console.log(page);
1893
2272
  }`
1894
2273
  };
1895
2274
  case "cursor":
1896
2275
  return {
1897
- content: `const result = ${this.#ddd(entry, payload)}`,
2276
+ content: `const result = ${this.#toRequest(entry, payload)}`,
1898
2277
  footer: `for await (const page of result) {
1899
2278
  console.log(page);
1900
2279
  }`
@@ -1904,25 +2283,25 @@ var TypeScriptGenerator = class {
1904
2283
  }
1905
2284
  #normal(entry, payload) {
1906
2285
  return {
1907
- content: `const result = ${this.#ddd(entry, payload)};`,
2286
+ content: `const result = ${this.#toRequest(entry, payload)};`,
1908
2287
  footer: "console.log(result.data)"
1909
2288
  };
1910
2289
  }
1911
2290
  #streamDownload(entry, payload) {
1912
2291
  return {
1913
- content: `const stream = ${this.#ddd(entry, payload)}`,
2292
+ content: `const stream = ${this.#toRequest(entry, payload)}`,
1914
2293
  footer: `await writeFile('./report.pdf', stream);`
1915
2294
  };
1916
2295
  }
1917
2296
  #httpStreaming(entry, payload) {
1918
2297
  return {
1919
- content: `const stream = ${this.#ddd(entry, payload)}`,
2298
+ content: `const stream = ${this.#toRequest(entry, payload)}`,
1920
2299
  footer: `for await (const chunk of stream) {
1921
2300
  console.log(chunk);
1922
2301
  }`
1923
2302
  };
1924
2303
  }
1925
- #ddd(entry, payload) {
2304
+ #toRequest(entry, payload) {
1926
2305
  return `await ${camelcase3(this.#clientName)}.request('${entry.method.toUpperCase()} ${entry.path}', ${payload});`;
1927
2306
  }
1928
2307
  snippet(entry, operation, config = {}) {
@@ -1935,8 +2314,7 @@ var TypeScriptGenerator = class {
1935
2314
  payload.footer
1936
2315
  ];
1937
2316
  if (config.frame !== false) {
1938
- content.unshift("```typescript");
1939
- content.push("```");
2317
+ return createCodeBlock("typescript", content);
1940
2318
  }
1941
2319
  return content.join("\n");
1942
2320
  }
@@ -1948,26 +2326,578 @@ var TypeScriptGenerator = class {
1948
2326
  );
1949
2327
  }
1950
2328
  client() {
1951
- const inputs = [
1952
- `baseUrl: '${this.#spec.servers?.[0]?.url ?? "http://localhost:3000"}'`
1953
- ];
2329
+ const options = {
2330
+ baseUrl: this.#spec.servers?.[0]?.url ?? "http://localhost:3000"
2331
+ };
1954
2332
  const authOptions = this.#authentication();
1955
- if (!isEmpty3(authOptions)) {
2333
+ if (!isEmpty4(authOptions)) {
1956
2334
  const [firstAuth] = authOptions;
1957
- inputs.push(
1958
- `'${firstAuth["x-optionName"] ?? firstAuth.name}': ${firstAuth.example}`
1959
- );
2335
+ const optionName = firstAuth["x-optionName"] ?? firstAuth.name;
2336
+ options[optionName] = firstAuth.example;
1960
2337
  }
1961
- return `import { ${this.#clientName} } from '${this.#packageName}';
2338
+ const client = this.#constructClient(options);
2339
+ return `${client.import}
1962
2340
 
1963
- const ${camelcase3(this.#clientName)} = new ${this.#clientName}({
1964
- ${inputs.join(",\n ")}
1965
- });`;
2341
+ ${client.use}`;
2342
+ }
2343
+ #constructClient(options = {}) {
2344
+ return {
2345
+ import: `import { ${this.#clientName} } from '${this.#packageName}';`,
2346
+ use: `const ${camelcase3(this.#clientName)} = new ${this.#clientName}({
2347
+ ${Object.entries(
2348
+ options
2349
+ ).map(([key, value]) => `${key}: ${JSON.stringify(value)}`).join(",\n ")}
2350
+ });`
2351
+ };
2352
+ }
2353
+ clientInstallDocs() {
2354
+ const sections = [];
2355
+ sections.push("## Installation");
2356
+ sections.push("");
2357
+ sections.push(
2358
+ createCodeBlock("bash", [`npm install ${this.#packageName}`])
2359
+ );
2360
+ sections.push("");
2361
+ sections.push("## Basic Usage");
2362
+ sections.push("");
2363
+ sections.push(createCodeBlock("typescript", [this.client()]));
2364
+ return sections.join("\n");
2365
+ }
2366
+ configurationOptions() {
2367
+ const sections = [];
2368
+ const hasServers = Boolean(
2369
+ this.#spec.servers && this.#spec.servers.length > 0
2370
+ );
2371
+ const baseUrl = this.#spec.servers?.[0]?.url || "https://api.example.com";
2372
+ const authOptions = this.#authentication();
2373
+ const hasApiKey = !isEmpty4(authOptions);
2374
+ sections.push("### Configuration Options");
2375
+ sections.push("");
2376
+ sections.push("| Option | Type | Required | Description |");
2377
+ sections.push("|--------|------|----------|-------------|");
2378
+ sections.push(
2379
+ "| `fetch` | `fetch compatible` | No | Fetch implementation to use for HTTP requests |"
2380
+ );
2381
+ if (hasServers) {
2382
+ sections.push(
2383
+ "| `baseUrl` | `string` | No | API base URL (default: `" + baseUrl + "`) |"
2384
+ );
2385
+ }
2386
+ for (const authOption of authOptions) {
2387
+ const optionName = authOption["x-optionName"] ?? authOption.name;
2388
+ const description = authOption.in === "header" && authOption.name === "authorization" ? "Bearer token for authentication" : `API key for authentication (${authOption.in}: ${authOption.name})`;
2389
+ sections.push(`| \`${optionName}\` | \`string\` | No | ${description} |`);
2390
+ }
2391
+ return { sections, hasServers, baseUrl, hasApiKey };
2392
+ }
2393
+ clientSetupDocs() {
2394
+ const sections = [];
2395
+ sections.push(this.clientInstallDocs());
2396
+ sections.push("");
2397
+ const config = this.configurationOptions();
2398
+ sections.push(...config.sections);
2399
+ sections.push("");
2400
+ sections.push(this.configurationUpdateDocs());
2401
+ return sections.join("\n");
2402
+ }
2403
+ paginationDocs() {
2404
+ const paginationTypes = availablePaginationTypes(this.#spec);
2405
+ if (!paginationTypes.offset && !paginationTypes.page && !paginationTypes.cursor) {
2406
+ return "";
2407
+ }
2408
+ const sections = [];
2409
+ sections.push("## Pagination");
2410
+ sections.push("");
2411
+ sections.push(
2412
+ "This SDK automatically handles pagination for endpoints that return multiple items."
2413
+ );
2414
+ sections.push("");
2415
+ sections.push("### How it Works");
2416
+ sections.push("");
2417
+ sections.push(
2418
+ "When you call a paginated endpoint, the SDK returns a pagination object that allows you to iterate through all results:"
2419
+ );
2420
+ sections.push("");
2421
+ const availableTypes = [];
2422
+ if (paginationTypes.offset) availableTypes.push("offset");
2423
+ if (paginationTypes.page) availableTypes.push("page");
2424
+ if (paginationTypes.cursor) availableTypes.push("cursor");
2425
+ const primaryPaginationType = availableTypes[0];
2426
+ const mockPaginatedOperation = {
2427
+ "x-pagination": { type: primaryPaginationType },
2428
+ tags: ["Products"],
2429
+ operationId: "listProducts",
2430
+ parameters: [],
2431
+ "x-fn-name": "listProducts",
2432
+ responses: {},
2433
+ requestBody: {}
2434
+ };
2435
+ const mockOperationEntry = {
2436
+ method: "get",
2437
+ path: "/products",
2438
+ tag: "Products"
2439
+ };
2440
+ const initialRequestPayload = createObjectLiteral({ limit: 20 });
2441
+ const paginationExample = this.#pagination(
2442
+ mockPaginatedOperation,
2443
+ mockOperationEntry,
2444
+ initialRequestPayload
2445
+ );
2446
+ sections.push(
2447
+ createCodeBlock("typescript", [
2448
+ "// The SDK automatically handles pagination",
2449
+ paginationExample.content,
2450
+ "",
2451
+ "// Access the current page data",
2452
+ "const currentPage = result.getCurrentPage();",
2453
+ "console.log(currentPage.data); // Array of product items",
2454
+ "",
2455
+ "// Check if more pages exist",
2456
+ "if (result.hasMore) {",
2457
+ " await result.getNextPage();",
2458
+ "}",
2459
+ "",
2460
+ "// Or iterate through all pages automatically",
2461
+ paginationExample.footer
2462
+ ])
2463
+ );
2464
+ sections.push("");
2465
+ sections.push("### Iterating Through All Pages");
2466
+ sections.push("");
2467
+ const iterationExample = this.#pagination(
2468
+ mockPaginatedOperation,
2469
+ mockOperationEntry,
2470
+ createObjectLiteral({ limit: 100 })
2471
+ );
2472
+ sections.push(
2473
+ createCodeBlock("typescript", [
2474
+ "// Using async iteration to process all pages",
2475
+ iterationExample.content,
2476
+ "",
2477
+ iterationExample.footer
2478
+ ])
2479
+ );
2480
+ sections.push("");
2481
+ if (availableTypes.length > 1) {
2482
+ sections.push("### Pagination Types");
2483
+ sections.push("");
2484
+ sections.push(
2485
+ "Your API uses the following pagination strategies, automatically detected by the SDK:"
2486
+ );
2487
+ sections.push("");
2488
+ } else {
2489
+ sections.push("### Pagination Strategy");
2490
+ sections.push("");
2491
+ sections.push(
2492
+ "Your API uses the following pagination strategy, automatically detected by the SDK:"
2493
+ );
2494
+ sections.push("");
2495
+ }
2496
+ for (const paginationType of availableTypes) {
2497
+ const typeSpecificOperation = {
2498
+ "x-pagination": { type: paginationType },
2499
+ tags: ["Products"],
2500
+ operationId: "listProducts",
2501
+ parameters: [],
2502
+ "x-fn-name": "listProducts",
2503
+ responses: {},
2504
+ requestBody: {}
2505
+ };
2506
+ const typeSpecificEntry = {
2507
+ method: "get",
2508
+ path: "/products",
2509
+ tag: "Products"
2510
+ };
2511
+ if (paginationType === "cursor") {
2512
+ sections.push("#### Cursor Pagination");
2513
+ sections.push("");
2514
+ sections.push("Uses a cursor token to fetch the next page:");
2515
+ sections.push("");
2516
+ const cursorPaginationExample = this.#pagination(
2517
+ typeSpecificOperation,
2518
+ typeSpecificEntry,
2519
+ createObjectLiteral({ limit: 20 })
2520
+ );
2521
+ sections.push(
2522
+ createCodeBlock("typescript", [
2523
+ cursorPaginationExample.content,
2524
+ "",
2525
+ "// Iterate through all pages using cursor",
2526
+ cursorPaginationExample.footer
2527
+ ])
2528
+ );
2529
+ sections.push("");
2530
+ }
2531
+ if (paginationType === "offset") {
2532
+ sections.push("#### Offset Pagination");
2533
+ sections.push("");
2534
+ sections.push("Uses offset and limit parameters:");
2535
+ sections.push("");
2536
+ const offsetPaginationExample = this.#pagination(
2537
+ typeSpecificOperation,
2538
+ typeSpecificEntry,
2539
+ createObjectLiteral({ limit: 20, offset: 0 })
2540
+ );
2541
+ sections.push(
2542
+ createCodeBlock("typescript", [
2543
+ offsetPaginationExample.content,
2544
+ "",
2545
+ "// Iterate through all pages using offset",
2546
+ offsetPaginationExample.footer
2547
+ ])
2548
+ );
2549
+ sections.push("");
2550
+ }
2551
+ if (paginationType === "page") {
2552
+ sections.push("#### Page Pagination");
2553
+ sections.push("");
2554
+ sections.push("Uses page number and page size:");
2555
+ sections.push("");
2556
+ const pagePaginationExample = this.#pagination(
2557
+ typeSpecificOperation,
2558
+ typeSpecificEntry,
2559
+ createObjectLiteral({ page: 1, pageSize: 20 })
2560
+ );
2561
+ sections.push(
2562
+ createCodeBlock("typescript", [
2563
+ pagePaginationExample.content,
2564
+ "",
2565
+ "// Iterate through all pages using page numbers",
2566
+ pagePaginationExample.footer
2567
+ ])
2568
+ );
2569
+ sections.push("");
2570
+ }
2571
+ }
2572
+ if (availableTypes.length > 1) {
2573
+ sections.push(
2574
+ "The SDK handles the differences transparently, providing a consistent interface regardless of the underlying pagination type."
2575
+ );
2576
+ }
2577
+ return sections.join("\n");
2578
+ }
2579
+ errorHandlingDocs() {
2580
+ const sections = [];
2581
+ sections.push("## Error Handling");
2582
+ sections.push("");
2583
+ sections.push(
2584
+ "The SDK provides structured error handling with typed HTTP error responses."
2585
+ );
2586
+ sections.push("");
2587
+ sections.push("### Error Response Types");
2588
+ sections.push("");
2589
+ sections.push(
2590
+ "All API errors extend from `APIError` and include the HTTP status code and response data:"
2591
+ );
2592
+ sections.push("");
2593
+ sections.push(
2594
+ createCodeBlock("typescript", [
2595
+ `import { BadRequest, Unauthorized, NotFound, TooManyRequests, InternalServerError, ParseError } from "${this.#packageName}";`,
2596
+ "try {",
2597
+ "const usersList = ",
2598
+ this.#toRequest(
2599
+ {
2600
+ method: "get",
2601
+ path: "/users",
2602
+ tag: "Users"
2603
+ },
2604
+ createObjectLiteral({})
2605
+ ),
2606
+ " // Handle successful response",
2607
+ "} catch (error) {",
2608
+ " // Handle different error types",
2609
+ " if (error instanceof BadRequest) {",
2610
+ ' console.error("Bad request:", error.data);',
2611
+ ' console.log("Status:", error.status); // 400',
2612
+ " } else if (error instanceof Unauthorized) {",
2613
+ ' console.error("Authentication failed:", error.data);',
2614
+ ' console.log("Status:", error.status); // 401',
2615
+ " } else if (error instanceof NotFound) {",
2616
+ ' console.error("Resource not found:", error.data);',
2617
+ ' console.log("Status:", error.status); // 404',
2618
+ " } else if (error instanceof TooManyRequests) {",
2619
+ ' console.error("Rate limited:", error.data);',
2620
+ " if (error.data.retryAfter) {",
2621
+ ' console.log("Retry after:", error.data.retryAfter);',
2622
+ " }",
2623
+ " } else if (error instanceof InternalServerError) {",
2624
+ ' console.error("Server error:", error.data);',
2625
+ ' console.log("Status:", error.status); // 500',
2626
+ " } else if (error instanceof ParseError) {",
2627
+ ' console.error("Input validation failed:", error.data);',
2628
+ " }",
2629
+ "}"
2630
+ ])
2631
+ );
2632
+ sections.push("");
2633
+ sections.push("### Available Error Classes");
2634
+ sections.push("");
2635
+ sections.push("#### Input Validation Errors");
2636
+ sections.push(
2637
+ "- `ParseError` - Request input validation failed against API schema"
2638
+ );
2639
+ sections.push("");
2640
+ sections.push("#### Client Errors (4xx)");
2641
+ sections.push("- `BadRequest` (400) - Invalid request data");
2642
+ sections.push("- `Unauthorized` (401) - Authentication required");
2643
+ sections.push("- `PaymentRequired` (402) - Payment required");
2644
+ sections.push("- `Forbidden` (403) - Access denied");
2645
+ sections.push("- `NotFound` (404) - Resource not found");
2646
+ sections.push("- `MethodNotAllowed` (405) - HTTP method not allowed");
2647
+ sections.push("- `NotAcceptable` (406) - Content type not acceptable");
2648
+ sections.push("- `Conflict` (409) - Resource conflict");
2649
+ sections.push("- `Gone` (410) - Resource no longer available");
2650
+ sections.push("- `PreconditionFailed` (412) - Precondition failed");
2651
+ sections.push("- `PayloadTooLarge` (413) - Request payload too large");
2652
+ sections.push("- `UnsupportedMediaType` (415) - Unsupported content type");
2653
+ sections.push("- `UnprocessableEntity` (422) - Validation errors");
2654
+ sections.push("- `TooManyRequests` (429) - Rate limit exceeded");
2655
+ sections.push("");
2656
+ sections.push("#### Server Errors (5xx)");
2657
+ sections.push("- `InternalServerError` (500) - Server error");
2658
+ sections.push("- `NotImplemented` (501) - Not implemented");
2659
+ sections.push("- `BadGateway` (502) - Bad gateway");
2660
+ sections.push("- `ServiceUnavailable` (503) - Service unavailable");
2661
+ sections.push("- `GatewayTimeout` (504) - Gateway timeout");
2662
+ sections.push("");
2663
+ sections.push("### Validation Errors");
2664
+ sections.push("");
2665
+ sections.push(
2666
+ "Validation errors (422) include detailed field-level error information:"
2667
+ );
2668
+ sections.push("### Input Validation Errors");
2669
+ sections.push("");
2670
+ sections.push(
2671
+ "When request input fails validation against the API schema, a `ParseError` is thrown:"
2672
+ );
2673
+ sections.push("");
2674
+ sections.push(
2675
+ createCodeBlock("typescript", [
2676
+ `import { ParseError } from "${this.#packageName}";`,
2677
+ "",
2678
+ "try {",
2679
+ " // Invalid input that doesn't match the expected schema",
2680
+ " const newUser = ",
2681
+ this.#toRequest(
2682
+ {
2683
+ method: "post",
2684
+ path: "/users",
2685
+ tag: "Users"
2686
+ },
2687
+ createObjectLiteral({
2688
+ email: 123,
2689
+ // should be string
2690
+ firstName: "",
2691
+ // empty required field
2692
+ age: -5
2693
+ // invalid age value
2694
+ })
2695
+ ),
2696
+ "} catch (error) {",
2697
+ " if (error instanceof ParseError) {",
2698
+ ' console.log("Input validation failed:");',
2699
+ " ",
2700
+ " // Field-level errors",
2701
+ " if (error.data.fieldErrors) {",
2702
+ " Object.entries(error.data.fieldErrors).forEach(([fieldName, validationIssues]) => {",
2703
+ ' console.log(` ${fieldName}: ${validationIssues.map(issue => issue.message).join(", ")}`);',
2704
+ " });",
2705
+ " }",
2706
+ " ",
2707
+ " // Form-level errors",
2708
+ " if (error.data.formErrors.length > 0) {",
2709
+ ' console.log(` Form errors: ${error.data.formErrors.map(issue => issue.message).join(", ")}`);',
2710
+ " }",
2711
+ " }",
2712
+ "}"
2713
+ ])
2714
+ );
2715
+ sections.push("");
2716
+ sections.push(
2717
+ "`ParseError` contains detailed validation information using Zod's flattened error format, providing specific field-level and form-level validation messages."
2718
+ );
2719
+ sections.push("");
2720
+ sections.push("### Rate Limiting");
2721
+ sections.push("");
2722
+ sections.push(
2723
+ "Rate limit responses may include a `retryAfter` field indicating when to retry:"
2724
+ );
2725
+ sections.push("");
2726
+ sections.push(
2727
+ createCodeBlock("typescript", [
2728
+ `import { TooManyRequests } from "${this.#packageName}";`,
2729
+ "",
2730
+ "try {",
2731
+ " const apiResponse = ",
2732
+ this.#toRequest(
2733
+ {
2734
+ method: "get",
2735
+ path: "/api/data",
2736
+ tag: "Data"
2737
+ },
2738
+ createObjectLiteral({})
2739
+ ),
2740
+ "} catch (error) {",
2741
+ " if (error instanceof TooManyRequests) {",
2742
+ " const retryAfterSeconds = error.data.retryAfter;",
2743
+ " if (retryAfterSeconds) {",
2744
+ " console.log(`Rate limited. Retry after: ${retryAfterSeconds} seconds`);",
2745
+ " // Implement your own retry logic",
2746
+ " setTimeout(() => {",
2747
+ " // Retry the request",
2748
+ " }, retryAfterSeconds * 1000);",
2749
+ " }",
2750
+ " }",
2751
+ "}"
2752
+ ])
2753
+ );
2754
+ return sections.join("\n");
2755
+ }
2756
+ authenticationDocs() {
2757
+ const authOptions = this.#authentication();
2758
+ if (isEmpty4(authOptions)) {
2759
+ return "";
2760
+ }
2761
+ const sections = [];
2762
+ sections.push("## Authentication");
2763
+ sections.push("");
2764
+ if (authOptions.length === 1) {
2765
+ sections.push(
2766
+ "The SDK requires authentication to access the API. Configure your client with the required credentials:"
2767
+ );
2768
+ } else {
2769
+ sections.push("The SDK supports the following authentication methods:");
2770
+ }
2771
+ sections.push("");
2772
+ for (const authOption of authOptions) {
2773
+ const optionName = authOption["x-optionName"] ?? authOption.name;
2774
+ const isBearer = authOption.in === "header" && authOption.name === "authorization";
2775
+ const isApiKey = authOption.in === "header" && authOption.name !== "authorization";
2776
+ const isQueryParam = authOption.in === "query";
2777
+ const headingLevel = authOptions.length === 1 ? "###" : "###";
2778
+ if (isBearer) {
2779
+ const authenticationHeading = authOptions.length === 1 ? "Bearer Token" : "Bearer Token Authentication";
2780
+ sections.push(`${headingLevel} ${authenticationHeading}`);
2781
+ sections.push("");
2782
+ sections.push(
2783
+ 'Pass your bearer token directly - the "Bearer" prefix is automatically added:'
2784
+ );
2785
+ sections.push("");
2786
+ const bearerAuthClient = this.#constructClient({
2787
+ [optionName]: "sk_live_51234567890abcdef1234567890abcdef"
2788
+ });
2789
+ sections.push(createCodeBlock("typescript", [bearerAuthClient.use]));
2790
+ sections.push("");
2791
+ } else if (isApiKey) {
2792
+ const apiKeyHeading = authOptions.length === 1 ? "API Key (Header)" : "API Key Authentication (Header)";
2793
+ sections.push(`${headingLevel} ${apiKeyHeading}`);
2794
+ sections.push("");
2795
+ const apiKeyAuthClient = this.#constructClient({
2796
+ [optionName]: "api_key_1234567890abcdef1234567890abcdef"
2797
+ });
2798
+ sections.push(createCodeBlock("typescript", [apiKeyAuthClient.use]));
2799
+ sections.push("");
2800
+ } else if (isQueryParam) {
2801
+ const queryParamHeading = authOptions.length === 1 ? "API Key (Query Parameter)" : "API Key Authentication (Query Parameter)";
2802
+ sections.push(`${headingLevel} ${queryParamHeading}`);
2803
+ sections.push("");
2804
+ const queryParamAuthClient = this.#constructClient({
2805
+ [optionName]: "qp_key_1234567890abcdef1234567890abcdef"
2806
+ });
2807
+ sections.push(
2808
+ createCodeBlock("typescript", [queryParamAuthClient.use])
2809
+ );
2810
+ sections.push("");
2811
+ } else {
2812
+ const genericAuthHeading = authOptions.length === 1 ? authOption.name : `${authOption.name} Authentication`;
2813
+ sections.push(`${headingLevel} ${genericAuthHeading}`);
2814
+ sections.push("");
2815
+ const genericAuthClient = this.#constructClient({
2816
+ [optionName]: "auth_token_1234567890abcdef1234567890abcdef"
2817
+ });
2818
+ sections.push(createCodeBlock("typescript", [genericAuthClient.use]));
2819
+ sections.push("");
2820
+ }
2821
+ }
2822
+ return sections.join("\n");
2823
+ }
2824
+ generalUsageDocs() {
2825
+ const sections = [];
2826
+ return sections.join("\n");
2827
+ }
2828
+ configurationUpdateDocs() {
2829
+ const sections = [];
2830
+ const authOptions = this.#authentication();
2831
+ sections.push("### Updating Configuration");
2832
+ sections.push("");
2833
+ sections.push(
2834
+ "You can update client configuration after initialization using the `setOptions` method:"
2835
+ );
2836
+ sections.push("");
2837
+ const initialClientOptions = {
2838
+ baseUrl: "https://api.production-service.com"
2839
+ };
2840
+ if (!isEmpty4(authOptions)) {
2841
+ const [primaryAuth] = authOptions;
2842
+ const authOptionName = primaryAuth["x-optionName"] ?? primaryAuth.name;
2843
+ initialClientOptions[authOptionName] = "prod_sk_1234567890abcdef";
2844
+ }
2845
+ const initialClientSetup = this.#constructClient(initialClientOptions);
2846
+ const configurationUpdateCode = [
2847
+ "// Initial client setup",
2848
+ initialClientSetup.use,
2849
+ "",
2850
+ "// Later, update specific options",
2851
+ "client.setOptions({",
2852
+ " baseUrl: 'https://api.staging-service.com',"
2853
+ ];
2854
+ if (!isEmpty4(authOptions)) {
2855
+ const [primaryAuth] = authOptions;
2856
+ const authOptionName = primaryAuth["x-optionName"] ?? primaryAuth.name;
2857
+ configurationUpdateCode.push(
2858
+ ` ${authOptionName}: 'staging_sk_abcdef1234567890'`
2859
+ );
2860
+ }
2861
+ configurationUpdateCode.push("});");
2862
+ sections.push(createCodeBlock("typescript", configurationUpdateCode));
2863
+ sections.push("");
2864
+ sections.push(
2865
+ "The `setOptions` method validates the provided options and only updates the specified fields, leaving other configuration unchanged."
2866
+ );
2867
+ return sections.join("\n");
1966
2868
  }
1967
2869
  };
1968
- function generateSnippet(spec, settings, entry, operation, config = {}) {
1969
- const generator = new TypeScriptGenerator(spec, settings);
1970
- return generator.snippet(entry, operation, config);
2870
+ function createCodeBlock(language, content) {
2871
+ return ["```" + language, ...content, "```"].join("\n");
2872
+ }
2873
+ function createObjectLiteral(obj, indent = " ") {
2874
+ return "{\n" + Object.entries(obj).map(([key, value]) => `${indent}${key}: ${JSON.stringify(value)}`).join(",\n") + `
2875
+ ${indent.slice(0, -1)}}`;
2876
+ }
2877
+ function availablePaginationTypes(spec) {
2878
+ let offset = false;
2879
+ let page = false;
2880
+ let cursor = false;
2881
+ forEachOperation3(spec, (entry, operation) => {
2882
+ if (operation["x-pagination"]) {
2883
+ switch (operation["x-pagination"].type) {
2884
+ case "offset":
2885
+ offset = true;
2886
+ break;
2887
+ case "page":
2888
+ page = true;
2889
+ break;
2890
+ case "cursor":
2891
+ cursor = true;
2892
+ break;
2893
+ }
2894
+ }
2895
+ });
2896
+ return {
2897
+ offset,
2898
+ page,
2899
+ cursor
2900
+ };
1971
2901
  }
1972
2902
 
1973
2903
  // packages/typescript/src/lib/generate.ts
@@ -2204,11 +3134,13 @@ ${template2(dispatcher_default, {})({ throwError: !style.errorAsValue, outputTyp
2204
3134
  )
2205
3135
  }
2206
3136
  };
2207
- if (settings.readme) {
2208
- configFiles["README.md"] = toReadme(spec, generator);
2209
- }
2210
3137
  await settings.writer(settings.output, configFiles);
2211
3138
  }
3139
+ if (settings.readme) {
3140
+ await settings.writer(settings.mode === "full" ? settings.output : output, {
3141
+ "README.md": toReadme(spec, generator)
3142
+ });
3143
+ }
2212
3144
  await settings.formatCode?.({
2213
3145
  output,
2214
3146
  env: npmRunPathEnv()
@@ -2299,7 +3231,6 @@ function toInputs(operationsSet, commonZod, makeImport) {
2299
3231
  export {
2300
3232
  TypeScriptGenerator,
2301
3233
  generate,
2302
- generateSnippet,
2303
3234
  toInputs
2304
3235
  };
2305
3236
  //# sourceMappingURL=index.js.map