-
Notifications
You must be signed in to change notification settings - Fork 45
/
DefaultSubscriptionAdapter.ts
112 lines (103 loc) · 3.27 KB
/
DefaultSubscriptionAdapter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
@class DefaultMutationAdapter
@desc A basic implementation to use
@desc modify the output of the subscription template by passing a second argument to subscription(options, AdapterClass)
*/
import Fields from "../Fields";
import IQueryBuilderOptions, { IOperation } from "../IQueryBuilderOptions";
import OperationType from "../OperationType";
import Utils from "../Utils";
import ISubscriptionAdapter from "./ISubscriptionAdapter";
export default class DefaultSubscriptionAdapter
implements ISubscriptionAdapter
{
private variables: any | undefined;
private fields: Fields | undefined;
private operation!: string | IOperation;
constructor(options: IQueryBuilderOptions | IQueryBuilderOptions[]) {
if (Array.isArray(options)) {
this.variables = Utils.resolveVariables(options);
} else {
this.variables = options.variables;
this.fields = options.fields;
this.operation = options.operation;
}
}
public subscriptionBuilder() {
return this.operationWrapperTemplate(
OperationType.Subscription,
this.variables,
this.operationTemplate(this.operation)
);
}
public subscriptionsBuilder(subscriptions: IQueryBuilderOptions[]) {
const content = subscriptions.map((opts) => {
this.operation = opts.operation;
this.variables = opts.variables;
this.fields = opts.fields;
return this.operationTemplate(opts.operation);
});
return this.operationWrapperTemplate(
OperationType.Subscription,
Utils.resolveVariables(subscriptions),
content.join("\n ")
);
}
// Convert object to name and argument map. eg: (id: $id)
private queryDataNameAndArgumentMap() {
return this.variables && Object.keys(this.variables).length
? `(${Object.keys(this.variables).reduce(
(dataString, key, i) =>
`${dataString}${i !== 0 ? ", " : ""}${key}: $${key}`,
""
)})`
: "";
}
private queryDataArgumentAndTypeMap(variables: any): string {
return Object.keys(variables).length
? `(${Object.keys(variables).reduce(
(dataString, key, i) =>
`${dataString}${i !== 0 ? ", " : ""}$${key}: ${Utils.queryDataType(
variables[key]
)}`,
""
)})`
: "";
}
// start of subscription building
private operationWrapperTemplate(
type: OperationType,
variables: any,
content: string
) {
return {
query: `${type} ${this.queryDataArgumentAndTypeMap(variables)} {
${content}
}`,
variables: Utils.queryVariablesMap(variables),
};
}
private operationTemplate(operation: string | IOperation) {
const operationName =
typeof this.operation === "string"
? this.operation
: `${this.operation.alias}: ${this.operation.name}`;
return `${operationName} ${this.queryDataNameAndArgumentMap()} {
${this.queryFieldsMap(this.fields)}
}`;
}
// Fields selection map. eg: { id, name }
private queryFieldsMap(fields?: Fields): string {
return fields
? fields
.map((field) =>
typeof field === "object"
? `${Object.keys(field)[0]} { ${this.queryFieldsMap(
Object.values(field)[0]
)} }`
: `${field}`
)
.join(", ")
: "";
}
}