@orpc/openapi 0.0.0-next.e6490f2 → 0.0.0-next.e77ba7d

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 (33) hide show
  1. package/README.md +7 -2
  2. package/dist/adapters/aws-lambda/index.d.mts +6 -3
  3. package/dist/adapters/aws-lambda/index.d.ts +6 -3
  4. package/dist/adapters/aws-lambda/index.mjs +3 -3
  5. package/dist/adapters/fastify/index.d.mts +23 -0
  6. package/dist/adapters/fastify/index.d.ts +23 -0
  7. package/dist/adapters/fastify/index.mjs +18 -0
  8. package/dist/adapters/fetch/index.d.mts +9 -3
  9. package/dist/adapters/fetch/index.d.ts +9 -3
  10. package/dist/adapters/fetch/index.mjs +1 -1
  11. package/dist/adapters/node/index.d.mts +9 -3
  12. package/dist/adapters/node/index.d.ts +9 -3
  13. package/dist/adapters/node/index.mjs +1 -1
  14. package/dist/adapters/standard/index.d.mts +8 -23
  15. package/dist/adapters/standard/index.d.ts +8 -23
  16. package/dist/adapters/standard/index.mjs +1 -1
  17. package/dist/index.d.mts +9 -2
  18. package/dist/index.d.ts +9 -2
  19. package/dist/index.mjs +2 -2
  20. package/dist/plugins/index.d.mts +18 -3
  21. package/dist/plugins/index.d.ts +18 -3
  22. package/dist/plugins/index.mjs +58 -18
  23. package/dist/shared/{openapi.C_UtQ8Us.mjs → openapi.DIt-Z9W1.mjs} +19 -8
  24. package/dist/shared/{openapi.DaYgbD_w.mjs → openapi.DNv9yFfn.mjs} +269 -68
  25. package/dist/shared/openapi.DwaweYRb.d.mts +54 -0
  26. package/dist/shared/openapi.DwaweYRb.d.ts +54 -0
  27. package/dist/shared/openapi.dbQeFCUJ.d.mts +120 -0
  28. package/dist/shared/openapi.dbQeFCUJ.d.ts +120 -0
  29. package/package.json +17 -10
  30. package/dist/shared/openapi.D3j94c9n.d.mts +0 -12
  31. package/dist/shared/openapi.D3j94c9n.d.ts +0 -12
  32. package/dist/shared/openapi.qZLdpE0a.d.mts +0 -52
  33. package/dist/shared/openapi.qZLdpE0a.d.ts +0 -52
@@ -1,5 +1,5 @@
1
1
  import { stringifyJSON, once, value } from '@orpc/shared';
2
- import { O as OpenAPIGenerator } from '../shared/openapi.DaYgbD_w.mjs';
2
+ import { O as OpenAPIGenerator } from '../shared/openapi.DNv9yFfn.mjs';
3
3
  import '@orpc/client';
4
4
  import '@orpc/client/standard';
5
5
  import '@orpc/contract';
@@ -14,7 +14,9 @@ class OpenAPIReferencePlugin {
14
14
  docsPath;
15
15
  docsTitle;
16
16
  docsHead;
17
+ docsProvider;
17
18
  docsScriptUrl;
19
+ docsCssUrl;
18
20
  docsConfig;
19
21
  renderDocsHtml;
20
22
  constructor(options = {}) {
@@ -22,16 +24,59 @@ class OpenAPIReferencePlugin {
22
24
  this.docsPath = options.docsPath ?? "/";
23
25
  this.docsTitle = options.docsTitle ?? "API Reference";
24
26
  this.docsConfig = options.docsConfig ?? void 0;
25
- this.docsScriptUrl = options.docsScriptUrl ?? "https://cdn.jsdelivr.net/npm/@scalar/api-reference";
27
+ this.docsProvider = options.docsProvider ?? "scalar";
28
+ this.docsScriptUrl = options.docsScriptUrl ?? (this.docsProvider === "swagger" ? "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js" : "https://cdn.jsdelivr.net/npm/@scalar/api-reference");
29
+ this.docsCssUrl = options.docsCssUrl ?? (this.docsProvider === "swagger" ? "https://unpkg.com/swagger-ui-dist/swagger-ui.css" : void 0);
26
30
  this.docsHead = options.docsHead ?? "";
27
31
  this.specPath = options.specPath ?? "/spec.json";
28
32
  this.generator = new OpenAPIGenerator(options);
29
33
  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, spec) => {
31
- const finalConfig = {
32
- content: stringifyJSON(spec),
33
- ...config
34
- };
34
+ this.renderDocsHtml = options.renderDocsHtml ?? ((specUrl, title, head, scriptUrl, config, spec, docsProvider, cssUrl) => {
35
+ let body;
36
+ if (docsProvider === "swagger") {
37
+ const swaggerConfig = {
38
+ dom_id: "#app",
39
+ spec,
40
+ deepLinking: true,
41
+ presets: [
42
+ "SwaggerUIBundle.presets.apis",
43
+ "SwaggerUIBundle.presets.standalone"
44
+ ],
45
+ plugins: [
46
+ "SwaggerUIBundle.plugins.DownloadUrl"
47
+ ],
48
+ ...config
49
+ };
50
+ body = `
51
+ <body>
52
+ <div id="app"></div>
53
+
54
+ <script src="${esc(scriptUrl)}"><\/script>
55
+
56
+ <script>
57
+ window.onload = () => {
58
+ window.ui = SwaggerUIBundle(${stringifyJSON(swaggerConfig).replace(/"(SwaggerUIBundle\.[^"]+)"/g, "$1")})
59
+ }
60
+ <\/script>
61
+ </body>
62
+ `;
63
+ } else {
64
+ const scalarConfig = {
65
+ content: stringifyJSON(spec),
66
+ ...config
67
+ };
68
+ body = `
69
+ <body>
70
+ <div id="app" data-config="${esc(stringifyJSON(scalarConfig))}"></div>
71
+
72
+ <script src="${esc(scriptUrl)}"><\/script>
73
+
74
+ <script>
75
+ Scalar.createApiReference('#app', JSON.parse(document.getElementById('app').dataset.config))
76
+ <\/script>
77
+ </body>
78
+ `;
79
+ }
35
80
  return `
36
81
  <!doctype html>
37
82
  <html>
@@ -39,19 +84,12 @@ class OpenAPIReferencePlugin {
39
84
  <meta charset="utf-8" />
40
85
  <meta name="viewport" content="width=device-width, initial-scale=1" />
41
86
  <title>${esc(title)}</title>
87
+ ${cssUrl ? `<link rel="stylesheet" type="text/css" href="${esc(cssUrl)}" />` : ""}
42
88
  ${head}
43
89
  </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>
90
+ ${body}
53
91
  </html>
54
- `;
92
+ `;
55
93
  });
56
94
  }
57
95
  init(options, router) {
@@ -89,7 +127,9 @@ class OpenAPIReferencePlugin {
89
127
  await value(this.docsHead, options2),
90
128
  await value(this.docsScriptUrl, options2),
91
129
  await value(this.docsConfig, options2),
92
- await generateSpec()
130
+ await generateSpec(),
131
+ this.docsProvider,
132
+ await value(this.docsCssUrl, options2)
93
133
  );
94
134
  return {
95
135
  matched: true,
@@ -2,15 +2,17 @@ import { standardizeHTTPPath, StandardOpenAPIJsonSerializer, StandardBracketNota
2
2
  import { StandardHandler } from '@orpc/server/standard';
3
3
  import { isORPCErrorStatus } from '@orpc/client';
4
4
  import { fallbackContractConfig } from '@orpc/contract';
5
- import { isObject, stringifyJSON } from '@orpc/shared';
5
+ import { isObject, stringifyJSON, tryDecodeURIComponent, value } from '@orpc/shared';
6
6
  import { toHttpPath } from '@orpc/client/standard';
7
7
  import { traverseContractProcedures, isProcedure, getLazyMeta, unlazy, getRouter, createContractedProcedure } from '@orpc/server';
8
8
  import { createRouter, addRoute, findRoute } from 'rou3';
9
9
 
10
10
  class StandardOpenAPICodec {
11
- constructor(serializer) {
11
+ constructor(serializer, options = {}) {
12
12
  this.serializer = serializer;
13
+ this.customErrorResponseBodyEncoder = options.customErrorResponseBodyEncoder;
13
14
  }
15
+ customErrorResponseBodyEncoder;
14
16
  async decode(request, params, procedure) {
15
17
  const inputStructure = fallbackContractConfig("defaultInputStructure", procedure["~orpc"].route.inputStructure);
16
18
  if (inputStructure === "compact") {
@@ -73,10 +75,11 @@ class StandardOpenAPICodec {
73
75
  };
74
76
  }
75
77
  encodeError(error) {
78
+ const body = this.customErrorResponseBodyEncoder?.(error) ?? error.toJSON();
76
79
  return {
77
80
  status: error.status,
78
81
  headers: {},
79
- body: this.serializer.serialize(error.toJSON(), { outputFormat: "plain" })
82
+ body: this.serializer.serialize(body, { outputFormat: "plain" })
80
83
  };
81
84
  }
82
85
  #isDetailedOutput(output) {
@@ -97,14 +100,22 @@ function toRou3Pattern(path) {
97
100
  return standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/**:$1").replace(/\/\{([^}]+)\}/g, "/:$1");
98
101
  }
99
102
  function decodeParams(params) {
100
- return Object.fromEntries(Object.entries(params).map(([key, value]) => [key, decodeURIComponent(value)]));
103
+ return Object.fromEntries(Object.entries(params).map(([key, value]) => [key, tryDecodeURIComponent(value)]));
101
104
  }
102
105
 
103
106
  class StandardOpenAPIMatcher {
107
+ filter;
104
108
  tree = createRouter();
105
109
  pendingRouters = [];
110
+ constructor(options = {}) {
111
+ this.filter = options.filter ?? true;
112
+ }
106
113
  init(router, path = []) {
107
- const laziedOptions = traverseContractProcedures({ router, path }, ({ path: path2, contract }) => {
114
+ const laziedOptions = traverseContractProcedures({ router, path }, (traverseOptions) => {
115
+ if (!value(this.filter, traverseOptions)) {
116
+ return;
117
+ }
118
+ const { path: path2, contract } = traverseOptions;
108
119
  const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route.method);
109
120
  const httpPath = toRou3Pattern(contract["~orpc"].route.path ?? toHttpPath(path2));
110
121
  if (isProcedure(contract)) {
@@ -168,10 +179,10 @@ class StandardOpenAPIMatcher {
168
179
  class StandardOpenAPIHandler extends StandardHandler {
169
180
  constructor(router, options) {
170
181
  const jsonSerializer = new StandardOpenAPIJsonSerializer(options);
171
- const bracketNotationSerializer = new StandardBracketNotationSerializer();
182
+ const bracketNotationSerializer = new StandardBracketNotationSerializer(options);
172
183
  const serializer = new StandardOpenAPISerializer(jsonSerializer, bracketNotationSerializer);
173
- const matcher = new StandardOpenAPIMatcher();
174
- const codec = new StandardOpenAPICodec(serializer);
184
+ const matcher = new StandardOpenAPIMatcher(options);
185
+ const codec = new StandardOpenAPICodec(serializer, options);
175
186
  super(router, matcher, codec, options);
176
187
  }
177
188
  }