@nkzw/fate 0.0.7 → 0.1.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/README.md +233 -127
- package/lib/cli.mjs +82 -27
- package/lib/index.d.mts +8 -567
- package/lib/index.mjs +148 -41
- package/lib/server.d.mts +35 -29
- package/lib/server.mjs +19 -9
- package/lib/types-CNKGKRtz.d.mts +615 -0
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -7,11 +7,11 @@ import { styleText } from "node:util";
|
|
|
7
7
|
const isDataViewField = (field) => Boolean(field) && typeof field === "object" && "fields" in field;
|
|
8
8
|
/**
|
|
9
9
|
* Builds the schema object used by the CLI generator from your data views and
|
|
10
|
-
*
|
|
10
|
+
* root resolver configs.
|
|
11
11
|
*/
|
|
12
|
-
const createSchema = (dataViews,
|
|
12
|
+
const createSchema = (dataViews, roots) => {
|
|
13
13
|
const canonicalViews = /* @__PURE__ */ new Map();
|
|
14
|
-
const
|
|
14
|
+
const rootSchema = {};
|
|
15
15
|
const fateTypes = /* @__PURE__ */ new Map();
|
|
16
16
|
const processing = /* @__PURE__ */ new Set();
|
|
17
17
|
const ensureType = (view) => {
|
|
@@ -36,20 +36,25 @@ const createSchema = (dataViews, lists) => {
|
|
|
36
36
|
const typeName = view.typeName;
|
|
37
37
|
if (!typeName) throw new Error("Data view is missing a type name.");
|
|
38
38
|
if (!canonicalViews.has(typeName)) canonicalViews.set(typeName, view);
|
|
39
|
-
entities[typeName.toLowerCase()] = { type: typeName };
|
|
40
39
|
}
|
|
41
|
-
for (const
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
for (const view of dataViews) ensureType(view);
|
|
41
|
+
for (const [name, root$1] of Object.entries(roots)) {
|
|
42
|
+
const config = "fields" in root$1 ? { view: root$1 } : root$1;
|
|
43
|
+
const view = config.view;
|
|
44
|
+
const type = ensureType(view);
|
|
45
|
+
if (!view.typeName) throw new Error(`Root "${name}" is missing a data view.`);
|
|
46
|
+
const router = config.router ?? view.typeName[0]?.toLowerCase() + view.typeName.slice(1);
|
|
47
|
+
if (!router) throw new Error(`Root "${name}" is missing a router name.`);
|
|
48
|
+
rootSchema[name] = {
|
|
49
|
+
kind: view.kind === "list" ? "list" : "query",
|
|
50
|
+
procedure: config.procedure ?? (view.kind === "list" ? "list" : name),
|
|
51
|
+
router,
|
|
52
|
+
type
|
|
48
53
|
};
|
|
49
54
|
}
|
|
50
55
|
for (const view of dataViews) ensureType(view);
|
|
51
56
|
return {
|
|
52
|
-
|
|
57
|
+
roots: rootSchema,
|
|
53
58
|
types: Array.from(fateTypes.values())
|
|
54
59
|
};
|
|
55
60
|
};
|
|
@@ -89,21 +94,29 @@ const formatTypes = (types) => {
|
|
|
89
94
|
const indentBlock = (value, spaces) => value.split("\n").map((line) => line.length ? `${" ".repeat(spaces)}${line}` : line).join("\n");
|
|
90
95
|
const generate = async () => {
|
|
91
96
|
console.log(styleText("bold", `Generating fate client…\n`));
|
|
92
|
-
const { appRouter,
|
|
93
|
-
const {
|
|
97
|
+
const { appRouter, Root, ...dataViews } = await import(moduleName);
|
|
98
|
+
const { roots, types } = createSchema(Object.values(dataViews), Root ?? {});
|
|
94
99
|
const routerRecord = appRouter._def?.record ?? {};
|
|
95
100
|
const mutationEntries = [];
|
|
96
101
|
const byIdEntries = [];
|
|
97
102
|
const listEntries = [];
|
|
103
|
+
const queryEntries = [];
|
|
104
|
+
const rootsByRouter = /* @__PURE__ */ new Map();
|
|
105
|
+
for (const entry of Object.entries(roots)) {
|
|
106
|
+
const list = rootsByRouter.get(entry[1].router) ?? [];
|
|
107
|
+
list.push(entry);
|
|
108
|
+
rootsByRouter.set(entry[1].router, list);
|
|
109
|
+
}
|
|
98
110
|
for (const [router, procedures] of Object.entries(routerRecord)) {
|
|
99
|
-
const
|
|
100
|
-
if (!
|
|
111
|
+
const routerRoots = rootsByRouter.get(router);
|
|
112
|
+
if (!routerRoots?.length) continue;
|
|
113
|
+
const entityType = routerRoots[0][1].type;
|
|
101
114
|
for (const [procedureName, procedure] of Object.entries(procedures)) {
|
|
102
115
|
const type = procedure?._def?.type;
|
|
103
116
|
if (!type) continue;
|
|
104
117
|
if (type === "mutation") {
|
|
105
118
|
mutationEntries.push({
|
|
106
|
-
entityType
|
|
119
|
+
entityType,
|
|
107
120
|
name: `${router}.${procedureName}`,
|
|
108
121
|
procedure: procedureName,
|
|
109
122
|
router
|
|
@@ -112,22 +125,53 @@ const generate = async () => {
|
|
|
112
125
|
}
|
|
113
126
|
if (procedureName === "byId" && type === "query") {
|
|
114
127
|
byIdEntries.push({
|
|
115
|
-
entityType
|
|
128
|
+
entityType,
|
|
116
129
|
router
|
|
117
130
|
});
|
|
118
131
|
continue;
|
|
119
132
|
}
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
133
|
+
for (const [queryName, root$1] of routerRoots) {
|
|
134
|
+
if (root$1.kind !== "query") continue;
|
|
135
|
+
if (procedureName === root$1.procedure && type === "query") queryEntries.push({
|
|
136
|
+
name: queryName,
|
|
137
|
+
procedure: root$1.procedure,
|
|
138
|
+
router,
|
|
139
|
+
type: root$1.type
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
for (const [listName, root$1] of routerRoots) {
|
|
143
|
+
if (root$1.kind !== "list") continue;
|
|
144
|
+
if (procedureName === root$1.procedure && type === "query") listEntries.push({
|
|
145
|
+
list: listName,
|
|
146
|
+
procedure: root$1.procedure,
|
|
147
|
+
router,
|
|
148
|
+
type: root$1.type
|
|
149
|
+
});
|
|
150
|
+
}
|
|
126
151
|
}
|
|
127
152
|
}
|
|
128
153
|
mutationEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
129
154
|
byIdEntries.sort((a, b) => a.entityType.localeCompare(b.entityType));
|
|
155
|
+
queryEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
130
156
|
listEntries.sort((a, b) => a.list.localeCompare(b.list));
|
|
157
|
+
const rootEntries = [
|
|
158
|
+
...byIdEntries.map(({ entityType, router }) => ({
|
|
159
|
+
name: router,
|
|
160
|
+
type: entityType,
|
|
161
|
+
value: `'${router}': clientRoot<RouterOutputs['${router}']['byId'], '${entityType}'>('${entityType}'),`
|
|
162
|
+
})),
|
|
163
|
+
...queryEntries.map(({ name, procedure, router, type }) => ({
|
|
164
|
+
name,
|
|
165
|
+
type,
|
|
166
|
+
value: `'${name}': clientRoot<RouterOutputs['${router}']['${procedure}'], '${type}'>('${type}'),`
|
|
167
|
+
})),
|
|
168
|
+
...listEntries.map(({ list, procedure, router, type }) => ({
|
|
169
|
+
name: list,
|
|
170
|
+
type,
|
|
171
|
+
value: `'${list}': clientRoot<RouterOutputs['${router}']['${procedure}'], '${type}'>('${type}'),`
|
|
172
|
+
}))
|
|
173
|
+
];
|
|
174
|
+
rootEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
131
175
|
const viewTypes = Array.from(["AppRouter", ...new Set(mutationEntries.map((entry) => entry.entityType))]).sort();
|
|
132
176
|
const mutationResolverLines = mutationEntries.map(({ name, procedure, router }) => `'${name}': (client: TRPCClientType) => client.${router}.${procedure}.mutate,`);
|
|
133
177
|
const mutationConfigLines = mutationEntries.map(({ entityType, name, procedure, router }) => `'${name}': mutation<
|
|
@@ -146,17 +190,21 @@ const generate = async () => {
|
|
|
146
190
|
select,
|
|
147
191
|
}),`);
|
|
148
192
|
const listLines = listEntries.map(({ list, procedure, router }) => `${list}: (client: TRPCClientType) => client.${router}.${procedure}.query,`);
|
|
193
|
+
const queryLines = queryEntries.map(({ name, procedure, router }) => `${name}: (client: TRPCClientType) => client.${router}.${procedure}.query,`);
|
|
149
194
|
const typeImports = `import type { ${viewTypes.join(", ")} } from '${moduleName}';`;
|
|
150
195
|
const typesBlock = indentBlock(formatTypes(types), 6);
|
|
151
196
|
const mutationResolverBlock = indentBlock(mutationResolverLines.join("\n"), 4);
|
|
152
197
|
const mutationConfigBlock = indentBlock(mutationConfigLines.join("\n"), 2);
|
|
153
198
|
const byIdBlock = indentBlock(byIdLines.join("\n"), 8);
|
|
199
|
+
const rootsBlock = indentBlock(rootEntries.map((entry) => entry.value).join("\n"), 2);
|
|
154
200
|
const listsBlockContent = listLines.join("\n");
|
|
201
|
+
const listsBlock = listLines.length ? ` lists: {\n${indentBlock(listsBlockContent, 8)}\n },\n` : "";
|
|
202
|
+
const queriesBlockContent = queryLines.join("\n");
|
|
155
203
|
const source = `// @generated by \`pnpm fate generate\`
|
|
156
204
|
${typeImports}
|
|
157
205
|
import { createTRPCProxyClient } from '@trpc/client';
|
|
158
206
|
import { inferRouterInputs, inferRouterOutputs } from '@trpc/server';
|
|
159
|
-
import { createClient, createTRPCTransport, mutation } from 'react-fate';
|
|
207
|
+
import { clientRoot, createClient, createTRPCTransport, mutation } from 'react-fate';
|
|
160
208
|
|
|
161
209
|
type TRPCClientType = ReturnType<typeof createTRPCProxyClient<AppRouter>>;
|
|
162
210
|
type RouterInputs = inferRouterInputs<AppRouter>;
|
|
@@ -166,10 +214,16 @@ const mutations = {
|
|
|
166
214
|
${mutationConfigBlock}
|
|
167
215
|
} as const;
|
|
168
216
|
|
|
217
|
+
const roots = {
|
|
218
|
+
${rootsBlock}
|
|
219
|
+
} as const;
|
|
220
|
+
|
|
169
221
|
type GeneratedClientMutations = typeof mutations;
|
|
222
|
+
type GeneratedClientRoots = typeof roots;
|
|
170
223
|
|
|
171
224
|
declare module 'react-fate' {
|
|
172
225
|
interface ClientMutations extends GeneratedClientMutations {}
|
|
226
|
+
interface ClientRoots extends GeneratedClientRoots {}
|
|
173
227
|
}
|
|
174
228
|
|
|
175
229
|
export const createFateClient = (options: {
|
|
@@ -181,14 +235,15 @@ export const createFateClient = (options: {
|
|
|
181
235
|
${mutationResolverBlock}
|
|
182
236
|
} as const;
|
|
183
237
|
|
|
184
|
-
return createClient({
|
|
238
|
+
return createClient<[GeneratedClientRoots, GeneratedClientMutations]>({
|
|
185
239
|
mutations,
|
|
240
|
+
roots,
|
|
186
241
|
transport: createTRPCTransport<AppRouter, typeof trpcMutations>({
|
|
187
242
|
byId: {
|
|
188
243
|
${byIdBlock}
|
|
189
244
|
},
|
|
190
245
|
client: trpcClient,
|
|
191
|
-
${
|
|
246
|
+
${queryLines.length ? ` queries: {\n${indentBlock(queriesBlockContent, 8)}\n },\n` : ""}${listsBlock} mutations: trpcMutations,
|
|
192
247
|
}),
|
|
193
248
|
types: ${typesBlock.trimStart()},
|
|
194
249
|
});
|