@orpc/openapi 1.1.1 → 1.2.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.
@@ -8,7 +8,7 @@ import '@orpc/server/standard';
8
8
  * OpenAPI Handler for Fetch Server
9
9
  *
10
10
  * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
11
- * @see {@link https://orpc.unnoq.com/docs/integrations/fetch-server Fetch Server Integration Docs}
11
+ * @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
12
12
  */
13
13
  declare class OpenAPIHandler<T extends Context> extends FetchHandler<T> {
14
14
  constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & FetchHandlerOptions<T>>);
@@ -8,7 +8,7 @@ import '@orpc/server/standard';
8
8
  * OpenAPI Handler for Fetch Server
9
9
  *
10
10
  * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
11
- * @see {@link https://orpc.unnoq.com/docs/integrations/fetch-server Fetch Server Integration Docs}
11
+ * @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
12
12
  */
13
13
  declare class OpenAPIHandler<T extends Context> extends FetchHandler<T> {
14
14
  constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & FetchHandlerOptions<T>>);
@@ -8,7 +8,7 @@ import '@orpc/server/standard';
8
8
  * OpenAPI Handler for Node Server
9
9
  *
10
10
  * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
11
- * @see {@link https://orpc.unnoq.com/docs/integrations/node Node Integration Docs}
11
+ * @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
12
12
  */
13
13
  declare class OpenAPIHandler<T extends Context> extends NodeHttpHandler<T> {
14
14
  constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & NodeHttpHandlerOptions<T>>);
@@ -8,7 +8,7 @@ import '@orpc/server/standard';
8
8
  * OpenAPI Handler for Node Server
9
9
  *
10
10
  * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-handler OpenAPI Handler Docs}
11
- * @see {@link https://orpc.unnoq.com/docs/integrations/node Node Integration Docs}
11
+ * @see {@link https://orpc.unnoq.com/docs/adapters/http HTTP Adapter Docs}
12
12
  */
13
13
  declare class OpenAPIHandler<T extends Context> extends NodeHttpHandler<T> {
14
14
  constructor(router: Router<any, T>, options?: NoInfer<StandardOpenAPIHandlerOptions<T> & NodeHttpHandlerOptions<T>>);
package/dist/index.d.mts CHANGED
@@ -4,10 +4,11 @@ export { OpenAPIV3_1 as OpenAPI } from 'openapi-types';
4
4
  export { d as CompositeSchemaConverter, C as ConditionalSchemaConverter, b as OpenAPIGenerator, a as OpenAPIGeneratorGenerateOptions, O as OpenAPIGeneratorOptions, S as SchemaConvertOptions, c as SchemaConverter } from './shared/openapi.DP97kr00.mjs';
5
5
  import { HTTPPath, HTTPMethod } from '@orpc/client';
6
6
  import { JSONSchema } from 'json-schema-typed/draft-2020-12';
7
- export { JSONSchema, Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
7
+ export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
8
+ import { JsonifiedClient } from '@orpc/openapi-client';
9
+ import { AnyRouter, ClientContext, Lazyable, CreateProcedureClientOptions, InferRouterInitialContext, Schema, ErrorMap, Meta, RouterClient } from '@orpc/server';
10
+ import { MaybeOptionalOptions } from '@orpc/shared';
8
11
  import '@orpc/openapi-client/standard';
9
- import '@orpc/server';
10
- import '@orpc/shared';
11
12
 
12
13
  type OverrideOperationValue = Partial<OpenAPIV3_1.OperationObject> | ((current: OpenAPIV3_1.OperationObject, procedure: AnyContractProcedure) => OpenAPIV3_1.OperationObject);
13
14
  /**
@@ -66,6 +67,8 @@ declare function checkParamsSchema(schema: ObjectSchema, params: string[]): bool
66
67
  */
67
68
  declare function toOpenAPISchema(schema: JSONSchema): OpenAPIV3_1.SchemaObject & object;
68
69
 
70
+ declare function createJsonifiedRouterClient<T extends AnyRouter, TClientContext extends ClientContext>(router: Lazyable<T | undefined>, ...rest: MaybeOptionalOptions<CreateProcedureClientOptions<InferRouterInitialContext<T>, Schema<unknown, unknown>, ErrorMap, Meta, TClientContext>>): JsonifiedClient<RouterClient<T, TClientContext>>;
71
+
69
72
  /**
70
73
  *@internal
71
74
  */
@@ -92,5 +95,5 @@ declare const oo: {
92
95
  spec: typeof customOpenAPIOperation;
93
96
  };
94
97
 
95
- export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, customOpenAPIOperation, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, oo, separateObjectSchema, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
98
+ export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, oo, separateObjectSchema, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
96
99
  export type { FileSchema, ObjectSchema, OverrideOperationValue };
package/dist/index.d.ts CHANGED
@@ -4,10 +4,11 @@ export { OpenAPIV3_1 as OpenAPI } from 'openapi-types';
4
4
  export { d as CompositeSchemaConverter, C as ConditionalSchemaConverter, b as OpenAPIGenerator, a as OpenAPIGeneratorGenerateOptions, O as OpenAPIGeneratorOptions, S as SchemaConvertOptions, c as SchemaConverter } from './shared/openapi.DP97kr00.js';
5
5
  import { HTTPPath, HTTPMethod } from '@orpc/client';
6
6
  import { JSONSchema } from 'json-schema-typed/draft-2020-12';
7
- export { JSONSchema, Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
7
+ export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
8
+ import { JsonifiedClient } from '@orpc/openapi-client';
9
+ import { AnyRouter, ClientContext, Lazyable, CreateProcedureClientOptions, InferRouterInitialContext, Schema, ErrorMap, Meta, RouterClient } from '@orpc/server';
10
+ import { MaybeOptionalOptions } from '@orpc/shared';
8
11
  import '@orpc/openapi-client/standard';
9
- import '@orpc/server';
10
- import '@orpc/shared';
11
12
 
12
13
  type OverrideOperationValue = Partial<OpenAPIV3_1.OperationObject> | ((current: OpenAPIV3_1.OperationObject, procedure: AnyContractProcedure) => OpenAPIV3_1.OperationObject);
13
14
  /**
@@ -66,6 +67,8 @@ declare function checkParamsSchema(schema: ObjectSchema, params: string[]): bool
66
67
  */
67
68
  declare function toOpenAPISchema(schema: JSONSchema): OpenAPIV3_1.SchemaObject & object;
68
69
 
70
+ declare function createJsonifiedRouterClient<T extends AnyRouter, TClientContext extends ClientContext>(router: Lazyable<T | undefined>, ...rest: MaybeOptionalOptions<CreateProcedureClientOptions<InferRouterInitialContext<T>, Schema<unknown, unknown>, ErrorMap, Meta, TClientContext>>): JsonifiedClient<RouterClient<T, TClientContext>>;
71
+
69
72
  /**
70
73
  *@internal
71
74
  */
@@ -92,5 +95,5 @@ declare const oo: {
92
95
  spec: typeof customOpenAPIOperation;
93
96
  };
94
97
 
95
- export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, customOpenAPIOperation, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, oo, separateObjectSchema, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
98
+ export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, customOpenAPIOperation, filterSchemaBranches, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, oo, separateObjectSchema, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
96
99
  export type { FileSchema, ObjectSchema, OverrideOperationValue };
package/dist/index.mjs CHANGED
@@ -1,15 +1,41 @@
1
1
  import { c as customOpenAPIOperation } from './shared/openapi.fMEQd3Yd.mjs';
2
2
  export { C as CompositeSchemaConverter, L as LOGIC_KEYWORDS, O as OpenAPIGenerator, a as applyCustomOpenAPIOperation, n as applySchemaOptionality, h as checkParamsSchema, m as filterSchemaBranches, g as getCustomOpenAPIOperation, l as isAnySchema, j as isFileSchema, k as isObjectSchema, s as separateObjectSchema, d as toOpenAPIContent, e as toOpenAPIEventIteratorContent, b as toOpenAPIMethod, f as toOpenAPIParameters, t as toOpenAPIPath, i as toOpenAPISchema } from './shared/openapi.fMEQd3Yd.mjs';
3
- export { Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
4
- import '@orpc/client';
3
+ import { createORPCErrorFromJson } from '@orpc/client';
4
+ import { StandardOpenAPISerializer, StandardOpenAPIJsonSerializer, StandardBracketNotationSerializer } from '@orpc/openapi-client/standard';
5
+ import { ORPCError, createRouterClient } from '@orpc/server';
6
+ import { resolveMaybeOptionalOptions } from '@orpc/shared';
7
+ export { ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat } from 'json-schema-typed/draft-2020-12';
5
8
  import '@orpc/client/standard';
6
9
  import '@orpc/contract';
7
- import '@orpc/openapi-client/standard';
8
- import '@orpc/server';
9
- import '@orpc/shared';
10
+
11
+ function createJsonifiedRouterClient(router, ...rest) {
12
+ const options = resolveMaybeOptionalOptions(rest);
13
+ const serializer = new StandardOpenAPISerializer(new StandardOpenAPIJsonSerializer(), new StandardBracketNotationSerializer());
14
+ options.interceptors ??= [];
15
+ options.interceptors.unshift(async (options2) => {
16
+ try {
17
+ return serializer.deserialize(
18
+ serializer.serialize(
19
+ await options2.next()
20
+ )
21
+ );
22
+ } catch (e) {
23
+ if (e instanceof ORPCError) {
24
+ throw createORPCErrorFromJson(serializer.deserialize(
25
+ serializer.serialize(
26
+ e.toJSON(),
27
+ { outputFormat: "plain" }
28
+ )
29
+ ));
30
+ }
31
+ throw e;
32
+ }
33
+ });
34
+ return createRouterClient(router, options);
35
+ }
10
36
 
11
37
  const oo = {
12
38
  spec: customOpenAPIOperation
13
39
  };
14
40
 
15
- export { customOpenAPIOperation, oo };
41
+ export { createJsonifiedRouterClient, customOpenAPIOperation, oo };
@@ -1,10 +1,10 @@
1
1
  import { Context, HTTPPath, Router } from '@orpc/server';
2
2
  import { StandardHandlerInterceptorOptions, StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
3
3
  import { Value } from '@orpc/shared';
4
+ import { OpenAPIV3_1 } from 'openapi-types';
4
5
  import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.DP97kr00.mjs';
5
6
  import '@orpc/contract';
6
7
  import '@orpc/openapi-client/standard';
7
- import 'openapi-types';
8
8
  import 'json-schema-typed/draft-2020-12';
9
9
 
10
10
  interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGeneratorOptions {
@@ -34,7 +34,7 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
34
34
  /**
35
35
  * Arbitrary configuration object for the UI.
36
36
  */
37
- docsConfig?: Value<object, [StandardHandlerInterceptorOptions<T>]>;
37
+ docsConfig?: Value<Record<string, unknown>, [StandardHandlerInterceptorOptions<T>]>;
38
38
  /**
39
39
  * HTML to inject into the <head> of the docs page.
40
40
  *
@@ -50,7 +50,7 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
50
50
  /**
51
51
  * Override function to generate the full HTML for the docs page.
52
52
  */
53
- renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: object | undefined) => string;
53
+ renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPIV3_1.Document) => string;
54
54
  }
55
55
  declare class OpenAPIReferencePlugin<T extends Context> implements StandardHandlerPlugin<T> {
56
56
  private readonly generator;
@@ -1,10 +1,10 @@
1
1
  import { Context, HTTPPath, Router } from '@orpc/server';
2
2
  import { StandardHandlerInterceptorOptions, StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
3
3
  import { Value } from '@orpc/shared';
4
+ import { OpenAPIV3_1 } from 'openapi-types';
4
5
  import { O as OpenAPIGeneratorOptions, a as OpenAPIGeneratorGenerateOptions } from '../shared/openapi.DP97kr00.js';
5
6
  import '@orpc/contract';
6
7
  import '@orpc/openapi-client/standard';
7
- import 'openapi-types';
8
8
  import 'json-schema-typed/draft-2020-12';
9
9
 
10
10
  interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGeneratorOptions {
@@ -34,7 +34,7 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
34
34
  /**
35
35
  * Arbitrary configuration object for the UI.
36
36
  */
37
- docsConfig?: Value<object, [StandardHandlerInterceptorOptions<T>]>;
37
+ docsConfig?: Value<Record<string, unknown>, [StandardHandlerInterceptorOptions<T>]>;
38
38
  /**
39
39
  * HTML to inject into the <head> of the docs page.
40
40
  *
@@ -50,7 +50,7 @@ interface OpenAPIReferencePluginOptions<T extends Context> extends OpenAPIGenera
50
50
  /**
51
51
  * Override function to generate the full HTML for the docs page.
52
52
  */
53
- renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: object | undefined) => string;
53
+ renderDocsHtml?: (specUrl: string, title: string, head: string, scriptUrl: string, config: Record<string, unknown> | undefined, spec: OpenAPIV3_1.Document) => string;
54
54
  }
55
55
  declare class OpenAPIReferencePlugin<T extends Context> implements StandardHandlerPlugin<T> {
56
56
  private readonly generator;
@@ -1,4 +1,4 @@
1
- import { stringifyJSON, value } from '@orpc/shared';
1
+ import { stringifyJSON, once, value } from '@orpc/shared';
2
2
  import { O as OpenAPIGenerator } from '../shared/openapi.fMEQd3Yd.mjs';
3
3
  import '@orpc/client';
4
4
  import '@orpc/client/standard';
@@ -27,25 +27,32 @@ class OpenAPIReferencePlugin {
27
27
  this.specPath = options.specPath ?? "/spec.json";
28
28
  this.generator = new OpenAPIGenerator(options);
29
29
  const esc = (s) => s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
30
- this.renderDocsHtml = options.renderDocsHtml ?? ((specUrl, title, head, scriptUrl, config) => `
31
- <!doctype html>
32
- <html>
33
- <head>
34
- <meta charset="utf-8" />
35
- <meta name="viewport" content="width=device-width, initial-scale=1" />
36
- <title>${esc(title)}</title>
37
- ${head}
38
- </head>
39
- <body>
40
- <script
41
- id="api-reference"
42
- data-url="${esc(specUrl)}"
43
- ${config !== void 0 ? `data-configuration="${esc(stringifyJSON(config))}"` : ""}
44
- ><\/script>
45
- <script src="${esc(scriptUrl)}"><\/script>
46
- </body>
47
- </html>
48
- `);
30
+ this.renderDocsHtml = options.renderDocsHtml ?? ((specUrl, title, head, scriptUrl, config, spec) => {
31
+ const finalConfig = {
32
+ content: stringifyJSON(spec),
33
+ ...config
34
+ };
35
+ return `
36
+ <!doctype html>
37
+ <html>
38
+ <head>
39
+ <meta charset="utf-8" />
40
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
41
+ <title>${esc(title)}</title>
42
+ ${head}
43
+ </head>
44
+ <body>
45
+ <div id="app" data-config="${esc(stringifyJSON(finalConfig))}"></div>
46
+
47
+ <script src="${esc(scriptUrl)}"><\/script>
48
+
49
+ <script>
50
+ Scalar.createApiReference('#app', JSON.parse(document.getElementById('app').dataset.config))
51
+ <\/script>
52
+ </body>
53
+ </html>
54
+ `;
55
+ });
49
56
  }
50
57
  init(options, router) {
51
58
  options.interceptors ??= [];
@@ -58,11 +65,14 @@ class OpenAPIReferencePlugin {
58
65
  const requestPathname = options2.request.url.pathname.replace(/\/$/, "") || "/";
59
66
  const docsUrl = new URL(`${prefix}${this.docsPath}`.replace(/\/$/, ""), options2.request.url.origin);
60
67
  const specUrl = new URL(`${prefix}${this.specPath}`.replace(/\/$/, ""), options2.request.url.origin);
61
- if (requestPathname === specUrl.pathname) {
62
- const spec = await this.generator.generate(router, {
68
+ const generateSpec = once(async () => {
69
+ return await this.generator.generate(router, {
63
70
  servers: [{ url: new URL(prefix, options2.request.url.origin).toString() }],
64
71
  ...await value(this.specGenerateOptions, options2)
65
72
  });
73
+ });
74
+ if (requestPathname === specUrl.pathname) {
75
+ const spec = await generateSpec();
66
76
  return {
67
77
  matched: true,
68
78
  response: {
@@ -78,7 +88,8 @@ class OpenAPIReferencePlugin {
78
88
  await value(this.docsTitle, options2),
79
89
  await value(this.docsHead, options2),
80
90
  await value(this.docsScriptUrl, options2),
81
- await value(this.docsConfig, options2)
91
+ await value(this.docsConfig, options2),
92
+ await generateSpec()
82
93
  );
83
94
  return {
84
95
  matched: true,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/openapi",
3
3
  "type": "module",
4
- "version": "1.1.1",
4
+ "version": "1.2.0",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -47,12 +47,12 @@
47
47
  "json-schema-typed": "^8.0.1",
48
48
  "openapi-types": "^12.1.3",
49
49
  "rou3": "^0.6.0",
50
- "@orpc/client": "1.1.1",
51
- "@orpc/openapi-client": "1.1.1",
52
- "@orpc/server": "1.1.1",
53
- "@orpc/contract": "1.1.1",
54
- "@orpc/standard-server": "1.1.1",
55
- "@orpc/shared": "1.1.1"
50
+ "@orpc/client": "1.2.0",
51
+ "@orpc/contract": "1.2.0",
52
+ "@orpc/openapi-client": "1.2.0",
53
+ "@orpc/server": "1.2.0",
54
+ "@orpc/standard-server": "1.2.0",
55
+ "@orpc/shared": "1.2.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "zod": "^3.24.2"