@miragejs/graphql
Version:
A library for handling GraphQL requests with Mirage JS
81 lines (69 loc) • 2.56 kB
text/typescript
import { camelize } from "miragejs/lib/utils/inflector.js";
import { capitalize } from "../utils.js";
import type { GraphQLObjectType } from "graphql";
import type MirageSchema from "miragejs/lib/orm/schema.js";
import type Model from "miragejs/lib/orm/model.js";
import type { QueryArgs } from "../@types/index.js";
export type TypedRecord = { [key: string]: any } & { __typename: string };
/**
* Adapts a record from Mirage's database to return in the GraphQL response. It
* flattens the attributes and relationships in a copy of the record. It also
* ensures the `__typename` attribute is added to the copy so GraphQL can
* resolve records of a polymorphic type.
*/
export function adaptRecord(record: Model): TypedRecord {
if (record == null) {
return;
}
const { attrs, associations } = record;
const __typename = capitalize(camelize(record.modelName));
const clone = { ...attrs, __typename };
for (const field in associations) {
clone[field] = record[field];
}
return clone;
}
/**
* Adapts a list of records from Mirage's database to return in the GraphQL
* response.
*/
export function adaptRecords(records: Model[]): TypedRecord[] {
return records.map(adaptRecord);
}
/**
* Gets records from Mirage's database for the given GraphQL type. It can filter
* the records by the given GraphQL arguments, if supplied. Filtering assumes
* each key in `args` corresponds to an attribute of the record.
*
* For more advanced filtering needs, or sorting, for example, you will need to
* implement your own resolver.
*/
export function getRecords(
type: GraphQLObjectType,
args: QueryArgs,
mirageSchema: MirageSchema
) {
const collectionName = mirageSchema.toCollectionName(type.name);
// TODO: Make the `where` bit opt-in
const records = mirageSchema[collectionName].where(args).models;
return adaptRecords(records);
}
/**
* Filters records by a hash of arguments. This is useful in cases where you
* have a list of records and don't need to fetch them from Mirage's database.
* Filtering assumes each key in `args` corresponds to an attribute of the
* record.
*
* For more advanced filtering needs, or sorting, for example, you will need to
* implement your own resolver.
*/
export function filterRecords(records: Model[], args: QueryArgs) {
if (args) {
records = records.filter(function (record) {
return Object.keys(args).reduce(function (isMatch, arg) {
return !isMatch ? isMatch : record[arg] === args[arg];
}, true);
});
}
return adaptRecords(records);
}