@scalar/schemas 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @scalar/schemas
2
2
 
3
+ ## 0.3.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#9309](https://github.com/scalar/scalar/pull/9309): feat: add `modelsSectionLabel` configuration (`'Models' | 'Schemas' | string`) to use OpenAPI-style Schemas terminology in the sidebar, content, and search.
8
+ - [#9383](https://github.com/scalar/scalar/pull/9383): fix: preserve multi-type schema arrays when coercing schemas with validation keywords
9
+ - [#7618](https://github.com/scalar/scalar/pull/7618): feat(api-reference): add `setPageTitle` to customize the browser tab title
10
+
11
+ Pass a `setPageTitle` function to control the browser tab title. It is called whenever the section in view changes — on sidebar clicks, on scroll, and when switching documents — and receives the section title and the active OpenAPI document:
12
+
13
+ ```js
14
+ setPageTitle: ({ title, document }) => `${document.title} – ${title}`
15
+ ```
16
+
17
+ ## 0.3.2
18
+
19
+ ### Patch Changes
20
+
21
+ - [#9313](https://github.com/scalar/scalar/pull/9313): feat: add AsyncAPI connection URL builder and server list helpers
22
+
3
23
  ## 0.3.1
4
24
 
5
25
  ### Patch Changes
@@ -71,6 +71,7 @@ export declare const apiReferenceConfigurationSchema: import("@scalar/validation
71
71
  isEditable: import("@scalar/validation").BooleanSchema;
72
72
  isLoading: import("@scalar/validation").BooleanSchema;
73
73
  hideModels: import("@scalar/validation").BooleanSchema;
74
+ modelsSectionLabel: import("@scalar/validation").OptionalSchema<import("@scalar/validation").UnionSchema<readonly [import("@scalar/validation").LiteralSchema<"Models">, import("@scalar/validation").LiteralSchema<"Schemas">, import("@scalar/validation").StringSchema]>>;
74
75
  documentDownloadType: import("@scalar/validation").UnionSchema<readonly [import("@scalar/validation").LiteralSchema<"both">, import("@scalar/validation").LiteralSchema<"yaml">, import("@scalar/validation").LiteralSchema<"json">, import("@scalar/validation").LiteralSchema<"direct">, import("@scalar/validation").LiteralSchema<"none">]>;
75
76
  hideDownloadButton: import("@scalar/validation").OptionalSchema<import("@scalar/validation").BooleanSchema>;
76
77
  hideTestRequestButton: import("@scalar/validation").BooleanSchema;
@@ -125,6 +126,13 @@ export declare const apiReferenceConfigurationSchema: import("@scalar/validation
125
126
  name: string;
126
127
  method?: string;
127
128
  }) => string>>;
129
+ setPageTitle: import("@scalar/validation").OptionalSchema<import("@scalar/validation").FunctionSchema<(input: {
130
+ title: string;
131
+ document: {
132
+ title: string;
133
+ slug: string;
134
+ };
135
+ }) => string>>;
128
136
  redirect: import("@scalar/validation").OptionalSchema<import("@scalar/validation").FunctionSchema<(input: string) => string | null | undefined>>;
129
137
  withDefaultFonts: import("@scalar/validation").BooleanSchema;
130
138
  defaultOpenFirstTag: import("@scalar/validation").BooleanSchema;
@@ -224,6 +232,7 @@ export declare const apiReferenceConfigurationWithSourceSchema: (rawInput: unkno
224
232
  }>>;
225
233
  apiClientPlugins: any[];
226
234
  })[] | undefined;
235
+ modelsSectionLabel?: string | undefined;
227
236
  hideDownloadButton?: boolean | undefined;
228
237
  darkMode?: boolean | undefined;
229
238
  forceDarkModeState?: "dark" | "light" | undefined;
@@ -273,6 +282,13 @@ export declare const apiReferenceConfigurationWithSourceSchema: (rawInput: unkno
273
282
  name: string;
274
283
  method?: string;
275
284
  }) => string) | undefined;
285
+ setPageTitle?: ((input: {
286
+ title: string;
287
+ document: {
288
+ title: string;
289
+ slug: string;
290
+ };
291
+ }) => string) | undefined;
276
292
  redirect?: ((input: string) => string | null | undefined) | undefined;
277
293
  tagsSorter?: "alpha" | ((a: any, b: any) => number) | undefined;
278
294
  operationsSorter?: "alpha" | "method" | ((a: any, b: any) => number) | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"api-reference-configuration.d.ts","sourceRoot":"","sources":["../../src/api-reference/api-reference-configuration.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kHAyFN,MAAM,KAAK,IAAI;oHAGb,MAAM,KAAK,IAAI;oHAGf,IAAI;6GAGX,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;qHAKhD;QACN,OAAO,EAAE,OAAO,CAAA;QAChB,cAAc,EAAE,OAAO,CAAA;QACvB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACrC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;gHAOE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;mHAG5B,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;;;;;;;;;yHA4BzB;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;uHAG9B;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;qHAG9B;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;2HAIpD;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;yHAKvD;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;8GAGvD,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS;;;;;;oNA0Bb,GAAG,KAAK,GAAG,KAAK,MAAM;gRAGG,GAAG,KAAK,GAAG,KAAK,MAAM;;;IAWtG,CAAA;AAKF,eAAO,MAAM,yCAAyC,GAAI,UAAU,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAvHrC,MAAM,KAAK,IAAI;8BAGb,MAAM,KAAK,IAAI;8BAGf,IAAI;uBAGX,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;+BAKhD;QACN,OAAO,EAAE,OAAO,CAAA;QAChB,cAAc,EAAE,OAAO,CAAA;QACvB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACrC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;0BAOE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;6BAG5B,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;;;;;;;;;mCA4BzB;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;iCAG9B;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;+BAG9B;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;qCAIpD;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;mCAKvD;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM;wBAGvD,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS;gCA0Bb,GAAG,KAAK,GAAG,KAAK,MAAM;iDAGG,GAAG,KAAK,GAAG,KAAK,MAAM;CAqFvG,CAAA"}
1
+ {"version":3,"file":"api-reference-configuration.d.ts","sourceRoot":"","sources":["../../src/api-reference/api-reference-configuration.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_MODELS_SECTION_LABEL } from '@scalar/types/api-reference';
1
2
  import { any, array, boolean, coerce, fn, intersection, literal, object, optional, record, string, union, } from '@scalar/validation';
2
3
  import { apiReferencePluginSchema } from '../api-reference/api-reference-plugin.js';
3
4
  import { baseConfigurationSchema } from './base-configuration.js';
@@ -33,6 +34,9 @@ export const apiReferenceConfigurationSchema = intersection([
33
34
  default: false,
34
35
  typeComment: 'Whether to show models in the sidebar, search, and content.',
35
36
  }),
37
+ modelsSectionLabel: optional(union([literal('Models'), literal('Schemas'), string()]), {
38
+ typeComment: 'Label for the components.schemas section in the sidebar, content, and search. Use `Schemas` for OpenAPI terminology.',
39
+ }),
36
40
  documentDownloadType: union([literal('both'), literal('yaml'), literal('json'), literal('direct'), literal('none')], {
37
41
  typeComment: 'Sets the file type of the document to download, set to `none` to hide the download button',
38
42
  }),
@@ -133,6 +137,9 @@ export const apiReferenceConfigurationSchema = intersection([
133
137
  generateWebhookSlug: optional(fn(), {
134
138
  typeComment: 'Customize the webhook portion of the hash',
135
139
  }),
140
+ setPageTitle: optional(fn(), {
141
+ typeComment: 'Customize the browser tab title for the section currently in view',
142
+ }),
136
143
  redirect: optional(fn(), {
137
144
  typeComment: 'To handle redirects, pass a function that receives the current path/hash and passes that to history.replaceState',
138
145
  }),
@@ -215,5 +222,6 @@ export const apiReferenceConfigurationWithSourceSchema = (rawInput) => {
215
222
  // @ts-expect-error - We're deleting the deprecated attribute
216
223
  delete input.showToolbar;
217
224
  }
225
+ input.modelsSectionLabel ??= DEFAULT_MODELS_SECTION_LABEL;
218
226
  return input;
219
227
  };
@@ -22,7 +22,7 @@ export declare const asyncApiObjectSchema: import("@scalar/validation").Intersec
22
22
  }>;
23
23
  servers: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").Schema>>;
24
24
  defaultContentType: import("@scalar/validation").OptionalSchema<import("@scalar/validation").StringSchema>;
25
- channels: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").LazySchema<() => import("@scalar/validation").Schema>>>;
25
+ channels: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").Schema>>;
26
26
  operations: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").LazySchema<() => import("@scalar/validation").Schema>>>;
27
27
  components: import("@scalar/validation").OptionalSchema<import("@scalar/validation").Schema>;
28
28
  }>, import("@scalar/validation").IntersectionSchema<readonly [import("@scalar/validation").ObjectSchema<{
@@ -46,5 +46,7 @@ export declare const asyncApiObjectSchema: import("@scalar/validation").Intersec
46
46
  conflictCheckedAgainstHash: import("@scalar/validation").OptionalSchema<import("@scalar/validation").StringSchema>;
47
47
  hasConflict: import("@scalar/validation").OptionalSchema<import("@scalar/validation").BooleanSchema>;
48
48
  }>>;
49
+ }>, import("@scalar/validation").ObjectSchema<{
50
+ 'x-scalar-selected-server': import("@scalar/validation").OptionalSchema<import("@scalar/validation").StringSchema>;
49
51
  }>]>]>;
50
52
  //# sourceMappingURL=asyncapi-object.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"asyncapi-object.d.ts","sourceRoot":"","sources":["../../../src/asyncapi/3.1/asyncapi-object.ts"],"names":[],"mappings":"AA8DA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAG/B,CAAA"}
1
+ {"version":3,"file":"asyncapi-object.d.ts","sourceRoot":"","sources":["../../../src/asyncapi/3.1/asyncapi-object.ts"],"names":[],"mappings":"AAgEA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAG/B,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import { intersection, object, optional, string } from '@scalar/validation';
2
2
  import { XOriginalAasVersion, XScalarIsDirty, XScalarNavigation, XScalarOriginalDocumentHash, XScalarOriginalSourceUrl, XScalarRegistryMeta, XScalarWatchMode, } from '../../extensions/document/index.js';
3
+ import { XScalarSelectedServer } from '../../extensions/server/index.js';
3
4
  import { asyncApiChannelsObject } from './channel.js';
4
5
  import { asyncApiComponentsObject } from './components.js';
5
6
  import { asyncApiInfoObject } from './info.js';
@@ -14,6 +15,7 @@ const asyncApiExtensions = intersection([
14
15
  XScalarIsDirty,
15
16
  XScalarWatchMode,
16
17
  XScalarRegistryMeta,
18
+ XScalarSelectedServer,
17
19
  ], {
18
20
  typeName: 'AsyncApiExtensions',
19
21
  typeComment: 'AsyncAPI document-level Scalar extensions shared with workspace tooling.',
@@ -1,4 +1,15 @@
1
- /** Channel Object | Reference Object */
2
- export declare const asyncApiChannelObject: import("@scalar/validation").LazySchema<() => import("@scalar/validation").Schema>;
3
- export declare const asyncApiChannelsObject: import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").LazySchema<() => import("@scalar/validation").Schema>>;
1
+ /** Channel Object */
2
+ export declare const asyncApiChannelObject: import("@scalar/validation").LazySchema<() => import("@scalar/validation").ObjectSchema<{
3
+ address: import("@scalar/validation").OptionalSchema<import("@scalar/validation").UnionSchema<readonly [import("@scalar/validation").StringSchema, import("@scalar/validation").NullableSchema]>>;
4
+ messages: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").LazySchema<() => import("@scalar/validation").Schema>>>;
5
+ title: import("@scalar/validation").OptionalSchema<import("@scalar/validation").StringSchema>;
6
+ summary: import("@scalar/validation").OptionalSchema<import("@scalar/validation").StringSchema>;
7
+ description: import("@scalar/validation").OptionalSchema<import("@scalar/validation").StringSchema>;
8
+ servers: import("@scalar/validation").OptionalSchema<import("@scalar/validation").ArraySchema<import("@scalar/validation").Schema>>;
9
+ parameters: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").Schema>>;
10
+ tags: import("@scalar/validation").OptionalSchema<import("@scalar/validation").ArraySchema<import("@scalar/validation").Schema>>;
11
+ externalDocs: import("@scalar/validation").OptionalSchema<import("@scalar/validation").Schema>;
12
+ bindings: import("@scalar/validation").OptionalSchema<import("@scalar/validation").Schema>;
13
+ }>>;
14
+ export declare const asyncApiChannelsObject: import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").Schema>;
4
15
  //# sourceMappingURL=channel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../../src/asyncapi/3.1/channel.ts"],"names":[],"mappings":"AAUA,wCAAwC;AACxC,eAAO,MAAM,qBAAqB,oFA4BjC,CAAA;AAED,eAAO,MAAM,sBAAsB,0KAGjC,CAAA"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../../src/asyncapi/3.1/channel.ts"],"names":[],"mappings":"AAUA,qBAAqB;AACrB,eAAO,MAAM,qBAAqB;;;;;;;;;;;GA0BjC,CAAA;AAED,eAAO,MAAM,sBAAsB,2HAGjC,CAAA"}
@@ -6,8 +6,8 @@ import { asyncApiParametersObject } from './parameters.js';
6
6
  import { asyncApiResolvedReference, recursiveRef } from './reference.js';
7
7
  import { asyncApiServerObject } from './server.js';
8
8
  import { asyncApiTagsObject } from './tag.js';
9
- /** Channel Object | Reference Object */
10
- export const asyncApiChannelObject = lazy(() => recursiveRef(object({
9
+ /** Channel Object */
10
+ export const asyncApiChannelObject = lazy(() => object({
11
11
  address: optional(union([string(), nullable()], { typeComment: 'Channel address or null when unknown.' })),
12
12
  messages: optional(asyncApiMessagesObject),
13
13
  title: optional(string({ typeComment: 'A human-friendly title for the channel.' })),
@@ -22,8 +22,8 @@ export const asyncApiChannelObject = lazy(() => recursiveRef(object({
22
22
  tags: optional(asyncApiTagsObject),
23
23
  externalDocs: optional(asyncApiExternalDocumentationObject),
24
24
  bindings: optional(recursiveRef(asyncApiChannelBindingsObject)),
25
- }, { typeName: 'AsyncApiChannelObject' })));
26
- export const asyncApiChannelsObject = record(string(), asyncApiChannelObject, {
25
+ }, { typeName: 'AsyncApiChannelObject' }));
26
+ export const asyncApiChannelsObject = record(string(), recursiveRef(asyncApiChannelObject), {
27
27
  typeName: 'AsyncApiChannelsObject',
28
28
  typeComment: 'Map of channelId to Channel Object or Reference Object.',
29
29
  });
@@ -1,7 +1,7 @@
1
1
  export declare const asyncApiComponentsObject: import("@scalar/validation").LazySchema<() => import("@scalar/validation").ObjectSchema<{
2
2
  schemas: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").Schema>>;
3
3
  servers: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").Schema>>;
4
- channels: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").LazySchema<() => import("@scalar/validation").Schema>>>;
4
+ channels: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").Schema>>;
5
5
  operations: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").LazySchema<() => import("@scalar/validation").Schema>>>;
6
6
  messages: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").LazySchema<() => import("@scalar/validation").Schema>>>;
7
7
  securitySchemes: import("@scalar/validation").OptionalSchema<import("@scalar/validation").RecordSchema<import("@scalar/validation").StringSchema, import("@scalar/validation").Schema>>;
@@ -1,6 +1,6 @@
1
1
  import { lazy, object, optional, record, string } from '@scalar/validation';
2
2
  import { asyncApiChannelBindingsObject, asyncApiMessageBindingsObject, asyncApiOperationBindingsObject, asyncApiServerBindingsObject, } from './bindings.js';
3
- import { asyncApiChannelObject } from './channel.js';
3
+ import { asyncApiChannelsObject } from './channel.js';
4
4
  import { asyncApiCorrelationIdObject } from './correlation-id.js';
5
5
  import { asyncApiExternalDocumentationObject } from './external-documentation.js';
6
6
  import { asyncApiMessageObject } from './message.js';
@@ -21,7 +21,7 @@ export const asyncApiComponentsObject = lazy(() => object({
21
21
  typeComment: 'Reusable Multi Format Schema, Schema Object, or Reference Object.',
22
22
  })),
23
23
  servers: optional(record(string(), asyncApiServerObject)),
24
- channels: optional(record(string(), asyncApiChannelObject)),
24
+ channels: optional(asyncApiChannelsObject),
25
25
  operations: optional(record(string(), asyncApiOperationObject)),
26
26
  messages: optional(record(string(), asyncApiMessageObject)),
27
27
  securitySchemes: optional(record(string(), asyncApiSecuritySchemeObject)),
@@ -1 +1 @@
1
- {"version":3,"file":"schema-payload.d.ts","sourceRoot":"","sources":["../../../src/asyncapi/3.1/schema-payload.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,+BAA+B;;;EAa3C,CAAA;AAcD,uCAAuC;AACvC,eAAO,MAAM,+BAA+B,qCAAwC,CAAA;AAEpF,oEAAoE;AACpE,eAAO,MAAM,qBAAqB,qCAIjC,CAAA"}
1
+ {"version":3,"file":"schema-payload.d.ts","sourceRoot":"","sources":["../../../src/asyncapi/3.1/schema-payload.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,+BAA+B;;;EAa3C,CAAA;AAQD,uCAAuC;AACvC,eAAO,MAAM,+BAA+B,qCAAwC,CAAA;AAEpF,oEAAoE;AACpE,eAAO,MAAM,qBAAqB,qCAIjC,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { literal, object, optional, string, union, unknown } from '@scalar/validation';
2
+ import { schema as schemaObject } from '../../openapi/3.1/schema.js';
2
3
  import { recursiveRef } from './reference.js';
3
4
  export const asyncApiMultiFormatSchemaObject = object({
4
5
  schemaFormat: optional(string({
@@ -8,14 +9,11 @@ export const asyncApiMultiFormatSchemaObject = object({
8
9
  typeComment: 'REQUIRED. Schema definition in the format given by schemaFormat.',
9
10
  }),
10
11
  }, { typeName: 'AsyncApiMultiFormatSchemaObject' });
11
- const asyncApiSchemaJsonShape = union([
12
- literal(true),
13
- literal(false),
14
- unknown({
15
- typeName: 'AsyncApiSchemaObject',
16
- typeComment: 'JSON Schema Draft 07 compatible schema (boolean true/false or object); see AsyncAPI Schema Object.',
17
- }),
18
- ], { typeName: 'AsyncApiSchemaJsonShape' });
12
+ // AsyncAPI's default schema format is JSON Schema, the same dialect OpenAPI 3.1 uses, so we reuse the
13
+ // OpenAPI Schema Object here instead of an opaque `unknown`. A schema may also be a boolean per JSON Schema.
14
+ const asyncApiSchemaJsonShape = union([literal(true), literal(false), schemaObject], {
15
+ typeName: 'AsyncApiSchemaJsonShape',
16
+ });
19
17
  /** Schema Object | Reference Object */
20
18
  export const asyncApiSchemaObjectOrReference = recursiveRef(asyncApiSchemaJsonShape);
21
19
  /** Multi Format Schema Object | Schema Object | Reference Object */
@@ -1 +1 @@
1
- {"version":3,"file":"x-scalar-selected-server.d.ts","sourceRoot":"","sources":["../../../src/extensions/server/x-scalar-selected-server.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,qBAAqB;;EAWjC,CAAA"}
1
+ {"version":3,"file":"x-scalar-selected-server.d.ts","sourceRoot":"","sources":["../../../src/extensions/server/x-scalar-selected-server.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,qBAAqB;;EAmBjC,CAAA"}
@@ -1,10 +1,12 @@
1
1
  import { object, optional, string } from '@scalar/validation';
2
2
  import { typeCommentWithExample } from '../type-comment.js';
3
3
  export const XScalarSelectedServer = object({
4
- 'x-scalar-selected-server': optional(string({ typeComment: 'The URL of the currently selected server' })),
4
+ 'x-scalar-selected-server': optional(string({
5
+ typeComment: 'The currently selected server. For OpenAPI documents this is the server URL; for AsyncAPI documents this is the server name (key in `document.servers`).',
6
+ })),
5
7
  }, {
6
8
  typeName: 'XScalarSelectedServer',
7
- typeComment: typeCommentWithExample('The URL of the currently selected server for this API description.', {
9
+ typeComment: typeCommentWithExample('The currently selected server for this API description. For OpenAPI documents the value is the server URL; for AsyncAPI documents the value is the server name (key in `document.servers`).', {
8
10
  language: 'yaml',
9
11
  body: 'x-scalar-selected-server: https://api.example.com',
10
12
  }),
@@ -18,7 +18,7 @@ const reference = object({
18
18
  * Use for `components.schemas` and schema composition (`allOf`, `properties`, `items`, and similar)
19
19
  * where references follow JSON Schema / OpenAPI schema rules only.
20
20
  */
21
- export const normalRef = (inner) => union([inner, reference]);
21
+ export const normalRef = (inner) => union([reference, inner]);
22
22
  const e = (value) => {
23
23
  if (isObject(value) && '$ref' in value) {
24
24
  return e(value['$ref-value']);
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/openapi/3.1/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EAaZ,MAAM,oBAAoB,CAAA;AAqI3B,eAAO,MAAM,MAAM,EAAE,MAOpB,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/openapi/3.1/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EAaZ,MAAM,oBAAoB,CAAA;AA0K3B,eAAO,MAAM,MAAM,EAAE,MAOpB,CAAA"}
@@ -43,24 +43,33 @@ const coreSchemaProperties = object({
43
43
  anyOf: optional(array(normalRef(lazy(() => schema)), { typeName: 'SchemaObjectAnyOf' })),
44
44
  not: optional(normalRef(lazy(() => schema))),
45
45
  });
46
- const numericSchema = object({
47
- type: union([literal('number'), literal('integer')]),
48
- format: optional(string({ typeComment: 'Different subtypes.' })),
46
+ const numericValidationKeywords = object({
49
47
  multipleOf: optional(number({ typeComment: 'Number must be a multiple of this value.' })),
50
48
  maximum: optional(number({ typeComment: 'Maximum value (inclusive).' })),
51
49
  exclusiveMaximum: optional(number({ typeComment: 'Maximum value (exclusive).' })),
52
50
  minimum: optional(number({ typeComment: 'Minimum value (inclusive).' })),
53
51
  exclusiveMinimum: optional(number({ typeComment: 'Minimum value (exclusive).' })),
54
- }, { typeName: 'NumberSchemaObject' });
55
- const stringSchema = object({
56
- type: literal('string'),
57
- format: optional(string({ typeComment: 'Different subtypes.' })),
52
+ });
53
+ const numericSchema = intersection([
54
+ object({
55
+ type: union([literal('number'), literal('integer')]),
56
+ format: optional(string({ typeComment: 'Different subtypes.' })),
57
+ }),
58
+ numericValidationKeywords,
59
+ ], { typeName: 'NumberSchemaObject' });
60
+ const stringValidationKeywords = object({
58
61
  maxLength: optional(number({ typeComment: 'Maximum string length.' })),
59
62
  minLength: optional(number({ typeComment: 'Minimum string length.' })),
60
63
  pattern: optional(string({ typeComment: 'Regular expression pattern.' })),
61
- }, { typeName: 'StringSchemaObject' });
62
- const objectSchema = object({
63
- type: literal('object'),
64
+ });
65
+ const stringSchema = intersection([
66
+ object({
67
+ type: literal('string'),
68
+ format: optional(string({ typeComment: 'Different subtypes.' })),
69
+ }),
70
+ stringValidationKeywords,
71
+ ], { typeName: 'StringSchemaObject' });
72
+ const objectValidationKeywords = object({
64
73
  maxProperties: optional(number({ typeComment: 'Maximum number of properties.' })),
65
74
  minProperties: optional(number({ typeComment: 'Minimum number of properties.' })),
66
75
  properties: optional(record(string(), normalRef(lazy(() => schema)), { typeName: 'SchemaObjectProperties' })),
@@ -70,15 +79,26 @@ const objectSchema = object({
70
79
  })),
71
80
  patternProperties: optional(record(string(), normalRef(lazy(() => schema)), { typeName: 'SchemaObjectPatternProperties' })),
72
81
  propertyNames: optional(normalRef(lazy(() => schema))),
73
- }, { typeName: 'ObjectSchemaObject' });
74
- const arraySchema = object({
75
- type: literal('array'),
82
+ });
83
+ const objectSchema = intersection([
84
+ object({
85
+ type: literal('object'),
86
+ }),
87
+ objectValidationKeywords,
88
+ ], { typeName: 'ObjectSchemaObject' });
89
+ const arrayValidationKeywords = object({
76
90
  maxItems: optional(number({ typeComment: 'Maximum number of items in array.' })),
77
91
  minItems: optional(number({ typeComment: 'Minimum number of items in array.' })),
78
92
  uniqueItems: optional(boolean({ typeComment: 'Whether array items must be unique.' })),
79
93
  items: optional(normalRef(lazy(() => schema))),
80
94
  prefixItems: optional(array(normalRef(lazy(() => schema)), { typeComment: 'Schema for tuple validation.' })),
81
- }, { typeName: 'ArraySchemaObject' });
95
+ });
96
+ const arraySchema = intersection([
97
+ object({
98
+ type: literal('array'),
99
+ }),
100
+ arrayValidationKeywords,
101
+ ], { typeName: 'ArraySchemaObject' });
82
102
  const schemaTypeMulti = union([
83
103
  literal('null'),
84
104
  literal('boolean'),
@@ -89,12 +109,24 @@ const schemaTypeMulti = union([
89
109
  literal('array'),
90
110
  ], { typeName: 'SchemaObjectMultiTypeKeywords' });
91
111
  const otherTypeSchema = object({
92
- type: union([literal('null'), literal('boolean'), array(schemaTypeMulti)], {
112
+ type: union([literal('null'), literal('boolean')], {
93
113
  typeName: 'SchemaObjectOtherTypeKeyword',
94
114
  }),
95
- }, { typeName: 'MultiTypeSchemaObject' });
115
+ });
116
+ const multiTypeSchema = intersection([
117
+ object({
118
+ type: array(schemaTypeMulti, {
119
+ typeName: 'SchemaObjectMultiTypeKeywordArray',
120
+ }),
121
+ format: optional(string({ typeComment: 'Different subtypes.' })),
122
+ }),
123
+ numericValidationKeywords,
124
+ stringValidationKeywords,
125
+ arrayValidationKeywords,
126
+ objectValidationKeywords,
127
+ ], { typeName: 'MultiTypeSchemaObject' });
96
128
  export const schema = intersection([
97
129
  coreSchemaProperties,
98
130
  ...schemaExtensionObjects,
99
- union([otherTypeSchema, numericSchema, stringSchema, objectSchema, arraySchema, object({})]),
131
+ union([otherTypeSchema, numericSchema, stringSchema, objectSchema, arraySchema, multiTypeSchema, object({})]),
100
132
  ], { typeName: 'SchemaObject' });
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "schemas",
15
15
  "scalar"
16
16
  ],
17
- "version": "0.3.1",
17
+ "version": "0.3.3",
18
18
  "engines": {
19
19
  "node": ">=22"
20
20
  },
@@ -41,12 +41,12 @@
41
41
  "CHANGELOG.md"
42
42
  ],
43
43
  "dependencies": {
44
- "@scalar/helpers": "0.8.0",
44
+ "@scalar/helpers": "0.8.1",
45
45
  "@scalar/validation": "0.6.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "vitest": "4.1.0",
49
- "@scalar/types": "0.12.1"
49
+ "@scalar/types": "0.12.3"
50
50
  },
51
51
  "scripts": {
52
52
  "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",