Skip to content

Commit 324f1a6

Browse files
committed
export Utils as module to allow access to custom adapters
1 parent 21b6e95 commit 324f1a6

File tree

6 files changed

+185
-181
lines changed

6 files changed

+185
-181
lines changed

src/Utils.ts

Lines changed: 142 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -3,183 +3,175 @@ import IQueryBuilderOptions from "./IQueryBuilderOptions";
33
import NestedField, { isNestedField } from "./NestedField";
44
import VariableOptions from "./VariableOptions";
55

6-
export default class Utils {
7-
public static resolveVariables(operations: IQueryBuilderOptions[]): any {
8-
let ret: any = {};
9-
10-
for (const { variables, fields } of operations) {
11-
ret = {
12-
...ret,
13-
...variables,
14-
...((fields && Utils.getNestedVariables(fields)) || {}),
15-
};
16-
}
17-
return ret;
6+
export function resolveVariables(operations: IQueryBuilderOptions[]): any {
7+
let ret: any = {};
8+
9+
for (const { variables, fields } of operations) {
10+
ret = {
11+
...ret,
12+
...variables,
13+
...((fields && getNestedVariables(fields)) || {}),
14+
};
1815
}
16+
return ret;
17+
}
1918

20-
// Convert object to name and argument map. eg: (id: $id)
21-
public static queryDataNameAndArgumentMap(variables: VariableOptions) {
22-
return variables && Object.keys(variables).length
23-
? `(${Object.entries(variables).reduce((dataString, [key, value], i) => {
24-
return `${dataString}${i !== 0 ? ", " : ""}${
25-
value && value.name ? value.name : key
26-
}: $${key}`;
27-
}, "")})`
28-
: "";
29-
}
19+
// Convert object to name and argument map. eg: (id: $id)
20+
export function queryDataNameAndArgumentMap(variables: VariableOptions) {
21+
return variables && Object.keys(variables).length
22+
? `(${Object.entries(variables).reduce((dataString, [key, value], i) => {
23+
return `${dataString}${i !== 0 ? ", " : ""}${
24+
value && value.name ? value.name : key
25+
}: $${key}`;
26+
}, "")})`
27+
: "";
28+
}
3029

31-
public static queryFieldsMap(fields?: Fields): string {
32-
return fields
33-
? fields
34-
.map((field) => {
35-
if (isNestedField(field)) {
36-
return Utils.queryNestedFieldMap(field);
37-
} else if (typeof field === "object") {
38-
let result = "";
39-
40-
Object.entries<Fields>(field as Record<string, Fields>).forEach(
41-
([key, values], index, array) => {
42-
result += `${key} ${
43-
values.length > 0
44-
? "{ " + this.queryFieldsMap(values) + " }"
45-
: ""
46-
}`;
47-
48-
// If it's not the last item in array, join with comma
49-
if (index < array.length - 1) {
50-
result += ", ";
51-
}
30+
export function queryFieldsMap(fields?: Fields): string {
31+
return fields
32+
? fields
33+
.map((field) => {
34+
if (isNestedField(field)) {
35+
return queryNestedFieldMap(field);
36+
} else if (typeof field === "object") {
37+
let result = "";
38+
39+
Object.entries<Fields>(field as Record<string, Fields>).forEach(
40+
([key, values], index, array) => {
41+
result += `${key} ${
42+
values.length > 0 ? "{ " + queryFieldsMap(values) + " }" : ""
43+
}`;
44+
45+
// If it's not the last item in array, join with comma
46+
if (index < array.length - 1) {
47+
result += ", ";
5248
}
53-
);
54-
55-
return result;
56-
} else {
57-
return `${field}`;
58-
}
59-
})
60-
.join(", ")
61-
: "";
62-
}
49+
}
50+
);
6351

64-
public static operationOrAlias(
65-
operation: IQueryBuilderOptions["operation"]
66-
): string {
67-
return typeof operation === "string"
68-
? operation
69-
: `${operation.alias}: ${operation.name}`;
70-
}
52+
return result;
53+
} else {
54+
return `${field}`;
55+
}
56+
})
57+
.join(", ")
58+
: "";
59+
}
7160

72-
public static isFragment(field: NestedField): boolean {
73-
return field?.fragment === true ?? false;
74-
}
61+
function operationOrAlias(
62+
operation: IQueryBuilderOptions["operation"]
63+
): string {
64+
return typeof operation === "string"
65+
? operation
66+
: `${operation.alias}: ${operation.name}`;
67+
}
7568

76-
public static operationOrFragment(field: NestedField): string {
77-
return Utils.isFragment(field)
78-
? field.operation
79-
: Utils.operationOrAlias(field.operation);
80-
}
69+
function isFragment(field: NestedField): boolean {
70+
return field?.fragment === true ?? false;
71+
}
8172

82-
public static getFragment(field: NestedField): string {
83-
return Utils.isFragment(field) ? "... on " : "";
84-
}
73+
function operationOrFragment(field: NestedField): string {
74+
return isFragment(field)
75+
? field.operation
76+
: operationOrAlias(field.operation);
77+
}
8578

86-
public static queryNestedFieldMap(field: NestedField) {
87-
return `${Utils.getFragment(field)}${Utils.operationOrFragment(field)} ${
88-
this.isFragment(field)
89-
? ""
90-
: this.queryDataNameAndArgumentMap(field.variables)
91-
} ${
92-
field.fields.length > 0
93-
? "{ " + this.queryFieldsMap(field.fields) + " }"
94-
: ""
95-
}`;
96-
}
79+
function getFragment(field: NestedField): string {
80+
return isFragment(field) ? "... on " : "";
81+
}
9782

98-
// Variables map. eg: { "id": 1, "name": "Jon Doe" }
99-
public static queryVariablesMap(variables: any, fields?: Fields) {
100-
const variablesMapped: { [key: string]: unknown } = {};
101-
const update = (vars: any) => {
102-
if (vars) {
103-
Object.keys(vars).map((key) => {
104-
variablesMapped[key] =
105-
typeof vars[key] === "object" ? vars[key].value : vars[key];
106-
});
107-
}
108-
};
83+
export function queryNestedFieldMap(field: NestedField) {
84+
return `${getFragment(field)}${operationOrFragment(field)} ${
85+
isFragment(field) ? "" : queryDataNameAndArgumentMap(field.variables)
86+
} ${
87+
field.fields.length > 0 ? "{ " + queryFieldsMap(field.fields) + " }" : ""
88+
}`;
89+
}
10990

110-
update(variables);
111-
if (fields && typeof fields === "object") {
112-
update(Utils.getNestedVariables(fields));
91+
// Variables map. eg: { "id": 1, "name": "Jon Doe" }
92+
export function queryVariablesMap(variables: any, fields?: Fields) {
93+
const variablesMapped: { [key: string]: unknown } = {};
94+
const update = (vars: any) => {
95+
if (vars) {
96+
Object.keys(vars).map((key) => {
97+
variablesMapped[key] =
98+
typeof vars[key] === "object" ? vars[key].value : vars[key];
99+
});
113100
}
114-
return variablesMapped;
101+
};
102+
103+
update(variables);
104+
if (fields && typeof fields === "object") {
105+
update(getNestedVariables(fields));
115106
}
107+
return variablesMapped;
108+
}
116109

117-
public static getNestedVariables(fields: Fields) {
118-
let variables = {};
119-
120-
function getDeepestVariables(innerFields: Fields) {
121-
innerFields?.forEach((field: string | object | NestedField) => {
122-
if (isNestedField(field)) {
123-
variables = {
124-
...field.variables,
125-
...variables,
126-
...(field.fields && getDeepestVariables(field.fields)),
127-
};
128-
} else {
129-
if (typeof field === "object") {
130-
for (const [, value] of Object.entries(field)) {
131-
getDeepestVariables(value);
132-
}
110+
export function getNestedVariables(fields: Fields) {
111+
let variables = {};
112+
113+
function getDeepestVariables(innerFields: Fields) {
114+
innerFields?.forEach((field: string | object | NestedField) => {
115+
if (isNestedField(field)) {
116+
variables = {
117+
...field.variables,
118+
...variables,
119+
...(field.fields && getDeepestVariables(field.fields)),
120+
};
121+
} else {
122+
if (typeof field === "object") {
123+
for (const [, value] of Object.entries(field)) {
124+
getDeepestVariables(value);
133125
}
134126
}
135-
});
136-
137-
return variables;
138-
}
139-
140-
getDeepestVariables(fields);
127+
}
128+
});
141129

142130
return variables;
143131
}
144132

145-
public static queryDataType(variable: any) {
146-
let type = "String";
133+
getDeepestVariables(fields);
147134

148-
const value = typeof variable === "object" ? variable.value : variable;
135+
return variables;
136+
}
149137

150-
if (variable?.type != null) {
151-
type = variable.type;
152-
} else {
153-
// TODO: Should handle the undefined value (either in array value or single value)
154-
const candidateValue = Array.isArray(value) ? value[0] : value;
155-
switch (typeof candidateValue) {
156-
case "object":
157-
type = "Object";
158-
break;
138+
export function queryDataType(variable: any) {
139+
let type = "String";
159140

160-
case "boolean":
161-
type = "Boolean";
162-
break;
141+
const value = typeof variable === "object" ? variable.value : variable;
163142

164-
case "number":
165-
type = candidateValue % 1 === 0 ? "Int" : "Float";
166-
break;
167-
}
168-
}
143+
if (variable?.type != null) {
144+
type = variable.type;
145+
} else {
146+
// TODO: Should handle the undefined value (either in array value or single value)
147+
const candidateValue = Array.isArray(value) ? value[0] : value;
148+
switch (typeof candidateValue) {
149+
case "object":
150+
type = "Object";
151+
break;
169152

170-
// set object based variable properties
171-
if (typeof variable === "object") {
172-
if (variable.list === true) {
173-
type = `[${type}]`;
174-
} else if (Array.isArray(variable.list)) {
175-
type = `[${type}${variable.list[0] ? "!" : ""}]`;
176-
}
153+
case "boolean":
154+
type = "Boolean";
155+
break;
177156

178-
if (variable.required) {
179-
type += "!";
180-
}
157+
case "number":
158+
type = candidateValue % 1 === 0 ? "Int" : "Float";
159+
break;
181160
}
161+
}
182162

183-
return type;
163+
// set object based variable properties
164+
if (typeof variable === "object") {
165+
if (variable.list === true) {
166+
type = `[${type}]`;
167+
} else if (Array.isArray(variable.list)) {
168+
type = `[${type}${variable.list[0] ? "!" : ""}]`;
169+
}
170+
171+
if (variable.required) {
172+
type += "!";
173+
}
184174
}
175+
176+
return type;
185177
}

src/adapters/DefaultAppSyncMutationAdapter.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import Fields from "../Fields";
77
import IQueryBuilderOptions, { IOperation } from "../IQueryBuilderOptions";
88
import OperationType from "../OperationType";
9-
import Utils from "../Utils";
109
import IMutationAdapter from "./IMutationAdapter";
10+
import { queryDataType, queryVariablesMap, resolveVariables } from "../Utils";
1111

1212
export default class DefaultAppSyncMutationAdapter implements IMutationAdapter {
1313
private variables: any | undefined;
@@ -16,7 +16,7 @@ export default class DefaultAppSyncMutationAdapter implements IMutationAdapter {
1616

1717
constructor(options: IQueryBuilderOptions | IQueryBuilderOptions[]) {
1818
if (Array.isArray(options)) {
19-
this.variables = Utils.resolveVariables(options);
19+
this.variables = resolveVariables(options);
2020
} else {
2121
this.variables = options.variables;
2222
this.fields = options.fields;
@@ -39,7 +39,7 @@ export default class DefaultAppSyncMutationAdapter implements IMutationAdapter {
3939
return this.operationTemplate(opts.operation);
4040
});
4141
return this.operationWrapperTemplate(
42-
Utils.resolveVariables(mutations),
42+
resolveVariables(mutations),
4343
content.join("\n ")
4444
);
4545
}
@@ -58,7 +58,7 @@ export default class DefaultAppSyncMutationAdapter implements IMutationAdapter {
5858
return Object.keys(variables).length
5959
? `(${Object.keys(variables).reduce(
6060
(dataString, key, i) =>
61-
`${dataString}${i !== 0 ? ", " : ""}$${key}: ${Utils.queryDataType(
61+
`${dataString}${i !== 0 ? ", " : ""}$${key}: ${queryDataType(
6262
variables[key]
6363
)}`,
6464
""
@@ -77,7 +77,7 @@ export default class DefaultAppSyncMutationAdapter implements IMutationAdapter {
7777
} ${this.queryDataArgumentAndTypeMap(variables)} {
7878
${content}
7979
}`,
80-
variables: Utils.queryVariablesMap(variables),
80+
variables: queryVariablesMap(variables),
8181
};
8282
}
8383

0 commit comments

Comments
 (0)