diff --git a/docs/articles/guide/graphql/quick.md b/docs/articles/guide/graphql/quick.md index 95c529936..355ba40b3 100644 --- a/docs/articles/guide/graphql/quick.md +++ b/docs/articles/guide/graphql/quick.md @@ -190,3 +190,37 @@ It will generate: } } ``` + +It is also possible to generate a block with fields if to pass an empty string as the query parameter. + +```ts +const shape = toGraphQL('', selectUser); +``` + +It will generate: + +```graphql +{ + id + someRel { + id + } + # ... +} +``` + +Or to get a shape if to pass a selector only. + +```ts +const shape = toGraphQL(selectUser); +``` + +It will generate: + +```graphql +id +someRel { + id +} +# ... +``` diff --git a/libs/ngrx-entity-relationship/graphql/src/lib/toGraphQL.ts b/libs/ngrx-entity-relationship/graphql/src/lib/toGraphQL.ts index b4b636186..b0e2ca236 100644 --- a/libs/ngrx-entity-relationship/graphql/src/lib/toGraphQL.ts +++ b/libs/ngrx-entity-relationship/graphql/src/lib/toGraphQL.ts @@ -126,10 +126,11 @@ function encodeValue(data: any): string | undefined { export function toGraphQL(...queries: Array): string; export function toGraphQL(query: string, params: object, selector: ENTITY_SELECTOR): string; export function toGraphQL(query: string, selector: ENTITY_SELECTOR): string; +export function toGraphQL(selector: ENTITY_SELECTOR): string; export function toGraphQL(...queries: Array): string { const prefix = (window as any).ngrxGraphqlPrefix || ''; - let query = ''; + let query: string | undefined = ''; let selector: ENTITY_SELECTOR | undefined; let params: Record | null | string | undefined; if (queries.length >= 2 && typeof queries[1] !== 'string') { @@ -138,6 +139,9 @@ export function toGraphQL(...queries: Array): string { } else { [query, selector] = queries; } + } else if (queries.length === 1 && typeof queries[0] !== 'string') { + [selector] = queries; + query = undefined; } const stringParams: Array = []; @@ -165,11 +169,19 @@ export function toGraphQL(...queries: Array): string { params = stringParams.length ? `(${stringParams.join(`,${prefix ? ' ' : ''}`)})` : ''; if (selector) { - return `{\n${prefix}${query}${params}${prefix ? ' ' : ''}{\n${resolveGraphQL(selector, { + let gql = resolveGraphQL(selector, { include: [], prefix: `${prefix}`, level: 2, - })}${prefix}}\n}`; + }); + + if (query === undefined) { + return gql; + } + + gql = `{\n${gql}${prefix}}`; + + return query ? `{\n${prefix}${query}${params}${prefix ? ' ' : ''}${gql}\n}` : gql; } const parts: Array = []; for (let part of queries) { diff --git a/libs/ngrx-entity-relationship/test/graphql/src/lib/toGraphQL.spec.ts b/libs/ngrx-entity-relationship/test/graphql/src/lib/toGraphQL.spec.ts new file mode 100644 index 000000000..bb2bb8318 --- /dev/null +++ b/libs/ngrx-entity-relationship/test/graphql/src/lib/toGraphQL.spec.ts @@ -0,0 +1,65 @@ +import {childEntitySelector, rootEntitySelector} from 'ngrx-entity-relationship'; +import {toGraphQL} from 'ngrx-entity-relationship/graphql'; + +describe('toGraphQL', () => { + const root = rootEntitySelector(jasmine.createSpy(), { + gqlFields: ['id', 'name'], + }); + const rootChild = childEntitySelector(jasmine.createSpy(), 'childId', 'child', { + gqlFields: ['subId', 'subName'], + }); + const selector = root(rootChild()); + + const normalize = (query: string) => + query + .replace(/\s+/gm, ' ') + .replace(/\s*([{}])\s*/gm, '$1') + .trim(); + + it('generates a wrapped block with a query', () => { + expect(normalize(toGraphQL('data', selector))).toEqual( + normalize(` + { + data { + child { + childId + subId + subName + } + id + name + } + }`), + ); + }); + + it('generates a block with an empty query', () => { + expect(normalize(toGraphQL('', selector))).toEqual( + normalize(` + { + child { + childId + subId + subName + } + id + name + } + `), + ); + }); + + it('generates fields without a query', () => { + expect(normalize(toGraphQL(selector))).toEqual( + normalize(` + child { + childId + subId + subName + } + id + name + `), + ); + }); +});