@zudojs/openapi 0.1.0 → 1.1.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.
Files changed (130) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +327 -21
  3. package/dist/index.d.ts +26 -21
  4. package/dist/index.js +31 -13
  5. package/dist/openApiComponents/index.d.ts +2 -2
  6. package/dist/openApiComponents/index.js +1 -1
  7. package/dist/openApiConstants/index.d.ts +1 -1
  8. package/dist/openApiConstants/index.js +1 -1
  9. package/dist/openApiConstants/openApiConstants.core.d.ts +15 -3
  10. package/dist/openApiConstants/openApiConstants.core.js +22 -3
  11. package/dist/openApiDocument/index.d.ts +1 -1
  12. package/dist/openApiDocument/index.js +1 -1
  13. package/dist/openApiDocument/openApiDocument.builder.d.ts +39 -52
  14. package/dist/openApiDocument/openApiDocument.builder.js +73 -72
  15. package/dist/openApiErrors/index.d.ts +2 -2
  16. package/dist/openApiErrors/index.js +2 -1
  17. package/dist/openApiErrors/openApiError.base.d.ts +9 -0
  18. package/dist/openApiErrors/openApiError.base.js +7 -0
  19. package/dist/openApiErrors/openApiError.types.d.ts +34 -14
  20. package/dist/openApiErrors/openApiError.types.js +83 -35
  21. package/dist/openApiHttp/index.d.ts +2 -2
  22. package/dist/openApiHttp/index.js +2 -2
  23. package/dist/openApiHttp/openApiHttpAdapter.core.d.ts +127 -25
  24. package/dist/openApiHttp/openApiHttpAdapter.core.js +212 -16
  25. package/dist/openApiRegistry/openApiRegistry.core.d.ts +38 -5
  26. package/dist/openApiRegistry/openApiRegistry.core.js +167 -66
  27. package/dist/openApiRegistry/openApiRegistry.type.d.ts +18 -13
  28. package/dist/openApiRegistry/openApiRegistry.type.js +1 -2
  29. package/dist/openApiRouting/index.d.ts +2 -2
  30. package/dist/openApiRouting/index.js +1 -1
  31. package/dist/openApiRouting/routeConverter.core.d.ts +25 -7
  32. package/dist/openApiRouting/routeConverter.core.js +104 -58
  33. package/dist/openApiRouting/routeMetadata.type.d.ts +40 -17
  34. package/dist/openApiRouting/routeMetadata.type.js +9 -0
  35. package/dist/openApiRouting/routeScanner.core.d.ts +17 -47
  36. package/dist/openApiRouting/routeScanner.core.js +40 -55
  37. package/dist/openApiSchema/index.d.ts +4 -4
  38. package/dist/openApiSchema/index.js +2 -2
  39. package/dist/openApiSchema/references.core.d.ts +18 -1
  40. package/dist/openApiSchema/references.core.js +21 -1
  41. package/dist/openApiSchema/schemaConverter.core.d.ts +51 -3
  42. package/dist/openApiSchema/schemaConverter.core.js +475 -118
  43. package/dist/openApiSchema/schemaRegistry.core.d.ts +27 -10
  44. package/dist/openApiSchema/schemaRegistry.core.js +33 -14
  45. package/dist/openApiSerialization/openApiSerializer.core.d.ts +10 -4
  46. package/dist/openApiSerialization/openApiSerializer.core.js +135 -9
  47. package/dist/openApiTypes/index.d.ts +1 -1
  48. package/dist/openApiTypes/openApiDocument.type.d.ts +16 -0
  49. package/dist/openApiTypes/openApiSchema.type.d.ts +24 -1
  50. package/dist/openApiTypes/openApiSchema.type.js +3 -0
  51. package/dist/openApiUi/index.d.ts +8 -0
  52. package/dist/openApiUi/index.js +8 -0
  53. package/dist/openApiUi/openApiUi.brand.d.ts +26 -0
  54. package/dist/openApiUi/openApiUi.brand.js +44 -0
  55. package/dist/openApiUi/openApiUi.core.d.ts +47 -0
  56. package/dist/openApiUi/openApiUi.core.js +143 -0
  57. package/dist/openApiValidation/index.d.ts +2 -2
  58. package/dist/openApiValidation/index.js +1 -1
  59. package/dist/openApiValidation/openApiValidator.core.d.ts +33 -11
  60. package/dist/openApiValidation/openApiValidator.core.js +274 -66
  61. package/package.json +25 -18
  62. package/dist/.tsbuildinfo +0 -1
  63. package/dist/index.d.ts.map +0 -1
  64. package/dist/index.js.map +0 -1
  65. package/dist/openApiComponents/index.d.ts.map +0 -1
  66. package/dist/openApiComponents/index.js.map +0 -1
  67. package/dist/openApiConstants/index.d.ts.map +0 -1
  68. package/dist/openApiConstants/index.js.map +0 -1
  69. package/dist/openApiConstants/openApiConstants.core.d.ts.map +0 -1
  70. package/dist/openApiConstants/openApiConstants.core.js.map +0 -1
  71. package/dist/openApiDocument/index.d.ts.map +0 -1
  72. package/dist/openApiDocument/index.js.map +0 -1
  73. package/dist/openApiDocument/openApiDocument.builder.d.ts.map +0 -1
  74. package/dist/openApiDocument/openApiDocument.builder.js.map +0 -1
  75. package/dist/openApiErrors/index.d.ts.map +0 -1
  76. package/dist/openApiErrors/index.js.map +0 -1
  77. package/dist/openApiErrors/openApiError.base.d.ts.map +0 -1
  78. package/dist/openApiErrors/openApiError.base.js.map +0 -1
  79. package/dist/openApiErrors/openApiError.core.d.ts.map +0 -1
  80. package/dist/openApiErrors/openApiError.core.js.map +0 -1
  81. package/dist/openApiErrors/openApiError.types.d.ts.map +0 -1
  82. package/dist/openApiErrors/openApiError.types.js.map +0 -1
  83. package/dist/openApiHttp/index.d.ts.map +0 -1
  84. package/dist/openApiHttp/index.js.map +0 -1
  85. package/dist/openApiHttp/openApiHttpAdapter.core.d.ts.map +0 -1
  86. package/dist/openApiHttp/openApiHttpAdapter.core.js.map +0 -1
  87. package/dist/openApiRegistry/index.d.ts.map +0 -1
  88. package/dist/openApiRegistry/index.js.map +0 -1
  89. package/dist/openApiRegistry/openApiRegistry.core.d.ts.map +0 -1
  90. package/dist/openApiRegistry/openApiRegistry.core.js.map +0 -1
  91. package/dist/openApiRegistry/openApiRegistry.type.d.ts.map +0 -1
  92. package/dist/openApiRegistry/openApiRegistry.type.js.map +0 -1
  93. package/dist/openApiRouting/index.d.ts.map +0 -1
  94. package/dist/openApiRouting/index.js.map +0 -1
  95. package/dist/openApiRouting/routeConverter.core.d.ts.map +0 -1
  96. package/dist/openApiRouting/routeConverter.core.js.map +0 -1
  97. package/dist/openApiRouting/routeMetadata.type.d.ts.map +0 -1
  98. package/dist/openApiRouting/routeMetadata.type.js.map +0 -1
  99. package/dist/openApiRouting/routeScanner.core.d.ts.map +0 -1
  100. package/dist/openApiRouting/routeScanner.core.js.map +0 -1
  101. package/dist/openApiSchema/index.d.ts.map +0 -1
  102. package/dist/openApiSchema/index.js.map +0 -1
  103. package/dist/openApiSchema/references.core.d.ts.map +0 -1
  104. package/dist/openApiSchema/references.core.js.map +0 -1
  105. package/dist/openApiSchema/schemaConverter.core.d.ts.map +0 -1
  106. package/dist/openApiSchema/schemaConverter.core.js.map +0 -1
  107. package/dist/openApiSchema/schemaRegistry.core.d.ts.map +0 -1
  108. package/dist/openApiSchema/schemaRegistry.core.js.map +0 -1
  109. package/dist/openApiSerialization/index.d.ts.map +0 -1
  110. package/dist/openApiSerialization/index.js.map +0 -1
  111. package/dist/openApiSerialization/openApiSerializer.core.d.ts.map +0 -1
  112. package/dist/openApiSerialization/openApiSerializer.core.js.map +0 -1
  113. package/dist/openApiTypes/index.d.ts.map +0 -1
  114. package/dist/openApiTypes/index.js.map +0 -1
  115. package/dist/openApiTypes/openApiComponent.type.d.ts.map +0 -1
  116. package/dist/openApiTypes/openApiComponent.type.js.map +0 -1
  117. package/dist/openApiTypes/openApiDocument.type.d.ts.map +0 -1
  118. package/dist/openApiTypes/openApiDocument.type.js.map +0 -1
  119. package/dist/openApiTypes/openApiPath.type.d.ts.map +0 -1
  120. package/dist/openApiTypes/openApiPath.type.js.map +0 -1
  121. package/dist/openApiTypes/openApiSchema.type.d.ts.map +0 -1
  122. package/dist/openApiTypes/openApiSchema.type.js.map +0 -1
  123. package/dist/openApiTypes/openApiSecurity.type.d.ts.map +0 -1
  124. package/dist/openApiTypes/openApiSecurity.type.js.map +0 -1
  125. package/dist/openApiTypes/openApiTypes.core.d.ts.map +0 -1
  126. package/dist/openApiTypes/openApiTypes.core.js.map +0 -1
  127. package/dist/openApiValidation/index.d.ts.map +0 -1
  128. package/dist/openApiValidation/index.js.map +0 -1
  129. package/dist/openApiValidation/openApiValidator.core.d.ts.map +0 -1
  130. package/dist/openApiValidation/openApiValidator.core.js.map +0 -1
@@ -1,28 +1,45 @@
1
- import type { OpenAPISchema } from "../openApiTypes/openApiTypes.core.js";
1
+ import type { OpenAPIReference, OpenAPISchema } from "../openApiTypes/openApiTypes.core.js";
2
+ import type { SchemaConversionOptions } from "./schemaConverter.core.js";
2
3
  /**
3
4
  * Schema registry for OpenAPI component schemas.
4
5
  */
5
6
  export interface SchemaRegistry {
6
- register(name: string, schema: unknown): void;
7
+ register(name: string, schema: unknown): OpenAPISchema;
7
8
  get(name: string): OpenAPISchema | undefined;
9
+ has(name: string): boolean;
8
10
  convert(name: string, schema: unknown): OpenAPISchema;
9
- ref(name: string): {
10
- $ref: string;
11
- };
11
+ ref(name: string): OpenAPIReference;
12
+ /** Conversion warnings, keyed by the component they came from. */
13
+ warnings(): ReadonlyMap<string, readonly string[]>;
14
+ /** Every registered schema, ready to drop into `components.schemas`. */
15
+ all(): Readonly<Record<string, OpenAPISchema>>;
12
16
  clear(): void;
13
17
  }
18
+ /** Options for {@link SchemaRegistryImpl}. */
19
+ export interface SchemaRegistryOptions extends SchemaConversionOptions {
20
+ /**
21
+ * Reports what a conversion could not express. Without a sink these are
22
+ * easy to lose, and "unsupported schema type" silently becoming `{}` is how
23
+ * a specification ends up documenting nothing.
24
+ */
25
+ readonly onWarning?: (name: string, warnings: readonly string[]) => void;
26
+ }
14
27
  /**
15
28
  * Default schema registry implementation.
16
29
  */
17
30
  export declare class SchemaRegistryImpl implements SchemaRegistry {
18
31
  private readonly schemas;
19
- private readonly pending;
20
- register(name: string, schema: unknown): void;
32
+ private readonly conversionWarnings;
33
+ private readonly options;
34
+ constructor(options?: SchemaRegistryOptions);
35
+ private convertAndRecord;
36
+ register(name: string, schema: unknown): OpenAPISchema;
21
37
  get(name: string): OpenAPISchema | undefined;
38
+ has(name: string): boolean;
22
39
  convert(name: string, schema: unknown): OpenAPISchema;
23
- ref(name: string): {
24
- $ref: string;
25
- };
40
+ ref(name: string): OpenAPIReference;
41
+ warnings(): ReadonlyMap<string, readonly string[]>;
42
+ all(): Readonly<Record<string, OpenAPISchema>>;
26
43
  clear(): void;
27
44
  }
28
45
  //# sourceMappingURL=schemaRegistry.core.d.ts.map
@@ -1,36 +1,55 @@
1
1
  import { convertSchema } from "./schemaConverter.core.js";
2
+ import { createComponentReference } from "./references.core.js";
3
+ import { OpenAPIComponentConflictError } from "../openApiErrors/openApiError.types.js";
2
4
  /**
3
5
  * Default schema registry implementation.
4
6
  */
5
7
  export class SchemaRegistryImpl {
6
8
  schemas = new Map();
7
- pending = new Map();
9
+ conversionWarnings = new Map();
10
+ options;
11
+ constructor(options = {}) {
12
+ this.options = options;
13
+ }
14
+ convertAndRecord(name, schema) {
15
+ const result = convertSchema(schema, this.options);
16
+ if (result.warnings.length > 0) {
17
+ this.conversionWarnings.set(name, result.warnings);
18
+ this.options.onWarning?.(name, result.warnings);
19
+ }
20
+ this.schemas.set(name, result.schema);
21
+ return result.schema;
22
+ }
8
23
  register(name, schema) {
9
24
  if (this.schemas.has(name)) {
10
- throw new Error(`Schema "${name}" is already registered.`);
25
+ throw new OpenAPIComponentConflictError("schemas", name);
11
26
  }
12
- const result = convertSchema(schema);
13
- this.schemas.set(name, result.schema);
27
+ return this.convertAndRecord(name, schema);
14
28
  }
15
29
  get(name) {
16
30
  return this.schemas.get(name);
17
31
  }
32
+ has(name) {
33
+ return this.schemas.has(name);
34
+ }
18
35
  convert(name, schema) {
19
- if (this.schemas.has(name)) {
20
- return this.schemas.get(name);
21
- }
22
- const result = convertSchema(schema);
23
- this.schemas.set(name, result.schema);
24
- return result.schema;
36
+ const existing = this.schemas.get(name);
37
+ if (existing)
38
+ return existing;
39
+ return this.convertAndRecord(name, schema);
25
40
  }
26
41
  ref(name) {
27
- return {
28
- $ref: `#/components/schemas/${name}`,
29
- };
42
+ return createComponentReference("schemas", name);
43
+ }
44
+ warnings() {
45
+ return new Map(this.conversionWarnings);
46
+ }
47
+ all() {
48
+ return Object.fromEntries(this.schemas);
30
49
  }
31
50
  clear() {
32
51
  this.schemas.clear();
33
- this.pending.clear();
52
+ this.conversionWarnings.clear();
34
53
  }
35
54
  }
36
55
  //# sourceMappingURL=schemaRegistry.core.js.map
@@ -1,12 +1,18 @@
1
1
  import type { OpenAPIDocument } from "../openApiTypes/openApiTypes.core.js";
2
2
  /**
3
- * Serializes an OpenAPI document to JSON string.
3
+ * Serializes an OpenAPI document to a JSON string.
4
4
  */
5
- export declare function toOpenAPIJSON(document: OpenAPIDocument): string;
5
+ export declare function toOpenAPIJSON(document: OpenAPIDocument, options?: {
6
+ readonly indent?: number;
7
+ }): string;
6
8
  /**
7
- * Serializes an OpenAPI document to YAML string.
9
+ * Serializes an OpenAPI document to a YAML string.
8
10
  *
9
- * Note: This requires a YAML library. For now, returns JSON as a fallback.
11
+ * A real YAML encoder, not JSON under a different name: an OpenAPI document
12
+ * is plain data — maps, arrays and scalars — which is exactly the subset of
13
+ * YAML that can be emitted correctly without a full library. Strings that
14
+ * YAML would reinterpret (`true`, `null`, `1.0`, anything starting with a
15
+ * reserved character) are quoted.
10
16
  */
11
17
  export declare function toOpenAPIYAML(document: OpenAPIDocument): string;
12
18
  //# sourceMappingURL=openApiSerializer.core.d.ts.map
@@ -1,26 +1,152 @@
1
- import { OpenAPISerializationError } from "../openApiErrors/openApiError.core.js";
1
+ import { OpenAPISerializationError } from "../openApiErrors/openApiError.types.js";
2
2
  /**
3
- * Serializes an OpenAPI document to JSON string.
3
+ * Serializes an OpenAPI document to a JSON string.
4
4
  */
5
- export function toOpenAPIJSON(document) {
5
+ export function toOpenAPIJSON(document, options) {
6
6
  try {
7
- return JSON.stringify(document, null, 2);
7
+ return JSON.stringify(document, null, options?.indent ?? 2);
8
8
  }
9
9
  catch (error) {
10
- throw new OpenAPISerializationError(`Failed to serialize OpenAPI document to JSON: ${error.message}`);
10
+ throw new OpenAPISerializationError(`Failed to serialize the OpenAPI document to JSON: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
11
11
  }
12
12
  }
13
+ /* ── YAML ──────────────────────────────────────────────────────────────── */
13
14
  /**
14
- * Serializes an OpenAPI document to YAML string.
15
+ * Strings that must be quoted because bare YAML would read them as something
16
+ * else: the booleans and null forms YAML 1.1 recognises, plus the empty
17
+ * string.
18
+ */
19
+ const YAML_RESERVED = new Set([
20
+ "",
21
+ "true",
22
+ "false",
23
+ "yes",
24
+ "no",
25
+ "on",
26
+ "off",
27
+ "null",
28
+ "~",
29
+ "y",
30
+ "n",
31
+ ]);
32
+ /** A bare (unquoted) YAML scalar may not start with these. */
33
+ const YAML_UNSAFE_START = /^[-?:,[\]{}#&*!|>'"%@`\s]/;
34
+ const YAML_UNSAFE_ANYWHERE = /[:#\n\r\t]|: |\s#/;
35
+ const YAML_NUMERIC = /^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$/;
36
+ function quoteYamlString(value) {
37
+ // Double quotes with JSON escaping is always valid YAML and needs no
38
+ // decision about block scalars or line folding.
39
+ return JSON.stringify(value);
40
+ }
41
+ function yamlScalar(value) {
42
+ if (YAML_RESERVED.has(value.toLowerCase()) ||
43
+ YAML_UNSAFE_START.test(value) ||
44
+ YAML_UNSAFE_ANYWHERE.test(value) ||
45
+ YAML_NUMERIC.test(value) ||
46
+ value !== value.trim()) {
47
+ return quoteYamlString(value);
48
+ }
49
+ return value;
50
+ }
51
+ function yamlKey(key) {
52
+ return yamlScalar(key);
53
+ }
54
+ function isEmptyContainer(value) {
55
+ if (Array.isArray(value))
56
+ return value.length === 0;
57
+ if (typeof value === "object" && value !== null) {
58
+ return Object.keys(value).length === 0;
59
+ }
60
+ return false;
61
+ }
62
+ function toYaml(value, indent, seen) {
63
+ const pad = " ".repeat(indent);
64
+ if (value === null)
65
+ return "null";
66
+ if (value === undefined)
67
+ return "null";
68
+ switch (typeof value) {
69
+ case "string":
70
+ return yamlScalar(value);
71
+ case "number":
72
+ if (Number.isFinite(value))
73
+ return String(value);
74
+ // YAML distinguishes infinity from not-a-number; collapsing both onto
75
+ // `.nan` turns an out-of-range bound into an unrepresentable one.
76
+ if (Number.isNaN(value))
77
+ return ".nan";
78
+ return value > 0 ? ".inf" : "-.inf";
79
+ case "boolean":
80
+ return value ? "true" : "false";
81
+ case "bigint":
82
+ return value.toString();
83
+ default:
84
+ break;
85
+ }
86
+ if (typeof value !== "object") {
87
+ return quoteYamlString(String(value));
88
+ }
89
+ const container = value;
90
+ if (seen.has(container)) {
91
+ throw new OpenAPISerializationError("Failed to serialize the OpenAPI document to YAML: the document contains a cycle.");
92
+ }
93
+ seen.add(container);
94
+ try {
95
+ if (Array.isArray(value)) {
96
+ if (value.length === 0)
97
+ return "[]";
98
+ return value
99
+ .map((entry) => {
100
+ const rendered = toYaml(entry, indent + 1, seen);
101
+ if (typeof entry === "object" &&
102
+ entry !== null &&
103
+ !isEmptyContainer(entry)) {
104
+ // Nested block: put the first line beside the dash.
105
+ return `${pad}- ${rendered.slice((indent + 1) * 2)}`;
106
+ }
107
+ return `${pad}- ${rendered}`;
108
+ })
109
+ .join("\n");
110
+ }
111
+ const entries = Object.entries(value).filter(([, entry]) => entry !== undefined);
112
+ if (entries.length === 0)
113
+ return "{}";
114
+ return entries
115
+ .map(([key, entry]) => {
116
+ const renderedKey = `${pad}${yamlKey(key)}:`;
117
+ if (entry === null)
118
+ return `${renderedKey} null`;
119
+ if (typeof entry !== "object") {
120
+ return `${renderedKey} ${toYaml(entry, indent + 1, seen)}`;
121
+ }
122
+ if (isEmptyContainer(entry)) {
123
+ return `${renderedKey} ${Array.isArray(entry) ? "[]" : "{}"}`;
124
+ }
125
+ return `${renderedKey}\n${toYaml(entry, indent + 1, seen)}`;
126
+ })
127
+ .join("\n");
128
+ }
129
+ finally {
130
+ seen.delete(container);
131
+ }
132
+ }
133
+ /**
134
+ * Serializes an OpenAPI document to a YAML string.
15
135
  *
16
- * Note: This requires a YAML library. For now, returns JSON as a fallback.
136
+ * A real YAML encoder, not JSON under a different name: an OpenAPI document
137
+ * is plain data — maps, arrays and scalars — which is exactly the subset of
138
+ * YAML that can be emitted correctly without a full library. Strings that
139
+ * YAML would reinterpret (`true`, `null`, `1.0`, anything starting with a
140
+ * reserved character) are quoted.
17
141
  */
18
142
  export function toOpenAPIYAML(document) {
19
143
  try {
20
- return JSON.stringify(document, null, 2);
144
+ return `${toYaml(document, 0, new WeakSet())}\n`;
21
145
  }
22
146
  catch (error) {
23
- throw new OpenAPISerializationError(`Failed to serialize OpenAPI document to YAML: ${error.message}`);
147
+ if (error instanceof OpenAPISerializationError)
148
+ throw error;
149
+ throw new OpenAPISerializationError(`Failed to serialize the OpenAPI document to YAML: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
24
150
  }
25
151
  }
26
152
  //# sourceMappingURL=openApiSerializer.core.js.map
@@ -3,5 +3,5 @@
3
3
  *
4
4
  * Core OpenAPI specification types.
5
5
  */
6
- export type { OpenAPIVersion, OpenAPIDocument, OpenAPIComponents, OpenAPISecurityRequirement, OpenAPIParameterLocation, OpenAPIResponse, OpenAPIParameter, OpenAPIRequestBody, OpenAPIMediaType, OpenAPIEncoding, OpenAPIHeader, OpenAPILink, OpenAPIExample, OpenAPIPaths, OpenAPIPathItem, OpenAPIOperation, OpenAPIResponses, OpenAPIServer, OpenAPIServerVariable, OpenAPIInfo, OpenAPIContact, OpenAPILicense, OpenAPIExternalDocumentation, OpenAPISchema, OpenAPIDiscriminator, OpenAPIXml, OpenAPISecurityScheme, OpenAPIOAuthFlows, OpenAPIOAuthFlow, OpenAPITag, OpenAPIReference, } from "./openApiTypes.core.js";
6
+ export type { OpenAPIVersion, OpenAPIDocument, OpenAPIComponents, OpenAPISecurityRequirement, OpenAPIParameterLocation, OpenAPIResponse, OpenAPIParameter, OpenAPIRequestBody, OpenAPIMediaType, OpenAPIEncoding, OpenAPIHeader, OpenAPILink, OpenAPIExample, OpenAPIPaths, OpenAPIPathItem, OpenAPIOperation, OpenAPIResponses, OpenAPIServer, OpenAPIServerVariable, OpenAPIInfo, OpenAPILogo, OpenAPIContact, OpenAPILicense, OpenAPIExternalDocumentation, OpenAPISchema, OpenAPIDiscriminator, OpenAPIXml, OpenAPISecurityScheme, OpenAPIOAuthFlows, OpenAPIOAuthFlow, OpenAPITag, OpenAPIReference, } from "./openApiTypes.core.js";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -23,6 +23,22 @@ export interface OpenAPIInfo {
23
23
  readonly termsOfService?: string;
24
24
  readonly contact?: OpenAPIContact;
25
25
  readonly license?: OpenAPILicense;
26
+ /**
27
+ * Vendor extension rendered as a logo by ReDoc, Scalar and other viewers.
28
+ * Set automatically to the Zudo mark by {@link OpenAPIManager} unless
29
+ * branding is disabled or a logo is supplied.
30
+ */
31
+ readonly "x-logo"?: OpenAPILogo;
32
+ }
33
+ /** The `x-logo` vendor extension (`info["x-logo"]`). */
34
+ export interface OpenAPILogo {
35
+ /** Image URL or data URI. */
36
+ readonly url: string;
37
+ /** Where clicking the logo navigates. */
38
+ readonly href?: string;
39
+ readonly altText?: string;
40
+ /** Background colour painted behind the logo by viewers that support it. */
41
+ readonly backgroundColor?: string;
26
42
  }
27
43
  export interface OpenAPIContact {
28
44
  readonly name?: string;
@@ -1,28 +1,51 @@
1
1
  /**
2
2
  * OpenAPI schema types.
3
+ *
4
+ * Follows JSON Schema 2020-12 as OpenAPI 3.1 does, while keeping the 3.0-only
5
+ * `nullable` keyword available for documents targeting 3.0.x.
3
6
  */
4
7
  export interface OpenAPISchema {
5
8
  readonly title?: string;
6
- readonly type?: string;
9
+ /** A single type, or — in 3.1 — a union such as `["string", "null"]`. */
10
+ readonly type?: string | readonly string[];
7
11
  readonly properties?: Readonly<Record<string, OpenAPISchema>>;
8
12
  readonly required?: readonly string[];
9
13
  readonly description?: string;
10
14
  readonly format?: string;
11
15
  readonly default?: unknown;
16
+ /** OpenAPI 3.0 only. In 3.1, nullability is part of `type`. */
12
17
  readonly nullable?: boolean;
13
18
  readonly readOnly?: boolean;
14
19
  readonly writeOnly?: boolean;
15
20
  readonly deprecated?: boolean;
16
21
  readonly example?: unknown;
22
+ readonly examples?: readonly unknown[];
17
23
  readonly enum?: readonly unknown[];
24
+ readonly const?: unknown;
18
25
  readonly $ref?: string;
19
26
  readonly allOf?: readonly OpenAPISchema[];
20
27
  readonly oneOf?: readonly OpenAPISchema[];
21
28
  readonly anyOf?: readonly OpenAPISchema[];
29
+ readonly not?: OpenAPISchema;
22
30
  readonly items?: OpenAPISchema;
31
+ /** JSON Schema 2020-12 positional items, used for tuples. */
32
+ readonly prefixItems?: readonly OpenAPISchema[];
23
33
  readonly additionalProperties?: OpenAPISchema | boolean;
24
34
  readonly discriminator?: OpenAPIDiscriminator;
25
35
  readonly xml?: OpenAPIXml;
36
+ readonly minLength?: number;
37
+ readonly maxLength?: number;
38
+ readonly pattern?: string;
39
+ readonly minimum?: number;
40
+ readonly maximum?: number;
41
+ readonly exclusiveMinimum?: number | boolean;
42
+ readonly exclusiveMaximum?: number | boolean;
43
+ readonly multipleOf?: number;
44
+ readonly minItems?: number;
45
+ readonly maxItems?: number;
46
+ readonly uniqueItems?: boolean;
47
+ readonly minProperties?: number;
48
+ readonly maxProperties?: number;
26
49
  readonly extensions?: Readonly<Record<string, unknown>>;
27
50
  }
28
51
  export interface OpenAPIDiscriminator {
@@ -1,5 +1,8 @@
1
1
  /**
2
2
  * OpenAPI schema types.
3
+ *
4
+ * Follows JSON Schema 2020-12 as OpenAPI 3.1 does, while keeping the 3.0-only
5
+ * `nullable` keyword available for documents targeting 3.0.x.
3
6
  */
4
7
  export {};
5
8
  //# sourceMappingURL=openApiSchema.type.js.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @zudojs/openapi/openApiUi
3
+ *
4
+ * Branded documentation pages (Swagger UI / ReDoc) and the Zudo brand assets.
5
+ */
6
+ export { renderOpenAPIUI, zudoLogo, escapeHtml, type OpenAPIUIOptions, type OpenAPIUIRenderer, } from "./openApiUi.core.js";
7
+ export { ZUDO_MARK_SVG, ZUDO_MARK_DARK_SVG, ZUDO_WORDMARK_SVG, ZUDO_WORDMARK_DARK_SVG, ZUDO_FAVICON_SVG, ZUDO_MARK_DATA_URI, ZUDO_MARK_DARK_DATA_URI, ZUDO_WORDMARK_DATA_URI, ZUDO_WORDMARK_DARK_DATA_URI, ZUDO_FAVICON_DATA_URI, ZUDO_SITE_URL, svgToDataUri, } from "./openApiUi.brand.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @zudojs/openapi/openApiUi
3
+ *
4
+ * Branded documentation pages (Swagger UI / ReDoc) and the Zudo brand assets.
5
+ */
6
+ export { renderOpenAPIUI, zudoLogo, escapeHtml, } from "./openApiUi.core.js";
7
+ export { ZUDO_MARK_SVG, ZUDO_MARK_DARK_SVG, ZUDO_WORDMARK_SVG, ZUDO_WORDMARK_DARK_SVG, ZUDO_FAVICON_SVG, ZUDO_MARK_DATA_URI, ZUDO_MARK_DARK_DATA_URI, ZUDO_WORDMARK_DATA_URI, ZUDO_WORDMARK_DARK_DATA_URI, ZUDO_FAVICON_DATA_URI, ZUDO_SITE_URL, svgToDataUri, } from "./openApiUi.brand.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @zudojs/openapi/openApiUi
3
+ *
4
+ * Zudo brand assets embedded as data URIs so generated documentation pages
5
+ * carry the logo without depending on any external host.
6
+ */
7
+ /** The Zudo mark for light backgrounds: navy modules, red diagonal. */
8
+ export declare const ZUDO_MARK_SVG: string;
9
+ /** The Zudo mark for dark backgrounds: off-white modules, red diagonal. */
10
+ export declare const ZUDO_MARK_DARK_SVG: string;
11
+ /** The full wordmark (mark + ZUDO letters) for light backgrounds. */
12
+ export declare const ZUDO_WORDMARK_SVG: string;
13
+ /** The wordmark for dark backgrounds. */
14
+ export declare const ZUDO_WORDMARK_DARK_SVG: string;
15
+ /** A 32×32 favicon: red tile, off-white Z. */
16
+ export declare const ZUDO_FAVICON_SVG: string;
17
+ /** Encodes an SVG string as a `data:` URI usable in `<img src>` or CSS. */
18
+ export declare function svgToDataUri(svg: string): string;
19
+ export declare const ZUDO_MARK_DATA_URI: string;
20
+ export declare const ZUDO_MARK_DARK_DATA_URI: string;
21
+ export declare const ZUDO_WORDMARK_DATA_URI: string;
22
+ export declare const ZUDO_WORDMARK_DARK_DATA_URI: string;
23
+ export declare const ZUDO_FAVICON_DATA_URI: string;
24
+ /** Where the logo links by default. */
25
+ export declare const ZUDO_SITE_URL = "https://zudo.dev";
26
+ //# sourceMappingURL=openApiUi.brand.d.ts.map
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @zudojs/openapi/openApiUi
3
+ *
4
+ * Zudo brand assets embedded as data URIs so generated documentation pages
5
+ * carry the logo without depending on any external host.
6
+ */
7
+ /** The Zudo mark for light backgrounds: navy modules, red diagonal. */
8
+ export const ZUDO_MARK_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80" role="img" aria-label="Zudo">' +
9
+ '<g fill="#1A1A2E"><rect x="6" y="6" width="12" height="12"/><rect x="20" y="6" width="12" height="12"/><rect x="34" y="6" width="12" height="12"/><rect x="48" y="6" width="12" height="12"/><rect x="62" y="6" width="12" height="12"/>' +
10
+ '<rect x="6" y="62" width="12" height="12"/><rect x="20" y="62" width="12" height="12"/><rect x="34" y="62" width="12" height="12"/><rect x="48" y="62" width="12" height="12"/><rect x="62" y="62" width="12" height="12"/></g>' +
11
+ '<g fill="#C0392B"><rect x="48" y="20" width="12" height="12"/><rect x="34" y="34" width="12" height="12"/><rect x="20" y="48" width="12" height="12"/></g>' +
12
+ "</svg>";
13
+ /** The Zudo mark for dark backgrounds: off-white modules, red diagonal. */
14
+ export const ZUDO_MARK_DARK_SVG = ZUDO_MARK_SVG.replace('fill="#1A1A2E"', 'fill="#FAFAF9"');
15
+ /** The full wordmark (mark + ZUDO letters) for light backgrounds. */
16
+ export const ZUDO_WORDMARK_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 330 80" role="img" aria-label="Zudo">' +
17
+ ZUDO_MARK_SVG.replace(/^<svg[^>]*>/, "").replace(/<\/svg>$/, "") +
18
+ '<g fill="none" stroke="#1A1A2E" stroke-width="12" stroke-linecap="square" stroke-linejoin="miter" transform="translate(100 18)">' +
19
+ '<path d="M6 6H34L6 38H34"/><path d="M64 6V38H92V6"/><path d="M122 6H140L150 16V28L140 38H122Z"/><path d="M180 6H208V38H180Z"/></g>' +
20
+ "</svg>";
21
+ /** The wordmark for dark backgrounds. */
22
+ export const ZUDO_WORDMARK_DARK_SVG = ZUDO_WORDMARK_SVG.replace(/#1A1A2E/g, "#FAFAF9");
23
+ /** A 32×32 favicon: red tile, off-white Z. */
24
+ export const ZUDO_FAVICON_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" fill="#C0392B"/>' +
25
+ '<rect x="5" y="6" width="22" height="5" fill="#FAFAF9"/><rect x="17" y="11" width="5" height="4" fill="#FAFAF9"/><rect x="13.5" y="14" width="5" height="4" fill="#FAFAF9"/>' +
26
+ '<rect x="10" y="17" width="5" height="4" fill="#FAFAF9"/><rect x="5" y="21" width="22" height="5" fill="#FAFAF9"/></svg>';
27
+ /** Encodes an SVG string as a `data:` URI usable in `<img src>` or CSS. */
28
+ export function svgToDataUri(svg) {
29
+ return ("data:image/svg+xml;charset=utf-8," +
30
+ encodeURIComponent(svg)
31
+ .replace(/%20/g, " ")
32
+ .replace(/%3D/g, "=")
33
+ .replace(/%3A/g, ":")
34
+ .replace(/%2F/g, "/")
35
+ .replace(/%22/g, "'"));
36
+ }
37
+ export const ZUDO_MARK_DATA_URI = svgToDataUri(ZUDO_MARK_SVG);
38
+ export const ZUDO_MARK_DARK_DATA_URI = svgToDataUri(ZUDO_MARK_DARK_SVG);
39
+ export const ZUDO_WORDMARK_DATA_URI = svgToDataUri(ZUDO_WORDMARK_SVG);
40
+ export const ZUDO_WORDMARK_DARK_DATA_URI = svgToDataUri(ZUDO_WORDMARK_DARK_SVG);
41
+ export const ZUDO_FAVICON_DATA_URI = svgToDataUri(ZUDO_FAVICON_SVG);
42
+ /** Where the logo links by default. */
43
+ export const ZUDO_SITE_URL = "https://zudo.dev";
44
+ //# sourceMappingURL=openApiUi.brand.js.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @zudojs/openapi/openApiUi
3
+ *
4
+ * Renders a branded documentation page (Swagger UI or ReDoc) for a served
5
+ * OpenAPI document. The page carries the Zudo mark in its header and as its
6
+ * favicon, and reads the specification from `specUrl`.
7
+ *
8
+ * The returned string is a complete HTML document; serve it with
9
+ * `content-type: text/html`. {@link OpenAPIManager.toUIResponse} does that.
10
+ */
11
+ import type { OpenAPILogo } from "../openApiTypes/openApiTypes.core.js";
12
+ /** Which viewer to render. */
13
+ export type OpenAPIUIRenderer = "swagger" | "redoc";
14
+ /** Options for {@link renderOpenAPIUI}. */
15
+ export interface OpenAPIUIOptions {
16
+ /** URL the page fetches the specification from, e.g. `/openapi.json`. */
17
+ readonly specUrl: string;
18
+ /** Page title. Default: "API reference". */
19
+ readonly title?: string;
20
+ /** Viewer. Default: "swagger". */
21
+ readonly renderer?: OpenAPIUIRenderer;
22
+ /**
23
+ * Logo shown in the page header. Default: the Zudo wordmark linking to
24
+ * zudo.dev. Pass `false` to render no logo at all.
25
+ */
26
+ readonly logo?: OpenAPILogo | false;
27
+ /** Favicon URL or data URI. Default: the Zudo favicon. */
28
+ readonly favicon?: string | false;
29
+ /** Extra CSS appended after the built-in theme. */
30
+ readonly customCss?: string;
31
+ /**
32
+ * Base URL the viewer's own assets load from. Defaults to a public CDN:
33
+ * `https://unpkg.com/swagger-ui-dist@5` for Swagger UI and
34
+ * `https://cdn.redoc.ly/redoc/latest/bundles` for ReDoc. Point it at a
35
+ * self-hosted copy for air-gapped deployments.
36
+ */
37
+ readonly assetsBaseUrl?: string;
38
+ /** Options forwarded to `SwaggerUIBundle(...)`; ignored by ReDoc. */
39
+ readonly swaggerOptions?: Readonly<Record<string, unknown>>;
40
+ }
41
+ /** The default logo used by every branded page and by `info["x-logo"]`. */
42
+ export declare function zudoLogo(overrides?: Partial<OpenAPILogo>): OpenAPILogo;
43
+ /** Escapes text for safe interpolation into HTML attribute or text nodes. */
44
+ export declare function escapeHtml(value: string): string;
45
+ /** Renders a complete, branded documentation page for `options.specUrl`. */
46
+ export declare function renderOpenAPIUI(options: OpenAPIUIOptions): string;
47
+ //# sourceMappingURL=openApiUi.core.d.ts.map