Skip to content

Commit 5ead9e2

Browse files
authored
Merge branch 'master' into landing/texts
2 parents 1f60d04 + 924070a commit 5ead9e2

File tree

13 files changed

+713
-383
lines changed

13 files changed

+713
-383
lines changed

package-lock.json

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/api/package-lock.json

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/api/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"cross-fetch": "3.1.4",
4545
"faunadb": "4.2.0",
4646
"graphql": "15.3.0",
47+
"graphql-scalars": "^1.10.0",
4748
"graphql-tag": "2.11.0",
4849
"toucan-js": "2.5.0-beta.1",
4950
"uuid": "8.3.2"

packages/api/src/data/__tests__/index.ts

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,7 @@ import { Client, query as q } from "faunadb";
33
import { getProjectSchema } from "../index";
44
import { GraphQLSchema } from "graphql";
55
import scaffold from "../fauna/scaffold";
6-
import {
7-
OrganizationRepository,
8-
ProjectRepository,
9-
TableRespository,
10-
ScalarFieldRepository,
11-
RelationshipFieldRepository,
12-
} from "../fauna/repositories";
6+
import repositories from "../fauna/repositories";
137
import { definitions } from "../definitions";
148

159
jest.setTimeout(30000);
@@ -37,51 +31,73 @@ test("Integration Test", async () => {
3731
const test_client = new Client({
3832
secret,
3933
});
40-
const Organization = new OrganizationRepository(test_client);
41-
const Project = new ProjectRepository(test_client);
42-
const Table = new TableRespository(test_client);
43-
const ScalarField = new ScalarFieldRepository(test_client);
44-
const RelationshipField = new RelationshipFieldRepository(test_client);
34+
35+
const { organization, project, table, scalarField, relationshipField } =
36+
repositories(test_client);
4537
await scaffold(test_client);
4638

47-
const organizationId = await Organization.create({
39+
const organizationId = await organization.create({
4840
name: "LibraryOrg",
4941
apiName: "LibraryOrg",
5042
});
51-
const projectId = await Project.create({
43+
expect(
44+
organization.create({
45+
name: "ABC",
46+
apiName: "LibraryOrg",
47+
})
48+
).rejects.toThrow(/already exists/);
49+
50+
const projectId = await project.create({
51+
name: "WrongName",
52+
apiName: "WrongApiName",
53+
organizationId,
54+
});
55+
await project.update(projectId, {
5256
name: "LibraryProj",
5357
apiName: "LibraryProj",
5458
organizationId,
5559
});
5660

61+
expect(project.get(projectId)).resolves.toHaveProperty(
62+
"apiName",
63+
"LibraryProj"
64+
);
65+
5766
for (const [key, value] of Object.entries(tables)) {
58-
tables[key].id = await Table.create({
67+
tables[key].id = await table.create({
5968
...value,
6069
projectId,
6170
});
6271
}
6372

64-
await ScalarField.create({
73+
await scalarField.create({
6574
name: "title",
6675
apiName: "title",
6776
tableId: tables["Book"].id,
6877
type: "String",
6978
});
70-
await ScalarField.create({
79+
await scalarField.create({
7180
name: "name",
7281
apiName: "name",
7382
tableId: tables["Author"].id,
7483
type: "String",
7584
});
7685

77-
await RelationshipField.create({
78-
name: "authors",
79-
apiName: "authors",
80-
backName: "books",
81-
apiBackName: "books",
82-
to: tables["Author"].id,
83-
tableId: tables["Book"].id,
84-
});
86+
const [authorsFieldId, booksFieldId] =
87+
await relationshipField.createBidirectional({
88+
name: "authors",
89+
apiName: "wrongAuthors",
90+
backName: "books",
91+
backApiName: "wrongBooks",
92+
to: tables["Author"].id,
93+
tableId: tables["Book"].id,
94+
});
95+
96+
/**
97+
* If the relationship fields do not update correctly then the GraphQL queries after will automatically fail
98+
*/
99+
await relationshipField.update(authorsFieldId, { apiName: "authors" });
100+
await relationshipField.update(booksFieldId, { apiName: "books" });
85101

86102
const schema: GraphQLSchema = await getProjectSchema(test_client, projectId);
87103
const server = new ApolloServer({

packages/api/src/data/definitions.ts

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Table, FaunaSchema, RelationshipField } from "./types";
55

66
const generateRelationQueries = (field: RelationshipField) => {
77
const existingRelation = (id: string) =>
8-
q.Match(q.Index("relationsUnique"), [
8+
q.Match(q.Index("relations_unique"), [
99
field.relationshipRef,
1010
field.relationKey === "A"
1111
? q.Var("docRef")
@@ -20,36 +20,62 @@ const generateRelationQueries = (field: RelationshipField) => {
2020
if (!ids) return [];
2121
return ids.map((id: string) =>
2222
q.If(
23-
q.IsEmpty(existingRelation(id)),
24-
q.Create(q.Collection("relations"), {
25-
data: {
23+
q.Exists(
24+
q.Ref(
2625
// @ts-ignore
27-
relationshipRef: field.relationshipRef,
26+
q.Collection(field.to.id),
2827
// @ts-ignore
29-
[field.relationKey]: q.Var("docRef"),
30-
// @ts-ignore
31-
[field.relationKey === "A" ? "B" : "A"]: q.Ref(
28+
id
29+
)
30+
),
31+
q.If(
32+
q.IsEmpty(existingRelation(id)),
33+
q.Create(q.Collection("relations"), {
34+
data: {
3235
// @ts-ignore
33-
q.Collection(field.to.id),
36+
relationshipRef: field.relationshipRef,
3437
// @ts-ignore
35-
id
36-
),
37-
},
38-
}),
39-
q.Abort(`Object with id ${field.to.id} is already connected.`)
38+
[field.relationKey]: q.Var("docRef"),
39+
// @ts-ignore
40+
[field.relationKey === "A" ? "B" : "A"]: q.Ref(
41+
// @ts-ignore
42+
q.Collection(field.to.id),
43+
// @ts-ignore
44+
id
45+
),
46+
},
47+
}),
48+
q.Abort(`Object with id ${field.to.id} is already connected.`)
49+
),
50+
q.Abort(
51+
`Cannot connect object with id ${field.to.id} as it does not exist.`
52+
)
4053
)
4154
);
4255
},
4356
disconnect: (ids: Array<string>) => {
4457
if (!ids) return [];
4558
return ids.map((id: string) =>
4659
q.If(
47-
q.IsEmpty(existingRelation(id)),
48-
q.Abort(`Object with id ${field.to.id} does not exist.`),
60+
q.Exists(
61+
q.Ref(
62+
// @ts-ignore
63+
q.Collection(field.to.id),
64+
// @ts-ignore
65+
id
66+
)
67+
),
68+
q.If(
69+
q.IsEmpty(existingRelation(id)),
70+
q.Abort(`Object with id ${field.to.id} was not connected.`),
4971

50-
q.Map(
51-
q.Paginate(existingRelation(id)),
52-
q.Lambda("X", q.Delete(q.Var("X")))
72+
q.Map(
73+
q.Paginate(existingRelation(id)),
74+
q.Lambda("X", q.Delete(q.Var("X")))
75+
)
76+
),
77+
q.Abort(
78+
`Cannot disconnect object with id ${field.to.id} as it does not exist.`
5379
)
5480
)
5581
);
@@ -82,8 +108,19 @@ export const definitions = (
82108
if (args.before) {
83109
options.before = q.Ref(q.Collection(table.id), args.before);
84110
}
111+
let filter: boolean | Expr = true;
112+
if (args.where?.title_eq) {
113+
filter = q.Equals(
114+
args.where.title_eq,
115+
q.Select(["data", "294845251673129473"], q.Get(q.Var("ref")))
116+
);
117+
}
118+
85119
return q.Map(
86-
q.Paginate(q.Documents(q.Collection(table.id)), { ...options }),
120+
q.Filter(
121+
q.Paginate(q.Documents(q.Collection(table.id)), { ...options }),
122+
q.Lambda("ref", filter)
123+
),
87124
q.Lambda("ref", q.Get(q.Var("ref")))
88125
);
89126
},

0 commit comments

Comments
 (0)