@orpc/openapi 0.0.0-next.8f9385e → 0.0.0-next.97446ff
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/dist/chunk-CMRY2Z4J.js +54 -0
- package/dist/fetch.js +74 -46
- package/dist/index.js +403 -240
- package/dist/src/fetch/base-handler.d.ts +5 -7
- package/dist/src/generator.d.ts +3 -3
- package/dist/src/utils.d.ts +17 -0
- package/dist/src/zod-to-json-schema.d.ts +2 -2
- package/package.json +8 -7
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// src/utils.ts
|
|
2
|
+
import { isContractProcedure } from "@orpc/contract";
|
|
3
|
+
import { flatLazy, getRouterContract, isLazy, isProcedure } from "@orpc/server";
|
|
4
|
+
function eachContractProcedureLeaf(options, callback, result = [], isCurrentRouterContract = false) {
|
|
5
|
+
const hiddenContract = getRouterContract(options.router);
|
|
6
|
+
if (!isCurrentRouterContract && hiddenContract) {
|
|
7
|
+
return eachContractProcedureLeaf(
|
|
8
|
+
{
|
|
9
|
+
path: options.path,
|
|
10
|
+
router: hiddenContract
|
|
11
|
+
},
|
|
12
|
+
callback,
|
|
13
|
+
result,
|
|
14
|
+
true
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
if (isLazy(options.router)) {
|
|
18
|
+
result.push({
|
|
19
|
+
lazy: flatLazy(options.router),
|
|
20
|
+
path: options.path
|
|
21
|
+
});
|
|
22
|
+
} else if (isProcedure(options.router)) {
|
|
23
|
+
callback({
|
|
24
|
+
contract: options.router["~orpc"].contract,
|
|
25
|
+
path: options.path
|
|
26
|
+
});
|
|
27
|
+
} else if (isContractProcedure(options.router)) {
|
|
28
|
+
callback({
|
|
29
|
+
contract: options.router,
|
|
30
|
+
path: options.path
|
|
31
|
+
});
|
|
32
|
+
} else {
|
|
33
|
+
for (const key in options.router) {
|
|
34
|
+
eachContractProcedureLeaf(
|
|
35
|
+
{
|
|
36
|
+
router: options.router[key],
|
|
37
|
+
path: [...options.path, key]
|
|
38
|
+
},
|
|
39
|
+
callback,
|
|
40
|
+
result
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
function standardizeHTTPPath(path) {
|
|
47
|
+
return `/${path.replace(/\/{2,}/g, "/").replace(/^\/|\/$/g, "")}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export {
|
|
51
|
+
eachContractProcedureLeaf,
|
|
52
|
+
standardizeHTTPPath
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=chunk-CMRY2Z4J.js.map
|
package/dist/fetch.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
eachContractProcedureLeaf,
|
|
3
|
+
standardizeHTTPPath
|
|
4
|
+
} from "./chunk-CMRY2Z4J.js";
|
|
5
|
+
|
|
1
6
|
// src/fetch/base-handler.ts
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { isPlainObject, mapValues, trim, value } from "@orpc/shared";
|
|
7
|
+
import { createProcedureClient, getLazyRouterPrefix, getRouterChild, isProcedure, LAZY_LOADER_SYMBOL, ORPCError, unlazy } from "@orpc/server";
|
|
8
|
+
import { executeWithHooks, isPlainObject, mapValues, ORPC_PROTOCOL_HEADER, ORPC_PROTOCOL_VALUE, trim, value } from "@orpc/shared";
|
|
5
9
|
import { OpenAPIDeserializer, OpenAPISerializer, zodCoerce } from "@orpc/transformer";
|
|
6
10
|
function createOpenAPIHandler(createHonoRouter) {
|
|
7
11
|
const resolveRouter = createResolveRouter(createHonoRouter);
|
|
8
12
|
return async (options) => {
|
|
9
|
-
if (options.request.headers.get(
|
|
13
|
+
if (options.request.headers.get(ORPC_PROTOCOL_HEADER)?.includes(ORPC_PROTOCOL_VALUE)) {
|
|
10
14
|
return void 0;
|
|
11
15
|
}
|
|
12
16
|
const context = await value(options.context);
|
|
@@ -17,25 +21,24 @@ function createOpenAPIHandler(createHonoRouter) {
|
|
|
17
21
|
const pathname = `/${trim(url.pathname.replace(options.prefix ?? "", ""), "/")}`;
|
|
18
22
|
const customMethod = options.request.method === "POST" ? url.searchParams.get("method")?.toUpperCase() : void 0;
|
|
19
23
|
const method = customMethod || options.request.method;
|
|
20
|
-
const match = resolveRouter(options.router, method, pathname);
|
|
24
|
+
const match = await resolveRouter(options.router, method, pathname);
|
|
21
25
|
if (!match) {
|
|
22
26
|
throw new ORPCError({ code: "NOT_FOUND", message: "Not found" });
|
|
23
27
|
}
|
|
24
|
-
const procedure = match
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
procedure.zz$p.contract.zz$cp.InputSchema,
|
|
28
|
+
const { path, procedure } = match;
|
|
29
|
+
const params = procedure["~orpc"].contract["~orpc"].InputSchema ? zodCoerce(
|
|
30
|
+
procedure["~orpc"].contract["~orpc"].InputSchema,
|
|
28
31
|
match.params,
|
|
29
32
|
{ bracketNotation: true }
|
|
30
33
|
) : match.params;
|
|
31
34
|
const input = await deserializeInput(options.request, procedure);
|
|
32
35
|
const mergedInput = mergeParamsAndInput(params, input);
|
|
33
|
-
const caller =
|
|
36
|
+
const caller = createProcedureClient({
|
|
34
37
|
context,
|
|
35
38
|
procedure,
|
|
36
39
|
path
|
|
37
40
|
});
|
|
38
|
-
const output = await caller(mergedInput);
|
|
41
|
+
const output = await caller(mergedInput, { signal: options.signal });
|
|
39
42
|
const { body, headers } = serializer.serialize(output);
|
|
40
43
|
return new Response(body, {
|
|
41
44
|
status: 200,
|
|
@@ -43,10 +46,15 @@ function createOpenAPIHandler(createHonoRouter) {
|
|
|
43
46
|
});
|
|
44
47
|
};
|
|
45
48
|
try {
|
|
46
|
-
return await
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
return await executeWithHooks({
|
|
50
|
+
context,
|
|
51
|
+
hooks: options,
|
|
52
|
+
execute: handler,
|
|
53
|
+
input: options.request,
|
|
54
|
+
meta: {
|
|
55
|
+
signal: options.signal
|
|
56
|
+
}
|
|
57
|
+
});
|
|
50
58
|
} catch (e) {
|
|
51
59
|
const error = toORPCError(e);
|
|
52
60
|
try {
|
|
@@ -69,27 +77,45 @@ function createOpenAPIHandler(createHonoRouter) {
|
|
|
69
77
|
};
|
|
70
78
|
}
|
|
71
79
|
var routingCache = /* @__PURE__ */ new Map();
|
|
80
|
+
var pendingCache = /* @__PURE__ */ new Map();
|
|
72
81
|
function createResolveRouter(createHonoRouter) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
routingCache.
|
|
82
|
+
const addRoutes = (routing, pending, options) => {
|
|
83
|
+
const lazies = eachContractProcedureLeaf(options, ({ path, contract }) => {
|
|
84
|
+
const method = contract["~orpc"].route?.method ?? "POST";
|
|
85
|
+
const httpPath = contract["~orpc"].route?.path ? openAPIPathToRouterPath(contract["~orpc"].route?.path) : `/${path.map(encodeURIComponent).join("/")}`;
|
|
86
|
+
routing.add(method, httpPath, path);
|
|
87
|
+
});
|
|
88
|
+
pending.ref.push(...lazies);
|
|
89
|
+
};
|
|
90
|
+
return async (router, method, pathname) => {
|
|
91
|
+
const pending = (() => {
|
|
92
|
+
let pending2 = pendingCache.get(router);
|
|
93
|
+
if (!pending2) {
|
|
94
|
+
pending2 = { ref: [] };
|
|
95
|
+
pendingCache.set(router, pending2);
|
|
96
|
+
}
|
|
97
|
+
return pending2;
|
|
98
|
+
})();
|
|
99
|
+
const routing = (() => {
|
|
100
|
+
let routing2 = routingCache.get(router);
|
|
101
|
+
if (!routing2) {
|
|
102
|
+
routing2 = createHonoRouter();
|
|
103
|
+
routingCache.set(router, routing2);
|
|
104
|
+
addRoutes(routing2, pending, { router, path: [] });
|
|
105
|
+
}
|
|
106
|
+
return routing2;
|
|
107
|
+
})();
|
|
108
|
+
const newPending = [];
|
|
109
|
+
for (const item of pending.ref) {
|
|
110
|
+
const lazyPrefix = getLazyRouterPrefix(item.lazy);
|
|
111
|
+
if (lazyPrefix && !pathname.startsWith(lazyPrefix) && !pathname.startsWith(`/${item.path.map(encodeURIComponent).join("/")}`)) {
|
|
112
|
+
newPending.push(item);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const router2 = (await item.lazy[LAZY_LOADER_SYMBOL]()).default;
|
|
116
|
+
addRoutes(routing, pending, { path: item.path, router: router2 });
|
|
92
117
|
}
|
|
118
|
+
pending.ref = newPending;
|
|
93
119
|
const [matches, params_] = routing.match(method, pathname);
|
|
94
120
|
const [match] = matches.sort((a, b) => {
|
|
95
121
|
return Object.keys(a[1]).length - Object.keys(b[1]).length;
|
|
@@ -97,15 +123,18 @@ function createResolveRouter(createHonoRouter) {
|
|
|
97
123
|
if (!match) {
|
|
98
124
|
return void 0;
|
|
99
125
|
}
|
|
100
|
-
const path = match[0]
|
|
101
|
-
const procedure = match[0][1];
|
|
126
|
+
const path = match[0];
|
|
102
127
|
const params = params_ ? mapValues(
|
|
103
128
|
match[1],
|
|
104
129
|
(v) => params_[v]
|
|
105
130
|
) : match[1];
|
|
131
|
+
const { default: maybeProcedure } = await unlazy(getRouterChild(router, ...path));
|
|
132
|
+
if (!isProcedure(maybeProcedure)) {
|
|
133
|
+
return void 0;
|
|
134
|
+
}
|
|
106
135
|
return {
|
|
107
136
|
path,
|
|
108
|
-
procedure,
|
|
137
|
+
procedure: maybeProcedure,
|
|
109
138
|
params: { ...params }
|
|
110
139
|
// params from hono not a normal object, so we need spread here
|
|
111
140
|
};
|
|
@@ -125,7 +154,7 @@ function mergeParamsAndInput(coercedParams, input) {
|
|
|
125
154
|
}
|
|
126
155
|
async function deserializeInput(request, procedure) {
|
|
127
156
|
const deserializer = new OpenAPIDeserializer({
|
|
128
|
-
schema: procedure.
|
|
157
|
+
schema: procedure["~orpc"].contract["~orpc"].InputSchema
|
|
129
158
|
});
|
|
130
159
|
try {
|
|
131
160
|
return await deserializer.deserialize(request);
|
|
@@ -148,13 +177,13 @@ function openAPIPathToRouterPath(path) {
|
|
|
148
177
|
return standardizeHTTPPath(path).replace(/\{([^}]+)\}/g, ":$1");
|
|
149
178
|
}
|
|
150
179
|
|
|
151
|
-
// ../../node_modules/.pnpm/hono@4.6.
|
|
180
|
+
// ../../node_modules/.pnpm/hono@4.6.13/node_modules/hono/dist/router.js
|
|
152
181
|
var METHOD_NAME_ALL = "ALL";
|
|
153
182
|
var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
|
|
154
183
|
var UnsupportedPathError = class extends Error {
|
|
155
184
|
};
|
|
156
185
|
|
|
157
|
-
// ../../node_modules/.pnpm/hono@4.6.
|
|
186
|
+
// ../../node_modules/.pnpm/hono@4.6.13/node_modules/hono/dist/utils/url.js
|
|
158
187
|
var checkOptionalParameter = (path) => {
|
|
159
188
|
if (!path.match(/\:.+\?$/)) {
|
|
160
189
|
return null;
|
|
@@ -183,7 +212,7 @@ var checkOptionalParameter = (path) => {
|
|
|
183
212
|
return results.filter((v, i, a) => a.indexOf(v) === i);
|
|
184
213
|
};
|
|
185
214
|
|
|
186
|
-
// ../../node_modules/.pnpm/hono@4.6.
|
|
215
|
+
// ../../node_modules/.pnpm/hono@4.6.13/node_modules/hono/dist/router/reg-exp-router/node.js
|
|
187
216
|
var LABEL_REG_EXP_STR = "[^/]+";
|
|
188
217
|
var ONLY_WILDCARD_REG_EXP_STR = ".*";
|
|
189
218
|
var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
|
|
@@ -288,7 +317,7 @@ var Node = class {
|
|
|
288
317
|
}
|
|
289
318
|
};
|
|
290
319
|
|
|
291
|
-
// ../../node_modules/.pnpm/hono@4.6.
|
|
320
|
+
// ../../node_modules/.pnpm/hono@4.6.13/node_modules/hono/dist/router/reg-exp-router/trie.js
|
|
292
321
|
var Trie = class {
|
|
293
322
|
#context = { varIndex: 0 };
|
|
294
323
|
#root = new Node();
|
|
@@ -344,7 +373,7 @@ var Trie = class {
|
|
|
344
373
|
}
|
|
345
374
|
};
|
|
346
375
|
|
|
347
|
-
// ../../node_modules/.pnpm/hono@4.6.
|
|
376
|
+
// ../../node_modules/.pnpm/hono@4.6.13/node_modules/hono/dist/router/reg-exp-router/router.js
|
|
348
377
|
var emptyParam = [];
|
|
349
378
|
var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
|
|
350
379
|
var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
@@ -545,7 +574,7 @@ function createOpenAPIServerHandler() {
|
|
|
545
574
|
return createOpenAPIHandler(() => new RegExpRouter());
|
|
546
575
|
}
|
|
547
576
|
|
|
548
|
-
// ../../node_modules/.pnpm/hono@4.6.
|
|
577
|
+
// ../../node_modules/.pnpm/hono@4.6.13/node_modules/hono/dist/router/linear-router/router.js
|
|
549
578
|
var emptyParams = /* @__PURE__ */ Object.create(null);
|
|
550
579
|
var splitPathRe = /\/(:\w+(?:{(?:(?:{[\d,]+})|[^}])+})?)|\/[^\/\?]+|(\?)/g;
|
|
551
580
|
var splitByStarRe = /\*/;
|
|
@@ -663,7 +692,6 @@ export {
|
|
|
663
692
|
createOpenAPIHandler,
|
|
664
693
|
createOpenAPIServerHandler,
|
|
665
694
|
createOpenAPIServerlessHandler,
|
|
666
|
-
createResolveRouter
|
|
667
|
-
openAPIPathToRouterPath
|
|
695
|
+
createResolveRouter
|
|
668
696
|
};
|
|
669
697
|
//# sourceMappingURL=fetch.js.map
|