Skip to content

Commit

Permalink
Add definition merging boilerplate code
Browse files Browse the repository at this point in the history
  • Loading branch information
kitten committed Jan 10, 2024
1 parent 1aac7a9 commit f87e67c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
32 changes: 29 additions & 3 deletions src/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { parse as _parse } from '@0no-co/graphql.web';
import { Kind, parse as _parse } from '@0no-co/graphql.web';
import type { DocumentNode } from '@0no-co/graphql.web';

import type {
Expand Down Expand Up @@ -59,9 +59,35 @@ function graphql<
const Fragments extends readonly [...FragmentDefDecorationLike[]],
>(
input: In,
_fragments?: Fragments
fragments?: Fragments
): getDocumentNode<In, Schema, getFragmentsOfDocumentsRec<Fragments>> {
return _parse(input) as any;
const fragmentNames = new Map<string, unknown>();
const definitions = [...source.definitions];
const source = _parse(input);
for (const document of fragments) {
for (const definition of document.definitions) {
if (definition.kind === Kind.FRAGMENT_DEFINITION) {
const name = definition.name.value;
if (!fragmentNames.has(definition.name.value)) {
fragmentNames.set(definition.name.value, definition);
definitions.push(definition);
} else if (
process.env.NODE_ENV !== 'production' &&
fragmentNames.get(name) !== definition
) {
// Fragments with the same names is expected to have the same contents
console.warn(
'[WARNING: Duplicate Fragment] A fragment with name `' +
name +
'` already exists in this document.\n' +
'While fragment names may not be unique across your source, each name must be unique per document.'
);
}
}
}
}

return { kind: Kind.DOCUMENT, definitions };
}

/** A GraphQL `DocumentNode` with attached generics for its result data and variables.
Expand Down
6 changes: 3 additions & 3 deletions src/namespace.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Kind } from '@0no-co/graphql.web';
import type { Kind, DocumentNode } from '@0no-co/graphql.web';
import type { DocumentNodeLike } from './parser';
import type { obj } from './utils';

Expand Down Expand Up @@ -33,7 +33,7 @@ type getFragmentsOfDocumentsRec<Documents> = Documents extends readonly [
infer Document,
...infer Rest,
]
? (Document extends FragmentDefDecorationLike
? (Document extends { [$tada.fragmentDef]?: any }
? Exclude<Document[$tada.fragmentDef], undefined> extends infer FragmentDef extends {
kind: Kind.FRAGMENT_DEFINITION;
name: any;
Expand All @@ -45,7 +45,7 @@ type getFragmentsOfDocumentsRec<Documents> = Documents extends readonly [
getFragmentsOfDocumentsRec<Rest>
: {};

interface FragmentDefDecorationLike {
interface FragmentDefDecorationLike extends DocumentNode {
[$tada.fragmentDef]?: {
readonly [$tada.fragmentId]: symbol;
kind: Kind.FRAGMENT_DEFINITION;
Expand Down

0 comments on commit f87e67c

Please sign in to comment.