@relkit/client-generator 0.0.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.
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/generate-contract.d.ts +14 -0
- package/dist/generate-contract.d.ts.map +1 -0
- package/dist/generate-contract.js +91 -0
- package/dist/generate-contract.js.map +1 -0
- package/dist/generate-request.d.ts +9 -0
- package/dist/generate-request.d.ts.map +1 -0
- package/dist/generate-request.js +144 -0
- package/dist/generate-request.js.map +1 -0
- package/dist/generate-schema.d.ts +5 -0
- package/dist/generate-schema.d.ts.map +1 -0
- package/dist/generate-schema.js +110 -0
- package/dist/generate-schema.js.map +1 -0
- package/dist/generate-types.d.ts +34 -0
- package/dist/generate-types.d.ts.map +1 -0
- package/dist/generate-types.js +104 -0
- package/dist/generate-types.js.map +1 -0
- package/dist/generate.d.ts +6 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +13 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/input-tree.d.ts +14 -0
- package/dist/input-tree.d.ts.map +1 -0
- package/dist/input-tree.js +27 -0
- package/dist/input-tree.js.map +1 -0
- package/dist/route-parameters.d.ts +8 -0
- package/dist/route-parameters.d.ts.map +1 -0
- package/dist/route-parameters.js +16 -0
- package/dist/route-parameters.js.map +1 -0
- package/package.json +40 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 rel-kit
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ApplicationGraph } from "@relkit/graph";
|
|
2
|
+
export declare function generateContract(graph: ApplicationGraph): string;
|
|
3
|
+
export interface ContractProcedureDocument {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly input: unknown;
|
|
6
|
+
readonly output: unknown;
|
|
7
|
+
readonly errors: readonly {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly schema: unknown;
|
|
10
|
+
}[];
|
|
11
|
+
}
|
|
12
|
+
export declare function generateContractFromDocument(procedures: readonly ContractProcedureDocument[]): string;
|
|
13
|
+
export declare function generateClientContractDocument(graph: ApplicationGraph, graphHash: string): string;
|
|
14
|
+
//# sourceMappingURL=generate-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-contract.d.ts","sourceRoot":"","sources":["../src/generate-contract.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAShE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CAC/E;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,SAAS,yBAAyB,EAAE,GAC/C,MAAM,CA0CR;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmBjG"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { canonicalJson, CONTRACT_VERSION } from "@relkit/contracts";
|
|
2
|
+
import { clientRoutes } from "./generate-types.js";
|
|
3
|
+
import { schemaType } from "./generate-schema.js";
|
|
4
|
+
export function generateContract(graph) {
|
|
5
|
+
return generateContractFromDocument(clientRoutes(graph).map((route) => ({
|
|
6
|
+
name: route.trigger.id,
|
|
7
|
+
input: route.target.input,
|
|
8
|
+
output: route.target.output,
|
|
9
|
+
errors: errors(route.target.errors),
|
|
10
|
+
})));
|
|
11
|
+
}
|
|
12
|
+
export function generateContractFromDocument(procedures) {
|
|
13
|
+
const entries = [...procedures]
|
|
14
|
+
.sort((left, right) => left.name.localeCompare(right.name))
|
|
15
|
+
.map((procedure) => {
|
|
16
|
+
const errorMap = procedure.errors.map((entry) => `${JSON.stringify(entry.id)}: { data: schema<${schemaType(entry.schema)}>() }`);
|
|
17
|
+
const builder = [
|
|
18
|
+
"oc",
|
|
19
|
+
errorMap.length === 0 ? "" : `.errors({ ${errorMap.join(", ")} })`,
|
|
20
|
+
`.input(schema<${schemaType(procedure.input)}>())`,
|
|
21
|
+
`.output(schema<${schemaType(procedure.output)}>())`,
|
|
22
|
+
].join("");
|
|
23
|
+
return ` ${JSON.stringify(procedure.name)}: ${builder},`;
|
|
24
|
+
});
|
|
25
|
+
return [
|
|
26
|
+
"/* generated by @relkit/client-generator; do not edit */",
|
|
27
|
+
'import { oc } from "@orpc/contract";',
|
|
28
|
+
"",
|
|
29
|
+
"function schema<Value>() {",
|
|
30
|
+
" return {",
|
|
31
|
+
' "~standard": {',
|
|
32
|
+
" version: 1 as const,",
|
|
33
|
+
' vendor: "relkit-contract",',
|
|
34
|
+
" types: undefined as unknown as { input: Value; output: Value },",
|
|
35
|
+
" validate: (value: unknown) => ({ value: value as Value }),",
|
|
36
|
+
" },",
|
|
37
|
+
" };",
|
|
38
|
+
"}",
|
|
39
|
+
"",
|
|
40
|
+
"export const contract = {",
|
|
41
|
+
...entries,
|
|
42
|
+
"} as const;",
|
|
43
|
+
"export default contract;",
|
|
44
|
+
"",
|
|
45
|
+
'declare module "@relkit/client" {',
|
|
46
|
+
" interface DefaultContractRegistry {",
|
|
47
|
+
" readonly contract: typeof contract;",
|
|
48
|
+
" }",
|
|
49
|
+
"}",
|
|
50
|
+
"",
|
|
51
|
+
].join("\n");
|
|
52
|
+
}
|
|
53
|
+
export function generateClientContractDocument(graph, graphHash) {
|
|
54
|
+
const procedures = clientRoutes(graph).map((route) => ({
|
|
55
|
+
name: route.trigger.id,
|
|
56
|
+
routeId: route.trigger.id,
|
|
57
|
+
functionId: route.target.id,
|
|
58
|
+
input: route.target.input,
|
|
59
|
+
output: route.target.output,
|
|
60
|
+
errors: errorDocuments(route.target.errors, route.responses),
|
|
61
|
+
route: {
|
|
62
|
+
method: route.trigger.config.method,
|
|
63
|
+
path: route.trigger.config.path,
|
|
64
|
+
},
|
|
65
|
+
}));
|
|
66
|
+
return `${canonicalJson({
|
|
67
|
+
protocol: "relkit.client-contract",
|
|
68
|
+
version: CONTRACT_VERSION,
|
|
69
|
+
graphHash,
|
|
70
|
+
procedures,
|
|
71
|
+
})}\n`;
|
|
72
|
+
}
|
|
73
|
+
function errorDocuments(value, responses) {
|
|
74
|
+
return errors(value).map((entry) => ({
|
|
75
|
+
id: entry.id,
|
|
76
|
+
schema: entry.schema,
|
|
77
|
+
status: responses.find((response) => response.errorId === entry.id)?.status ?? 500,
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
function errors(value) {
|
|
81
|
+
return (Array.isArray(value) ? value : []).flatMap((entry) => {
|
|
82
|
+
if (!isRecord(entry) || typeof entry.id !== "string")
|
|
83
|
+
return [];
|
|
84
|
+
const data = isRecord(entry.data) && isRecord(entry.data.jsonSchema) ? entry.data.jsonSchema : entry.data;
|
|
85
|
+
return [{ id: entry.id, schema: data ?? {} }];
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function isRecord(value) {
|
|
89
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=generate-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-contract.js","sourceRoot":"","sources":["../src/generate-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ClientRoute } from "./generate-types.js";
|
|
2
|
+
export interface RouteMethodNames {
|
|
3
|
+
readonly method: string;
|
|
4
|
+
readonly type: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function routeMethod(route: ClientRoute, names: RouteMethodNames): string[];
|
|
7
|
+
export declare function acceptsMissingInput(route: ClientRoute): boolean;
|
|
8
|
+
export declare function runtimeHelpers(): string[];
|
|
9
|
+
//# sourceMappingURL=generate-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-request.d.ts","sourceRoot":"","sources":["../src/generate-request.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,qBAAqB,CAAC;AAGpE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAoBjF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAU/D;AAED,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAiDzC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { canonicalJson } from "@relkit/contracts";
|
|
2
|
+
import { routeParameters } from "./route-parameters.js";
|
|
3
|
+
export function routeMethod(route, names) {
|
|
4
|
+
const optional = acceptsMissingInput(route);
|
|
5
|
+
const lines = [
|
|
6
|
+
` async ${names.method}(input${optional ? `: ${names.type}Input = {} as ${names.type}Input` : `: ${names.type}Input`}) {`,
|
|
7
|
+
` let path = ${JSON.stringify(route.trigger.config.path)};`,
|
|
8
|
+
];
|
|
9
|
+
lines.push(...pathStatements(route));
|
|
10
|
+
lines.push(" const query = new URLSearchParams();", ...queryStatements(route), " const queryString = query.toString();", ' const url = joinUrl(baseUrl, path) + (queryString === "" ? "" : `?${queryString}`);', " const headers: Record<string, string> = {};", ...headerStatements(route), ...bodyStatements(route), ` const result = await request(fetcher, url, { method: ${JSON.stringify(route.trigger.config.method)}, headers, ...(${hasBody(route) ? "requestBody === undefined ? {} : { body: requestBody }" : "{}"}) });`, ` return result as ${names.type}Result;`, " },");
|
|
11
|
+
return lines;
|
|
12
|
+
}
|
|
13
|
+
export function acceptsMissingInput(route) {
|
|
14
|
+
const requiredUnmappedPath = routeParameters(route.trigger.config.path).some((parameter) => !parameter.optional &&
|
|
15
|
+
!route.fields.some((field) => field.kind === parameter.kind && field.name === parameter.name));
|
|
16
|
+
return (!requiredUnmappedPath &&
|
|
17
|
+
route.fields.every((field) => field.kind === "constant" || field.optional || field.defaulted));
|
|
18
|
+
}
|
|
19
|
+
export function runtimeHelpers() {
|
|
20
|
+
return [
|
|
21
|
+
"function joinUrl(baseUrl: string, path: string): string {",
|
|
22
|
+
' return baseUrl.replace(/\\/+$/, "") + (path.startsWith("/") ? path : `/${path}`);',
|
|
23
|
+
"}",
|
|
24
|
+
"function readPath(value: unknown, path: readonly string[]): unknown {",
|
|
25
|
+
" let current = value;",
|
|
26
|
+
" for (const key of path) {",
|
|
27
|
+
' if (current === null || typeof current !== "object") return undefined;',
|
|
28
|
+
" current = (current as Record<string, unknown>)[key];",
|
|
29
|
+
" }",
|
|
30
|
+
" return current;",
|
|
31
|
+
"}",
|
|
32
|
+
"function setBodyValue(target: Record<string, unknown>, path: readonly string[], value: unknown): void {",
|
|
33
|
+
" if (value === undefined || path.length === 0) return;",
|
|
34
|
+
" let current = target;",
|
|
35
|
+
" for (const key of path.slice(0, -1)) {",
|
|
36
|
+
' const next = current[key]; current = (next && typeof next === "object" && !Array.isArray(next) ? next : (current[key] = {})) as Record<string, unknown>;',
|
|
37
|
+
" }",
|
|
38
|
+
" current[path[path.length - 1]!] = value;",
|
|
39
|
+
"}",
|
|
40
|
+
"function appendQuery(query: URLSearchParams, name: string, value: unknown): void {",
|
|
41
|
+
" if (value === undefined) return;",
|
|
42
|
+
" if (Array.isArray(value)) value.forEach((item) => query.append(name, String(item)));",
|
|
43
|
+
" else query.append(name, String(value));",
|
|
44
|
+
"}",
|
|
45
|
+
"function setHeader(headers: Record<string, string>, name: string, value: unknown): void {",
|
|
46
|
+
" if (value !== undefined) headers[name] = String(value);",
|
|
47
|
+
"}",
|
|
48
|
+
"function replacePathSegments(path: string, token: string, value: unknown): string {",
|
|
49
|
+
' if ((value === undefined || (Array.isArray(value) && value.length === 0)) && token.endsWith("?")) return path.replace(`/\${token}`, "") || "/";',
|
|
50
|
+
' if (!Array.isArray(value) || value.length === 0) throw new TypeError(`Catch-all path "${token}" needs at least one segment`);',
|
|
51
|
+
' return path.replace(token, value.map((segment) => encodeURIComponent(String(segment))).join("/"));',
|
|
52
|
+
"}",
|
|
53
|
+
"function appendCookie(cookies: string[], name: string, value: unknown): void {",
|
|
54
|
+
" if (value !== undefined) cookies.push(`${name}=${encodeURIComponent(String(value))}`);",
|
|
55
|
+
"}",
|
|
56
|
+
"function appendFormValue(form: FormData, name: string, value: unknown): void {",
|
|
57
|
+
" if (Array.isArray(value)) { value.forEach((item) => appendFormValue(form, name, item)); return; }",
|
|
58
|
+
' if (value !== undefined) form.append(name, value instanceof Blob ? value : typeof value === "string" ? value : JSON.stringify(value));',
|
|
59
|
+
"}",
|
|
60
|
+
"async function request(fetcher: typeof globalThis.fetch, url: string, init: RequestInit): Promise<{ readonly status: number; readonly data: unknown }> {",
|
|
61
|
+
" const response = await fetcher(url, init);",
|
|
62
|
+
" const text = await response.text();",
|
|
63
|
+
" let data: unknown;",
|
|
64
|
+
' if (text !== "") { try { data = JSON.parse(text); } catch { data = text; } }',
|
|
65
|
+
" return { status: response.status, data };",
|
|
66
|
+
"}",
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
function pathStatements(route) {
|
|
70
|
+
return routeParameters(route.trigger.config.path).flatMap(({ segment, name, kind }) => {
|
|
71
|
+
const field = route.fields.find((entry) => entry.kind === kind && entry.name === name);
|
|
72
|
+
const path = field?.inputPath ?? [name];
|
|
73
|
+
if (kind === "path-segments") {
|
|
74
|
+
return [
|
|
75
|
+
` path = replacePathSegments(path, ${JSON.stringify(segment)}, readPath(input, ${canonicalJson(path)}));`,
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
return [
|
|
79
|
+
` path = path.replace(${JSON.stringify(segment)}, encodeURIComponent(String(readPath(input, ${canonicalJson(path)}))));`,
|
|
80
|
+
];
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function queryStatements(route) {
|
|
84
|
+
return route.fields
|
|
85
|
+
.filter((field) => field.kind === "query")
|
|
86
|
+
.map((field, index) => {
|
|
87
|
+
const path = canonicalJson(field.inputPath);
|
|
88
|
+
const name = JSON.stringify(field.name ?? field.outputPath.at(-1) ?? `query${index}`);
|
|
89
|
+
return ` appendQuery(query, ${name}, readPath(input, ${path}));`;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function headerStatements(route) {
|
|
93
|
+
const headers = route.fields.filter((field) => field.kind === "header");
|
|
94
|
+
const cookies = route.fields.filter((field) => field.kind === "cookie");
|
|
95
|
+
const lines = headers.map((field, index) => ` setHeader(headers, ${JSON.stringify(field.name ?? `header${index}`)}, readPath(input, ${canonicalJson(field.inputPath)}));`);
|
|
96
|
+
if (cookies.length > 0) {
|
|
97
|
+
lines.push(" const cookies: string[] = [];");
|
|
98
|
+
for (const [index, field] of cookies.entries())
|
|
99
|
+
lines.push(` appendCookie(cookies, ${JSON.stringify(field.name ?? `cookie${index}`)}, readPath(input, ${canonicalJson(field.inputPath)}));`);
|
|
100
|
+
lines.push(' if (cookies.length > 0) headers.cookie = cookies.join("; ");');
|
|
101
|
+
}
|
|
102
|
+
return lines;
|
|
103
|
+
}
|
|
104
|
+
function bodyStatements(route) {
|
|
105
|
+
if (!hasBody(route))
|
|
106
|
+
return [];
|
|
107
|
+
const fields = route.fields.filter(isBody);
|
|
108
|
+
const lines = [" let requestBody: string | FormData | undefined;"];
|
|
109
|
+
const whole = fields.filter((field) => field.kind === "whole-body");
|
|
110
|
+
if (whole.length === 1 && fields.length === 1) {
|
|
111
|
+
lines.push(` const wholeBody = readPath(input, ${canonicalJson(whole[0].inputPath)});`, " if (wholeBody !== undefined) requestBody = JSON.stringify(wholeBody);");
|
|
112
|
+
return lines;
|
|
113
|
+
}
|
|
114
|
+
if (fields.some((field) => field.kind === "multipart" || field.kind === "multipart-all")) {
|
|
115
|
+
lines.push(" const form = new FormData();");
|
|
116
|
+
for (const [index, field] of fields.entries()) {
|
|
117
|
+
const value = field.kind === "constant"
|
|
118
|
+
? literal(field.value)
|
|
119
|
+
: `readPath(input, ${canonicalJson(field.inputPath)})`;
|
|
120
|
+
lines.push(` appendFormValue(form, ${JSON.stringify(field.name ?? field.outputPath.at(-1) ?? `field${index}`)}, ${value});`);
|
|
121
|
+
}
|
|
122
|
+
lines.push(" requestBody = form;");
|
|
123
|
+
return lines;
|
|
124
|
+
}
|
|
125
|
+
lines.push(" const payload: Record<string, unknown> = {};");
|
|
126
|
+
for (const field of fields) {
|
|
127
|
+
const value = field.kind === "constant"
|
|
128
|
+
? literal(field.value)
|
|
129
|
+
: `readPath(input, ${canonicalJson(field.inputPath)})`;
|
|
130
|
+
lines.push(` setBodyValue(payload, ${canonicalJson(field.outputPath)}, ${value});`);
|
|
131
|
+
}
|
|
132
|
+
lines.push(' headers["content-type"] = "application/json";', " requestBody = JSON.stringify(payload);");
|
|
133
|
+
return lines;
|
|
134
|
+
}
|
|
135
|
+
function hasBody(route) {
|
|
136
|
+
return route.fields.some(isBody);
|
|
137
|
+
}
|
|
138
|
+
function isBody(field) {
|
|
139
|
+
return ["body", "whole-body", "multipart", "multipart-all", "constant"].includes(field.kind);
|
|
140
|
+
}
|
|
141
|
+
function literal(value) {
|
|
142
|
+
return canonicalJson(value);
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=generate-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-request.js","sourceRoot":"","sources":["../src/generate-request.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ClientRoute, ResponseContract } from "./generate-types.js";
|
|
2
|
+
export declare function schemaType(value: unknown): string;
|
|
3
|
+
export declare function schemaAt(root: unknown, path: readonly string[]): unknown;
|
|
4
|
+
export declare function responseSchema(route: ClientRoute, response: ResponseContract): unknown;
|
|
5
|
+
//# sourceMappingURL=generate-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-schema.d.ts","sourceRoot":"","sources":["../src/generate-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEzE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAwBjD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAQxE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAsCtF"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export function schemaType(value) {
|
|
2
|
+
const schema = schemaDocument(value);
|
|
3
|
+
if (schema === undefined)
|
|
4
|
+
return "unknown";
|
|
5
|
+
if (Object.prototype.hasOwnProperty.call(schema, "const"))
|
|
6
|
+
return literalType(schema.const);
|
|
7
|
+
if (Array.isArray(schema.enum))
|
|
8
|
+
return schema.enum.map(literalType).join(" | ") || "unknown";
|
|
9
|
+
const unions = schema.oneOf ?? schema.anyOf;
|
|
10
|
+
if (Array.isArray(unions))
|
|
11
|
+
return unions.map(schemaType).join(" | ") || "unknown";
|
|
12
|
+
if (schema.type === "array")
|
|
13
|
+
return `readonly ${schemaType(schema.items)}[]`;
|
|
14
|
+
if (schema.type === "object" || schema.properties !== undefined) {
|
|
15
|
+
const properties = isRecord(schema.properties) ? schema.properties : {};
|
|
16
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
17
|
+
const entries = Object.keys(properties)
|
|
18
|
+
.sort()
|
|
19
|
+
.map((key) => `${JSON.stringify(key)}${required.has(key) ? "" : "?"}: ${schemaType(properties[key])}`);
|
|
20
|
+
return entries.length === 0 ? "Record<string, unknown>" : `{ ${entries.join("; ")} }`;
|
|
21
|
+
}
|
|
22
|
+
if (schema.type === "string")
|
|
23
|
+
return "string";
|
|
24
|
+
if (schema.type === "integer" || schema.type === "number")
|
|
25
|
+
return "number";
|
|
26
|
+
if (schema.type === "boolean")
|
|
27
|
+
return "boolean";
|
|
28
|
+
if (schema.type === "null")
|
|
29
|
+
return "null";
|
|
30
|
+
return "unknown";
|
|
31
|
+
}
|
|
32
|
+
export function schemaAt(root, path) {
|
|
33
|
+
let current = schemaDocument(root);
|
|
34
|
+
for (const key of path) {
|
|
35
|
+
const properties = current?.properties;
|
|
36
|
+
if (!isRecord(properties))
|
|
37
|
+
return undefined;
|
|
38
|
+
current = schemaDocument(properties[key]);
|
|
39
|
+
}
|
|
40
|
+
return current;
|
|
41
|
+
}
|
|
42
|
+
export function responseSchema(route, response) {
|
|
43
|
+
if (response.kind === "success")
|
|
44
|
+
return route.target.output;
|
|
45
|
+
if (response.kind === "validation-error")
|
|
46
|
+
return validationSchema;
|
|
47
|
+
if (response.status === 429)
|
|
48
|
+
return rateLimitSchema;
|
|
49
|
+
if (response.kind !== "error")
|
|
50
|
+
return undefined;
|
|
51
|
+
const errors = Array.isArray(route.target.errors) ? route.target.errors : [];
|
|
52
|
+
const declared = errors.find((entry) => isRecord(entry) && entry.id === (response.errorId ?? response.id));
|
|
53
|
+
const data = isRecord(declared) ? declared.data : undefined;
|
|
54
|
+
const http = isRecord(declared) && isRecord(declared.http) ? declared.http : undefined;
|
|
55
|
+
const status = typeof http?.status === "number" ? http.status : undefined;
|
|
56
|
+
const retry = declared?.retry === "never" || declared?.retry === "later" ? declared.retry : undefined;
|
|
57
|
+
return {
|
|
58
|
+
type: "object",
|
|
59
|
+
required: [
|
|
60
|
+
"kind",
|
|
61
|
+
"outcome",
|
|
62
|
+
"code",
|
|
63
|
+
"message",
|
|
64
|
+
"retry",
|
|
65
|
+
...(status === undefined ? [] : ["status"]),
|
|
66
|
+
...(response.schema === undefined && data === undefined ? [] : ["data"]),
|
|
67
|
+
],
|
|
68
|
+
properties: {
|
|
69
|
+
kind: { const: "application" },
|
|
70
|
+
outcome: { const: "declared-error" },
|
|
71
|
+
code: { const: response.errorId ?? response.id },
|
|
72
|
+
message: { type: "string" },
|
|
73
|
+
...(response.schema === undefined && data === undefined
|
|
74
|
+
? {}
|
|
75
|
+
: { data: response.schema ?? data }),
|
|
76
|
+
status: status === undefined ? { type: "integer", minimum: 100, maximum: 599 } : { const: status },
|
|
77
|
+
retry: retry === undefined ? { enum: ["never", "later"] } : { const: retry },
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const validationSchema = {
|
|
82
|
+
type: "object",
|
|
83
|
+
required: ["error", "issues"],
|
|
84
|
+
properties: {
|
|
85
|
+
error: { const: "validation" },
|
|
86
|
+
issues: { type: "array", items: { type: "object" } },
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
const rateLimitSchema = {
|
|
90
|
+
type: "object",
|
|
91
|
+
required: ["error", "retryAfterMs"],
|
|
92
|
+
properties: {
|
|
93
|
+
error: { const: "rate-limit" },
|
|
94
|
+
retryAfterMs: { type: "integer" },
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
function schemaDocument(value) {
|
|
98
|
+
if (!isRecord(value))
|
|
99
|
+
return undefined;
|
|
100
|
+
if (value.$relkit === "schema" && isRecord(value.jsonSchema))
|
|
101
|
+
return value.jsonSchema;
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
function literalType(value) {
|
|
105
|
+
return value === undefined ? "unknown" : (JSON.stringify(value) ?? "unknown");
|
|
106
|
+
}
|
|
107
|
+
function isRecord(value) {
|
|
108
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=generate-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-schema.js","sourceRoot":"","sources":["../src/generate-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ApplicationGraph, FunctionNode, GraphNode, HttpTriggerConfig } from "@relkit/graph";
|
|
2
|
+
export interface MappingLeaf {
|
|
3
|
+
readonly inputPath: readonly string[];
|
|
4
|
+
readonly outputPath: readonly string[];
|
|
5
|
+
readonly kind: string;
|
|
6
|
+
readonly name?: string;
|
|
7
|
+
readonly value?: unknown;
|
|
8
|
+
readonly optional: boolean;
|
|
9
|
+
readonly defaulted: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ResponseContract {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly kind: string;
|
|
14
|
+
readonly status: number;
|
|
15
|
+
readonly errorId?: string;
|
|
16
|
+
readonly schema?: unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface ClientRoute {
|
|
19
|
+
readonly trigger: HttpGraphTrigger;
|
|
20
|
+
readonly target: FunctionNode;
|
|
21
|
+
readonly fields: readonly MappingLeaf[];
|
|
22
|
+
readonly responses: readonly ResponseContract[];
|
|
23
|
+
}
|
|
24
|
+
export declare function clientRoutes(graph: ApplicationGraph): readonly ClientRoute[];
|
|
25
|
+
export declare function mappedInputType(route: ClientRoute): string;
|
|
26
|
+
export declare function responseType(route: ClientRoute, response: ResponseContract): string;
|
|
27
|
+
type HttpGraphTrigger = Extract<GraphNode, {
|
|
28
|
+
readonly kind: "trigger";
|
|
29
|
+
}> & {
|
|
30
|
+
readonly triggerType: "http";
|
|
31
|
+
readonly config: HttpTriggerConfig;
|
|
32
|
+
};
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=generate-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-types.d.ts","sourceRoot":"","sources":["../src/generate-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAKlG,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACjD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,WAAW,EAAE,CAsB5E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CA+B1D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAMnF;AAkED,KAAK,gBAAgB,GAAG,OAAO,CAAC,SAAS,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,GAAG;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;CACpC,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { responseSchema, schemaAt, schemaType } from "./generate-schema.js";
|
|
2
|
+
import { addInputField, renderInputTree } from "./input-tree.js";
|
|
3
|
+
import { routeParameters } from "./route-parameters.js";
|
|
4
|
+
export function clientRoutes(graph) {
|
|
5
|
+
const functions = new Map(graph.nodes
|
|
6
|
+
.filter((node) => node.kind === "function")
|
|
7
|
+
.map((node) => [node.id, node]));
|
|
8
|
+
return graph.nodes
|
|
9
|
+
.filter(isHttpTrigger)
|
|
10
|
+
.map((trigger) => {
|
|
11
|
+
const target = functions.get(trigger.targetFunctionId);
|
|
12
|
+
if (target === undefined)
|
|
13
|
+
throw new TypeError(`HTTP trigger "${trigger.id}" targets missing function "${trigger.targetFunctionId}".`);
|
|
14
|
+
return {
|
|
15
|
+
trigger,
|
|
16
|
+
target,
|
|
17
|
+
fields: collectMappings(trigger.config.request),
|
|
18
|
+
responses: responseContracts(trigger.config.responses),
|
|
19
|
+
};
|
|
20
|
+
})
|
|
21
|
+
.sort((left, right) => left.trigger.id.localeCompare(right.trigger.id));
|
|
22
|
+
}
|
|
23
|
+
export function mappedInputType(route) {
|
|
24
|
+
const root = { fields: new Map() };
|
|
25
|
+
if (route.fields.some((field) => field.kind === "whole-body" && field.inputPath.length === 0))
|
|
26
|
+
return schemaType(route.target.input);
|
|
27
|
+
for (const field of route.fields) {
|
|
28
|
+
if (field.kind === "constant")
|
|
29
|
+
continue;
|
|
30
|
+
const schema = schemaAt(route.target.input, field.inputPath);
|
|
31
|
+
addInputField(root, field.inputPath, schemaType(schema ?? (isParameter(field.kind) ? { type: "string" } : undefined)), { optional: field.optional || field.defaulted });
|
|
32
|
+
}
|
|
33
|
+
for (const parameter of routeParameters(route.trigger.config.path)) {
|
|
34
|
+
if (route.fields.some((field) => field.kind === parameter.kind && field.name === parameter.name))
|
|
35
|
+
continue;
|
|
36
|
+
addInputField(root, [parameter.name], schemaType(parameter.kind === "path-segments"
|
|
37
|
+
? { type: "array", items: { type: "string" } }
|
|
38
|
+
: { type: "string" }), { optional: parameter.optional });
|
|
39
|
+
}
|
|
40
|
+
return renderInputTree(root);
|
|
41
|
+
}
|
|
42
|
+
export function responseType(route, response) {
|
|
43
|
+
const schema = response.kind === "error"
|
|
44
|
+
? responseSchema(route, response)
|
|
45
|
+
: (response.schema ?? responseSchema(route, response));
|
|
46
|
+
return schemaType(schema);
|
|
47
|
+
}
|
|
48
|
+
function collectMappings(value) {
|
|
49
|
+
const result = [];
|
|
50
|
+
visitMapping(value, [], false, false, result);
|
|
51
|
+
return result.sort((left, right) => left.inputPath.join(".").localeCompare(right.inputPath.join(".")) ||
|
|
52
|
+
left.kind.localeCompare(right.kind) ||
|
|
53
|
+
(left.name ?? "").localeCompare(right.name ?? ""));
|
|
54
|
+
}
|
|
55
|
+
function visitMapping(value, path, optional, defaulted, result) {
|
|
56
|
+
if (!isRecord(value) || typeof value.kind !== "string")
|
|
57
|
+
return;
|
|
58
|
+
if ((value.kind === "input" || value.kind === "nested") && isRecord(value.fields)) {
|
|
59
|
+
for (const key of Object.keys(value.fields).sort())
|
|
60
|
+
visitMapping(value.fields[key], [...path, key], optional, defaulted, result);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (value.kind === "optional" || value.kind === "default" || value.kind === "transform") {
|
|
64
|
+
visitMapping(value.value, path, optional || value.kind === "optional", defaulted || value.kind === "default", result);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
result.push({
|
|
68
|
+
inputPath: path,
|
|
69
|
+
outputPath: value.kind === "body" || value.kind === "multipart" || value.kind === "multipart-all"
|
|
70
|
+
? [typeof value.name === "string" ? value.name : (path.at(-1) ?? "value")]
|
|
71
|
+
: path,
|
|
72
|
+
kind: value.kind,
|
|
73
|
+
...(typeof value.name === "string" ? { name: value.name } : {}),
|
|
74
|
+
...(value.kind === "constant" ? { value: value.value } : {}),
|
|
75
|
+
optional,
|
|
76
|
+
defaulted,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function responseContracts(value) {
|
|
80
|
+
const responses = (Array.isArray(value) ? value : []).filter(isRecord).map((entry) => ({
|
|
81
|
+
id: typeof entry.id === "string" ? entry.id : "response",
|
|
82
|
+
kind: typeof entry.kind === "string" ? entry.kind : "response",
|
|
83
|
+
status: typeof entry.status === "number" ? entry.status : 0,
|
|
84
|
+
...(typeof entry.errorId === "string" ? { errorId: entry.errorId } : {}),
|
|
85
|
+
...(entry.schema === undefined || entry.schema === null ? {} : { schema: entry.schema }),
|
|
86
|
+
}));
|
|
87
|
+
if (!responses.some((response) => response.kind === "validation-error")) {
|
|
88
|
+
responses.push({ id: "validation.422", kind: "validation-error", status: 422 });
|
|
89
|
+
}
|
|
90
|
+
return responses.sort((left, right) => left.status - right.status || left.id.localeCompare(right.id));
|
|
91
|
+
}
|
|
92
|
+
function isHttpTrigger(node) {
|
|
93
|
+
return (node.kind === "trigger" &&
|
|
94
|
+
node.triggerType === "http" &&
|
|
95
|
+
isRecord(node.config) &&
|
|
96
|
+
node.config.rawHandler !== true);
|
|
97
|
+
}
|
|
98
|
+
function isParameter(value) {
|
|
99
|
+
return ["path", "path-segments", "query", "header", "cookie"].includes(value);
|
|
100
|
+
}
|
|
101
|
+
function isRecord(value) {
|
|
102
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=generate-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-types.js","sourceRoot":"","sources":["../src/generate-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ApplicationGraph } from "@relkit/graph";
|
|
2
|
+
/** Generates the default typed client entrypoint backed by the generated oRPC contract. */
|
|
3
|
+
export declare function generateClient(graph: ApplicationGraph): string;
|
|
4
|
+
/** Alias with an explicit output-format name for compiler callers. */
|
|
5
|
+
export declare const generateClientTypeScript: typeof generateClient;
|
|
6
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAQ9D;AAED,sEAAsE;AACtE,eAAO,MAAM,wBAAwB,uBAAiB,CAAC"}
|
package/dist/generate.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Generates the default typed client entrypoint backed by the generated oRPC contract. */
|
|
2
|
+
export function generateClient(graph) {
|
|
3
|
+
void graph;
|
|
4
|
+
return [
|
|
5
|
+
"/* generated by @relkit/client-generator; do not edit */",
|
|
6
|
+
'export { createClient, ORPCError } from "@relkit/client";',
|
|
7
|
+
'export { contract } from "./contract.js";',
|
|
8
|
+
"",
|
|
9
|
+
].join("\n");
|
|
10
|
+
}
|
|
11
|
+
/** Alias with an explicit output-format name for compiler callers. */
|
|
12
|
+
export const generateClientTypeScript = generateClient;
|
|
13
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAEA,2FAA2F;AAC3F,MAAM,UAAU,cAAc,CAAC,KAAuB;IACpD,KAAK,KAAK,CAAC;IACX,OAAO;QACL,0DAA0D;QAC1D,2DAA2D;QAC3D,2CAA2C;QAC3C,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,MAAM,wBAAwB,GAAG,cAAc,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface InputTree {
|
|
2
|
+
readonly fields: Map<string, InputField>;
|
|
3
|
+
}
|
|
4
|
+
export declare function addInputField(tree: InputTree, path: readonly string[], type: string, options: {
|
|
5
|
+
readonly optional: boolean;
|
|
6
|
+
}): void;
|
|
7
|
+
export declare function renderInputTree(tree: InputTree): string;
|
|
8
|
+
interface InputField {
|
|
9
|
+
optional: boolean;
|
|
10
|
+
type: string;
|
|
11
|
+
children?: InputTree;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=input-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-tree.d.ts","sourceRoot":"","sources":["../src/input-tree.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAC1C;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GACtC,IAAI,CAYN;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CASvD;AAED,UAAU,UAAU;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function addInputField(tree, path, type, options) {
|
|
2
|
+
const key = path[0];
|
|
3
|
+
if (key === undefined)
|
|
4
|
+
return;
|
|
5
|
+
const field = tree.fields.get(key) ?? { optional: options.optional, type };
|
|
6
|
+
if (path.length === 1) {
|
|
7
|
+
field.optional = field.optional && options.optional;
|
|
8
|
+
field.type = type;
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
field.children ??= { fields: new Map() };
|
|
12
|
+
addInputField(field.children, path.slice(1), type, options);
|
|
13
|
+
}
|
|
14
|
+
tree.fields.set(key, field);
|
|
15
|
+
}
|
|
16
|
+
export function renderInputTree(tree) {
|
|
17
|
+
const entries = [...tree.fields.entries()].sort(([left], [right]) => left.localeCompare(right));
|
|
18
|
+
if (entries.length === 0)
|
|
19
|
+
return "{}";
|
|
20
|
+
return `{ ${entries
|
|
21
|
+
.map(([key, field]) => {
|
|
22
|
+
const value = field.children === undefined ? field.type : renderInputTree(field.children);
|
|
23
|
+
return `${JSON.stringify(key)}${field.optional ? "?" : ""}: ${value}`;
|
|
24
|
+
})
|
|
25
|
+
.join("; ")} }`;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=input-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-tree.js","sourceRoot":"","sources":["../src/input-tree.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,aAAa,CAC3B,IAAe,EACf,IAAuB,EACvB,IAAY,EACZ,OAAuC;IAEvC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC3E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;QACpD,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,QAAQ,KAAK,EAAE,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;QACzC,aAAa,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAe;IAC7C,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IAChG,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,KAAK,OAAO;SAChB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1F,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;IACxE,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface RouteParameter {
|
|
2
|
+
readonly segment: string;
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly kind: "path" | "path-segments";
|
|
5
|
+
readonly optional: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function routeParameters(path: string): readonly RouteParameter[];
|
|
8
|
+
//# sourceMappingURL=route-parameters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-parameters.d.ts","sourceRoot":"","sources":["../src/route-parameters.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,cAAc,EAAE,CAavE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function routeParameters(path) {
|
|
2
|
+
return path.split("/").flatMap((segment) => {
|
|
3
|
+
if (!segment.startsWith(":") && !segment.startsWith("*"))
|
|
4
|
+
return [];
|
|
5
|
+
const optional = segment.endsWith("?");
|
|
6
|
+
return [
|
|
7
|
+
{
|
|
8
|
+
segment,
|
|
9
|
+
name: segment.slice(1).replace(/\?$/, ""),
|
|
10
|
+
kind: segment.startsWith("*") ? "path-segments" : "path",
|
|
11
|
+
optional,
|
|
12
|
+
},
|
|
13
|
+
];
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=route-parameters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-parameters.js","sourceRoot":"","sources":["../src/route-parameters.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACzC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACvC,OAAO;YACL;gBACE,OAAO;gBACP,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;gBACzC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM;gBACxD,QAAQ;aACT;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@relkit/client-generator",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Unsupported internal RELKIT client generator; use @relkit/app.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/rel-kit/relkit.git",
|
|
9
|
+
"directory": "packages/client-generator"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/rel-kit/relkit#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/rel-kit/relkit/issues"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"bun": ">=1.3.10"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@relkit/contracts": "0.0.0",
|
|
33
|
+
"@relkit/graph": "0.0.0"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -b",
|
|
37
|
+
"check": "tsc -b --pretty false",
|
|
38
|
+
"typecheck": "tsc -b --pretty false"
|
|
39
|
+
}
|
|
40
|
+
}
|