@trpc-panel/core 1.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.
Files changed (60) hide show
  1. package/README.md +173 -0
  2. package/lib/index.js +431 -0
  3. package/lib/index.mjs +427 -0
  4. package/lib/react-app/bundle.js +291 -0
  5. package/lib/react-app/bundle.js.map +1 -0
  6. package/lib/react-app/index.css +1076 -0
  7. package/lib/react-app/index.html +16 -0
  8. package/lib/src/index.d.ts +3 -0
  9. package/lib/src/meta.d.ts +9 -0
  10. package/lib/src/parse/__tests__/parseProcedure.test.d.ts +1 -0
  11. package/lib/src/parse/__tests__/parseRouter.test.d.ts +1 -0
  12. package/lib/src/parse/__tests__/utils/router.d.ts +159 -0
  13. package/lib/src/parse/__tests__/utils/schemas.d.ts +7 -0
  14. package/lib/src/parse/input-mappers/__tests__/zod/array.test.d.ts +1 -0
  15. package/lib/src/parse/input-mappers/__tests__/zod/bigint.test.d.ts +1 -0
  16. package/lib/src/parse/input-mappers/__tests__/zod/boolean.test.d.ts +1 -0
  17. package/lib/src/parse/input-mappers/__tests__/zod/branded.test.d.ts +1 -0
  18. package/lib/src/parse/input-mappers/__tests__/zod/default.test.d.ts +1 -0
  19. package/lib/src/parse/input-mappers/__tests__/zod/discriminatedUnion.test.d.ts +1 -0
  20. package/lib/src/parse/input-mappers/__tests__/zod/effects.test.d.ts +1 -0
  21. package/lib/src/parse/input-mappers/__tests__/zod/enum.test.d.ts +1 -0
  22. package/lib/src/parse/input-mappers/__tests__/zod/literal.test.d.ts +1 -0
  23. package/lib/src/parse/input-mappers/__tests__/zod/null.test.d.ts +1 -0
  24. package/lib/src/parse/input-mappers/__tests__/zod/nullable.test.d.ts +1 -0
  25. package/lib/src/parse/input-mappers/__tests__/zod/number.test.d.ts +1 -0
  26. package/lib/src/parse/input-mappers/__tests__/zod/object.test.d.ts +1 -0
  27. package/lib/src/parse/input-mappers/__tests__/zod/optional.test.d.ts +1 -0
  28. package/lib/src/parse/input-mappers/__tests__/zod/promise.test.d.ts +1 -0
  29. package/lib/src/parse/input-mappers/__tests__/zod/string.test.d.ts +1 -0
  30. package/lib/src/parse/input-mappers/__tests__/zod/undefined.test.d.ts +1 -0
  31. package/lib/src/parse/input-mappers/__tests__/zod/void.test.d.ts +1 -0
  32. package/lib/src/parse/input-mappers/defaultReferences.d.ts +2 -0
  33. package/lib/src/parse/input-mappers/zod/parsers/parseZodArrayDef.d.ts +3 -0
  34. package/lib/src/parse/input-mappers/zod/parsers/parseZodBigIntDef.d.ts +3 -0
  35. package/lib/src/parse/input-mappers/zod/parsers/parseZodBooleanFieldDef.d.ts +3 -0
  36. package/lib/src/parse/input-mappers/zod/parsers/parseZodBrandedDef.d.ts +3 -0
  37. package/lib/src/parse/input-mappers/zod/parsers/parseZodDefaultDef.d.ts +3 -0
  38. package/lib/src/parse/input-mappers/zod/parsers/parseZodDiscriminatedUnionDef.d.ts +16 -0
  39. package/lib/src/parse/input-mappers/zod/parsers/parseZodEffectsDef.d.ts +3 -0
  40. package/lib/src/parse/input-mappers/zod/parsers/parseZodEnumDef.d.ts +3 -0
  41. package/lib/src/parse/input-mappers/zod/parsers/parseZodLiteralDef.d.ts +3 -0
  42. package/lib/src/parse/input-mappers/zod/parsers/parseZodNullDef.d.ts +3 -0
  43. package/lib/src/parse/input-mappers/zod/parsers/parseZodNullableDef.d.ts +3 -0
  44. package/lib/src/parse/input-mappers/zod/parsers/parseZodNumberDef.d.ts +3 -0
  45. package/lib/src/parse/input-mappers/zod/parsers/parseZodObjectDef.d.ts +3 -0
  46. package/lib/src/parse/input-mappers/zod/parsers/parseZodOptionalDef.d.ts +3 -0
  47. package/lib/src/parse/input-mappers/zod/parsers/parseZodPromiseDef.d.ts +3 -0
  48. package/lib/src/parse/input-mappers/zod/parsers/parseZodStringDef.d.ts +3 -0
  49. package/lib/src/parse/input-mappers/zod/parsers/parseZodUndefinedDef.d.ts +3 -0
  50. package/lib/src/parse/input-mappers/zod/parsers/parseZodVoidDef.d.ts +3 -0
  51. package/lib/src/parse/input-mappers/zod/selector.d.ts +3 -0
  52. package/lib/src/parse/input-mappers/zod/zod-types.d.ts +4 -0
  53. package/lib/src/parse/parseErrorLogs.d.ts +1 -0
  54. package/lib/src/parse/parseNodeTypes.d.ts +61 -0
  55. package/lib/src/parse/parseProcedure.d.ts +18 -0
  56. package/lib/src/parse/parseRouter.d.ts +21 -0
  57. package/lib/src/parse/routerType.d.ts +486 -0
  58. package/lib/src/parse/utils.d.ts +2 -0
  59. package/lib/src/render.d.ts +7 -0
  60. package/package.json +100 -0
package/lib/index.mjs ADDED
@@ -0,0 +1,427 @@
1
+ import fs from 'fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { dirname } from 'node:path';
4
+ import { z, ZodFirstPartyTypeKind } from 'zod';
5
+ import { zodToJsonSchema } from 'zod-to-json-schema';
6
+
7
+ const TRPCPanelMetaSchema = z.object({
8
+ description: z.string().optional(),
9
+ });
10
+
11
+ z.object({});
12
+ const SharedProcedureDefPropertiesSchema = z.object({
13
+ inputs: z.unknown().array().optional(),
14
+ input: z.unknown().optional(),
15
+ meta: TRPCPanelMetaSchema.optional(),
16
+ });
17
+ const QueryDefSchema = SharedProcedureDefPropertiesSchema.and(z.union([
18
+ z.object({
19
+ query: z.literal(true),
20
+ }),
21
+ z.object({
22
+ type: z.literal("query"),
23
+ }),
24
+ ]));
25
+ function isQueryDef(obj) {
26
+ return QueryDefSchema.safeParse(obj).success;
27
+ }
28
+ const MutationDefSchema = SharedProcedureDefPropertiesSchema.and(z.union([
29
+ z.object({
30
+ mutation: z.literal(true),
31
+ }),
32
+ z.object({
33
+ type: z.literal("mutation"),
34
+ }),
35
+ ]));
36
+ function isMutationDef(obj) {
37
+ return MutationDefSchema.safeParse(obj).success;
38
+ }
39
+ const SubscriptionDefSchema = SharedProcedureDefPropertiesSchema.and(z.union([
40
+ z.object({
41
+ subscription: z.literal(true),
42
+ }),
43
+ z.object({
44
+ type: z.literal("subscription"),
45
+ }),
46
+ ]));
47
+ function isSubscriptionDef(obj) {
48
+ return SubscriptionDefSchema.safeParse(obj).success;
49
+ }
50
+ const ProcedureDefSchema = QueryDefSchema.or(MutationDefSchema).or(SubscriptionDefSchema);
51
+ const RouterDefSchema = z.object({
52
+ router: z.literal(true).optional(),
53
+ type: z.undefined(),
54
+ query: z.undefined(),
55
+ mutation: z.undefined(),
56
+ subscription: z.undefined(),
57
+ inputs: z.undefined(),
58
+ input: z.undefined(),
59
+ });
60
+ const RouterSchema = z.object({
61
+ _def: RouterDefSchema,
62
+ });
63
+ function isRouter(obj) {
64
+ return RouterSchema.safeParse(obj).success;
65
+ }
66
+ z.object({
67
+ _def: ProcedureDefSchema,
68
+ });
69
+ function isProcedure(obj) {
70
+ if (typeof obj !== "function" || !("_def" in obj))
71
+ return false;
72
+ return ProcedureDefSchema.safeParse(obj._def).success;
73
+ }
74
+ z.object({
75
+ _def: QueryDefSchema,
76
+ });
77
+
78
+ function logParseError(procedurePath, error) {
79
+ console.warn(`trpc-panel: Failed to parse procedure ${procedurePath}, ${error}`);
80
+ }
81
+
82
+ function nodePropertiesFromRef(references) {
83
+ return Object.assign({ path: references.path }, (references.optional && { optional: true }));
84
+ }
85
+
86
+ const parseZodStringDef = (def, refs) => {
87
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
88
+ return Object.assign({ type: "string" }, nodePropertiesFromRef(refs));
89
+ };
90
+
91
+ const parseZodArrayDef = (def, refs) => {
92
+ const { type } = def;
93
+ const childType = zodSelectorFunction(type._def, Object.assign(Object.assign({}, refs), { path: [] }));
94
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
95
+ return Object.assign({ type: "array", childType }, nodePropertiesFromRef(refs));
96
+ };
97
+
98
+ const parseZodBooleanFieldDef = (def, refs) => {
99
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
100
+ return Object.assign({ type: "boolean" }, nodePropertiesFromRef(refs));
101
+ };
102
+
103
+ function isZodThreePointTwenty(def) {
104
+ return "optionsMap" in def;
105
+ }
106
+ function makeDefConsistent(def) {
107
+ const optionsMap = isZodThreePointTwenty(def) ? def.optionsMap : def.options;
108
+ return {
109
+ typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,
110
+ discriminator: def.discriminator,
111
+ options: optionsMap,
112
+ };
113
+ }
114
+ const parseZodDiscriminatedUnionDef = (def, refs) => {
115
+ const defConsistent = makeDefConsistent(def);
116
+ const entries = Array.from(defConsistent.options.entries());
117
+ const nodeEntries = entries.map(([discriminatorValue, zodObj]) => [
118
+ discriminatorValue,
119
+ zodSelectorFunction(zodObj._def, refs),
120
+ ]);
121
+ const nodesMap = Object.fromEntries(nodeEntries);
122
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
123
+ return Object.assign({ type: "discriminated-union", discriminatedUnionValues: entries.map(([n]) => n), discriminatedUnionChildrenMap: nodesMap, discriminatorName: def.discriminator }, nodePropertiesFromRef(refs));
124
+ };
125
+
126
+ const parseZodEnumDef = (def, refs) => {
127
+ const values = def.values;
128
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
129
+ return Object.assign({ type: "enum", enumValues: values }, nodePropertiesFromRef(refs));
130
+ };
131
+
132
+ const parseZodLiteralDef = (def, refs) => {
133
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
134
+ return Object.assign({ type: "literal", value: def.value }, nodePropertiesFromRef(refs));
135
+ };
136
+
137
+ const parseZodNumberDef = (def, refs) => {
138
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
139
+ return Object.assign({ type: "number" }, nodePropertiesFromRef(refs));
140
+ };
141
+
142
+ const parseZodObjectDef = (def, refs) => {
143
+ const shape = def.shape();
144
+ const children = {};
145
+ for (var propertyName of Object.keys(shape)) {
146
+ const node = zodSelectorFunction(shape[propertyName]._def, Object.assign(Object.assign({}, refs), { path: refs.path.concat([propertyName]) }));
147
+ children[propertyName] = node;
148
+ }
149
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
150
+ return Object.assign({ type: "object", children }, nodePropertiesFromRef(refs));
151
+ };
152
+
153
+ const parseZodOptionalDef = (def, refs) => {
154
+ const parsedInner = zodSelectorFunction(def.innerType._def, refs);
155
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
156
+ return Object.assign(Object.assign({}, parsedInner), { optional: true });
157
+ };
158
+
159
+ function parseZodNullableDef(def, refs) {
160
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
161
+ return zodSelectorFunction(def.innerType._def, refs);
162
+ }
163
+
164
+ function parseZodBigIntDef(def, refs) {
165
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
166
+ return Object.assign({ type: "number" }, nodePropertiesFromRef(refs));
167
+ }
168
+
169
+ function parseZodBrandedDef(def, refs) {
170
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
171
+ return zodSelectorFunction(def.type._def, refs);
172
+ }
173
+
174
+ function parseZodDefaultDef(def, refs) {
175
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
176
+ return zodSelectorFunction(def.innerType._def, refs);
177
+ }
178
+
179
+ function parseZodEffectsDef(def, refs) {
180
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
181
+ return zodSelectorFunction(def.schema._def, refs);
182
+ }
183
+
184
+ function parseZodNullDef(def, refs) {
185
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
186
+ return Object.assign({ type: "literal", value: null }, nodePropertiesFromRef(refs));
187
+ }
188
+
189
+ function parseZodPromiseDef(def, refs) {
190
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
191
+ return zodSelectorFunction(def.type._def, refs);
192
+ }
193
+
194
+ function parseZodUndefinedDef(def, refs) {
195
+ refs.addDataFunctions.addDescriptionIfExists(def, refs);
196
+ return Object.assign({ type: "literal", value: undefined }, nodePropertiesFromRef(refs));
197
+ }
198
+
199
+ function parseZodVoidDef(_, refs) {
200
+ return {
201
+ type: "literal",
202
+ value: undefined,
203
+ path: refs.path,
204
+ };
205
+ }
206
+
207
+ const zodSelectorFunction = (def, references) => {
208
+ switch (def.typeName) {
209
+ case ZodFirstPartyTypeKind.ZodArray:
210
+ return parseZodArrayDef(def, references);
211
+ case ZodFirstPartyTypeKind.ZodBoolean:
212
+ return parseZodBooleanFieldDef(def, references);
213
+ case ZodFirstPartyTypeKind.ZodDiscriminatedUnion:
214
+ return parseZodDiscriminatedUnionDef(def, references);
215
+ case ZodFirstPartyTypeKind.ZodEnum:
216
+ return parseZodEnumDef(def, references);
217
+ case ZodFirstPartyTypeKind.ZodLiteral:
218
+ return parseZodLiteralDef(def, references);
219
+ case ZodFirstPartyTypeKind.ZodNumber:
220
+ return parseZodNumberDef(def, references);
221
+ case ZodFirstPartyTypeKind.ZodObject:
222
+ return parseZodObjectDef(def, references);
223
+ case ZodFirstPartyTypeKind.ZodOptional:
224
+ return parseZodOptionalDef(def, references);
225
+ case ZodFirstPartyTypeKind.ZodString:
226
+ return parseZodStringDef(def, references);
227
+ case ZodFirstPartyTypeKind.ZodNullable:
228
+ return parseZodNullableDef(def, references);
229
+ case ZodFirstPartyTypeKind.ZodBigInt:
230
+ return parseZodBigIntDef(def, references);
231
+ case ZodFirstPartyTypeKind.ZodBranded:
232
+ return parseZodBrandedDef(def, references);
233
+ case ZodFirstPartyTypeKind.ZodDefault:
234
+ return parseZodDefaultDef(def, references);
235
+ case ZodFirstPartyTypeKind.ZodEffects:
236
+ return parseZodEffectsDef(def, references);
237
+ case ZodFirstPartyTypeKind.ZodNull:
238
+ return parseZodNullDef(def, references);
239
+ case ZodFirstPartyTypeKind.ZodPromise:
240
+ return parseZodPromiseDef(def, references);
241
+ case ZodFirstPartyTypeKind.ZodUndefined:
242
+ return parseZodUndefinedDef(def, references);
243
+ case ZodFirstPartyTypeKind.ZodVoid:
244
+ return parseZodVoidDef(def, references);
245
+ }
246
+ return { type: "unsupported", path: references.path };
247
+ };
248
+
249
+ const inputParserMap = {
250
+ zod: (zodObject, refs) => {
251
+ return zodSelectorFunction(zodObject._def, refs);
252
+ },
253
+ };
254
+ const emptyZodObject = z.object({});
255
+ function nodeAndInputSchemaFromInputs(inputs, _routerPath, options, addDataFunctions) {
256
+ if (!inputs.length) {
257
+ return {
258
+ parseInputResult: "success",
259
+ schema: zodToJsonSchema(emptyZodObject, {
260
+ errorMessages: true,
261
+ $refStrategy: "none",
262
+ target: "jsonSchema7"
263
+ }),
264
+ node: inputParserMap["zod"](emptyZodObject, {
265
+ path: [],
266
+ options,
267
+ addDataFunctions,
268
+ }),
269
+ };
270
+ }
271
+ if (inputs.length !== 1) {
272
+ return { parseInputResult: "failure" };
273
+ }
274
+ const input = inputs[0];
275
+ return {
276
+ parseInputResult: "success",
277
+ schema: zodToJsonSchema(input, {
278
+ errorMessages: true,
279
+ $refStrategy: "none",
280
+ target: "jsonSchema7"
281
+ }),
282
+ node: zodSelectorFunction(input._def, {
283
+ path: [],
284
+ options,
285
+ addDataFunctions,
286
+ }),
287
+ };
288
+ }
289
+ function parseProcedure(procedure, path, options) {
290
+ var _a, _b;
291
+ const { _def } = procedure;
292
+ const inputs = (_a = _def.inputs) !== null && _a !== void 0 ? _a : (_def.input ? [_def.input] : []);
293
+ const parseExtraData = {
294
+ parameterDescriptions: {},
295
+ };
296
+ const nodeAndInput = nodeAndInputSchemaFromInputs(inputs, path, options, {
297
+ addDescriptionIfExists: (def, refs) => {
298
+ if (def.description) {
299
+ parseExtraData.parameterDescriptions[refs.path.join(".")] =
300
+ def.description;
301
+ }
302
+ },
303
+ });
304
+ if (nodeAndInput.parseInputResult === "failure") {
305
+ return null;
306
+ }
307
+ const t = (() => {
308
+ if (isQueryDef(_def))
309
+ return "query";
310
+ if (isMutationDef(_def))
311
+ return "mutation";
312
+ if (isSubscriptionDef(_def))
313
+ return "subscription";
314
+ return null;
315
+ })();
316
+ if (!t) {
317
+ return null;
318
+ }
319
+ return {
320
+ inputSchema: nodeAndInput.schema,
321
+ node: nodeAndInput.node,
322
+ nodeType: "procedure",
323
+ procedureType: t,
324
+ pathFromRootRouter: path,
325
+ extraData: Object.assign(Object.assign({}, parseExtraData), (((_b = procedure._def.meta) === null || _b === void 0 ? void 0 : _b.description) && {
326
+ description: procedure._def.meta.description,
327
+ })),
328
+ };
329
+ }
330
+
331
+ const skipSet = new Set(["createCaller", "_def", "getErrorShape"]);
332
+ function parseRouter(router, routerPath, options) {
333
+ const children = {};
334
+ var hasChild = false;
335
+ for (var [procedureOrRouterPath, child] of Object.entries(router)) {
336
+ if (skipSet.has(procedureOrRouterPath))
337
+ continue;
338
+ const newPath = routerPath.concat([procedureOrRouterPath]);
339
+ const parsedNode = (() => {
340
+ if (isRouter(child)) {
341
+ return parseRouter(child, newPath, options);
342
+ }
343
+ if (isProcedure(child)) {
344
+ return parseProcedure(child, newPath, options);
345
+ }
346
+ return null;
347
+ })();
348
+ if (!parsedNode) {
349
+ logParseError(newPath.join("."), "Couldn't parse node.");
350
+ continue;
351
+ }
352
+ hasChild = true;
353
+ children[procedureOrRouterPath] = parsedNode;
354
+ }
355
+ if (!hasChild)
356
+ logParseError(routerPath.join("."), `Router doesn't have any successfully parsed children.`);
357
+ return { children, nodeType: "router", path: routerPath };
358
+ }
359
+ function parseRouterWithOptions(router, parseRouterOptions) {
360
+ if (!isRouter(router)) {
361
+ throw new Error("Non trpc router passed to trpc panel.");
362
+ }
363
+ return parseRouter(router, [], parseRouterOptions);
364
+ }
365
+
366
+ const defaultParseRouterOptions = {
367
+ logFailedProcedureParse: true,
368
+ transformer: "superjson",
369
+ };
370
+ const __dirname = dirname(fileURLToPath(import.meta.url));
371
+ const javascriptReplaceSymbol = "{{js}}";
372
+ const cssReplaceSymbol = "{{css}}";
373
+ const routerReplaceSymbol = '"{{parsed_router}}"';
374
+ const optionsReplaceSymbol = '"{{options}}"';
375
+ const bundlePath = __dirname + "/react-app/bundle.js";
376
+ const indexPath = __dirname + "/react-app/index.html";
377
+ const cssPath = __dirname + "/react-app/index.css";
378
+ const bundleJs = fs.readFileSync(bundlePath).toString();
379
+ const indexHtml = fs.readFileSync(indexPath).toString();
380
+ const indexCss = fs.readFileSync(cssPath).toString();
381
+ function injectParams(string, injectionParams) {
382
+ var r = string;
383
+ for (var param of injectionParams) {
384
+ r = injectInString(param.searchFor, r, param.injectString);
385
+ }
386
+ return r;
387
+ }
388
+ function injectInString(searchFor, string, injectString) {
389
+ const startIndex = string.indexOf(searchFor);
390
+ return (string.slice(0, startIndex) +
391
+ injectString +
392
+ string.slice(startIndex + searchFor.length));
393
+ }
394
+ let cache = {
395
+ val: null,
396
+ };
397
+ function renderTrpcPanel(router, options) {
398
+ if (options.cache === true && cache.val)
399
+ return cache.val;
400
+ const bundleInjectionParams = [
401
+ {
402
+ searchFor: routerReplaceSymbol,
403
+ injectString: JSON.stringify(parseRouterWithOptions(router, Object.assign(Object.assign({}, defaultParseRouterOptions), options))),
404
+ },
405
+ {
406
+ searchFor: optionsReplaceSymbol,
407
+ injectString: JSON.stringify(options),
408
+ },
409
+ ];
410
+ const bundleInjected = injectParams(bundleJs, bundleInjectionParams);
411
+ const script = `<script>${bundleInjected}</script>`;
412
+ const css = `<style>${indexCss}</style>`;
413
+ const htmlReplaceParams = [
414
+ {
415
+ searchFor: javascriptReplaceSymbol,
416
+ injectString: script,
417
+ },
418
+ {
419
+ searchFor: cssReplaceSymbol,
420
+ injectString: css,
421
+ },
422
+ ];
423
+ cache.val = injectParams(indexHtml, htmlReplaceParams);
424
+ return cache.val;
425
+ }
426
+
427
+ export { parseRouterWithOptions, renderTrpcPanel };