Skip to content

Commit

Permalink
export Utils functions separately instead of exporting a class with s…
Browse files Browse the repository at this point in the history
…tatic methods
  • Loading branch information
yargyropoulos committed Dec 18, 2023
1 parent 21b6e95 commit ad693ea
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 181 deletions.
292 changes: 142 additions & 150 deletions src/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,183 +3,175 @@ import IQueryBuilderOptions from "./IQueryBuilderOptions";
import NestedField, { isNestedField } from "./NestedField";
import VariableOptions from "./VariableOptions";

export default class Utils {
public static resolveVariables(operations: IQueryBuilderOptions[]): any {
let ret: any = {};

for (const { variables, fields } of operations) {
ret = {
...ret,
...variables,
...((fields && Utils.getNestedVariables(fields)) || {}),
};
}
return ret;
export function resolveVariables(operations: IQueryBuilderOptions[]): any {
let ret: any = {};

for (const { variables, fields } of operations) {
ret = {
...ret,
...variables,
...((fields && getNestedVariables(fields)) || {}),
};
}
return ret;
}

// Convert object to name and argument map. eg: (id: $id)
public static queryDataNameAndArgumentMap(variables: VariableOptions) {
return variables && Object.keys(variables).length
? `(${Object.entries(variables).reduce((dataString, [key, value], i) => {
return `${dataString}${i !== 0 ? ", " : ""}${
value && value.name ? value.name : key
}: $${key}`;
}, "")})`
: "";
}
// Convert object to name and argument map. eg: (id: $id)
export function queryDataNameAndArgumentMap(variables: VariableOptions) {
return variables && Object.keys(variables).length
? `(${Object.entries(variables).reduce((dataString, [key, value], i) => {
return `${dataString}${i !== 0 ? ", " : ""}${
value && value.name ? value.name : key
}: $${key}`;
}, "")})`
: "";
}

public static queryFieldsMap(fields?: Fields): string {
return fields
? fields
.map((field) => {
if (isNestedField(field)) {
return Utils.queryNestedFieldMap(field);
} else if (typeof field === "object") {
let result = "";

Object.entries<Fields>(field as Record<string, Fields>).forEach(
([key, values], index, array) => {
result += `${key} ${
values.length > 0
? "{ " + this.queryFieldsMap(values) + " }"
: ""
}`;

// If it's not the last item in array, join with comma
if (index < array.length - 1) {
result += ", ";
}
export function queryFieldsMap(fields?: Fields): string {
return fields
? fields
.map((field) => {
if (isNestedField(field)) {
return queryNestedFieldMap(field);
} else if (typeof field === "object") {
let result = "";

Object.entries<Fields>(field as Record<string, Fields>).forEach(
([key, values], index, array) => {
result += `${key} ${
values.length > 0 ? "{ " + queryFieldsMap(values) + " }" : ""
}`;

// If it's not the last item in array, join with comma
if (index < array.length - 1) {
result += ", ";
}
);

return result;
} else {
return `${field}`;
}
})
.join(", ")
: "";
}
}
);

public static operationOrAlias(
operation: IQueryBuilderOptions["operation"]
): string {
return typeof operation === "string"
? operation
: `${operation.alias}: ${operation.name}`;
}
return result;
} else {
return `${field}`;
}
})
.join(", ")
: "";
}

public static isFragment(field: NestedField): boolean {
return field?.fragment === true ?? false;
}
function operationOrAlias(
operation: IQueryBuilderOptions["operation"]
): string {
return typeof operation === "string"
? operation
: `${operation.alias}: ${operation.name}`;
}

public static operationOrFragment(field: NestedField): string {
return Utils.isFragment(field)
? field.operation
: Utils.operationOrAlias(field.operation);
}
function isFragment(field: NestedField): boolean {
return field?.fragment === true ?? false;
}

public static getFragment(field: NestedField): string {
return Utils.isFragment(field) ? "... on " : "";
}
function operationOrFragment(field: NestedField): string {
return isFragment(field)
? field.operation
: operationOrAlias(field.operation);
}

public static queryNestedFieldMap(field: NestedField) {
return `${Utils.getFragment(field)}${Utils.operationOrFragment(field)} ${
this.isFragment(field)
? ""
: this.queryDataNameAndArgumentMap(field.variables)
} ${
field.fields.length > 0
? "{ " + this.queryFieldsMap(field.fields) + " }"
: ""
}`;
}
function getFragment(field: NestedField): string {
return isFragment(field) ? "... on " : "";
}

// Variables map. eg: { "id": 1, "name": "Jon Doe" }
public static queryVariablesMap(variables: any, fields?: Fields) {
const variablesMapped: { [key: string]: unknown } = {};
const update = (vars: any) => {
if (vars) {
Object.keys(vars).map((key) => {
variablesMapped[key] =
typeof vars[key] === "object" ? vars[key].value : vars[key];
});
}
};
export function queryNestedFieldMap(field: NestedField) {
return `${getFragment(field)}${operationOrFragment(field)} ${
isFragment(field) ? "" : queryDataNameAndArgumentMap(field.variables)
} ${
field.fields.length > 0 ? "{ " + queryFieldsMap(field.fields) + " }" : ""
}`;
}

update(variables);
if (fields && typeof fields === "object") {
update(Utils.getNestedVariables(fields));
// Variables map. eg: { "id": 1, "name": "Jon Doe" }
export function queryVariablesMap(variables: any, fields?: Fields) {
const variablesMapped: { [key: string]: unknown } = {};
const update = (vars: any) => {
if (vars) {
Object.keys(vars).map((key) => {
variablesMapped[key] =
typeof vars[key] === "object" ? vars[key].value : vars[key];
});
}
return variablesMapped;
};

update(variables);
if (fields && typeof fields === "object") {
update(getNestedVariables(fields));
}
return variablesMapped;
}

public static getNestedVariables(fields: Fields) {
let variables = {};

function getDeepestVariables(innerFields: Fields) {
innerFields?.forEach((field: string | object | NestedField) => {
if (isNestedField(field)) {
variables = {
...field.variables,
...variables,
...(field.fields && getDeepestVariables(field.fields)),
};
} else {
if (typeof field === "object") {
for (const [, value] of Object.entries(field)) {
getDeepestVariables(value);
}
export function getNestedVariables(fields: Fields) {
let variables = {};

function getDeepestVariables(innerFields: Fields) {
innerFields?.forEach((field: string | object | NestedField) => {
if (isNestedField(field)) {
variables = {
...field.variables,
...variables,
...(field.fields && getDeepestVariables(field.fields)),
};
} else {
if (typeof field === "object") {
for (const [, value] of Object.entries(field)) {
getDeepestVariables(value);
}
}
});

return variables;
}

getDeepestVariables(fields);
}
});

return variables;
}

public static queryDataType(variable: any) {
let type = "String";
getDeepestVariables(fields);

const value = typeof variable === "object" ? variable.value : variable;
return variables;
}

if (variable?.type != null) {
type = variable.type;
} else {
// TODO: Should handle the undefined value (either in array value or single value)
const candidateValue = Array.isArray(value) ? value[0] : value;
switch (typeof candidateValue) {
case "object":
type = "Object";
break;
export function queryDataType(variable: any) {
let type = "String";

case "boolean":
type = "Boolean";
break;
const value = typeof variable === "object" ? variable.value : variable;

case "number":
type = candidateValue % 1 === 0 ? "Int" : "Float";
break;
}
}
if (variable?.type != null) {
type = variable.type;
} else {
// TODO: Should handle the undefined value (either in array value or single value)
const candidateValue = Array.isArray(value) ? value[0] : value;
switch (typeof candidateValue) {
case "object":
type = "Object";
break;

// set object based variable properties
if (typeof variable === "object") {
if (variable.list === true) {
type = `[${type}]`;
} else if (Array.isArray(variable.list)) {
type = `[${type}${variable.list[0] ? "!" : ""}]`;
}
case "boolean":
type = "Boolean";
break;

if (variable.required) {
type += "!";
}
case "number":
type = candidateValue % 1 === 0 ? "Int" : "Float";
break;
}
}

return type;
// set object based variable properties
if (typeof variable === "object") {
if (variable.list === true) {
type = `[${type}]`;
} else if (Array.isArray(variable.list)) {
type = `[${type}${variable.list[0] ? "!" : ""}]`;
}

if (variable.required) {
type += "!";
}
}

return type;
}
10 changes: 5 additions & 5 deletions src/adapters/DefaultAppSyncMutationAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import Fields from "../Fields";
import IQueryBuilderOptions, { IOperation } from "../IQueryBuilderOptions";
import OperationType from "../OperationType";
import Utils from "../Utils";
import IMutationAdapter from "./IMutationAdapter";
import { queryDataType, queryVariablesMap, resolveVariables } from "../Utils";

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

constructor(options: IQueryBuilderOptions | IQueryBuilderOptions[]) {
if (Array.isArray(options)) {
this.variables = Utils.resolveVariables(options);
this.variables = resolveVariables(options);
} else {
this.variables = options.variables;
this.fields = options.fields;
Expand All @@ -39,7 +39,7 @@ export default class DefaultAppSyncMutationAdapter implements IMutationAdapter {
return this.operationTemplate(opts.operation);
});
return this.operationWrapperTemplate(
Utils.resolveVariables(mutations),
resolveVariables(mutations),
content.join("\n ")
);
}
Expand All @@ -58,7 +58,7 @@ export default class DefaultAppSyncMutationAdapter implements IMutationAdapter {
return Object.keys(variables).length
? `(${Object.keys(variables).reduce(
(dataString, key, i) =>
`${dataString}${i !== 0 ? ", " : ""}$${key}: ${Utils.queryDataType(
`${dataString}${i !== 0 ? ", " : ""}$${key}: ${queryDataType(
variables[key]
)}`,
""
Expand All @@ -77,7 +77,7 @@ export default class DefaultAppSyncMutationAdapter implements IMutationAdapter {
} ${this.queryDataArgumentAndTypeMap(variables)} {
${content}
}`,
variables: Utils.queryVariablesMap(variables),
variables: queryVariablesMap(variables),
};
}

Expand Down
Loading

0 comments on commit ad693ea

Please sign in to comment.