diff --git a/docs-src/docs/replication-graphql.md b/docs-src/docs/replication-graphql.md index 5e4ffa40dc6..b4199db160c 100644 --- a/docs-src/docs/replication-graphql.md +++ b/docs-src/docs/replication-graphql.md @@ -157,6 +157,7 @@ const pullQueryBuilder = (checkpoint, limit) => { }`; return { query, + operationName: 'PullHuman', variables: { checkpoint, limit @@ -229,6 +230,7 @@ const pushQueryBuilder = rows => { }; return { query, + operationName: 'PushHuman', variables }; }; diff --git a/src/plugins/replication-graphql/query-builder-from-rx-schema.ts b/src/plugins/replication-graphql/query-builder-from-rx-schema.ts index 9e3d762c8ee..2414a857840 100644 --- a/src/plugins/replication-graphql/query-builder-from-rx-schema.ts +++ b/src/plugins/replication-graphql/query-builder-from-rx-schema.ts @@ -22,6 +22,7 @@ export function pullQueryBuilderFromRxSchema( const ucCollectionName = ucfirst(collectionName); const queryName = prefixes.pull + ucCollectionName; + const operationName = ucfirst(queryName); const outputFields = Object.keys(schema.properties).filter(k => !(input.ignoreOutputKeys as string[]).includes(k)); // outputFields.push(input.deletedField); @@ -29,7 +30,7 @@ export function pullQueryBuilderFromRxSchema( const checkpointInputName = ucCollectionName + 'Input' + prefixes.checkpoint; const builder: RxGraphQLReplicationPullQueryBuilder = (checkpoint: any, limit: number) => { - const query = 'query ' + ucfirst(queryName) + '($checkpoint: ' + checkpointInputName + ', $limit: Int!) {\n' + + const query = 'query ' + operationName + '($checkpoint: ' + checkpointInputName + ', $limit: Int!) {\n' + SPACING + SPACING + queryName + '(checkpoint: $checkpoint, limit: $limit) {\n' + SPACING + SPACING + SPACING + 'documents {\n' + SPACING + SPACING + SPACING + SPACING + outputFields.join('\n' + SPACING + SPACING + SPACING + SPACING) + '\n' + @@ -41,6 +42,7 @@ export function pullQueryBuilderFromRxSchema( '}'; return { query, + operationName, variables: { checkpoint, limit @@ -60,12 +62,13 @@ export function pullStreamBuilderFromRxSchema( const prefixes: Prefixes = input.prefixes as any; const ucCollectionName = ucfirst(collectionName); + const queryName = prefixes.stream + ucCollectionName; const outputFields = Object.keys(schema.properties).filter(k => !(input.ignoreOutputKeys as string[]).includes(k)); const headersName = ucCollectionName + 'Input' + prefixes.headers; const query = 'subscription on' + ucfirst(ensureNotFalsy(prefixes.stream)) + '($headers: ' + headersName + ') {\n' + - SPACING + prefixes.stream + ucCollectionName + '(headers: $headers) {\n' + + SPACING + queryName + '(headers: $headers) {\n' + SPACING + SPACING + SPACING + 'documents {\n' + SPACING + SPACING + SPACING + SPACING + outputFields.join('\n' + SPACING + SPACING + SPACING + SPACING) + '\n' + SPACING + SPACING + SPACING + '}\n' + @@ -96,15 +99,15 @@ export function pushQueryBuilderFromRxSchema( const ucCollectionName = ucfirst(collectionName); const queryName = prefixes.push + ucCollectionName; + const operationName = ucfirst(queryName); const variableName = collectionName + prefixes.pushRow; - const returnFields: string[] = Object.keys(input.schema.properties); const builder: RxGraphQLReplicationPushQueryBuilder = (pushRows) => { const query = '' + - 'mutation ' + prefixes.push + ucCollectionName + '($' + variableName + ': [' + ucCollectionName + 'Input' + prefixes.pushRow + '!]) {\n' + + 'mutation ' + operationName + '($' + variableName + ': [' + ucCollectionName + 'Input' + prefixes.pushRow + '!]) {\n' + SPACING + queryName + '(' + variableName + ': $' + variableName + ') {\n' + SPACING + SPACING + returnFields.join(',\n' + SPACING + SPACING) + '\n' + SPACING + '}\n' + @@ -137,6 +140,7 @@ export function pushQueryBuilderFromRxSchema( }; return { query, + operationName, variables }; }; diff --git a/src/types/plugins/replication-graphql.d.ts b/src/types/plugins/replication-graphql.d.ts index 562a820ef56..4a19ff9e31d 100644 --- a/src/types/plugins/replication-graphql.d.ts +++ b/src/types/plugins/replication-graphql.d.ts @@ -7,6 +7,7 @@ import { export interface RxGraphQLReplicationQueryBuilderResponseObject { query: string; + operationName?: string; variables: any; } diff --git a/test/helper/graphql-server.ts b/test/helper/graphql-server.ts index a5c07804efa..46cf3831b56 100644 --- a/test/helper/graphql-server.ts +++ b/test/helper/graphql-server.ts @@ -356,6 +356,7 @@ export async function spawn( writeHumans(writeRows: $writeRows) { id } } `, + operationName: 'CreateHumans', variables: { writeRows: [row] } diff --git a/test/unit/replication-graphql.test.ts b/test/unit/replication-graphql.test.ts index 1cd7461a264..0198cd5bb05 100644 --- a/test/unit/replication-graphql.test.ts +++ b/test/unit/replication-graphql.test.ts @@ -101,6 +101,7 @@ describe('replication-graphql.test.ts', () => { }; return Promise.resolve({ query, + operationName: 'FeedForRxDBReplication', variables }); }; @@ -122,6 +123,7 @@ describe('replication-graphql.test.ts', () => { }`; return { query, + operationName: 'onHumanChanged', variables: { headers } @@ -147,6 +149,7 @@ describe('replication-graphql.test.ts', () => { }; return Promise.resolve({ query, + operationName: 'CreateHumans', variables }); }; @@ -205,6 +208,27 @@ describe('replication-graphql.test.ts', () => { assert.strictEqual(res.data.info, 1); server.close(); }); + it('spawn and throw an unknown operation name', async () => { + const server = await SpawnServer.spawn(); + try { + await graphQLRequest( + ensureNotFalsy(server.url.http), + { + headers: {}, + credentials: undefined + }, + { + query: '{ info }', + operationName: 'info', + variables: {} + } + ); + } catch (err: any) { + assert.ok(err.message.includes('Unknown operation named "info".')); + } + + server.close(); + }); it('server.setDocument()', async () => { const server = await SpawnServer.spawn(); const doc = getTestData(1).pop(); @@ -508,6 +532,7 @@ describe('replication-graphql.test.ts', () => { return { query, + operationName: 'FeedForRxDBReplication', variables }; };