@elysiajs/openapi 1.4.0 → 1.4.1

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.
@@ -5,7 +5,7 @@ import type { ElysiaOpenAPIConfig, OpenAPIProvider } from './types';
5
5
  *
6
6
  * @see https://github.com/elysiajs/elysia-swagger
7
7
  */
8
- export declare const openapi: <const Enabled extends boolean = true, const Path extends string = "/openapi", const Provider extends OpenAPIProvider = "scalar">({ enabled, path, provider, specPath, documentation, exclude, swagger, scalar, references }?: ElysiaOpenAPIConfig<Enabled, Path, Provider>) => Elysia<"", {
8
+ export declare const openapi: <const Enabled extends boolean = true, const Path extends string = "/openapi", const Provider extends OpenAPIProvider = "scalar">({ enabled, path, provider, specPath, documentation, exclude, swagger, scalar, references, mapJsonSchema }?: ElysiaOpenAPIConfig<Enabled, Path, Provider>) => Elysia<"", {
9
9
  decorator: {};
10
10
  store: {};
11
11
  derive: {};
package/dist/cjs/index.js CHANGED
@@ -295,7 +295,6 @@ var Hint = Symbol.for("TypeBox.Hint");
295
295
  var Kind = Symbol.for("TypeBox.Kind");
296
296
 
297
297
  // src/openapi.ts
298
- var import_xsschema = require("xsschema");
299
298
  var capitalize = (word) => word.charAt(0).toUpperCase() + word.slice(1);
300
299
  var toRef = (name) => import_elysia.t.Ref(`#/components/schemas/${name}`);
301
300
  var toOperationId = (method, paths) => {
@@ -324,14 +323,21 @@ var getLoosePath = (path) => {
324
323
  return path.slice(0, path.length - 1);
325
324
  return path + "/";
326
325
  };
327
- var unwrapSchema = (schema) => {
326
+ var unwrapSchema = (schema, mapJsonSchema) => {
328
327
  if (!schema) return;
329
328
  if (typeof schema === "string") schema = toRef(schema);
330
329
  if (Kind in schema) return schema;
331
- if (Kind in schema === false && schema["~standard"])
332
- return (0, import_xsschema.toJsonSchema)(schema);
330
+ if (Kind in schema || !schema?.["~standard"]) return;
331
+ const vendor = schema["~standard"].vendor;
332
+ if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
333
+ return mapJsonSchema[vendor](schema);
334
+ if (vendor === "zod" || vendor === "sury")
335
+ return schema.toJSONSchema?.();
336
+ if (vendor === "arktype")
337
+ return schema?.toJsonSchema?.();
338
+ return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
333
339
  };
334
- async function toOpenAPISchema(app, exclude, references) {
340
+ function toOpenAPISchema(app, exclude, references, vendors) {
335
341
  const {
336
342
  methods: excludeMethods = ["OPTIONS"],
337
343
  staticFile: excludeStaticFile = true,
@@ -384,8 +390,7 @@ async function toOpenAPISchema(app, exclude, references) {
384
390
  };
385
391
  const parameters = [];
386
392
  if (hooks.params) {
387
- let params = unwrapSchema(hooks.params);
388
- if (params) params = await params;
393
+ const params = unwrapSchema(hooks.params, vendors);
389
394
  if (params && params.type === "object" && params.properties)
390
395
  for (const [paramName, paramSchema] of Object.entries(
391
396
  params.properties
@@ -399,8 +404,7 @@ async function toOpenAPISchema(app, exclude, references) {
399
404
  });
400
405
  }
401
406
  if (hooks.query) {
402
- let query = unwrapSchema(hooks.query);
403
- if (query) query = await query;
407
+ let query = unwrapSchema(hooks.query, vendors);
404
408
  if (query && query.type === "object" && query.properties) {
405
409
  const required = query.required || [];
406
410
  for (const [queryName, querySchema] of Object.entries(
@@ -415,8 +419,7 @@ async function toOpenAPISchema(app, exclude, references) {
415
419
  }
416
420
  }
417
421
  if (hooks.headers) {
418
- let headers = unwrapSchema(hooks.query);
419
- if (headers) headers = await headers;
422
+ const headers = unwrapSchema(hooks.query, vendors);
420
423
  if (headers && headers.type === "object" && headers.properties) {
421
424
  const required = headers.required || [];
422
425
  for (const [headerName, headerSchema] of Object.entries(
@@ -431,8 +434,7 @@ async function toOpenAPISchema(app, exclude, references) {
431
434
  }
432
435
  }
433
436
  if (hooks.cookie) {
434
- let cookie = unwrapSchema(hooks.cookie);
435
- if (cookie) cookie = await cookie;
437
+ const cookie = unwrapSchema(hooks.cookie, vendors);
436
438
  if (cookie && cookie.type === "object" && cookie.properties) {
437
439
  const required = cookie.required || [];
438
440
  for (const [cookieName, cookieSchema] of Object.entries(
@@ -448,8 +450,7 @@ async function toOpenAPISchema(app, exclude, references) {
448
450
  }
449
451
  if (parameters.length > 0) operation.parameters = parameters;
450
452
  if (hooks.body && method !== "get" && method !== "head") {
451
- let body = unwrapSchema(hooks.body);
452
- if (body) body = await body;
453
+ const body = unwrapSchema(hooks.body, vendors);
453
454
  if (body) {
454
455
  const { type: _type, description, ...options } = body;
455
456
  const type = _type;
@@ -511,8 +512,7 @@ async function toOpenAPISchema(app, exclude, references) {
511
512
  operation.responses = {};
512
513
  if (typeof hooks.response === "object" && !hooks.response.type && !hooks.response.$ref) {
513
514
  for (let [status, schema] of Object.entries(hooks.response)) {
514
- let response = unwrapSchema(schema);
515
- if (response) response = await response;
515
+ const response = unwrapSchema(schema, vendors);
516
516
  if (!response) continue;
517
517
  const { type: _type, description, ...options } = response;
518
518
  const type = _type;
@@ -531,8 +531,7 @@ async function toOpenAPISchema(app, exclude, references) {
531
531
  };
532
532
  }
533
533
  } else {
534
- let response = unwrapSchema(hooks.response);
535
- if (response) response = await response;
534
+ const response = unwrapSchema(hooks.response, vendors);
536
535
  if (response) {
537
536
  const { type: _type, description, ...options } = response;
538
537
  const type = _type;
@@ -583,8 +582,7 @@ async function toOpenAPISchema(app, exclude, references) {
583
582
  const schemas = /* @__PURE__ */ Object.create(null);
584
583
  if (_schemas)
585
584
  for (const [name, schema] of Object.entries(_schemas)) {
586
- let jsonSchema = unwrapSchema(schema);
587
- if (jsonSchema instanceof Promise) jsonSchema = await jsonSchema;
585
+ const jsonSchema = unwrapSchema(schema, vendors);
588
586
  if (jsonSchema) schemas[name] = jsonSchema;
589
587
  }
590
588
  return {
@@ -608,7 +606,8 @@ var openapi = ({
608
606
  exclude,
609
607
  swagger,
610
608
  scalar,
611
- references
609
+ references,
610
+ mapJsonSchema
612
611
  } = {}) => {
613
612
  if (!enabled) return new import_elysia2.Elysia({ name: "@elysiajs/openapi" });
614
613
  const info = {
@@ -652,13 +651,13 @@ var openapi = ({
652
651
  );
653
652
  }).get(
654
653
  specPath,
655
- async function openAPISchema() {
654
+ function openAPISchema() {
656
655
  if (totalRoutes === app.routes.length) return cachedSchema;
657
656
  totalRoutes = app.routes.length;
658
657
  const {
659
658
  paths,
660
659
  components: { schemas }
661
- } = await toOpenAPISchema(app, exclude, references);
660
+ } = toOpenAPISchema(app, exclude, references, mapJsonSchema);
662
661
  return cachedSchema = {
663
662
  openapi: "3.0.3",
664
663
  ...documentation,
@@ -1,7 +1,7 @@
1
1
  import { type AnyElysia, type TSchema, type InputSchema } from 'elysia';
2
2
  import type { OpenAPIV3 } from 'openapi-types';
3
3
  import { type TProperties } from '@sinclair/typebox';
4
- import type { AdditionalReferences, ElysiaOpenAPIConfig } from './types';
4
+ import type { AdditionalReferences, ElysiaOpenAPIConfig, MapJsonSchema } from './types';
5
5
  export declare const capitalize: (word: string) => string;
6
6
  /**
7
7
  * Get all possible paths of a path with optional parameters
@@ -10,20 +10,18 @@ export declare const capitalize: (word: string) => string;
10
10
  */
11
11
  export declare const getPossiblePath: (path: string) => string[];
12
12
  export declare const getLoosePath: (path: string) => string;
13
- type MaybePromise<T> = T | Promise<T>;
14
- export declare const unwrapSchema: (schema: InputSchema["body"]) => MaybePromise<OpenAPIV3.SchemaObject | undefined>;
13
+ export declare const unwrapSchema: (schema: InputSchema["body"], mapJsonSchema?: MapJsonSchema) => OpenAPIV3.SchemaObject | undefined;
15
14
  /**
16
15
  * Converts Elysia routes to OpenAPI 3.0.3 paths schema
17
16
  * @param routes Array of Elysia route objects
18
17
  * @returns OpenAPI paths object
19
18
  */
20
- export declare function toOpenAPISchema(app: AnyElysia, exclude?: ElysiaOpenAPIConfig['exclude'], references?: AdditionalReferences): Promise<{
19
+ export declare function toOpenAPISchema(app: AnyElysia, exclude?: ElysiaOpenAPIConfig['exclude'], references?: AdditionalReferences, vendors?: MapJsonSchema): {
21
20
  components: {
22
21
  schemas: any;
23
22
  };
24
23
  paths: OpenAPIV3.PathsObject<{}, {}>;
25
- }>;
24
+ };
26
25
  export declare const withHeaders: (schema: TSchema, headers: TProperties) => TSchema & {
27
26
  headers: TProperties;
28
27
  };
29
- export {};
@@ -38,7 +38,6 @@ var Hint = Symbol.for("TypeBox.Hint");
38
38
  var Kind = Symbol.for("TypeBox.Kind");
39
39
 
40
40
  // src/openapi.ts
41
- var import_xsschema = require("xsschema");
42
41
  var capitalize = (word) => word.charAt(0).toUpperCase() + word.slice(1);
43
42
  var toRef = (name) => import_elysia.t.Ref(`#/components/schemas/${name}`);
44
43
  var toOperationId = (method, paths) => {
@@ -67,14 +66,21 @@ var getLoosePath = (path) => {
67
66
  return path.slice(0, path.length - 1);
68
67
  return path + "/";
69
68
  };
70
- var unwrapSchema = (schema) => {
69
+ var unwrapSchema = (schema, mapJsonSchema) => {
71
70
  if (!schema) return;
72
71
  if (typeof schema === "string") schema = toRef(schema);
73
72
  if (Kind in schema) return schema;
74
- if (Kind in schema === false && schema["~standard"])
75
- return (0, import_xsschema.toJsonSchema)(schema);
73
+ if (Kind in schema || !schema?.["~standard"]) return;
74
+ const vendor = schema["~standard"].vendor;
75
+ if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
76
+ return mapJsonSchema[vendor](schema);
77
+ if (vendor === "zod" || vendor === "sury")
78
+ return schema.toJSONSchema?.();
79
+ if (vendor === "arktype")
80
+ return schema?.toJsonSchema?.();
81
+ return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
76
82
  };
77
- async function toOpenAPISchema(app, exclude, references) {
83
+ function toOpenAPISchema(app, exclude, references, vendors) {
78
84
  const {
79
85
  methods: excludeMethods = ["OPTIONS"],
80
86
  staticFile: excludeStaticFile = true,
@@ -127,8 +133,7 @@ async function toOpenAPISchema(app, exclude, references) {
127
133
  };
128
134
  const parameters = [];
129
135
  if (hooks.params) {
130
- let params = unwrapSchema(hooks.params);
131
- if (params) params = await params;
136
+ const params = unwrapSchema(hooks.params, vendors);
132
137
  if (params && params.type === "object" && params.properties)
133
138
  for (const [paramName, paramSchema] of Object.entries(
134
139
  params.properties
@@ -142,8 +147,7 @@ async function toOpenAPISchema(app, exclude, references) {
142
147
  });
143
148
  }
144
149
  if (hooks.query) {
145
- let query = unwrapSchema(hooks.query);
146
- if (query) query = await query;
150
+ let query = unwrapSchema(hooks.query, vendors);
147
151
  if (query && query.type === "object" && query.properties) {
148
152
  const required = query.required || [];
149
153
  for (const [queryName, querySchema] of Object.entries(
@@ -158,8 +162,7 @@ async function toOpenAPISchema(app, exclude, references) {
158
162
  }
159
163
  }
160
164
  if (hooks.headers) {
161
- let headers = unwrapSchema(hooks.query);
162
- if (headers) headers = await headers;
165
+ const headers = unwrapSchema(hooks.query, vendors);
163
166
  if (headers && headers.type === "object" && headers.properties) {
164
167
  const required = headers.required || [];
165
168
  for (const [headerName, headerSchema] of Object.entries(
@@ -174,8 +177,7 @@ async function toOpenAPISchema(app, exclude, references) {
174
177
  }
175
178
  }
176
179
  if (hooks.cookie) {
177
- let cookie = unwrapSchema(hooks.cookie);
178
- if (cookie) cookie = await cookie;
180
+ const cookie = unwrapSchema(hooks.cookie, vendors);
179
181
  if (cookie && cookie.type === "object" && cookie.properties) {
180
182
  const required = cookie.required || [];
181
183
  for (const [cookieName, cookieSchema] of Object.entries(
@@ -191,8 +193,7 @@ async function toOpenAPISchema(app, exclude, references) {
191
193
  }
192
194
  if (parameters.length > 0) operation.parameters = parameters;
193
195
  if (hooks.body && method !== "get" && method !== "head") {
194
- let body = unwrapSchema(hooks.body);
195
- if (body) body = await body;
196
+ const body = unwrapSchema(hooks.body, vendors);
196
197
  if (body) {
197
198
  const { type: _type, description, ...options } = body;
198
199
  const type = _type;
@@ -254,8 +255,7 @@ async function toOpenAPISchema(app, exclude, references) {
254
255
  operation.responses = {};
255
256
  if (typeof hooks.response === "object" && !hooks.response.type && !hooks.response.$ref) {
256
257
  for (let [status, schema] of Object.entries(hooks.response)) {
257
- let response = unwrapSchema(schema);
258
- if (response) response = await response;
258
+ const response = unwrapSchema(schema, vendors);
259
259
  if (!response) continue;
260
260
  const { type: _type, description, ...options } = response;
261
261
  const type = _type;
@@ -274,8 +274,7 @@ async function toOpenAPISchema(app, exclude, references) {
274
274
  };
275
275
  }
276
276
  } else {
277
- let response = unwrapSchema(hooks.response);
278
- if (response) response = await response;
277
+ const response = unwrapSchema(hooks.response, vendors);
279
278
  if (response) {
280
279
  const { type: _type, description, ...options } = response;
281
280
  const type = _type;
@@ -326,8 +325,7 @@ async function toOpenAPISchema(app, exclude, references) {
326
325
  const schemas = /* @__PURE__ */ Object.create(null);
327
326
  if (_schemas)
328
327
  for (const [name, schema] of Object.entries(_schemas)) {
329
- let jsonSchema = unwrapSchema(schema);
330
- if (jsonSchema instanceof Promise) jsonSchema = await jsonSchema;
328
+ const jsonSchema = unwrapSchema(schema, vendors);
331
329
  if (jsonSchema) schemas[name] = jsonSchema;
332
330
  }
333
331
  return {
@@ -4,6 +4,9 @@ import type { ApiReferenceConfiguration } from '@scalar/types';
4
4
  import type { SwaggerUIOptions } from './swagger/types';
5
5
  export type OpenAPIProvider = 'scalar' | 'swagger-ui' | null;
6
6
  type MaybeArray<T> = T | T[];
7
+ export type MapJsonSchema = {
8
+ [vendor: string]: Function;
9
+ };
7
10
  export type AdditionalReference = {
8
11
  [path in string]: {
9
12
  [method in string]: {
@@ -69,6 +72,21 @@ export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extend
69
72
  * Additional reference for each endpoint
70
73
  */
71
74
  references?: AdditionalReferences;
75
+ /**
76
+ * Mapping function from Standard schema to OpenAPI schema
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * import { openapi } from '@elysiajs/openapi'
81
+ * import { toJsonSchema } from '@valibot/to-json-schema'
82
+ *
83
+ * openapi({
84
+ * vendors: {
85
+ * valibot: toJsonSchema
86
+ * }
87
+ * })
88
+ */
89
+ mapJsonSchema?: MapJsonSchema;
72
90
  /**
73
91
  * Scalar configuration to customize scalar
74
92
  *'
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import type { ElysiaOpenAPIConfig, OpenAPIProvider } from './types';
5
5
  *
6
6
  * @see https://github.com/elysiajs/elysia-swagger
7
7
  */
8
- export declare const openapi: <const Enabled extends boolean = true, const Path extends string = "/openapi", const Provider extends OpenAPIProvider = "scalar">({ enabled, path, provider, specPath, documentation, exclude, swagger, scalar, references }?: ElysiaOpenAPIConfig<Enabled, Path, Provider>) => Elysia<"", {
8
+ export declare const openapi: <const Enabled extends boolean = true, const Path extends string = "/openapi", const Provider extends OpenAPIProvider = "scalar">({ enabled, path, provider, specPath, documentation, exclude, swagger, scalar, references, mapJsonSchema }?: ElysiaOpenAPIConfig<Enabled, Path, Provider>) => Elysia<"", {
9
9
  decorator: {};
10
10
  store: {};
11
11
  derive: {};
package/dist/index.mjs CHANGED
@@ -268,7 +268,6 @@ var Hint = Symbol.for("TypeBox.Hint");
268
268
  var Kind = Symbol.for("TypeBox.Kind");
269
269
 
270
270
  // src/openapi.ts
271
- import { toJsonSchema } from "xsschema";
272
271
  var capitalize = (word) => word.charAt(0).toUpperCase() + word.slice(1);
273
272
  var toRef = (name) => t.Ref(`#/components/schemas/${name}`);
274
273
  var toOperationId = (method, paths) => {
@@ -297,14 +296,21 @@ var getLoosePath = (path) => {
297
296
  return path.slice(0, path.length - 1);
298
297
  return path + "/";
299
298
  };
300
- var unwrapSchema = (schema) => {
299
+ var unwrapSchema = (schema, mapJsonSchema) => {
301
300
  if (!schema) return;
302
301
  if (typeof schema === "string") schema = toRef(schema);
303
302
  if (Kind in schema) return schema;
304
- if (Kind in schema === false && schema["~standard"])
305
- return toJsonSchema(schema);
303
+ if (Kind in schema || !schema?.["~standard"]) return;
304
+ const vendor = schema["~standard"].vendor;
305
+ if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
306
+ return mapJsonSchema[vendor](schema);
307
+ if (vendor === "zod" || vendor === "sury")
308
+ return schema.toJSONSchema?.();
309
+ if (vendor === "arktype")
310
+ return schema?.toJsonSchema?.();
311
+ return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
306
312
  };
307
- async function toOpenAPISchema(app, exclude, references) {
313
+ function toOpenAPISchema(app, exclude, references, vendors) {
308
314
  const {
309
315
  methods: excludeMethods = ["OPTIONS"],
310
316
  staticFile: excludeStaticFile = true,
@@ -357,8 +363,7 @@ async function toOpenAPISchema(app, exclude, references) {
357
363
  };
358
364
  const parameters = [];
359
365
  if (hooks.params) {
360
- let params = unwrapSchema(hooks.params);
361
- if (params) params = await params;
366
+ const params = unwrapSchema(hooks.params, vendors);
362
367
  if (params && params.type === "object" && params.properties)
363
368
  for (const [paramName, paramSchema] of Object.entries(
364
369
  params.properties
@@ -372,8 +377,7 @@ async function toOpenAPISchema(app, exclude, references) {
372
377
  });
373
378
  }
374
379
  if (hooks.query) {
375
- let query = unwrapSchema(hooks.query);
376
- if (query) query = await query;
380
+ let query = unwrapSchema(hooks.query, vendors);
377
381
  if (query && query.type === "object" && query.properties) {
378
382
  const required = query.required || [];
379
383
  for (const [queryName, querySchema] of Object.entries(
@@ -388,8 +392,7 @@ async function toOpenAPISchema(app, exclude, references) {
388
392
  }
389
393
  }
390
394
  if (hooks.headers) {
391
- let headers = unwrapSchema(hooks.query);
392
- if (headers) headers = await headers;
395
+ const headers = unwrapSchema(hooks.query, vendors);
393
396
  if (headers && headers.type === "object" && headers.properties) {
394
397
  const required = headers.required || [];
395
398
  for (const [headerName, headerSchema] of Object.entries(
@@ -404,8 +407,7 @@ async function toOpenAPISchema(app, exclude, references) {
404
407
  }
405
408
  }
406
409
  if (hooks.cookie) {
407
- let cookie = unwrapSchema(hooks.cookie);
408
- if (cookie) cookie = await cookie;
410
+ const cookie = unwrapSchema(hooks.cookie, vendors);
409
411
  if (cookie && cookie.type === "object" && cookie.properties) {
410
412
  const required = cookie.required || [];
411
413
  for (const [cookieName, cookieSchema] of Object.entries(
@@ -421,8 +423,7 @@ async function toOpenAPISchema(app, exclude, references) {
421
423
  }
422
424
  if (parameters.length > 0) operation.parameters = parameters;
423
425
  if (hooks.body && method !== "get" && method !== "head") {
424
- let body = unwrapSchema(hooks.body);
425
- if (body) body = await body;
426
+ const body = unwrapSchema(hooks.body, vendors);
426
427
  if (body) {
427
428
  const { type: _type, description, ...options } = body;
428
429
  const type = _type;
@@ -484,8 +485,7 @@ async function toOpenAPISchema(app, exclude, references) {
484
485
  operation.responses = {};
485
486
  if (typeof hooks.response === "object" && !hooks.response.type && !hooks.response.$ref) {
486
487
  for (let [status, schema] of Object.entries(hooks.response)) {
487
- let response = unwrapSchema(schema);
488
- if (response) response = await response;
488
+ const response = unwrapSchema(schema, vendors);
489
489
  if (!response) continue;
490
490
  const { type: _type, description, ...options } = response;
491
491
  const type = _type;
@@ -504,8 +504,7 @@ async function toOpenAPISchema(app, exclude, references) {
504
504
  };
505
505
  }
506
506
  } else {
507
- let response = unwrapSchema(hooks.response);
508
- if (response) response = await response;
507
+ const response = unwrapSchema(hooks.response, vendors);
509
508
  if (response) {
510
509
  const { type: _type, description, ...options } = response;
511
510
  const type = _type;
@@ -556,8 +555,7 @@ async function toOpenAPISchema(app, exclude, references) {
556
555
  const schemas = /* @__PURE__ */ Object.create(null);
557
556
  if (_schemas)
558
557
  for (const [name, schema] of Object.entries(_schemas)) {
559
- let jsonSchema = unwrapSchema(schema);
560
- if (jsonSchema instanceof Promise) jsonSchema = await jsonSchema;
558
+ const jsonSchema = unwrapSchema(schema, vendors);
561
559
  if (jsonSchema) schemas[name] = jsonSchema;
562
560
  }
563
561
  return {
@@ -581,7 +579,8 @@ var openapi = ({
581
579
  exclude,
582
580
  swagger,
583
581
  scalar,
584
- references
582
+ references,
583
+ mapJsonSchema
585
584
  } = {}) => {
586
585
  if (!enabled) return new Elysia({ name: "@elysiajs/openapi" });
587
586
  const info = {
@@ -625,13 +624,13 @@ var openapi = ({
625
624
  );
626
625
  }).get(
627
626
  specPath,
628
- async function openAPISchema() {
627
+ function openAPISchema() {
629
628
  if (totalRoutes === app.routes.length) return cachedSchema;
630
629
  totalRoutes = app.routes.length;
631
630
  const {
632
631
  paths,
633
632
  components: { schemas }
634
- } = await toOpenAPISchema(app, exclude, references);
633
+ } = toOpenAPISchema(app, exclude, references, mapJsonSchema);
635
634
  return cachedSchema = {
636
635
  openapi: "3.0.3",
637
636
  ...documentation,
package/dist/openapi.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { type AnyElysia, type TSchema, type InputSchema } from 'elysia';
2
2
  import type { OpenAPIV3 } from 'openapi-types';
3
3
  import { type TProperties } from '@sinclair/typebox';
4
- import type { AdditionalReferences, ElysiaOpenAPIConfig } from './types';
4
+ import type { AdditionalReferences, ElysiaOpenAPIConfig, MapJsonSchema } from './types';
5
5
  export declare const capitalize: (word: string) => string;
6
6
  /**
7
7
  * Get all possible paths of a path with optional parameters
@@ -10,20 +10,18 @@ export declare const capitalize: (word: string) => string;
10
10
  */
11
11
  export declare const getPossiblePath: (path: string) => string[];
12
12
  export declare const getLoosePath: (path: string) => string;
13
- type MaybePromise<T> = T | Promise<T>;
14
- export declare const unwrapSchema: (schema: InputSchema["body"]) => MaybePromise<OpenAPIV3.SchemaObject | undefined>;
13
+ export declare const unwrapSchema: (schema: InputSchema["body"], mapJsonSchema?: MapJsonSchema) => OpenAPIV3.SchemaObject | undefined;
15
14
  /**
16
15
  * Converts Elysia routes to OpenAPI 3.0.3 paths schema
17
16
  * @param routes Array of Elysia route objects
18
17
  * @returns OpenAPI paths object
19
18
  */
20
- export declare function toOpenAPISchema(app: AnyElysia, exclude?: ElysiaOpenAPIConfig['exclude'], references?: AdditionalReferences): Promise<{
19
+ export declare function toOpenAPISchema(app: AnyElysia, exclude?: ElysiaOpenAPIConfig['exclude'], references?: AdditionalReferences, vendors?: MapJsonSchema): {
21
20
  components: {
22
21
  schemas: any;
23
22
  };
24
23
  paths: OpenAPIV3.PathsObject<{}, {}>;
25
- }>;
24
+ };
26
25
  export declare const withHeaders: (schema: TSchema, headers: TProperties) => TSchema & {
27
26
  headers: TProperties;
28
27
  };
29
- export {};
package/dist/openapi.mjs CHANGED
@@ -9,7 +9,6 @@ var Hint = Symbol.for("TypeBox.Hint");
9
9
  var Kind = Symbol.for("TypeBox.Kind");
10
10
 
11
11
  // src/openapi.ts
12
- import { toJsonSchema } from "xsschema";
13
12
  var capitalize = (word) => word.charAt(0).toUpperCase() + word.slice(1);
14
13
  var toRef = (name) => t.Ref(`#/components/schemas/${name}`);
15
14
  var toOperationId = (method, paths) => {
@@ -38,14 +37,21 @@ var getLoosePath = (path) => {
38
37
  return path.slice(0, path.length - 1);
39
38
  return path + "/";
40
39
  };
41
- var unwrapSchema = (schema) => {
40
+ var unwrapSchema = (schema, mapJsonSchema) => {
42
41
  if (!schema) return;
43
42
  if (typeof schema === "string") schema = toRef(schema);
44
43
  if (Kind in schema) return schema;
45
- if (Kind in schema === false && schema["~standard"])
46
- return toJsonSchema(schema);
44
+ if (Kind in schema || !schema?.["~standard"]) return;
45
+ const vendor = schema["~standard"].vendor;
46
+ if (mapJsonSchema?.[vendor] && typeof mapJsonSchema[vendor] === "function")
47
+ return mapJsonSchema[vendor](schema);
48
+ if (vendor === "zod" || vendor === "sury")
49
+ return schema.toJSONSchema?.();
50
+ if (vendor === "arktype")
51
+ return schema?.toJsonSchema?.();
52
+ return schema.toJSONSchema?.() ?? schema?.toJsonSchema?.();
47
53
  };
48
- async function toOpenAPISchema(app, exclude, references) {
54
+ function toOpenAPISchema(app, exclude, references, vendors) {
49
55
  const {
50
56
  methods: excludeMethods = ["OPTIONS"],
51
57
  staticFile: excludeStaticFile = true,
@@ -98,8 +104,7 @@ async function toOpenAPISchema(app, exclude, references) {
98
104
  };
99
105
  const parameters = [];
100
106
  if (hooks.params) {
101
- let params = unwrapSchema(hooks.params);
102
- if (params) params = await params;
107
+ const params = unwrapSchema(hooks.params, vendors);
103
108
  if (params && params.type === "object" && params.properties)
104
109
  for (const [paramName, paramSchema] of Object.entries(
105
110
  params.properties
@@ -113,8 +118,7 @@ async function toOpenAPISchema(app, exclude, references) {
113
118
  });
114
119
  }
115
120
  if (hooks.query) {
116
- let query = unwrapSchema(hooks.query);
117
- if (query) query = await query;
121
+ let query = unwrapSchema(hooks.query, vendors);
118
122
  if (query && query.type === "object" && query.properties) {
119
123
  const required = query.required || [];
120
124
  for (const [queryName, querySchema] of Object.entries(
@@ -129,8 +133,7 @@ async function toOpenAPISchema(app, exclude, references) {
129
133
  }
130
134
  }
131
135
  if (hooks.headers) {
132
- let headers = unwrapSchema(hooks.query);
133
- if (headers) headers = await headers;
136
+ const headers = unwrapSchema(hooks.query, vendors);
134
137
  if (headers && headers.type === "object" && headers.properties) {
135
138
  const required = headers.required || [];
136
139
  for (const [headerName, headerSchema] of Object.entries(
@@ -145,8 +148,7 @@ async function toOpenAPISchema(app, exclude, references) {
145
148
  }
146
149
  }
147
150
  if (hooks.cookie) {
148
- let cookie = unwrapSchema(hooks.cookie);
149
- if (cookie) cookie = await cookie;
151
+ const cookie = unwrapSchema(hooks.cookie, vendors);
150
152
  if (cookie && cookie.type === "object" && cookie.properties) {
151
153
  const required = cookie.required || [];
152
154
  for (const [cookieName, cookieSchema] of Object.entries(
@@ -162,8 +164,7 @@ async function toOpenAPISchema(app, exclude, references) {
162
164
  }
163
165
  if (parameters.length > 0) operation.parameters = parameters;
164
166
  if (hooks.body && method !== "get" && method !== "head") {
165
- let body = unwrapSchema(hooks.body);
166
- if (body) body = await body;
167
+ const body = unwrapSchema(hooks.body, vendors);
167
168
  if (body) {
168
169
  const { type: _type, description, ...options } = body;
169
170
  const type = _type;
@@ -225,8 +226,7 @@ async function toOpenAPISchema(app, exclude, references) {
225
226
  operation.responses = {};
226
227
  if (typeof hooks.response === "object" && !hooks.response.type && !hooks.response.$ref) {
227
228
  for (let [status, schema] of Object.entries(hooks.response)) {
228
- let response = unwrapSchema(schema);
229
- if (response) response = await response;
229
+ const response = unwrapSchema(schema, vendors);
230
230
  if (!response) continue;
231
231
  const { type: _type, description, ...options } = response;
232
232
  const type = _type;
@@ -245,8 +245,7 @@ async function toOpenAPISchema(app, exclude, references) {
245
245
  };
246
246
  }
247
247
  } else {
248
- let response = unwrapSchema(hooks.response);
249
- if (response) response = await response;
248
+ const response = unwrapSchema(hooks.response, vendors);
250
249
  if (response) {
251
250
  const { type: _type, description, ...options } = response;
252
251
  const type = _type;
@@ -297,8 +296,7 @@ async function toOpenAPISchema(app, exclude, references) {
297
296
  const schemas = /* @__PURE__ */ Object.create(null);
298
297
  if (_schemas)
299
298
  for (const [name, schema] of Object.entries(_schemas)) {
300
- let jsonSchema = unwrapSchema(schema);
301
- if (jsonSchema instanceof Promise) jsonSchema = await jsonSchema;
299
+ const jsonSchema = unwrapSchema(schema, vendors);
302
300
  if (jsonSchema) schemas[name] = jsonSchema;
303
301
  }
304
302
  return {
package/dist/types.d.ts CHANGED
@@ -4,6 +4,9 @@ import type { ApiReferenceConfiguration } from '@scalar/types';
4
4
  import type { SwaggerUIOptions } from './swagger/types';
5
5
  export type OpenAPIProvider = 'scalar' | 'swagger-ui' | null;
6
6
  type MaybeArray<T> = T | T[];
7
+ export type MapJsonSchema = {
8
+ [vendor: string]: Function;
9
+ };
7
10
  export type AdditionalReference = {
8
11
  [path in string]: {
9
12
  [method in string]: {
@@ -69,6 +72,21 @@ export interface ElysiaOpenAPIConfig<Enabled extends boolean = true, Path extend
69
72
  * Additional reference for each endpoint
70
73
  */
71
74
  references?: AdditionalReferences;
75
+ /**
76
+ * Mapping function from Standard schema to OpenAPI schema
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * import { openapi } from '@elysiajs/openapi'
81
+ * import { toJsonSchema } from '@valibot/to-json-schema'
82
+ *
83
+ * openapi({
84
+ * vendors: {
85
+ * valibot: toJsonSchema
86
+ * }
87
+ * })
88
+ */
89
+ mapJsonSchema?: MapJsonSchema;
72
90
  /**
73
91
  * Scalar configuration to customize scalar
74
92
  *'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elysiajs/openapi",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Plugin for Elysia to auto-generate API documentation",
5
5
  "author": {
6
6
  "name": "saltyAom",