Skip to content

Commit

Permalink
Merge branch 'gs-11-api-scaffolding' of github.com:glenstack/.glensta…
Browse files Browse the repository at this point in the history
…ck into gs-11-api-scaffolding
  • Loading branch information
GregBrimble committed Jun 12, 2021
2 parents 8ca19cc + 678a6b8 commit 60b01bf
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 89 deletions.
185 changes: 143 additions & 42 deletions packages/api/src/data/definitions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,61 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Expr, query as q } from "faunadb";
import { Table, FaunaSchema } from "./types";
import { Table, FaunaSchema, RelationshipField } from "./types";

const generateRelationQueries = (field: RelationshipField) => {
const existingRelation = (id: string) =>
q.Match(q.Index("relationsUnique"), [
field.relationshipRef,
field.relationKey === "A"
? q.Var("docRef")
: q.Ref(q.Collection(field.to.id), id),
field.relationKey === "B"
? q.Var("docRef")
: q.Ref(q.Collection(field.to.id), id),
]);

return {
connect: (ids: Array<string>) => {
if (!ids) return [];
return ids.map((id: string) =>
q.If(
q.IsEmpty(existingRelation(id)),
q.Create(q.Collection("relations"), {
data: {
// @ts-ignore
relationshipRef: field.relationshipRef,
// @ts-ignore
[field.relationKey]: q.Var("docRef"),
// @ts-ignore
[field.relationKey === "A" ? "B" : "A"]: q.Ref(
// @ts-ignore
q.Collection(field.to.id),
// @ts-ignore
id
),
},
}),
q.Abort(`Object with id ${field.to.id} is already connected.`)
)
);
},
disconnect: (ids: Array<string>) => {
if (!ids) return [];
return ids.map((id: string) =>
q.If(
q.IsEmpty(existingRelation(id)),
q.Abort(`Object with id ${field.to.id} does not exist.`),

q.Map(
q.Paginate(existingRelation(id)),
q.Lambda("X", q.Delete(q.Var("X")))
)
)
);
},
};
};

export const definitions = (
table: Pick<Table, "apiName" | "id">
Expand All @@ -16,7 +70,7 @@ export const definitions = (
} => ({
queries: {
findMany: {
name: (): string => table.apiName + "GetMany",
name: (): string => "query" + table.apiName,
// @ts-ignore
query: (args): Expr => {
const options: { size: number; after?: Expr; before?: Expr } = {
Expand All @@ -34,6 +88,13 @@ export const definitions = (
);
},
},
findOne: {
name: (): string => "get" + table.apiName,
// @ts-ignore
query: (args: { id: string }): Expr => {
return q.Get(q.Ref(q.Collection(table.id), args.id));
},
},
createOne: {
name: () => table.apiName + "CreateOne",
// @ts-ignore
Expand All @@ -42,52 +103,92 @@ export const definitions = (
args,
faunaSchema: FaunaSchema
) => {
{
const data: Record<string, unknown> = {};
let relationQueries;
// const args = getArgumentValues(field, node);
for (const [key, value] of Object.entries(args.input)) {
const faunaField = faunaSchema[table.apiName].fields[key];
if (faunaField.type === "Relation") {
relationQueries = q.Do(
// @ts-ignore
value.connect.map((idToConnect: string) =>
q.Create(q.Collection("relations"), {
data: {
// @ts-ignore
relationshipRef: faunaField.relationshipRef,
// @ts-ignore
[faunaField.relationKey]: q.Var("docRef"),
// @ts-ignore
[faunaField.relationKey === "A" ? "B" : "A"]: q.Ref(
// @ts-ignore
q.Collection(faunaField.to.id),
// @ts-ignore
idToConnect
),
},
})
)
);
} else {
data[faunaField.id] = value;
const data: Record<string, unknown> = {};
let relationQueries: Array<Expr> = [];
// const args = getArgumentValues(field, node);
for (const [key, value] of Object.entries(args.input)) {
const faunaField = faunaSchema[table.apiName].fields[key];
if (faunaField.type === "Relation") {
relationQueries = [
...relationQueries,
// @ts-ignore
...generateRelationQueries(faunaField).connect(value.connect),
];
} else {
data[faunaField.id] = value;
}
}
return q.Select(
["doc"],
q.Let(
{
docRef: q.Select(
["ref"],
q.Create(q.Collection(faunaSchema[table.apiName].id), {
data,
})
),
},
{
doc: q.Get(q.Var("docRef")),
relationQueries: q.Do(relationQueries),
}
)
);
},
},
updateOne: {
name: () => table.apiName + "UpdateOne",
// @ts-ignore
query: (
// @ts-ignore
args: GiraphQLFieldKindToConfig<table.apiName, "args">,
faunaSchema: FaunaSchema
) => {
const data: Record<string, unknown> = {};
let relationQueries: Array<Expr> = [];
// const args = getArgumentValues(field, node);
for (const [key, value] of Object.entries(args.input)) {
const faunaField = faunaSchema[table.apiName].fields[key];
if (faunaField.type === "Relation") {
relationQueries = [
...relationQueries,
// @ts-ignore
...generateRelationQueries(faunaField).connect(value.connect),
...generateRelationQueries(faunaField).disconnect(
// @ts-ignore
value.disconnect
),
];
} else {
data[faunaField.id] = value;
}
return q.Select(
["doc"],
q.Let(
{
docRef: q.Select(
}
return q.Select(
["doc"],
q.Let(
{
toUpdateRef: q.Ref(
q.Collection(faunaSchema[table.apiName].id),
args.id
),
docRef: q.If(
q.Exists(q.Var("toUpdateRef")),
q.Select(
["ref"],
q.Create(q.Collection(faunaSchema[table.apiName].id), {
q.Update(q.Var("toUpdateRef"), {
data,
})
),
},
{ doc: q.Get(q.Var("docRef")), relationQueries }
)
);
}
q.Abort("Object does not exist.")
),
},
{
doc: q.Get(q.Var("docRef")),
relationQueries: q.Do(relationQueries),
}
)
);
},
},
},
Expand Down
20 changes: 20 additions & 0 deletions packages/api/src/data/fauna/scaffold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,24 @@ export default async (client: Client): Promise<void> => {
],
})
);

await client.query(
q.CreateIndex({
name: "relationsUnique",
unique: true,
serialized: true,
source: q.Collection("relations"),
terms: [
{
field: ["data", "relationshipRef"],
},
{
field: ["data", "A"],
},
{
field: ["data", "B"],
},
],
})
);
};
3 changes: 2 additions & 1 deletion packages/api/src/data/generateFaunaQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ const generateSelector = (
name,
q.Select(
["data", faunaSchema[parentType.name].fields[name].id],
CURRENT_DOC_VAR
CURRENT_DOC_VAR,
null
),
];
};
Expand Down

0 comments on commit 60b01bf

Please sign in to comment.