fumadocs-openapi 10.6.3 → 10.6.4

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.
Files changed (71) hide show
  1. package/css/generated/shared.css +8 -17
  2. package/dist/generate-file.d.ts +2 -2
  3. package/dist/generate-file.d.ts.map +1 -1
  4. package/dist/generate-file.js.map +1 -1
  5. package/dist/playground/client.d.ts +15 -19
  6. package/dist/playground/client.d.ts.map +1 -1
  7. package/dist/playground/client.js +30 -18
  8. package/dist/playground/client.js.map +1 -1
  9. package/dist/playground/schema.js +14 -35
  10. package/dist/playground/schema.js.map +1 -1
  11. package/dist/server/create.d.ts +1 -1
  12. package/dist/server/create.js +1 -1
  13. package/dist/server/create.js.map +1 -1
  14. package/dist/server/source-api.d.ts +2 -2
  15. package/dist/server/source-api.d.ts.map +1 -1
  16. package/dist/server/source-api.js.map +1 -1
  17. package/dist/types.d.ts +4 -4
  18. package/dist/types.d.ts.map +1 -1
  19. package/dist/ui/base.d.ts +10 -9
  20. package/dist/ui/base.d.ts.map +1 -1
  21. package/dist/ui/base.js +22 -0
  22. package/dist/ui/base.js.map +1 -1
  23. package/dist/ui/create-client.d.ts.map +1 -1
  24. package/dist/ui/create-client.js +18 -13
  25. package/dist/ui/create-client.js.map +1 -1
  26. package/dist/ui/operation/get-example-requests.js +2 -2
  27. package/dist/ui/operation/get-example-requests.js.map +1 -1
  28. package/dist/ui/operation/index.js +5 -6
  29. package/dist/ui/operation/index.js.map +1 -1
  30. package/dist/ui/operation/response-tabs.d.ts +1 -1
  31. package/dist/ui/schema/index.d.ts +1 -1
  32. package/dist/utils/deep-equal.js +8 -4
  33. package/dist/utils/deep-equal.js.map +1 -1
  34. package/dist/utils/document/dereference.d.ts +18 -0
  35. package/dist/utils/document/dereference.d.ts.map +1 -0
  36. package/dist/utils/document/dereference.js +21 -0
  37. package/dist/utils/document/dereference.js.map +1 -0
  38. package/dist/utils/document/process.d.ts +7 -0
  39. package/dist/utils/document/process.d.ts.map +1 -0
  40. package/dist/utils/{process-document.js → document/process.js} +5 -18
  41. package/dist/utils/document/process.js.map +1 -0
  42. package/dist/utils/is-plain-object.js +10 -0
  43. package/dist/utils/is-plain-object.js.map +1 -0
  44. package/dist/utils/pages/builder.d.ts +4 -4
  45. package/dist/utils/pages/builder.d.ts.map +1 -1
  46. package/dist/utils/pages/builder.js.map +1 -1
  47. package/dist/utils/pages/preset-auto.d.ts +2 -2
  48. package/dist/utils/pages/preset-auto.d.ts.map +1 -1
  49. package/dist/utils/pages/preset-auto.js.map +1 -1
  50. package/dist/utils/pages/to-text.js.map +1 -1
  51. package/dist/utils/remove-undefined.js +10 -8
  52. package/dist/utils/remove-undefined.js.map +1 -1
  53. package/dist/utils/schema/index.d.ts +7 -2
  54. package/dist/utils/schema/index.d.ts.map +1 -1
  55. package/dist/utils/schema/index.js +21 -2
  56. package/dist/utils/schema/index.js.map +1 -1
  57. package/dist/utils/schema/pick.js +46 -0
  58. package/dist/utils/schema/pick.js.map +1 -0
  59. package/dist/utils/schema/ref.js +37 -0
  60. package/dist/utils/schema/ref.js.map +1 -0
  61. package/dist/utils/schema/resolve-ref.js +4 -12
  62. package/dist/utils/schema/resolve-ref.js.map +1 -1
  63. package/dist/utils/schema/to-string.js.map +1 -1
  64. package/package.json +3 -4
  65. package/dist/playground/index.d.ts +0 -22
  66. package/dist/playground/index.d.ts.map +0 -1
  67. package/dist/playground/index.js +0 -118
  68. package/dist/playground/index.js.map +0 -1
  69. package/dist/utils/process-document.d.ts +0 -18
  70. package/dist/utils/process-document.d.ts.map +0 -1
  71. package/dist/utils/process-document.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"to-text.js","names":[],"sources":["../../../src/utils/pages/to-text.ts"],"sourcesContent":["import type { ApiPageProps, OperationItem, WebhookItem } from '@/ui/api-page';\nimport type { ProcessedDocument } from '@/utils/process-document';\nimport type { TagObject } from '@/types';\nimport { dump } from 'js-yaml';\nimport { removeUndefined } from '@/utils/remove-undefined';\nimport type { OperationOutput, PageOutput, WebhookOutput } from '@/utils/pages/builder';\nimport type { InternalOpenAPIMeta } from '@/server/source-api';\nimport { toStaticData } from '@/utils/pages/to-static-data';\n\nexport interface PagesToTextOptions {\n /**\n * Additional imports of your MDX components.\n */\n imports?: {\n names: string[];\n from: string;\n }[];\n\n /**\n * Customise frontmatter.\n *\n * A `full: true` property will be added by default.\n */\n frontmatter?: (\n title: string,\n description: string | undefined,\n context: DocumentContext,\n ) => Record<string, unknown>;\n\n /**\n * Add description to document body.\n *\n * We recommend but don't enable it by default because some OpenAPI schemas have invalid description that breaks MDX syntax.\n *\n * @defaultValue false\n */\n includeDescription?: boolean;\n\n /**\n * Add a comment to the top of generated files indicating they are auto-generated.\n * - `true`: Adds a standardized comment\n * - `false`: No comment is added\n * - `string`: Adds the provided custom comment\n *\n * @defaultValue true\n */\n addGeneratedComment?: boolean | string;\n}\n\nexport function toText(\n entry: PageOutput | OperationOutput | WebhookOutput,\n processed: ProcessedDocument,\n options: PagesToTextOptions = {},\n) {\n switch (entry.type) {\n case 'operation':\n return generatePage(\n entry.schemaId,\n processed,\n {\n operations: [entry.item],\n },\n {\n ...options,\n ...entry.info,\n },\n {\n type: 'operation',\n },\n );\n case 'page':\n return generatePage(\n entry.schemaId,\n processed,\n {\n operations: entry.operations,\n webhooks: entry.webhooks,\n showTitle: true,\n },\n {\n ...options,\n ...entry.info,\n },\n entry.tag\n ? {\n type: 'tag',\n tag: entry.tag,\n }\n : {\n type: 'file',\n },\n );\n case 'webhook':\n return generatePage(\n entry.schemaId,\n processed,\n {\n webhooks: [entry.item],\n },\n {\n ...options,\n ...entry.info,\n },\n {\n type: 'operation',\n },\n );\n }\n}\n\nexport function generateDocument(\n frontmatter: unknown,\n content: string,\n options: PagesToTextOptions,\n): string {\n const { addGeneratedComment = true, imports } = options;\n const out: string[] = [];\n const banner = dump(removeUndefined(frontmatter as object)).trimEnd();\n if (banner.length > 0) out.push(`---\\n${banner}\\n---`);\n\n if (addGeneratedComment) {\n let commentContent =\n 'This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again.';\n\n if (typeof addGeneratedComment === 'string') {\n commentContent = addGeneratedComment;\n }\n\n commentContent = commentContent.replaceAll('/', '\\\\/');\n out.push(`{/* ${commentContent} */}`);\n }\n\n if (imports) {\n out.push(\n ...imports\n .map((item) => `import { ${item.names.join(', ')} } from ${JSON.stringify(item.from)};`)\n .join('\\n'),\n );\n }\n\n out.push(content);\n return out.join('\\n\\n');\n}\n\nexport type DocumentContext =\n | {\n type: 'tag';\n tag: TagObject | undefined;\n }\n | {\n type: 'operation';\n }\n | {\n type: 'file';\n };\n\nfunction generatePage(\n schemaId: string,\n processed: ProcessedDocument,\n pageProps: Omit<ApiPageProps, 'document'>,\n options: PagesToTextOptions & {\n title: string;\n description?: string;\n },\n context: DocumentContext,\n): string {\n const { frontmatter, includeDescription = false } = options;\n const extend = frontmatter?.(options.title, options.description, context);\n const page: ApiPageProps = {\n ...pageProps,\n document: schemaId,\n };\n\n let meta: InternalOpenAPIMeta | undefined;\n if (page.operations?.length === 1) {\n const operation = page.operations[0];\n\n meta = {\n method: operation.method.toUpperCase(),\n };\n } else if (page.webhooks?.length === 1) {\n const webhook = page.webhooks[0];\n\n meta = {\n method: webhook.method.toUpperCase(),\n webhook: true,\n };\n }\n\n const data = toStaticData(page, processed.dereferenced);\n const content: string[] = [];\n\n if (options.description && includeDescription) content.push(options.description);\n content.push(pageContent(page));\n\n return generateDocument(\n {\n title: options.title,\n description: !includeDescription ? options.description : undefined,\n full: true,\n ...extend,\n _openapi: {\n ...meta,\n ...data,\n ...(extend?._openapi as object | undefined),\n },\n },\n content.join('\\n\\n'),\n options,\n );\n}\n\nfunction pageContent({\n showTitle,\n showDescription,\n document,\n webhooks,\n operations,\n}: ApiPageProps): string {\n const propStrs: string[] = [`document={${JSON.stringify(document)}}`];\n\n // filter extra properties in props\n if (webhooks) {\n propStrs.push(\n `webhooks={${JSON.stringify(\n webhooks.map(\n (item) =>\n ({\n name: item.name,\n method: item.method,\n }) satisfies WebhookItem,\n ),\n )}}`,\n );\n }\n if (operations) {\n propStrs.push(\n `operations={${JSON.stringify(\n operations.map(\n (item) =>\n ({\n path: item.path,\n method: item.method,\n }) satisfies OperationItem,\n ),\n )}}`,\n );\n }\n if (showTitle) {\n propStrs.push(`showTitle={${JSON.stringify(showTitle)}}`);\n }\n if (showDescription) {\n propStrs.push(`showDescription={${JSON.stringify(showDescription)}}`);\n }\n\n return `<APIPage ${propStrs.join(' ')} />`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"to-text.js","names":[],"sources":["../../../src/utils/pages/to-text.ts"],"sourcesContent":["import type { ApiPageProps, OperationItem, WebhookItem } from '@/ui/api-page';\nimport type { DereferencedDocument } from '@/utils/document/dereference';\nimport type { TagObject } from '@/types';\nimport { dump } from 'js-yaml';\nimport { removeUndefined } from '@/utils/remove-undefined';\nimport type { OperationOutput, PageOutput, WebhookOutput } from '@/utils/pages/builder';\nimport type { InternalOpenAPIMeta } from '@/server/source-api';\nimport { toStaticData } from '@/utils/pages/to-static-data';\n\nexport interface PagesToTextOptions {\n /**\n * Additional imports of your MDX components.\n */\n imports?: {\n names: string[];\n from: string;\n }[];\n\n /**\n * Customise frontmatter.\n *\n * A `full: true` property will be added by default.\n */\n frontmatter?: (\n title: string,\n description: string | undefined,\n context: DocumentContext,\n ) => Record<string, unknown>;\n\n /**\n * Add description to document body.\n *\n * We recommend but don't enable it by default because some OpenAPI schemas have invalid description that breaks MDX syntax.\n *\n * @defaultValue false\n */\n includeDescription?: boolean;\n\n /**\n * Add a comment to the top of generated files indicating they are auto-generated.\n * - `true`: Adds a standardized comment\n * - `false`: No comment is added\n * - `string`: Adds the provided custom comment\n *\n * @defaultValue true\n */\n addGeneratedComment?: boolean | string;\n}\n\nexport function toText(\n entry: PageOutput | OperationOutput | WebhookOutput,\n processed: DereferencedDocument,\n options: PagesToTextOptions = {},\n) {\n switch (entry.type) {\n case 'operation':\n return generatePage(\n entry.schemaId,\n processed,\n {\n operations: [entry.item],\n },\n {\n ...options,\n ...entry.info,\n },\n {\n type: 'operation',\n },\n );\n case 'page':\n return generatePage(\n entry.schemaId,\n processed,\n {\n operations: entry.operations,\n webhooks: entry.webhooks,\n showTitle: true,\n },\n {\n ...options,\n ...entry.info,\n },\n entry.tag\n ? {\n type: 'tag',\n tag: entry.tag,\n }\n : {\n type: 'file',\n },\n );\n case 'webhook':\n return generatePage(\n entry.schemaId,\n processed,\n {\n webhooks: [entry.item],\n },\n {\n ...options,\n ...entry.info,\n },\n {\n type: 'operation',\n },\n );\n }\n}\n\nexport function generateDocument(\n frontmatter: unknown,\n content: string,\n options: PagesToTextOptions,\n): string {\n const { addGeneratedComment = true, imports } = options;\n const out: string[] = [];\n const banner = dump(removeUndefined(frontmatter as object)).trimEnd();\n if (banner.length > 0) out.push(`---\\n${banner}\\n---`);\n\n if (addGeneratedComment) {\n let commentContent =\n 'This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again.';\n\n if (typeof addGeneratedComment === 'string') {\n commentContent = addGeneratedComment;\n }\n\n commentContent = commentContent.replaceAll('/', '\\\\/');\n out.push(`{/* ${commentContent} */}`);\n }\n\n if (imports) {\n out.push(\n ...imports\n .map((item) => `import { ${item.names.join(', ')} } from ${JSON.stringify(item.from)};`)\n .join('\\n'),\n );\n }\n\n out.push(content);\n return out.join('\\n\\n');\n}\n\nexport type DocumentContext =\n | {\n type: 'tag';\n tag: TagObject | undefined;\n }\n | {\n type: 'operation';\n }\n | {\n type: 'file';\n };\n\nfunction generatePage(\n schemaId: string,\n processed: DereferencedDocument,\n pageProps: Omit<ApiPageProps, 'document'>,\n options: PagesToTextOptions & {\n title: string;\n description?: string;\n },\n context: DocumentContext,\n): string {\n const { frontmatter, includeDescription = false } = options;\n const extend = frontmatter?.(options.title, options.description, context);\n const page: ApiPageProps = {\n ...pageProps,\n document: schemaId,\n };\n\n let meta: InternalOpenAPIMeta | undefined;\n if (page.operations?.length === 1) {\n const operation = page.operations[0];\n\n meta = {\n method: operation.method.toUpperCase(),\n };\n } else if (page.webhooks?.length === 1) {\n const webhook = page.webhooks[0];\n\n meta = {\n method: webhook.method.toUpperCase(),\n webhook: true,\n };\n }\n\n const data = toStaticData(page, processed.dereferenced);\n const content: string[] = [];\n\n if (options.description && includeDescription) content.push(options.description);\n content.push(pageContent(page));\n\n return generateDocument(\n {\n title: options.title,\n description: !includeDescription ? options.description : undefined,\n full: true,\n ...extend,\n _openapi: {\n ...meta,\n ...data,\n ...(extend?._openapi as object | undefined),\n },\n },\n content.join('\\n\\n'),\n options,\n );\n}\n\nfunction pageContent({\n showTitle,\n showDescription,\n document,\n webhooks,\n operations,\n}: ApiPageProps): string {\n const propStrs: string[] = [`document={${JSON.stringify(document)}}`];\n\n // filter extra properties in props\n if (webhooks) {\n propStrs.push(\n `webhooks={${JSON.stringify(\n webhooks.map(\n (item) =>\n ({\n name: item.name,\n method: item.method,\n }) satisfies WebhookItem,\n ),\n )}}`,\n );\n }\n if (operations) {\n propStrs.push(\n `operations={${JSON.stringify(\n operations.map(\n (item) =>\n ({\n path: item.path,\n method: item.method,\n }) satisfies OperationItem,\n ),\n )}}`,\n );\n }\n if (showTitle) {\n propStrs.push(`showTitle={${JSON.stringify(showTitle)}}`);\n }\n if (showDescription) {\n propStrs.push(`showDescription={${JSON.stringify(showDescription)}}`);\n }\n\n return `<APIPage ${propStrs.join(' ')} />`;\n}\n"],"mappings":"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"}
@@ -1,15 +1,17 @@
1
+ import { isPlainObject } from "./is-plain-object.js";
1
2
  //#region src/utils/remove-undefined.ts
2
3
  function removeUndefined(value, deep = false) {
3
- const obj = value;
4
- for (const key in obj) {
5
- if (obj[key] === void 0) delete obj[key];
6
- if (!deep) continue;
7
- const entry = obj[key];
8
- if (typeof entry === "object" && entry !== null) {
9
- removeUndefined(entry, deep);
4
+ if (!isPlainObject(value)) return value;
5
+ for (const key in value) {
6
+ const prop = value[key];
7
+ if (prop === void 0) {
8
+ delete value[key];
10
9
  continue;
11
10
  }
12
- if (Array.isArray(entry)) for (const item of entry) removeUndefined(item, deep);
11
+ if (deep) {
12
+ if (Array.isArray(prop)) for (const item of prop) removeUndefined(item, deep);
13
+ if (isPlainObject(prop)) removeUndefined(prop, deep);
14
+ }
13
15
  }
14
16
  return value;
15
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remove-undefined.js","names":[],"sources":["../../src/utils/remove-undefined.ts"],"sourcesContent":["export function removeUndefined<T extends object>(value: T, deep = false): T {\n const obj = value as Record<string, unknown>;\n\n for (const key in obj) {\n if (obj[key] === undefined) delete obj[key];\n if (!deep) continue;\n\n const entry = obj[key];\n\n if (typeof entry === 'object' && entry !== null) {\n removeUndefined(entry, deep);\n continue;\n }\n\n if (Array.isArray(entry)) {\n for (const item of entry) removeUndefined(item, deep);\n }\n }\n\n return value;\n}\n"],"mappings":";AAAA,SAAgB,gBAAkC,OAAU,OAAO,OAAU;CAC3E,MAAM,MAAM;AAEZ,MAAK,MAAM,OAAO,KAAK;AACrB,MAAI,IAAI,SAAS,KAAA,EAAW,QAAO,IAAI;AACvC,MAAI,CAAC,KAAM;EAEX,MAAM,QAAQ,IAAI;AAElB,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,mBAAgB,OAAO,KAAK;AAC5B;;AAGF,MAAI,MAAM,QAAQ,MAAM,CACtB,MAAK,MAAM,QAAQ,MAAO,iBAAgB,MAAM,KAAK;;AAIzD,QAAO"}
1
+ {"version":3,"file":"remove-undefined.js","names":[],"sources":["../../src/utils/remove-undefined.ts"],"sourcesContent":["import { isPlainObject } from './is-plain-object';\n\nexport function removeUndefined<T extends object>(value: T, deep = false): T {\n if (!isPlainObject(value)) return value;\n\n for (const key in value) {\n const prop = value[key];\n if (prop === undefined) {\n delete value[key];\n continue;\n }\n\n if (deep) {\n if (Array.isArray(prop)) {\n for (const item of prop) removeUndefined(item, deep);\n }\n\n if (isPlainObject(prop)) {\n removeUndefined(prop, deep);\n }\n }\n }\n\n return value;\n}\n"],"mappings":";;AAEA,SAAgB,gBAAkC,OAAU,OAAO,OAAU;AAC3E,KAAI,CAAC,cAAc,MAAM,CAAE,QAAO;AAElC,MAAK,MAAM,OAAO,OAAO;EACvB,MAAM,OAAO,MAAM;AACnB,MAAI,SAAS,KAAA,GAAW;AACtB,UAAO,MAAM;AACb;;AAGF,MAAI,MAAM;AACR,OAAI,MAAM,QAAQ,KAAK,CACrB,MAAK,MAAM,QAAQ,KAAM,iBAAgB,MAAM,KAAK;AAGtD,OAAI,cAAc,KAAK,CACrB,iBAAgB,MAAM,KAAK;;;AAKjC,QAAO"}
@@ -1,4 +1,4 @@
1
- import { ReferenceObject } from "../../types.js";
1
+ import { ReferenceObject, SecuritySchemeObject } from "../../types.js";
2
2
  import { JSONSchema } from "json-schema-typed/draft-2020-12";
3
3
 
4
4
  //#region src/utils/schema/index.d.ts
@@ -10,6 +10,11 @@ type ParsedSchema = (JSONSchema & {
10
10
  'x-playground-lazy'?: boolean;
11
11
  }) | boolean;
12
12
  type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;
13
+ /** parsed security scheme objects */
14
+ type SecurityEntry = SecuritySchemeObject & {
15
+ scopes: string[];
16
+ id: string;
17
+ };
13
18
  //#endregion
14
- export { NoReference, ParsedSchema, ResolvedSchema };
19
+ export { NoReference, ParsedSchema, ResolvedSchema, SecurityEntry };
15
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/utils/schema/index.ts"],"mappings":";;;;KAcY,WAAA,MAAiB,CAAA,uBACzB,WAAA,CAAY,CAAA,MACZ,CAAA,SAAU,eAAA,GACR,OAAA,CAAQ,CAAA,EAAG,eAAA,IACX,CAAA,gCAEgB,CAAA,GAAI,WAAA,CAAY,CAAA,CAAE,CAAA,OAEhC,CAAA;AAAA,KAEH,qBAAA,MAA2B,CAAA,uBAC5B,WAAA,CAAY,CAAA,MACZ,CAAA;EAAY,IAAA;AAAA,IACV,IAAA,CAAK,CAAA,YACL,CAAA;AAAA,KAEM,YAAA,IACP,UAAA;EACC,mBAAA;AAAA;AAAA,KAGM,cAAA,GAAiB,qBAAA,CAAsB,YAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/utils/schema/index.ts"],"mappings":";;;;KAiBY,WAAA,MAAiB,CAAA,uBACzB,WAAA,CAAY,CAAA,MACZ,CAAA,SAAU,eAAA,GACR,OAAA,CAAQ,CAAA,EAAG,eAAA,IACX,CAAA,gCAEgB,CAAA,GAAI,WAAA,CAAY,CAAA,CAAE,CAAA,OAEhC,CAAA;AAAA,KAEH,qBAAA,MAA2B,CAAA,uBAC5B,WAAA,CAAY,CAAA,MACZ,CAAA;EAAY,IAAA;AAAA,IACV,IAAA,CAAK,CAAA,YACL,CAAA;AAAA,KAEM,YAAA,IACP,UAAA;EACC,mBAAA;AAAA;AAAA,KAGM,cAAA,GAAiB,qBAAA,CAAsB,YAAA;;KAkEvC,aAAA,GAAgB,oBAAA;EAC1B,MAAA;EACA,EAAA;AAAA"}
@@ -27,7 +27,7 @@ function createMethod(method, path, operation) {
27
27
  ...operation,
28
28
  servers: operation.servers ?? path.servers,
29
29
  parameters: [...operation.parameters ?? [], ...path.parameters ?? []],
30
- method: method.toUpperCase()
30
+ method
31
31
  };
32
32
  }
33
33
  function pickExample(value) {
@@ -45,7 +45,26 @@ function pickExample(value) {
45
45
  if (examples.length > 0) return examples[0].value;
46
46
  }
47
47
  }
48
+ function parseSecurities(method, dereferenced) {
49
+ const result = [];
50
+ const security = method.security ?? dereferenced.security ?? [];
51
+ if (security.length === 0) return result;
52
+ for (const map of security) {
53
+ const list = [];
54
+ for (const [key, scopes] of Object.entries(map)) {
55
+ const scheme = dereferenced.components?.securitySchemes?.[key];
56
+ if (!scheme) continue;
57
+ list.push({
58
+ ...scheme,
59
+ scopes,
60
+ id: key
61
+ });
62
+ }
63
+ if (list.length > 0) result.push(list);
64
+ }
65
+ return result;
66
+ }
48
67
  //#endregion
49
- export { createMethod, getPreferredType, getTagDisplayName, methodKeys, pickExample };
68
+ export { createMethod, getPreferredType, getTagDisplayName, methodKeys, parseSecurities, pickExample };
50
69
 
51
70
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/schema/index.ts"],"sourcesContent":["import type { JSONSchema } from 'json-schema-typed/draft-2020-12';\nimport type {\n ExampleObject,\n MediaTypeObject,\n MethodInformation,\n OperationObject,\n PathItemObject,\n ReferenceObject,\n TagObject,\n} from '@/types';\nimport { idToTitle } from '@/utils/id-to-title';\n\nexport const methodKeys = ['get', 'post', 'patch', 'delete', 'head', 'put'] as const;\n\nexport type NoReference<T> = T extends (infer I)[]\n ? NoReference<I>[]\n : T extends ReferenceObject\n ? Exclude<T, ReferenceObject>\n : T extends object\n ? {\n [K in keyof T]: NoReference<T[K]>;\n }\n : T;\n\ntype NoReferenceJSONSchema<T> = T extends (infer I)[]\n ? NoReference<I>[]\n : T extends { $ref?: string }\n ? Omit<T, '$ref'>\n : T;\n\nexport type ParsedSchema =\n | (JSONSchema & {\n 'x-playground-lazy'?: boolean;\n })\n | boolean;\nexport type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;\n\nexport function getPreferredType(body: Record<string, unknown>): string | undefined {\n if ('application/json' in body) return 'application/json';\n\n return Object.keys(body)[0];\n}\n\nexport function getTagDisplayName(tag: TagObject): string {\n if ('x-displayName' in tag && typeof tag['x-displayName'] === 'string')\n return tag['x-displayName'];\n\n if (tag.summary) return tag.summary;\n return idToTitle(tag.name!);\n}\n\n/**\n * Summarize method endpoint information\n */\nexport function createMethod(\n method: string,\n path: NoReference<PathItemObject>,\n operation: NoReference<OperationObject>,\n): MethodInformation {\n return {\n description: path.description,\n summary: path.summary,\n ...operation,\n servers: operation.servers ?? path.servers,\n parameters: [...(operation.parameters ?? []), ...(path.parameters ?? [])],\n method: method.toUpperCase(),\n };\n}\n\ninterface ExampleLike {\n example?: unknown;\n examples?: {\n [media: string]: ExampleObject;\n };\n content?: {\n [media: string]: MediaTypeObject;\n };\n}\n\nexport function pickExample(value: ExampleLike): unknown | undefined {\n if (value.example !== undefined) {\n return value.example;\n }\n\n if (value.content) {\n const type = getPreferredType(value.content);\n const content = type ? value.content[type] : undefined;\n\n if (type && content) {\n const out = value.examples?.[type].value ?? pickExample(content);\n if (out !== undefined) return out;\n }\n }\n\n if (value.examples) {\n const examples = Object.values(value.examples);\n if (examples.length > 0) return examples[0].value;\n }\n}\n"],"mappings":";;AAYA,MAAa,aAAa;CAAC;CAAO;CAAQ;CAAS;CAAU;CAAQ;CAAM;AAyB3E,SAAgB,iBAAiB,MAAmD;AAClF,KAAI,sBAAsB,KAAM,QAAO;AAEvC,QAAO,OAAO,KAAK,KAAK,CAAC;;AAG3B,SAAgB,kBAAkB,KAAwB;AACxD,KAAI,mBAAmB,OAAO,OAAO,IAAI,qBAAqB,SAC5D,QAAO,IAAI;AAEb,KAAI,IAAI,QAAS,QAAO,IAAI;AAC5B,QAAO,UAAU,IAAI,KAAM;;;;;AAM7B,SAAgB,aACd,QACA,MACA,WACmB;AACnB,QAAO;EACL,aAAa,KAAK;EAClB,SAAS,KAAK;EACd,GAAG;EACH,SAAS,UAAU,WAAW,KAAK;EACnC,YAAY,CAAC,GAAI,UAAU,cAAc,EAAE,EAAG,GAAI,KAAK,cAAc,EAAE,CAAE;EACzE,QAAQ,OAAO,aAAa;EAC7B;;AAaH,SAAgB,YAAY,OAAyC;AACnE,KAAI,MAAM,YAAY,KAAA,EACpB,QAAO,MAAM;AAGf,KAAI,MAAM,SAAS;EACjB,MAAM,OAAO,iBAAiB,MAAM,QAAQ;EAC5C,MAAM,UAAU,OAAO,MAAM,QAAQ,QAAQ,KAAA;AAE7C,MAAI,QAAQ,SAAS;GACnB,MAAM,MAAM,MAAM,WAAW,MAAM,SAAS,YAAY,QAAQ;AAChE,OAAI,QAAQ,KAAA,EAAW,QAAO;;;AAIlC,KAAI,MAAM,UAAU;EAClB,MAAM,WAAW,OAAO,OAAO,MAAM,SAAS;AAC9C,MAAI,SAAS,SAAS,EAAG,QAAO,SAAS,GAAG"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/schema/index.ts"],"sourcesContent":["import type { JSONSchema } from 'json-schema-typed/draft-2020-12';\nimport type {\n Document,\n ExampleObject,\n HttpMethods,\n MediaTypeObject,\n MethodInformation,\n OperationObject,\n PathItemObject,\n ReferenceObject,\n SecuritySchemeObject,\n TagObject,\n} from '@/types';\nimport { idToTitle } from '@/utils/id-to-title';\n\nexport const methodKeys = ['get', 'post', 'patch', 'delete', 'head', 'put'] as const;\n\nexport type NoReference<T> = T extends (infer I)[]\n ? NoReference<I>[]\n : T extends ReferenceObject\n ? Exclude<T, ReferenceObject>\n : T extends object\n ? {\n [K in keyof T]: NoReference<T[K]>;\n }\n : T;\n\ntype NoReferenceJSONSchema<T> = T extends (infer I)[]\n ? NoReference<I>[]\n : T extends { $ref?: string }\n ? Omit<T, '$ref'>\n : T;\n\nexport type ParsedSchema =\n | (JSONSchema & {\n 'x-playground-lazy'?: boolean;\n })\n | boolean;\nexport type ResolvedSchema = NoReferenceJSONSchema<ParsedSchema>;\n\nexport function getPreferredType(body: Record<string, unknown>): string | undefined {\n if ('application/json' in body) return 'application/json';\n\n return Object.keys(body)[0];\n}\n\nexport function getTagDisplayName(tag: TagObject): string {\n if ('x-displayName' in tag && typeof tag['x-displayName'] === 'string')\n return tag['x-displayName'];\n\n if (tag.summary) return tag.summary;\n return idToTitle(tag.name!);\n}\n\n/**\n * Summarize method endpoint information\n */\nexport function createMethod(\n method: HttpMethods,\n path: NoReference<PathItemObject>,\n operation: NoReference<OperationObject>,\n): MethodInformation {\n return {\n description: path.description,\n summary: path.summary,\n ...operation,\n servers: operation.servers ?? path.servers,\n parameters: [...(operation.parameters ?? []), ...(path.parameters ?? [])],\n method,\n };\n}\n\ninterface ExampleLike {\n example?: unknown;\n examples?: {\n [media: string]: ExampleObject;\n };\n content?: {\n [media: string]: MediaTypeObject;\n };\n}\n\nexport function pickExample(value: ExampleLike): unknown | undefined {\n if (value.example !== undefined) {\n return value.example;\n }\n\n if (value.content) {\n const type = getPreferredType(value.content);\n const content = type ? value.content[type] : undefined;\n\n if (type && content) {\n const out = value.examples?.[type].value ?? pickExample(content);\n if (out !== undefined) return out;\n }\n }\n\n if (value.examples) {\n const examples = Object.values(value.examples);\n if (examples.length > 0) return examples[0].value;\n }\n}\n\n/** parsed security scheme objects */\nexport type SecurityEntry = SecuritySchemeObject & {\n scopes: string[];\n id: string;\n};\n\nexport function parseSecurities(\n method: MethodInformation,\n dereferenced: NoReference<Document>,\n): SecurityEntry[][] {\n const result: SecurityEntry[][] = [];\n const security = method.security ?? dereferenced.security ?? [];\n if (security.length === 0) return result;\n\n for (const map of security) {\n const list: SecurityEntry[] = [];\n\n for (const [key, scopes] of Object.entries(map)) {\n const scheme = dereferenced.components?.securitySchemes?.[key];\n if (!scheme) continue;\n\n list.push({\n ...scheme,\n scopes,\n id: key,\n });\n }\n\n if (list.length > 0) result.push(list);\n }\n\n return result;\n}\n"],"mappings":";;AAeA,MAAa,aAAa;CAAC;CAAO;CAAQ;CAAS;CAAU;CAAQ;CAAM;AAyB3E,SAAgB,iBAAiB,MAAmD;AAClF,KAAI,sBAAsB,KAAM,QAAO;AAEvC,QAAO,OAAO,KAAK,KAAK,CAAC;;AAG3B,SAAgB,kBAAkB,KAAwB;AACxD,KAAI,mBAAmB,OAAO,OAAO,IAAI,qBAAqB,SAC5D,QAAO,IAAI;AAEb,KAAI,IAAI,QAAS,QAAO,IAAI;AAC5B,QAAO,UAAU,IAAI,KAAM;;;;;AAM7B,SAAgB,aACd,QACA,MACA,WACmB;AACnB,QAAO;EACL,aAAa,KAAK;EAClB,SAAS,KAAK;EACd,GAAG;EACH,SAAS,UAAU,WAAW,KAAK;EACnC,YAAY,CAAC,GAAI,UAAU,cAAc,EAAE,EAAG,GAAI,KAAK,cAAc,EAAE,CAAE;EACzE;EACD;;AAaH,SAAgB,YAAY,OAAyC;AACnE,KAAI,MAAM,YAAY,KAAA,EACpB,QAAO,MAAM;AAGf,KAAI,MAAM,SAAS;EACjB,MAAM,OAAO,iBAAiB,MAAM,QAAQ;EAC5C,MAAM,UAAU,OAAO,MAAM,QAAQ,QAAQ,KAAA;AAE7C,MAAI,QAAQ,SAAS;GACnB,MAAM,MAAM,MAAM,WAAW,MAAM,SAAS,YAAY,QAAQ;AAChE,OAAI,QAAQ,KAAA,EAAW,QAAO;;;AAIlC,KAAI,MAAM,UAAU;EAClB,MAAM,WAAW,OAAO,OAAO,MAAM,SAAS;AAC9C,MAAI,SAAS,SAAS,EAAG,QAAO,SAAS,GAAG;;;AAUhD,SAAgB,gBACd,QACA,cACmB;CACnB,MAAM,SAA4B,EAAE;CACpC,MAAM,WAAW,OAAO,YAAY,aAAa,YAAY,EAAE;AAC/D,KAAI,SAAS,WAAW,EAAG,QAAO;AAElC,MAAK,MAAM,OAAO,UAAU;EAC1B,MAAM,OAAwB,EAAE;AAEhC,OAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,IAAI,EAAE;GAC/C,MAAM,SAAS,aAAa,YAAY,kBAAkB;AAC1D,OAAI,CAAC,OAAQ;AAEb,QAAK,KAAK;IACR,GAAG;IACH;IACA,IAAI;IACL,CAAC;;AAGJ,MAAI,KAAK,SAAS,EAAG,QAAO,KAAK,KAAK;;AAGxC,QAAO"}
@@ -0,0 +1,46 @@
1
+ import { isPlainObject } from "../is-plain-object.js";
2
+ import { decodeInternalRef } from "./ref.js";
3
+ import { resolveRefSync } from "./resolve-ref.js";
4
+ //#region src/utils/schema/pick.ts
5
+ /**
6
+ * return a filtered object that only contains the given `$ref` & its referenced fields.
7
+ */
8
+ function pickSchema(root, $ref) {
9
+ const out = {};
10
+ const scanned = /* @__PURE__ */ new Set();
11
+ function scan(next) {
12
+ if (isPlainObject(next)) {
13
+ if (typeof next.$ref === "string") {
14
+ if (scanned.has(next.$ref)) return;
15
+ const resolved = resolveRefSync(next.$ref, root);
16
+ scanned.add(next.$ref);
17
+ scan(resolved);
18
+ setField(out, decodeInternalRef(next.$ref), resolved);
19
+ }
20
+ for (const k in next) scan(next[k]);
21
+ return;
22
+ }
23
+ if (Array.isArray(next)) for (const item of next) scan(item);
24
+ }
25
+ scan({ $ref });
26
+ return out;
27
+ }
28
+ function setField(obj, field, value) {
29
+ if (field.length === 0) return value;
30
+ const out = isPlainObject(obj) ? obj : {};
31
+ let current = out;
32
+ for (let i = 0; i < field.length; i++) {
33
+ const k = field[i];
34
+ if (i === field.length - 1) current[k] = value;
35
+ else {
36
+ const v = current[k];
37
+ if (isPlainObject(v)) current = v;
38
+ else current = current[k] = {};
39
+ }
40
+ }
41
+ return out;
42
+ }
43
+ //#endregion
44
+ export { pickSchema };
45
+
46
+ //# sourceMappingURL=pick.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pick.js","names":[],"sources":["../../../src/utils/schema/pick.ts"],"sourcesContent":["import { isPlainObject } from '../is-plain-object';\nimport { decodeInternalRef } from './ref';\nimport { resolveRefSync } from './resolve-ref';\n\n/**\n * return a filtered object that only contains the given `$ref` & its referenced fields.\n */\nexport function pickSchema(root: object, $ref: string): object {\n const out: object = {};\n const scanned = new Set<string>();\n\n function scan(next: unknown) {\n if (isPlainObject(next)) {\n if (typeof next.$ref === 'string') {\n if (scanned.has(next.$ref)) return;\n\n const resolved = resolveRefSync(next.$ref, root);\n scanned.add(next.$ref);\n scan(resolved);\n setField(out, decodeInternalRef(next.$ref), resolved);\n }\n\n for (const k in next) scan(next[k]);\n return;\n }\n\n if (Array.isArray(next)) {\n for (const item of next) scan(item);\n }\n }\n\n scan({ $ref });\n return out;\n}\n\nfunction setField(obj: unknown, field: string[], value: unknown): unknown {\n if (field.length === 0) return value;\n\n const out: Record<string, unknown> = isPlainObject(obj) ? obj : {};\n let current = out;\n\n for (let i = 0; i < field.length; i++) {\n const k = field[i];\n\n if (i === field.length - 1) {\n current[k] = value;\n } else {\n const v = current[k];\n\n if (isPlainObject(v)) {\n current = v;\n } else {\n current = current[k] = {};\n }\n }\n }\n\n return out;\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,WAAW,MAAc,MAAsB;CAC7D,MAAM,MAAc,EAAE;CACtB,MAAM,0BAAU,IAAI,KAAa;CAEjC,SAAS,KAAK,MAAe;AAC3B,MAAI,cAAc,KAAK,EAAE;AACvB,OAAI,OAAO,KAAK,SAAS,UAAU;AACjC,QAAI,QAAQ,IAAI,KAAK,KAAK,CAAE;IAE5B,MAAM,WAAW,eAAe,KAAK,MAAM,KAAK;AAChD,YAAQ,IAAI,KAAK,KAAK;AACtB,SAAK,SAAS;AACd,aAAS,KAAK,kBAAkB,KAAK,KAAK,EAAE,SAAS;;AAGvD,QAAK,MAAM,KAAK,KAAM,MAAK,KAAK,GAAG;AACnC;;AAGF,MAAI,MAAM,QAAQ,KAAK,CACrB,MAAK,MAAM,QAAQ,KAAM,MAAK,KAAK;;AAIvC,MAAK,EAAE,MAAM,CAAC;AACd,QAAO;;AAGT,SAAS,SAAS,KAAc,OAAiB,OAAyB;AACxE,KAAI,MAAM,WAAW,EAAG,QAAO;CAE/B,MAAM,MAA+B,cAAc,IAAI,GAAG,MAAM,EAAE;CAClE,IAAI,UAAU;AAEd,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,IAAI,MAAM;AAEhB,MAAI,MAAM,MAAM,SAAS,EACvB,SAAQ,KAAK;OACR;GACL,MAAM,IAAI,QAAQ;AAElB,OAAI,cAAc,EAAE,CAClB,WAAU;OAEV,WAAU,QAAQ,KAAK,EAAE;;;AAK/B,QAAO"}
@@ -0,0 +1,37 @@
1
+ //#region src/utils/schema/ref.ts
2
+ /**
3
+ * RFC 6901 reference-token encoding for JSON Pointer fragments used in in-document `$ref` (`#/…`).
4
+ *
5
+ * @see https://datatracker.ietf.org/doc/html/rfc6901
6
+ */
7
+ function encodeSegment(segment) {
8
+ return segment.replace(/~/g, "~0").replace(/\//g, "~1");
9
+ }
10
+ function decodeSegment(segment) {
11
+ return segment.replace(/~1/g, "/").replace(/~0/g, "~");
12
+ }
13
+ /**
14
+ * Build an in-document `$ref` string from logical path segments (e.g. `['components','schemas','Pet']` → `#/components/schemas/Pet`).
15
+ */
16
+ function encodeInternalRef(segments) {
17
+ if (segments.length === 0) return "#/";
18
+ return `#/${segments.map(encodeSegment).join("/")}`;
19
+ }
20
+ /**
21
+ * Parse an in-document `$ref` (`#/…`) into decoded path segments for walking the root document.
22
+ */
23
+ function decodeInternalRef(ref) {
24
+ if (!ref.startsWith("#")) throw new Error("expected in-document $ref starting with `#`");
25
+ const raw = ref.slice(1);
26
+ const out = [];
27
+ if (raw.length === 0) return out;
28
+ for (const token of raw.split("/")) {
29
+ if (token.length === 0) continue;
30
+ out.push(decodeSegment(token));
31
+ }
32
+ return out;
33
+ }
34
+ //#endregion
35
+ export { decodeInternalRef, encodeInternalRef };
36
+
37
+ //# sourceMappingURL=ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.js","names":[],"sources":["../../../src/utils/schema/ref.ts"],"sourcesContent":["/**\n * RFC 6901 reference-token encoding for JSON Pointer fragments used in in-document `$ref` (`#/…`).\n *\n * @see https://datatracker.ietf.org/doc/html/rfc6901\n */\n\nfunction encodeSegment(segment: string): string {\n return segment.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n\nfunction decodeSegment(segment: string): string {\n return segment.replace(/~1/g, '/').replace(/~0/g, '~');\n}\n\n/**\n * Build an in-document `$ref` string from logical path segments (e.g. `['components','schemas','Pet']` → `#/components/schemas/Pet`).\n */\nexport function encodeInternalRef(segments: readonly string[]): string {\n if (segments.length === 0) return '#/';\n return `#/${segments.map(encodeSegment).join('/')}`;\n}\n\n/**\n * Parse an in-document `$ref` (`#/…`) into decoded path segments for walking the root document.\n */\nexport function decodeInternalRef(ref: string): string[] {\n if (!ref.startsWith('#')) {\n throw new Error('expected in-document $ref starting with `#`');\n }\n\n const raw = ref.slice(1);\n const out: string[] = [];\n if (raw.length === 0) return out;\n\n for (const token of raw.split('/')) {\n if (token.length === 0) continue;\n out.push(decodeSegment(token));\n }\n\n return out;\n}\n"],"mappings":";;;;;;AAMA,SAAS,cAAc,SAAyB;AAC9C,QAAO,QAAQ,QAAQ,MAAM,KAAK,CAAC,QAAQ,OAAO,KAAK;;AAGzD,SAAS,cAAc,SAAyB;AAC9C,QAAO,QAAQ,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI;;;;;AAMxD,SAAgB,kBAAkB,UAAqC;AACrE,KAAI,SAAS,WAAW,EAAG,QAAO;AAClC,QAAO,KAAK,SAAS,IAAI,cAAc,CAAC,KAAK,IAAI;;;;;AAMnD,SAAgB,kBAAkB,KAAuB;AACvD,KAAI,CAAC,IAAI,WAAW,IAAI,CACtB,OAAM,IAAI,MAAM,8CAA8C;CAGhE,MAAM,MAAM,IAAI,MAAM,EAAE;CACxB,MAAM,MAAgB,EAAE;AACxB,KAAI,IAAI,WAAW,EAAG,QAAO;AAE7B,MAAK,MAAM,SAAS,IAAI,MAAM,IAAI,EAAE;AAClC,MAAI,MAAM,WAAW,EAAG;AACxB,MAAI,KAAK,cAAc,MAAM,CAAC;;AAGhC,QAAO"}
@@ -1,20 +1,12 @@
1
+ import { isPlainObject } from "../is-plain-object.js";
2
+ import { decodeInternalRef } from "./ref.js";
1
3
  //#region src/utils/schema/resolve-ref.ts
2
4
  function resolveRefSync(ref, schema) {
3
- if (!ref.startsWith("#")) return;
4
- const segments = ref.slice(1).split("/");
5
5
  let current = schema;
6
- for (const seg of segments) {
7
- if (seg.length === 0) continue;
8
- if (isPlainObject(current)) current = current[seg];
9
- else return;
10
- }
6
+ for (const seg of decodeInternalRef(ref)) if (isPlainObject(current)) current = current[seg];
7
+ else return;
11
8
  return current;
12
9
  }
13
- function isPlainObject(value) {
14
- if (typeof value !== "object" || value === null) return false;
15
- const prototype = Object.getPrototypeOf(value);
16
- return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
17
- }
18
10
  //#endregion
19
11
  export { resolveRefSync };
20
12
 
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-ref.js","names":[],"sources":["../../../src/utils/schema/resolve-ref.ts"],"sourcesContent":["import type { JSONSchema } from 'json-schema-typed/draft-2020-12';\n\nexport function resolveRefSync(ref: string, schema: JSONSchema): unknown | undefined {\n if (!ref.startsWith('#')) return;\n const segments = ref.slice(1).split('/');\n let current: unknown = schema;\n\n for (const seg of segments) {\n if (seg.length === 0) continue;\n\n if (isPlainObject(current)) current = current[seg];\n else return;\n }\n\n return current;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n return (\n prototype === null ||\n prototype === Object.prototype ||\n Object.getPrototypeOf(prototype) === null\n );\n}\n"],"mappings":";AAEA,SAAgB,eAAe,KAAa,QAAyC;AACnF,KAAI,CAAC,IAAI,WAAW,IAAI,CAAE;CAC1B,MAAM,WAAW,IAAI,MAAM,EAAE,CAAC,MAAM,IAAI;CACxC,IAAI,UAAmB;AAEvB,MAAK,MAAM,OAAO,UAAU;AAC1B,MAAI,IAAI,WAAW,EAAG;AAEtB,MAAI,cAAc,QAAQ,CAAE,WAAU,QAAQ;MACzC;;AAGP,QAAO;;AAGT,SAAS,cAAc,OAAkD;AACvE,KAAI,OAAO,UAAU,YAAY,UAAU,KACzC,QAAO;CAGT,MAAM,YAAY,OAAO,eAAe,MAAM;AAC9C,QACE,cAAc,QACd,cAAc,OAAO,aACrB,OAAO,eAAe,UAAU,KAAK"}
1
+ {"version":3,"file":"resolve-ref.js","names":[],"sources":["../../../src/utils/schema/resolve-ref.ts"],"sourcesContent":["import { isPlainObject } from '../is-plain-object';\nimport { decodeInternalRef } from './ref';\n\nexport function resolveRefSync(ref: string, schema: unknown): unknown | undefined {\n let current = schema;\n\n for (const seg of decodeInternalRef(ref)) {\n if (isPlainObject(current)) current = current[seg];\n else return;\n }\n\n return current;\n}\n"],"mappings":";;;AAGA,SAAgB,eAAe,KAAa,QAAsC;CAChF,IAAI,UAAU;AAEd,MAAK,MAAM,OAAO,kBAAkB,IAAI,CACtC,KAAI,cAAc,QAAQ,CAAE,WAAU,QAAQ;KACzC;AAGP,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"to-string.js","names":[],"sources":["../../../src/utils/schema/to-string.ts"],"sourcesContent":["import type { ParsedSchema, ResolvedSchema } from '@/utils/schema';\nimport type { ProcessedDocument } from '@/utils/process-document';\n\nexport enum FormatFlags {\n None = 0,\n UseAlias = 1 << 0,\n}\n\ntype Resolver = (schema: ResolvedSchema) => {\n dereferenced: ResolvedSchema;\n raw?: ParsedSchema;\n};\n\nexport function schemaToString(\n value: ResolvedSchema,\n _resolver?: ProcessedDocument | Resolver,\n flags: FormatFlags = FormatFlags.None,\n): string {\n const resolver: Resolver =\n typeof _resolver === 'function'\n ? _resolver\n : (schema) => {\n const ref =\n _resolver && typeof schema === 'object' ? _resolver.getRawRef(schema) : undefined;\n\n return {\n dereferenced: schema,\n raw: ref ? { $ref: ref } : undefined,\n };\n };\n function union(union: readonly ResolvedSchema[], sep: string, flags: FormatFlags) {\n const members = new Set();\n let nullable = false;\n\n for (const item of union) {\n const result = run(item, flags | FormatFlags.UseAlias);\n\n if (result === 'null') {\n nullable = true;\n } else if (result !== 'unknown') {\n members.add(result);\n }\n }\n\n const result = Array.from(members).join(sep);\n return nullable ? `${result} | null` : result;\n }\n\n function run(schema: ResolvedSchema, flags: FormatFlags): string {\n const resolved = resolver(schema);\n schema = resolved.dereferenced;\n\n if (schema === true) return 'any';\n else if (schema === false) return 'never';\n\n if ((flags & FormatFlags.UseAlias) === FormatFlags.UseAlias) {\n if (schema.title) return schema.title;\n\n if (typeof resolved.raw === 'object' && resolved.raw.$ref) {\n const ref = resolved.raw.$ref.split('/');\n if (ref.length > 0) return ref[ref.length - 1];\n }\n }\n\n if (Array.isArray(schema.type)) {\n return union(\n schema.type.map((type) => ({\n ...schema,\n type,\n })),\n ' | ',\n flags,\n );\n }\n\n if (schema.type === 'array')\n return `array<${schema.items ? run(schema.items, flags | FormatFlags.UseAlias) : 'unknown'}>`;\n\n const or = schema.oneOf ?? schema.anyOf;\n if (schema.oneOf && schema.anyOf) {\n return `(${union(schema.oneOf, ' | ', flags)}) & (${union(schema.anyOf, ' | ', flags)})`;\n } else if (or) {\n return union(or, ' | ', flags);\n }\n\n if (schema.allOf) {\n return union(schema.allOf, ' & ', flags);\n }\n\n if (schema.not) return `not ${run(schema.not, flags)}`;\n if (schema.type === 'string' && schema.format === 'binary') return 'file';\n\n if (schema.type && Array.isArray(schema.type)) {\n return schema.type.filter((v) => v !== 'null').join(' | ');\n }\n\n if (schema.type) {\n return schema.type as string;\n }\n\n return 'unknown';\n }\n\n return run(value, flags);\n}\n"],"mappings":";AAGA,IAAY,cAAL,yBAAA,aAAA;AACL,aAAA,YAAA,UAAA,KAAA;AACA,aAAA,YAAA,cAAA,KAAA;;KACD;AAOD,SAAgB,eACd,OACA,WACA,QAAqB,YAAY,MACzB;CACR,MAAM,WACJ,OAAO,cAAc,aACjB,aACC,WAAW;EACV,MAAM,MACJ,aAAa,OAAO,WAAW,WAAW,UAAU,UAAU,OAAO,GAAG,KAAA;AAE1E,SAAO;GACL,cAAc;GACd,KAAK,MAAM,EAAE,MAAM,KAAK,GAAG,KAAA;GAC5B;;CAET,SAAS,MAAM,OAAkC,KAAa,OAAoB;EAChF,MAAM,0BAAU,IAAI,KAAK;EACzB,IAAI,WAAW;AAEf,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,SAAS,IAAI,MAAM,QAAQ,YAAY,SAAS;AAEtD,OAAI,WAAW,OACb,YAAW;YACF,WAAW,UACpB,SAAQ,IAAI,OAAO;;EAIvB,MAAM,SAAS,MAAM,KAAK,QAAQ,CAAC,KAAK,IAAI;AAC5C,SAAO,WAAW,GAAG,OAAO,WAAW;;CAGzC,SAAS,IAAI,QAAwB,OAA4B;EAC/D,MAAM,WAAW,SAAS,OAAO;AACjC,WAAS,SAAS;AAElB,MAAI,WAAW,KAAM,QAAO;WACnB,WAAW,MAAO,QAAO;AAElC,OAAK,QAAQ,YAAY,cAAc,YAAY,UAAU;AAC3D,OAAI,OAAO,MAAO,QAAO,OAAO;AAEhC,OAAI,OAAO,SAAS,QAAQ,YAAY,SAAS,IAAI,MAAM;IACzD,MAAM,MAAM,SAAS,IAAI,KAAK,MAAM,IAAI;AACxC,QAAI,IAAI,SAAS,EAAG,QAAO,IAAI,IAAI,SAAS;;;AAIhD,MAAI,MAAM,QAAQ,OAAO,KAAK,CAC5B,QAAO,MACL,OAAO,KAAK,KAAK,UAAU;GACzB,GAAG;GACH;GACD,EAAE,EACH,OACA,MACD;AAGH,MAAI,OAAO,SAAS,QAClB,QAAO,SAAS,OAAO,QAAQ,IAAI,OAAO,OAAO,QAAQ,YAAY,SAAS,GAAG,UAAU;EAE7F,MAAM,KAAK,OAAO,SAAS,OAAO;AAClC,MAAI,OAAO,SAAS,OAAO,MACzB,QAAO,IAAI,MAAM,OAAO,OAAO,OAAO,MAAM,CAAC,OAAO,MAAM,OAAO,OAAO,OAAO,MAAM,CAAC;WAC7E,GACT,QAAO,MAAM,IAAI,OAAO,MAAM;AAGhC,MAAI,OAAO,MACT,QAAO,MAAM,OAAO,OAAO,OAAO,MAAM;AAG1C,MAAI,OAAO,IAAK,QAAO,OAAO,IAAI,OAAO,KAAK,MAAM;AACpD,MAAI,OAAO,SAAS,YAAY,OAAO,WAAW,SAAU,QAAO;AAEnE,MAAI,OAAO,QAAQ,MAAM,QAAQ,OAAO,KAAK,CAC3C,QAAO,OAAO,KAAK,QAAQ,MAAM,MAAM,OAAO,CAAC,KAAK,MAAM;AAG5D,MAAI,OAAO,KACT,QAAO,OAAO;AAGhB,SAAO;;AAGT,QAAO,IAAI,OAAO,MAAM"}
1
+ {"version":3,"file":"to-string.js","names":[],"sources":["../../../src/utils/schema/to-string.ts"],"sourcesContent":["import type { ParsedSchema, ResolvedSchema } from '@/utils/schema';\nimport type { DereferencedDocument } from '@/utils/document/dereference';\n\nexport enum FormatFlags {\n None = 0,\n UseAlias = 1 << 0,\n}\n\ntype Resolver = (schema: ResolvedSchema) => {\n dereferenced: ResolvedSchema;\n raw?: ParsedSchema;\n};\n\nexport function schemaToString(\n value: ResolvedSchema,\n _resolver?: DereferencedDocument | Resolver,\n flags: FormatFlags = FormatFlags.None,\n): string {\n const resolver: Resolver =\n typeof _resolver === 'function'\n ? _resolver\n : (schema) => {\n const ref =\n _resolver && typeof schema === 'object' ? _resolver.getRawRef(schema) : undefined;\n\n return {\n dereferenced: schema,\n raw: ref ? { $ref: ref } : undefined,\n };\n };\n function union(union: readonly ResolvedSchema[], sep: string, flags: FormatFlags) {\n const members = new Set();\n let nullable = false;\n\n for (const item of union) {\n const result = run(item, flags | FormatFlags.UseAlias);\n\n if (result === 'null') {\n nullable = true;\n } else if (result !== 'unknown') {\n members.add(result);\n }\n }\n\n const result = Array.from(members).join(sep);\n return nullable ? `${result} | null` : result;\n }\n\n function run(schema: ResolvedSchema, flags: FormatFlags): string {\n const resolved = resolver(schema);\n schema = resolved.dereferenced;\n\n if (schema === true) return 'any';\n else if (schema === false) return 'never';\n\n if ((flags & FormatFlags.UseAlias) === FormatFlags.UseAlias) {\n if (schema.title) return schema.title;\n\n if (typeof resolved.raw === 'object' && resolved.raw.$ref) {\n const ref = resolved.raw.$ref.split('/');\n if (ref.length > 0) return ref[ref.length - 1];\n }\n }\n\n if (Array.isArray(schema.type)) {\n return union(\n schema.type.map((type) => ({\n ...schema,\n type,\n })),\n ' | ',\n flags,\n );\n }\n\n if (schema.type === 'array')\n return `array<${schema.items ? run(schema.items, flags | FormatFlags.UseAlias) : 'unknown'}>`;\n\n const or = schema.oneOf ?? schema.anyOf;\n if (schema.oneOf && schema.anyOf) {\n return `(${union(schema.oneOf, ' | ', flags)}) & (${union(schema.anyOf, ' | ', flags)})`;\n } else if (or) {\n return union(or, ' | ', flags);\n }\n\n if (schema.allOf) {\n return union(schema.allOf, ' & ', flags);\n }\n\n if (schema.not) return `not ${run(schema.not, flags)}`;\n if (schema.type === 'string' && schema.format === 'binary') return 'file';\n\n if (schema.type && Array.isArray(schema.type)) {\n return schema.type.filter((v) => v !== 'null').join(' | ');\n }\n\n if (schema.type) {\n return schema.type as string;\n }\n\n return 'unknown';\n }\n\n return run(value, flags);\n}\n"],"mappings":";AAGA,IAAY,cAAL,yBAAA,aAAA;AACL,aAAA,YAAA,UAAA,KAAA;AACA,aAAA,YAAA,cAAA,KAAA;;KACD;AAOD,SAAgB,eACd,OACA,WACA,QAAqB,YAAY,MACzB;CACR,MAAM,WACJ,OAAO,cAAc,aACjB,aACC,WAAW;EACV,MAAM,MACJ,aAAa,OAAO,WAAW,WAAW,UAAU,UAAU,OAAO,GAAG,KAAA;AAE1E,SAAO;GACL,cAAc;GACd,KAAK,MAAM,EAAE,MAAM,KAAK,GAAG,KAAA;GAC5B;;CAET,SAAS,MAAM,OAAkC,KAAa,OAAoB;EAChF,MAAM,0BAAU,IAAI,KAAK;EACzB,IAAI,WAAW;AAEf,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,SAAS,IAAI,MAAM,QAAQ,YAAY,SAAS;AAEtD,OAAI,WAAW,OACb,YAAW;YACF,WAAW,UACpB,SAAQ,IAAI,OAAO;;EAIvB,MAAM,SAAS,MAAM,KAAK,QAAQ,CAAC,KAAK,IAAI;AAC5C,SAAO,WAAW,GAAG,OAAO,WAAW;;CAGzC,SAAS,IAAI,QAAwB,OAA4B;EAC/D,MAAM,WAAW,SAAS,OAAO;AACjC,WAAS,SAAS;AAElB,MAAI,WAAW,KAAM,QAAO;WACnB,WAAW,MAAO,QAAO;AAElC,OAAK,QAAQ,YAAY,cAAc,YAAY,UAAU;AAC3D,OAAI,OAAO,MAAO,QAAO,OAAO;AAEhC,OAAI,OAAO,SAAS,QAAQ,YAAY,SAAS,IAAI,MAAM;IACzD,MAAM,MAAM,SAAS,IAAI,KAAK,MAAM,IAAI;AACxC,QAAI,IAAI,SAAS,EAAG,QAAO,IAAI,IAAI,SAAS;;;AAIhD,MAAI,MAAM,QAAQ,OAAO,KAAK,CAC5B,QAAO,MACL,OAAO,KAAK,KAAK,UAAU;GACzB,GAAG;GACH;GACD,EAAE,EACH,OACA,MACD;AAGH,MAAI,OAAO,SAAS,QAClB,QAAO,SAAS,OAAO,QAAQ,IAAI,OAAO,OAAO,QAAQ,YAAY,SAAS,GAAG,UAAU;EAE7F,MAAM,KAAK,OAAO,SAAS,OAAO;AAClC,MAAI,OAAO,SAAS,OAAO,MACzB,QAAO,IAAI,MAAM,OAAO,OAAO,OAAO,MAAM,CAAC,OAAO,MAAM,OAAO,OAAO,OAAO,MAAM,CAAC;WAC7E,GACT,QAAO,MAAM,IAAI,OAAO,MAAM;AAGhC,MAAI,OAAO,MACT,QAAO,MAAM,OAAO,OAAO,OAAO,MAAM;AAG1C,MAAI,OAAO,IAAK,QAAO,OAAO,IAAI,OAAO,KAAK,MAAM;AACpD,MAAI,OAAO,SAAS,YAAY,OAAO,WAAW,SAAU,QAAO;AAEnE,MAAI,OAAO,QAAQ,MAAM,QAAQ,OAAO,KAAK,CAC3C,QAAO,OAAO,KAAK,QAAQ,MAAM,MAAM,OAAO,CAAC,KAAK,MAAM;AAG5D,MAAI,OAAO,KACT,QAAO,OAAO;AAGhB,SAAO;;AAGT,QAAO,IAAI,OAAO,MAAM"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-openapi",
3
- "version": "10.6.3",
3
+ "version": "10.6.4",
4
4
  "description": "Generate MDX docs for your OpenAPI spec",
5
5
  "keywords": [
6
6
  "Docs",
@@ -21,7 +21,6 @@
21
21
  "exports": {
22
22
  ".": "./dist/index.js",
23
23
  "./i18n": "./dist/i18n.js",
24
- "./playground": "./dist/playground/index.js",
25
24
  "./playground/client": "./dist/playground/client.js",
26
25
  "./requests/generators": "./dist/requests/generators/index.js",
27
26
  "./requests/generators/all": "./dist/requests/generators/all.js",
@@ -79,8 +78,8 @@
79
78
  "tailwindcss": "^4.2.2",
80
79
  "tsdown": "0.21.6",
81
80
  "@fumadocs/tailwind": "0.0.3",
82
- "fumadocs-core": "16.7.9",
83
- "fumadocs-ui": "16.7.9",
81
+ "fumadocs-core": "16.7.10",
82
+ "fumadocs-ui": "16.7.10",
84
83
  "tsconfig": "0.0.0"
85
84
  },
86
85
  "peerDependencies": {
@@ -1,22 +0,0 @@
1
- import { MethodInformation, RenderContext, SecuritySchemeObject } from "../types.js";
2
- import * as _$react from "react";
3
- import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
-
5
- //#region src/playground/index.d.ts
6
- interface APIPlaygroundProps {
7
- path: string;
8
- method: MethodInformation;
9
- ctx: RenderContext;
10
- }
11
- type SecurityEntry = SecuritySchemeObject & {
12
- scopes: string[];
13
- id: string;
14
- };
15
- declare function APIPlayground({
16
- path,
17
- method,
18
- ctx
19
- }: APIPlaygroundProps): string | number | bigint | boolean | _$react_jsx_runtime0.JSX.Element | Iterable<_$react.ReactNode> | Promise<_$react.ReactNode> | null | undefined;
20
- //#endregion
21
- export { APIPlayground, APIPlaygroundProps, SecurityEntry };
22
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/playground/index.tsx"],"mappings":";;;;;UAgBiB,kBAAA;EACf,IAAA;EACA,MAAA,EAAQ,iBAAA;EACR,GAAA,EAAK,aAAA;AAAA;AAAA,KAGK,aAAA,GAAgB,oBAAA;EAC1B,MAAA;EACA,EAAA;AAAA;AAAA,iBAGc,aAAA,CAAA;EAAgB,IAAA;EAAM,MAAA;EAAQ;AAAA,GAAO,kBAAA,wCAAkB,oBAAA,CAAA,GAAA,CAAA,OAAA,GAAA,QAAA,CAAA,OAAA,CAAA,SAAA,IAAA,OAAA,CAAA,OAAA,CAAA,SAAA"}
@@ -1,118 +0,0 @@
1
- import { getPreferredType } from "../utils/schema/index.js";
2
- import { jsx } from "react/jsx-runtime";
3
- //#region src/playground/index.tsx
4
- function APIPlayground({ path, method, ctx }) {
5
- if (ctx.playground?.render) return ctx.playground.render({
6
- path,
7
- method,
8
- ctx
9
- });
10
- const bodyContent = method.requestBody?.content;
11
- const mediaType = bodyContent ? getPreferredType(bodyContent) : void 0;
12
- const takenIds = /* @__PURE__ */ new Map();
13
- const context = {
14
- references: {},
15
- id(schema) {
16
- let name = "r";
17
- if (schema) {
18
- const ref = ctx.schema.getRawRef(schema)?.split("/");
19
- if (ref && ref.length > 0) name = ref[ref.length - 1];
20
- }
21
- const count = takenIds.get(name) ?? 0;
22
- takenIds.set(name, count + 1);
23
- return count === 0 ? name : `${name}${count}`;
24
- },
25
- registered: /* @__PURE__ */ new WeakMap()
26
- };
27
- const props = {
28
- securities: parseSecurities(method, ctx),
29
- method: method.method,
30
- route: path,
31
- parameters: method.parameters?.map((param) => {
32
- if (param.schema !== void 0) return {
33
- ...param,
34
- schema: writeReferences(param.schema, context)
35
- };
36
- if (param.content !== void 0) {
37
- const content = {};
38
- for (const k in param.content) {
39
- const original = param.content[k];
40
- if (!original || original.schema === void 0) continue;
41
- content[k] = {
42
- ...original,
43
- schema: writeReferences(original.schema, context)
44
- };
45
- }
46
- return {
47
- ...param,
48
- content
49
- };
50
- }
51
- return param;
52
- }),
53
- body: bodyContent && mediaType ? {
54
- schema: writeReferences(bodyContent[mediaType].schema, context),
55
- mediaType
56
- } : void 0,
57
- references: context.references,
58
- proxyUrl: ctx.proxyUrl,
59
- writeOnly: true,
60
- readOnly: false
61
- };
62
- return /* @__PURE__ */ jsx(ctx.clientBoundary.PlaygroundClient, { ...props });
63
- }
64
- function writeReferences(schema, ctx, stack = /* @__PURE__ */ new WeakMap()) {
65
- if (typeof schema !== "object" || !schema) return schema;
66
- if (stack.has(schema)) {
67
- const out = stack.get(schema);
68
- const id = ctx.id(schema);
69
- ctx.references[id] = out;
70
- return { $ref: `#/${id}` };
71
- }
72
- const output = { ...schema };
73
- stack.set(schema, output);
74
- for (const _n in output) {
75
- const name = _n;
76
- if (!output[name]) continue;
77
- switch (name) {
78
- case "oneOf":
79
- case "allOf":
80
- case "anyOf":
81
- output[name] = output[name].map((item) => writeReferences(item, ctx, stack));
82
- continue;
83
- case "items":
84
- case "additionalProperties":
85
- case "not":
86
- output[name] = writeReferences(output[name], ctx, stack);
87
- continue;
88
- case "properties":
89
- case "patternProperties":
90
- output[name] = { ...output[name] };
91
- for (const key in output[name]) output[name][key] = writeReferences(output[name][key], ctx, stack);
92
- }
93
- }
94
- return output;
95
- }
96
- function parseSecurities(method, { schema: { dereferenced } }) {
97
- const result = [];
98
- const security = method.security ?? dereferenced.security ?? [];
99
- if (security.length === 0) return result;
100
- for (const map of security) {
101
- const list = [];
102
- for (const [key, scopes] of Object.entries(map)) {
103
- const scheme = dereferenced.components?.securitySchemes?.[key];
104
- if (!scheme) continue;
105
- list.push({
106
- ...scheme,
107
- scopes,
108
- id: key
109
- });
110
- }
111
- if (list.length > 0) result.push(list);
112
- }
113
- return result;
114
- }
115
- //#endregion
116
- export { APIPlayground };
117
-
118
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/playground/index.tsx"],"sourcesContent":["import type {\n MediaTypeObject,\n MethodInformation,\n ParameterObject,\n RenderContext,\n SecuritySchemeObject,\n} from '@/types';\nimport { getPreferredType, NoReference, type ParsedSchema } from '@/utils/schema';\nimport { type PlaygroundClientProps } from './client';\n\ninterface Context {\n references: Record<string, ParsedSchema>;\n registered: WeakMap<Exclude<ParsedSchema, boolean>, string>;\n id: (schema?: object) => string;\n}\n\nexport interface APIPlaygroundProps {\n path: string;\n method: MethodInformation;\n ctx: RenderContext;\n}\n\nexport type SecurityEntry = SecuritySchemeObject & {\n scopes: string[];\n id: string;\n};\n\nexport function APIPlayground({ path, method, ctx }: APIPlaygroundProps) {\n if (ctx.playground?.render) {\n return ctx.playground.render({ path, method, ctx });\n }\n\n const bodyContent = method.requestBody?.content;\n const mediaType = bodyContent ? getPreferredType(bodyContent) : undefined;\n const takenIds = new Map<string, number>();\n\n const context: Context = {\n references: {},\n id(schema) {\n let name = 'r';\n if (schema) {\n const ref = ctx.schema.getRawRef(schema)?.split('/');\n if (ref && ref.length > 0) name = ref[ref.length - 1];\n }\n\n const count = takenIds.get(name) ?? 0;\n takenIds.set(name, count + 1);\n return count === 0 ? name : `${name}${count}`;\n },\n registered: new WeakMap(),\n };\n\n const props: PlaygroundClientProps = {\n securities: parseSecurities(method, ctx),\n method: method.method,\n route: path,\n parameters: method.parameters?.map((param: NoReference<ParameterObject>): ParameterObject => {\n if (param.schema !== undefined) {\n return {\n ...param,\n schema: writeReferences(param.schema, context),\n } as ParameterObject;\n }\n\n if (param.content !== undefined) {\n const content: Record<string, MediaTypeObject> = {};\n\n for (const k in param.content) {\n const original = param.content[k] as NoReference<MediaTypeObject>;\n if (!original || original.schema === undefined) continue;\n\n content[k] = {\n ...original,\n schema: writeReferences(original.schema, context),\n } as MediaTypeObject;\n }\n\n return {\n ...param,\n content,\n } as ParameterObject;\n }\n\n return param;\n }),\n body:\n bodyContent && mediaType\n ? ({\n schema: writeReferences(bodyContent[mediaType].schema as ParsedSchema, context),\n mediaType,\n } as PlaygroundClientProps['body'])\n : undefined,\n references: context.references,\n proxyUrl: ctx.proxyUrl,\n writeOnly: true,\n readOnly: false,\n };\n\n return <ctx.clientBoundary.PlaygroundClient {...props} />;\n}\n\nfunction writeReferences(\n schema: ParsedSchema,\n ctx: Context,\n stack: WeakMap<object, object> = new WeakMap(),\n): ParsedSchema {\n if (typeof schema !== 'object' || !schema) return schema;\n if (stack.has(schema)) {\n const out = stack.get(schema)!;\n const id = ctx.id(schema);\n ctx.references[id] = out;\n\n return {\n $ref: `#/${id}`,\n };\n }\n\n const output = { ...schema };\n stack.set(schema, output);\n for (const _n in output) {\n const name = _n as keyof typeof output;\n if (!output[name]) continue;\n\n switch (name) {\n case 'oneOf':\n case 'allOf':\n case 'anyOf':\n output[name] = output[name].map((item) => writeReferences(item, ctx, stack));\n continue;\n case 'items':\n case 'additionalProperties':\n case 'not':\n output[name] = writeReferences(output[name], ctx, stack);\n continue;\n case 'properties':\n case 'patternProperties':\n output[name] = { ...output[name] };\n\n for (const key in output[name]) {\n output[name][key] = writeReferences(output[name][key], ctx, stack);\n }\n }\n }\n\n return output;\n}\n\nfunction parseSecurities(\n method: MethodInformation,\n { schema: { dereferenced } }: RenderContext,\n): PlaygroundClientProps['securities'] {\n const result: PlaygroundClientProps['securities'] = [];\n const security = method.security ?? dereferenced.security ?? [];\n if (security.length === 0) return result;\n\n for (const map of security) {\n const list: PlaygroundClientProps['securities'][number] = [];\n\n for (const [key, scopes] of Object.entries(map)) {\n const scheme = dereferenced.components?.securitySchemes?.[key];\n if (!scheme) continue;\n\n list.push({\n ...scheme,\n scopes,\n id: key,\n });\n }\n\n if (list.length > 0) result.push(list);\n }\n\n return result;\n}\n"],"mappings":"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"}
@@ -1,18 +0,0 @@
1
- import { NoReference } from "./schema/index.js";
2
- import { Document } from "../types.js";
3
-
4
- //#region src/utils/process-document.d.ts
5
- interface ProcessedDocument {
6
- /**
7
- * dereferenced document
8
- */
9
- dereferenced: NoReference<Document>;
10
- /**
11
- * Get raw $ref from dereferenced object
12
- */
13
- getRawRef: (obj: object) => string | undefined;
14
- bundled: Document;
15
- }
16
- //#endregion
17
- export { ProcessedDocument };
18
- //# sourceMappingURL=process-document.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"process-document.d.ts","names":[],"sources":["../../src/utils/process-document.ts"],"mappings":";;;;UAQiB,iBAAA;;AAAjB;;EAIE,YAAA,EAAc,WAAA,CAAY,QAAA;EAAA;;;EAK1B,SAAA,GAAY,GAAA;EAEZ,OAAA,EAAS,QAAA;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"process-document.js","names":[],"sources":["../../src/utils/process-document.ts"],"sourcesContent":["import type { Document } from '@/types';\nimport type { NoReference } from '@/utils/schema';\nimport { bundle } from '@scalar/json-magic/bundle';\nimport { upgrade } from '@scalar/openapi-upgrader';\nimport { fetchUrls, readFiles } from '@scalar/json-magic/bundle/plugins/node';\nimport type { JSONSchema } from 'json-schema-typed/draft-2020-12';\nimport { dereferenceSync } from './schema/dereference';\n\nexport interface ProcessedDocument {\n /**\n * dereferenced document\n */\n dereferenced: NoReference<Document>;\n\n /**\n * Get raw $ref from dereferenced object\n */\n getRawRef: (obj: object) => string | undefined;\n\n bundled: Document;\n}\n\n/**\n * process & reference input document to a Fumadocs OpenAPI compatible format\n */\nexport async function processDocument(input: string | Document): Promise<ProcessedDocument> {\n const bundled: Document = await bundle(input, {\n plugins: [fetchUrls(), readFiles()],\n treeShake: true,\n hooks: {\n onResolveError(node) {\n throw new Error(`Failed to resolve ${node.$ref}`);\n },\n },\n })\n .then((v) => upgrade(v as never, '3.2') as Document)\n .catch((e) => {\n throw new Error(`[OpenAPI] Failed to resolve input: ${input}`, {\n cause: e,\n });\n });\n\n /**\n * Dereferenced value and its original `$ref` value\n */\n const dereferenceMap = new Map<object, string>();\n\n return {\n dereferenced: dereferenceSync(bundled as JSONSchema, (schema, ref) => {\n dereferenceMap.set(schema as object, ref);\n }) as NoReference<Document>,\n getRawRef(obj) {\n return dereferenceMap.get(obj);\n },\n bundled,\n };\n}\n"],"mappings":";;;;;;;;AAyBA,eAAsB,gBAAgB,OAAsD;CAC1F,MAAM,UAAoB,MAAM,OAAO,OAAO;EAC5C,SAAS,CAAC,WAAW,EAAE,WAAW,CAAC;EACnC,WAAW;EACX,OAAO,EACL,eAAe,MAAM;AACnB,SAAM,IAAI,MAAM,qBAAqB,KAAK,OAAO;KAEpD;EACF,CAAC,CACC,MAAM,MAAM,QAAQ,GAAY,MAAM,CAAa,CACnD,OAAO,MAAM;AACZ,QAAM,IAAI,MAAM,sCAAsC,SAAS,EAC7D,OAAO,GACR,CAAC;GACF;;;;CAKJ,MAAM,iCAAiB,IAAI,KAAqB;AAEhD,QAAO;EACL,cAAc,gBAAgB,UAAwB,QAAQ,QAAQ;AACpE,kBAAe,IAAI,QAAkB,IAAI;IACzC;EACF,UAAU,KAAK;AACb,UAAO,eAAe,IAAI,IAAI;;EAEhC;EACD"}