Skip to content

Commit

Permalink
requires + inaccessible + fragments (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilkisiela authored Apr 19, 2024
1 parent 5677f21 commit 00c0542
Show file tree
Hide file tree
Showing 6 changed files with 360 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import overrideWithRequiresTestCase from "./test-cases/override-with-requires";
import simpleInaccessible from "./test-cases/simple-inaccessible";
import enumIntersection from "./test-cases/enum-intersection";
import inputObjectIntersection from "./test-cases/input-object-intersection";
import requiresWithFragments from "./test-cases/requires-with-fragments";

const testCases = [
unionIntersectionTestCase,
Expand All @@ -27,6 +28,7 @@ const testCases = [
simpleInaccessible,
enumIntersection,
inputObjectIntersection,
requiresWithFragments,
];

function routerFetch(request: Request) {
Expand Down
81 changes: 81 additions & 0 deletions src/test-cases/requires-with-fragments/a.subgraph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { createSubgraph } from "../../subgraph";
import { bazs, entities, quxs } from "./data";

export default createSubgraph("a", {
typeDefs: /* GraphQL */ `
extend schema
@link(
url: "https://specs.apollo.dev/federation/v2.5"
import: ["@key", "@shareable"]
)
type Query @shareable {
a: Entity
}
type Entity @key(fields: "id") {
id: ID!
data: Foo
}
interface Foo {
foo: String!
}
interface Bar implements Foo {
foo: String!
bar: String!
}
type Baz implements Foo & Bar @shareable {
foo: String!
bar: String!
baz: String!
}
type Qux implements Foo & Bar @shareable {
foo: String!
bar: String!
qux: String!
}
`,
resolvers: {
Query: {
a() {
return entities[1];
},
},
Entity: {
__resolveReference(key: { id: string }) {
const entity = entities.find((e) => e.id === key.id);

if (!entity) {
return null;
}

return entity;
},
data(entity: { id: string; data: string }) {
const data = entities.find((e) => e.id === entity.id)?.data;

if (!data) {
return null;
}

const baz = bazs.find((b) => b.id === data);

if (baz) {
return baz;
}

const qux = quxs.find((q) => q.id === data);

if (qux) {
return qux;
}

throw new Error("Invalid data");
},
},
},
});
125 changes: 125 additions & 0 deletions src/test-cases/requires-with-fragments/b.subgraph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { createSubgraph } from "../../subgraph";
import { entities, bazs, quxs } from "./data";

type WithData<T> = T & {
data: {
foo: string;
} & ({ bar: string; baz: string } | { bar: string; qux: string });
};

export default createSubgraph("b", {
typeDefs: /* GraphQL */ `
extend schema
@link(
url: "https://specs.apollo.dev/federation/v2.5"
import: [
"@key"
"@shareable"
"@inaccessible"
"@external"
"@requires"
]
)
type Query @shareable {
b: Entity
bb: Entity
}
type Entity @key(fields: "id") {
id: ID!
data: Foo @external
requirer: String!
@requires(
fields: """
data {
foo
... on Bar {
bar
... on Baz {
baz
}
... on Qux {
qux
}
}
}
"""
)
}
interface Foo {
foo: String!
}
interface Bar implements Foo {
foo: String!
bar: String!
}
type Baz implements Foo & Bar @shareable @inaccessible {
foo: String!
bar: String!
baz: String!
}
type Qux implements Foo & Bar @shareable {
foo: String!
bar: String!
qux: String!
}
`,
resolvers: {
Query: {
b() {
return entities[0];
},
bb() {
return entities[1];
},
},
Entity: {
__resolveReference(key: { id: string } | WithData<{ id: string }>) {
const entity = entities.find((e) => e.id === key.id);

if (!entity) {
return null;
}

return {
...entity,
...key,
};
},
data(entity: { id: string }) {
const data = entities.find((e) => e.id === entity.id)?.data;

if (!data) {
return null;
}

const baz = bazs.find((b) => b.id === data);

if (baz) {
return baz;
}

const qux = quxs.find((q) => q.id === data);

if (qux) {
return qux;
}

throw new Error("Invalid data");
},
requirer(entity: WithData<{ id: string }>) {
console.log();
if (!("data" in entity)) {
throw new Error("Expected entity to have a data field");
}

return entity.data.foo + "_requirer";
},
},
},
});
30 changes: 30 additions & 0 deletions src/test-cases/requires-with-fragments/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const entities = [
{
id: "e1",
data: "b1",
},
{
id: "e2",
data: "q1",
},
];

export const bazs = [
{
__typename: "Baz",
id: "b1",
foo: "b1-foo",
bar: "b1-bar",
baz: "b1-baz",
},
];

export const quxs = [
{
__typename: "Qux",
id: "q1",
foo: "q1-foo",
bar: "q1-bar",
qux: "q1-qux",
},
];
6 changes: 6 additions & 0 deletions src/test-cases/requires-with-fragments/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { serve } from "../../supergraph";
import a from "./a.subgraph";
import b from "./b.subgraph";
import test from "./test";

export default serve("requires-with-fragments", [a, b], test);
116 changes: 116 additions & 0 deletions src/test-cases/requires-with-fragments/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { createTest } from "../../test";

export default [
createTest(
/* GraphQL */ `
query {
b {
id
data {
__typename
}
}
bb {
id
data {
__typename
}
}
}
`,
{
data: {
b: {
id: "e1",
data: null,
},
bb: {
id: "e2",
data: {
__typename: "Qux",
},
},
},
}
),
createTest(
/* GraphQL */ `
query {
a {
requirer
}
}
`,
{
data: {
a: {
requirer: "q1-foo_requirer",
},
},
}
),
createTest(
/* GraphQL */ `
query {
a {
data {
__typename
}
requirer
}
}
`,
{
data: {
a: {
data: {
__typename: "Qux",
},
requirer: "q1-foo_requirer",
},
},
}
),
createTest(
/* GraphQL */ `
query {
bb {
data {
__typename
}
requirer
}
}
`,
{
data: {
bb: {
data: {
__typename: "Qux",
},
requirer: "q1-foo_requirer",
},
},
}
),
createTest(
/* GraphQL */ `
query {
b {
data {
__typename
}
requirer
}
}
`,
{
data: {
b: {
data: null,
requirer: "b1-foo_requirer",
},
},
}
),
];

0 comments on commit 00c0542

Please sign in to comment.