graphql-data-generator 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/esm/init.js ADDED
@@ -0,0 +1,133 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { parse } from "graphql";
3
+ import { dirname, join } from "node:path";
4
+ import { operation, proxy, withGetDefaultPatch } from "./proxy.js";
5
+ import { toObject } from "./util.js";
6
+ const files = {};
7
+ const loadFile = (path) => files[path] = readFileSync(path, "utf-8").replace(/#import "(.*)"/, (_, fragmentPath) => loadFile(join(dirname(path), fragmentPath)));
8
+ // - Types will be suffixed with their type: fooQuery or fooMutation
9
+ export const init = (schema, queries, mutations, subscriptions, types, inputs, scalars, options) => (fn) => {
10
+ const doc = parse(schema);
11
+ const build = {};
12
+ const transforms = fn(build);
13
+ const addObjectTransforms = (type, obj) => {
14
+ Object.defineProperty(obj, "patch", {
15
+ value: (...patches) => build[type]((typeof obj === "function" ? obj() : obj), ...patches),
16
+ });
17
+ Object.defineProperties(obj, Object.fromEntries(Object.entries(transforms[type] ?? {}).map(([name, fn]) => [name, {
18
+ value: (...args) => {
19
+ const prev = typeof obj === "function" ? obj() : obj;
20
+ const patch = (typeof fn === "function"
21
+ ? fn(prev, ...args)
22
+ : fn);
23
+ return build[type](prev, patch);
24
+ },
25
+ }])));
26
+ return obj;
27
+ };
28
+ const wrap = (type, patches) => withGetDefaultPatch((type) => transforms[type]?.default, () => toObject(proxy(doc.definitions, scalars, type, ...patches)));
29
+ const objectBuilder = (type) => addObjectTransforms(type, (...patches) => {
30
+ if (transforms[type] && "default" in transforms[type]) {
31
+ patches = [
32
+ transforms[type].default,
33
+ ...patches,
34
+ ];
35
+ }
36
+ return addObjectTransforms(type, wrap(type, patches));
37
+ });
38
+ for (const type of types) {
39
+ build[type] = objectBuilder(type);
40
+ }
41
+ for (const input of inputs) {
42
+ build[input] = objectBuilder(input);
43
+ }
44
+ const resolveOperationConflicts = (operation, kind, otherNames) => {
45
+ if (!otherNames.includes(operation))
46
+ return operation;
47
+ return `${kind}${operation[0].toUpperCase()}${operation.slice(1)}`;
48
+ };
49
+ const addOperationTransforms = (operation, obj) => {
50
+ Object.defineProperty(obj, "patch", {
51
+ value: (...patches) => {
52
+ const prev = typeof obj === "function" ? obj() : obj;
53
+ const builder = build[operation];
54
+ const { result, request, error, ...rest } = prev;
55
+ return builder({
56
+ data: result.data,
57
+ variables: request.variables,
58
+ error: error,
59
+ errors: result.errors,
60
+ ...rest,
61
+ }, ...patches);
62
+ },
63
+ });
64
+ Object.defineProperties(obj, Object.fromEntries(Object.entries(transforms[operation] ?? {}).map(([name, fn]) => [name, {
65
+ value: (...args) => {
66
+ const prev = typeof obj === "function" ? obj() : obj;
67
+ const prevInput = {
68
+ data: prev.result.data,
69
+ variables: prev.request.variables,
70
+ error: prev.error,
71
+ errors: prev.result.errors,
72
+ };
73
+ const operationFn = fn;
74
+ const patch = (typeof operationFn === "function"
75
+ ? operationFn(prevInput, ...args)
76
+ : operationFn);
77
+ const builder = build[operation];
78
+ return builder(prevInput, patch);
79
+ },
80
+ }])));
81
+ return obj;
82
+ };
83
+ const operationBuilder = (name, path) => addOperationTransforms(name, (...patches) => {
84
+ const query = files[path] ?? loadFile(path);
85
+ if (transforms[name] && "default" in transforms[name]) {
86
+ patches = [transforms[name].default, ...patches];
87
+ }
88
+ const result = toObject(operation(doc.definitions, scalars, query, ...patches));
89
+ return addOperationTransforms(name, options?.finalizeOperation
90
+ ? options.finalizeOperation(result)
91
+ : result);
92
+ });
93
+ {
94
+ const nonQueryNames = [
95
+ ...Object.keys(mutations),
96
+ ...Object.keys(subscriptions),
97
+ ...types,
98
+ ...inputs,
99
+ ];
100
+ for (const query in queries) {
101
+ build[resolveOperationConflicts(query, "query", nonQueryNames)] =
102
+ // deno-lint-ignore no-explicit-any
103
+ operationBuilder(query, queries[query]);
104
+ }
105
+ }
106
+ {
107
+ const nonMutationNames = [
108
+ ...Object.keys(queries),
109
+ ...Object.keys(subscriptions),
110
+ ...types,
111
+ ...inputs,
112
+ ];
113
+ for (const mutation in mutations) {
114
+ build[resolveOperationConflicts(mutation, "mutation", nonMutationNames)] =
115
+ // deno-lint-ignore no-explicit-any
116
+ operationBuilder(mutation, mutations[mutation]);
117
+ }
118
+ }
119
+ {
120
+ const nonSubscriptionNames = [
121
+ ...Object.keys(queries),
122
+ ...Object.keys(mutations),
123
+ ...types,
124
+ ...inputs,
125
+ ];
126
+ for (const subscription in subscriptions) {
127
+ build[resolveOperationConflicts(subscription, "subscription", nonSubscriptionNames)
128
+ // deno-lint-ignore no-explicit-any
129
+ ] = operationBuilder(subscription, subscriptions[subscription]);
130
+ }
131
+ }
132
+ return build;
133
+ };
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/esm/proxy.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { DefinitionNode } from "graphql";
2
+ import type { OperationMock, Patch, SimpleOperationMock } from "./types.js";
3
+ export declare const withGetDefaultPatch: <T>(newGetDefaultPatch: <U>(__typename: string) => Patch<U> | ((prev: U) => Patch<U> | undefined) | undefined, fn: () => T) => T;
4
+ export declare const proxy: <T>(definitions: readonly DefinitionNode[], scalars: Record<string, unknown | ((typename: string) => unknown)>, type: string, ...patches: (Patch<T> | ((prev: T) => Patch<T>))[]) => T;
5
+ export declare const operation: <O extends SimpleOperationMock, Extra = object>(definitions: readonly DefinitionNode[], scalars: Record<string, unknown | ((typename: string) => unknown)>, query: string, ...patches: (Patch<Omit<O, "error" | "errors">> & {
6
+ error?: O["error"];
7
+ errors?: O["errors"];
8
+ } & Partial<Extra>)[]) => OperationMock<O["data"], O["variables"]> & Partial<Extra>;