mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-26 02:35:58 +08:00
refactor(graphql): codegen (#10626)
This commit is contained in:
@@ -32,7 +32,5 @@ packages/backend/server/src/__tests__/__snapshots__
|
|||||||
packages/common/native/fixtures/**
|
packages/common/native/fixtures/**
|
||||||
packages/frontend/native/index.d.ts
|
packages/frontend/native/index.d.ts
|
||||||
packages/frontend/native/index.js
|
packages/frontend/native/index.js
|
||||||
packages/frontend/graphql/src/graphql/index.ts
|
|
||||||
packages/frontend/graphql/src/schema.ts
|
|
||||||
packages/frontend/apps/android/App/app/build/**
|
packages/frontend/apps/android/App/app/build/**
|
||||||
blocksuite/tests-legacy/snapshots
|
blocksuite/tests-legacy/snapshots
|
||||||
|
|||||||
@@ -33,8 +33,6 @@
|
|||||||
"packages/common/native/fixtures/**",
|
"packages/common/native/fixtures/**",
|
||||||
"packages/frontend/native/index.d.ts",
|
"packages/frontend/native/index.d.ts",
|
||||||
"packages/frontend/native/index.js",
|
"packages/frontend/native/index.js",
|
||||||
"packages/frontend/graphql/src/graphql/index.ts",
|
|
||||||
"packages/frontend/graphql/src/schema.ts",
|
|
||||||
"packages/frontend/apps/android/App/app/build/**",
|
"packages/frontend/apps/android/App/app/build/**",
|
||||||
"blocksuite/tests-legacy/snapshots"
|
"blocksuite/tests-legacy/snapshots"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export function Auth() {
|
|||||||
fetch('/graphql', {
|
fetch('/graphql', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
operationName: getUserFeaturesQuery.operationName,
|
operationName: getUserFeaturesQuery.op,
|
||||||
query: getUserFeaturesQuery.query,
|
query: getUserFeaturesQuery.query,
|
||||||
variables: {},
|
variables: {},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
type GetDocRolePermissionsQuery,
|
type GetDocRolePermissionsQuery,
|
||||||
getDocRolePermissionsQuery,
|
getDocRolePermissionsQuery,
|
||||||
|
type GetWorkspaceRolePermissionsQuery,
|
||||||
getWorkspaceRolePermissionsQuery,
|
getWorkspaceRolePermissionsQuery,
|
||||||
type WorkspacePermissions,
|
|
||||||
} from '@affine/graphql';
|
} from '@affine/graphql';
|
||||||
import { Store } from '@toeverything/infra';
|
import { Store } from '@toeverything/infra';
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ import type { WorkspaceServerService } from '../../cloud';
|
|||||||
import type { WorkspaceService } from '../../workspace';
|
import type { WorkspaceService } from '../../workspace';
|
||||||
|
|
||||||
export type WorkspacePermissionActions = keyof Omit<
|
export type WorkspacePermissionActions = keyof Omit<
|
||||||
WorkspacePermissions,
|
GetWorkspaceRolePermissionsQuery['workspaceRolePermissions']['permissions'],
|
||||||
'__typename'
|
'__typename'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const fs = require('node:fs');
|
const fs = require('node:fs');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
|
|
||||||
const { Kind, print } = require('graphql');
|
const { Kind, print, visit, TypeInfo, visitWithTypeInfo } = require('graphql');
|
||||||
const { upperFirst, lowerFirst } = require('lodash');
|
const { upperFirst, lowerFirst } = require('lodash');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,11 +19,82 @@ function getExportedName(def) {
|
|||||||
return name.endsWith(suffix) ? name : name + suffix;
|
return name.endsWith(suffix) ? name : name + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a field is deprecated in the schema
|
||||||
|
*
|
||||||
|
* @param {import('graphql').GraphQLSchema} schema
|
||||||
|
* @param {string} typeName
|
||||||
|
* @param {string} fieldName
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function fieldDeprecation(schema, typeName, fieldName) {
|
||||||
|
const type = schema.getType(typeName);
|
||||||
|
if (!type || !type.getFields) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fields = type.getFields();
|
||||||
|
const field = fields[fieldName];
|
||||||
|
|
||||||
|
return field?.deprecationReason
|
||||||
|
? {
|
||||||
|
name: fieldName,
|
||||||
|
reason: field.deprecationReason,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a query uses deprecated fields
|
||||||
|
*
|
||||||
|
* @param {import('graphql').GraphQLSchema} schema
|
||||||
|
* @param {import('graphql').DocumentNode} document
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function parseDeprecations(schema, document) {
|
||||||
|
const deprecations = [];
|
||||||
|
|
||||||
|
const typeInfo = new TypeInfo(schema);
|
||||||
|
|
||||||
|
visit(
|
||||||
|
document,
|
||||||
|
visitWithTypeInfo(typeInfo, {
|
||||||
|
Field: {
|
||||||
|
enter(node) {
|
||||||
|
const parentType = typeInfo.getParentType();
|
||||||
|
if (parentType && node.name) {
|
||||||
|
const fieldName = node.name.value;
|
||||||
|
let deprecation;
|
||||||
|
if (
|
||||||
|
parentType.name &&
|
||||||
|
(deprecation = fieldDeprecation(
|
||||||
|
schema,
|
||||||
|
parentType.name,
|
||||||
|
fieldName
|
||||||
|
))
|
||||||
|
) {
|
||||||
|
deprecations.push(deprecation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return deprecations.map(
|
||||||
|
({ name, reason }) => `'${name}' is deprecated: ${reason}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import('@graphql-codegen/plugin-helpers').CodegenPlugin}
|
* @type {import('@graphql-codegen/plugin-helpers').CodegenPlugin}
|
||||||
*/
|
*/
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugin: (schema, documents, { output }) => {
|
plugin: (schema, documents, { output }) => {
|
||||||
|
const defs = new Map();
|
||||||
|
const queries = [];
|
||||||
|
const mutations = [];
|
||||||
|
|
||||||
const nameLocationMap = new Map();
|
const nameLocationMap = new Map();
|
||||||
const locationSourceMap = new Map(
|
const locationSourceMap = new Map(
|
||||||
documents
|
documents
|
||||||
@@ -31,167 +102,162 @@ module.exports = {
|
|||||||
.map(source => [source.location, source])
|
.map(source => [source.location, source])
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
function addDef(exportedName, location) {
|
||||||
* @type {string[]}
|
if (nameLocationMap.has(exportedName)) {
|
||||||
*/
|
throw new Error(
|
||||||
const defs = [];
|
`name ${exportedName} export from ${location} are duplicated.`
|
||||||
const queries = [];
|
);
|
||||||
const mutations = [];
|
}
|
||||||
|
|
||||||
|
nameLocationMap.set(exportedName, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseImports(location) {
|
||||||
|
if (!location) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse '#import' lines
|
||||||
|
const importedDefinitions = [];
|
||||||
|
fs.readFileSync(location, 'utf-8')
|
||||||
|
.split(/\r\n|\r|\n/)
|
||||||
|
.forEach(line => {
|
||||||
|
if (line[0] === '#') {
|
||||||
|
const [importKeyword, importPath] = line.split(' ').filter(Boolean);
|
||||||
|
if (importKeyword === '#import') {
|
||||||
|
const realImportPath = path.posix.join(
|
||||||
|
location,
|
||||||
|
'..',
|
||||||
|
importPath.replace(/["']/g, '')
|
||||||
|
);
|
||||||
|
const imports =
|
||||||
|
locationSourceMap.get(realImportPath)?.document.definitions;
|
||||||
|
if (imports) {
|
||||||
|
importedDefinitions.push(...imports);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return importedDefinitions
|
||||||
|
.map(def => `\${${getExportedName(def)}}`)
|
||||||
|
.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
for (const [location, source] of locationSourceMap) {
|
for (const [location, source] of locationSourceMap) {
|
||||||
if (
|
if (!source || !source.document || !source.rawSDL) {
|
||||||
!source ||
|
|
||||||
!source.document ||
|
|
||||||
!location ||
|
|
||||||
source.document.kind !== Kind.DOCUMENT ||
|
|
||||||
!source.document.definitions ||
|
|
||||||
!source.document.definitions.length
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const doc = source.document;
|
visit(source.document, {
|
||||||
|
[Kind.OPERATION_DEFINITION]: {
|
||||||
|
enter: node => {
|
||||||
|
if (!node.name) {
|
||||||
|
throw new Error(
|
||||||
|
`Anonymous operation definition found in ${location}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (doc.definitions.length > 1) {
|
const exportedName = getExportedName(node);
|
||||||
throw new Error('Only support one definition per file.');
|
addDef(exportedName, location);
|
||||||
}
|
|
||||||
const definition = doc.definitions[0];
|
|
||||||
if (!definition) {
|
|
||||||
throw new Error(`Found empty file ${location}.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
// parse 'file' fields
|
||||||
!definition.selectionSet ||
|
const containsFile = node.variableDefinitions.some(def => {
|
||||||
!definition.selectionSet.selections ||
|
const varType = def?.type?.type?.name?.value;
|
||||||
definition.selectionSet.selections.length === 0
|
const checkContainFile = type => {
|
||||||
) {
|
if (schema.getType(type)?.name === 'Upload') return true;
|
||||||
throw new Error(`Found empty fields selection in file ${location}`);
|
const typeDef = schema.getType(type);
|
||||||
}
|
const fields = typeDef.getFields?.();
|
||||||
|
if (!fields || typeof fields !== 'object') return false;
|
||||||
if (
|
for (let field of Object.values(fields)) {
|
||||||
definition.kind === Kind.OPERATION_DEFINITION ||
|
let type = field.type;
|
||||||
definition.kind === Kind.FRAGMENT_DEFINITION
|
while (type.ofType) {
|
||||||
) {
|
type = type.ofType;
|
||||||
if (!definition.name) {
|
}
|
||||||
throw new Error(`Anonymous definition found in ${location}`);
|
if (type.name === 'Upload') {
|
||||||
}
|
return true;
|
||||||
|
|
||||||
const exportedName = getExportedName(definition);
|
|
||||||
|
|
||||||
// duplication checking
|
|
||||||
if (nameLocationMap.has(exportedName)) {
|
|
||||||
throw new Error(
|
|
||||||
`name ${exportedName} export from ${location} are duplicated.`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
/**
|
|
||||||
* @type {import('graphql').DefinitionNode[]}
|
|
||||||
*/
|
|
||||||
let importedDefinitions = [];
|
|
||||||
if (source.location) {
|
|
||||||
fs.readFileSync(source.location, 'utf8')
|
|
||||||
.split(/\r\n|\r|\n/)
|
|
||||||
.forEach(line => {
|
|
||||||
if (line[0] === '#') {
|
|
||||||
const [importKeyword, importPath] = line
|
|
||||||
.split(' ')
|
|
||||||
.filter(Boolean);
|
|
||||||
if (importKeyword === '#import') {
|
|
||||||
const realImportPath = path.posix.join(
|
|
||||||
location,
|
|
||||||
'..',
|
|
||||||
importPath.replace(/["']/g, '')
|
|
||||||
);
|
|
||||||
const imports =
|
|
||||||
locationSourceMap.get(realImportPath)?.document
|
|
||||||
.definitions;
|
|
||||||
if (imports) {
|
|
||||||
importedDefinitions = [
|
|
||||||
...importedDefinitions,
|
|
||||||
...imports,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const importing = importedDefinitions
|
|
||||||
.map(def => `\${${getExportedName(def)}}`)
|
|
||||||
.join('\n');
|
|
||||||
|
|
||||||
// is query or mutation
|
|
||||||
if (definition.kind === Kind.OPERATION_DEFINITION) {
|
|
||||||
// add for runtime usage
|
|
||||||
doc.operationName = definition.name.value;
|
|
||||||
doc.defName = definition.selectionSet.selections
|
|
||||||
.filter(field => field.kind === Kind.FIELD)
|
|
||||||
.map(field => field.name.value)
|
|
||||||
.join(',');
|
|
||||||
nameLocationMap.set(exportedName, location);
|
|
||||||
const containsFile = doc.definitions.some(def => {
|
|
||||||
const { variableDefinitions } = def;
|
|
||||||
if (variableDefinitions) {
|
|
||||||
return variableDefinitions.some(variableDefinition => {
|
|
||||||
const varType = variableDefinition?.type?.type?.name?.value;
|
|
||||||
const checkContainFile = type => {
|
|
||||||
if (schema.getType(type)?.name === 'Upload') return true;
|
|
||||||
const typeDef = schema.getType(type);
|
|
||||||
const fields = typeDef.getFields?.();
|
|
||||||
if (!fields || typeof fields !== 'object') return false;
|
|
||||||
for (let field of Object.values(fields)) {
|
|
||||||
let type = field.type;
|
|
||||||
while (type.ofType) {
|
|
||||||
type = type.ofType;
|
|
||||||
}
|
|
||||||
if (type.name === 'Upload') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
return varType ? checkContainFile(varType) : false;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
|
return varType ? checkContainFile(varType) : false;
|
||||||
});
|
});
|
||||||
defs.push(`export const ${exportedName} = {
|
|
||||||
id: '${exportedName}' as const,
|
// Check if the query uses deprecated fields
|
||||||
operationName: '${doc.operationName}',
|
const deprecations = parseDeprecations(schema, source.document);
|
||||||
definitionName: '${doc.defName}',
|
|
||||||
containsFile: ${containsFile},
|
const imports = parseImports(location);
|
||||||
query: \`
|
|
||||||
${print(doc)}${importing || ''}\`,
|
defs.set(exportedName, {
|
||||||
};
|
type: node.operation,
|
||||||
`);
|
name: exportedName,
|
||||||
if (definition.operation === 'query') {
|
operationName: node.name.value,
|
||||||
|
containsFile,
|
||||||
|
deprecations,
|
||||||
|
query: `${print(node)}${imports ? `\n${imports}` : ''}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (node.operation === 'query') {
|
||||||
queries.push(exportedName);
|
queries.push(exportedName);
|
||||||
} else if (definition.operation === 'mutation') {
|
} else if (node.operation === 'mutation') {
|
||||||
mutations.push(exportedName);
|
mutations.push(exportedName);
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
defs.unshift(`export const ${exportedName} = \`
|
},
|
||||||
${print(doc)}${importing || ''}\``);
|
[Kind.FRAGMENT_DEFINITION]: {
|
||||||
}
|
enter: node => {
|
||||||
}
|
const exportedName = getExportedName(node);
|
||||||
}
|
addDef(exportedName, location);
|
||||||
|
|
||||||
|
const imports = parseImports(location);
|
||||||
|
|
||||||
|
defs.set(exportedName, {
|
||||||
|
type: 'fragment',
|
||||||
|
name: exportedName,
|
||||||
|
content: `${print(node)}${imports || ''}`,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const preludes = [
|
||||||
|
'/* do not manipulate this file manually. */',
|
||||||
|
`export interface GraphQLQuery {
|
||||||
|
id: string;
|
||||||
|
op: string;
|
||||||
|
query: string;
|
||||||
|
file?: boolean;
|
||||||
|
deprecations?: string[];
|
||||||
|
}`,
|
||||||
|
];
|
||||||
|
|
||||||
|
const operations = [];
|
||||||
|
|
||||||
|
defs.forEach(def => {
|
||||||
|
if (def.type === 'fragment') {
|
||||||
|
preludes.push(`export const ${def.name} = \`${def.content}\`;`);
|
||||||
|
} else {
|
||||||
|
let item = `export const ${def.name} = {
|
||||||
|
id: '${def.name}' as const,
|
||||||
|
op: '${def.operationName}',
|
||||||
|
query: \`${def.query}\`,
|
||||||
|
`;
|
||||||
|
if (def.containsFile) {
|
||||||
|
item += ' file: true,\n';
|
||||||
|
}
|
||||||
|
if (def.deprecations.length) {
|
||||||
|
item += ` deprecations: ${JSON.stringify(def.deprecations)},\n`;
|
||||||
|
}
|
||||||
|
item += '};\n';
|
||||||
|
|
||||||
|
operations.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
output,
|
output,
|
||||||
[
|
preludes.join('\n') + '\n' + operations.join('\n')
|
||||||
'/* do not manipulate this file manually. */',
|
|
||||||
`export interface GraphQLQuery {
|
|
||||||
id: string;
|
|
||||||
operationName: string;
|
|
||||||
definitionName: string;
|
|
||||||
query: string;
|
|
||||||
containsFile?: boolean;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
...defs,
|
|
||||||
].join('\n')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const queriesUnion = queries
|
const queriesUnion = queries
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"build": "gql-gen --errors-only"
|
"build": "gql-gen --errors-only"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@affine/debug": "workspace:*",
|
||||||
"@affine/env": "workspace:*",
|
"@affine/env": "workspace:*",
|
||||||
"graphql": "^16.9.0",
|
"graphql": "^16.9.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import type { GraphQLQuery } from '../graphql';
|
|||||||
const query: GraphQLQuery = {
|
const query: GraphQLQuery = {
|
||||||
id: 'query',
|
id: 'query',
|
||||||
query: 'query { field }',
|
query: 'query { field }',
|
||||||
operationName: 'query',
|
op: 'query',
|
||||||
definitionName: 'query',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let fetch: Mock;
|
let fetch: Mock;
|
||||||
@@ -55,7 +54,6 @@ describe('GraphQL fetcher', () => {
|
|||||||
body: '{"query":"query { field }","variables":{"a":1,"b":"2","c":{"d":false}},"operationName":"query"}',
|
body: '{"query":"query { field }","variables":{"a":1,"b":"2","c":{"d":false}},"operationName":"query"}',
|
||||||
headers: expect.objectContaining({
|
headers: expect.objectContaining({
|
||||||
'content-type': 'application/json',
|
'content-type': 'application/json',
|
||||||
'x-definition-name': 'query',
|
|
||||||
'x-operation-name': 'query',
|
'x-operation-name': 'query',
|
||||||
}),
|
}),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { DebugLogger } from '@affine/debug';
|
||||||
import type { ExecutionResult } from 'graphql';
|
import type { ExecutionResult } from 'graphql';
|
||||||
import { isNil, isObject, merge } from 'lodash-es';
|
import { isNil, isObject, merge } from 'lodash-es';
|
||||||
|
|
||||||
@@ -156,11 +157,11 @@ function formatRequestBody<Q extends GraphQLQuery>({
|
|||||||
(keepNilVariables ?? true) ? variables : filterEmptyValue(variables),
|
(keepNilVariables ?? true) ? variables : filterEmptyValue(variables),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (query.operationName) {
|
if (query.op) {
|
||||||
body.operationName = query.operationName;
|
body.operationName = query.op;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.containsFile) {
|
if (query.file) {
|
||||||
return transformToForm(body);
|
return transformToForm(body);
|
||||||
}
|
}
|
||||||
return body;
|
return body;
|
||||||
@@ -170,15 +171,24 @@ export const gqlFetcherFactory = (
|
|||||||
endpoint: string,
|
endpoint: string,
|
||||||
fetcher: (input: string, init?: RequestInit) => Promise<Response> = fetch
|
fetcher: (input: string, init?: RequestInit) => Promise<Response> = fetch
|
||||||
) => {
|
) => {
|
||||||
|
const logger = new DebugLogger('GraphQL');
|
||||||
const gqlFetch = async <Query extends GraphQLQuery>(
|
const gqlFetch = async <Query extends GraphQLQuery>(
|
||||||
options: QueryOptions<Query>
|
options: QueryOptions<Query>
|
||||||
): Promise<QueryResponse<Query>> => {
|
): Promise<QueryResponse<Query>> => {
|
||||||
|
if (
|
||||||
|
BUILD_CONFIG.appBuildType === 'canary' &&
|
||||||
|
options.query.deprecations?.length
|
||||||
|
) {
|
||||||
|
options.query.deprecations.forEach(deprecation => {
|
||||||
|
logger.warn(deprecation);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const body = formatRequestBody(options);
|
const body = formatRequestBody(options);
|
||||||
|
|
||||||
const isFormData = body instanceof FormData;
|
const isFormData = body instanceof FormData;
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
'x-operation-name': options.query.operationName,
|
'x-operation-name': options.query.op,
|
||||||
'x-definition-name': options.query.definitionName,
|
|
||||||
};
|
};
|
||||||
if (!isFormData) {
|
if (!isFormData) {
|
||||||
headers['content-type'] = 'application/json';
|
headers['content-type'] = 'application/json';
|
||||||
@@ -208,8 +218,7 @@ export const gqlFetcherFactory = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw new GraphQLError(
|
throw new GraphQLError(
|
||||||
'GraphQL query responds unexpected result, query ' +
|
'GraphQL query responds unexpected result, query ' + options.query.op
|
||||||
options.query.operationName
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -571,6 +571,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@affine/graphql@workspace:packages/frontend/graphql"
|
resolution: "@affine/graphql@workspace:packages/frontend/graphql"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@affine/debug": "workspace:*"
|
||||||
"@affine/env": "workspace:*"
|
"@affine/env": "workspace:*"
|
||||||
"@graphql-codegen/add": "npm:^5.0.3"
|
"@graphql-codegen/add": "npm:^5.0.3"
|
||||||
"@graphql-codegen/cli": "npm:5.0.5"
|
"@graphql-codegen/cli": "npm:5.0.5"
|
||||||
|
|||||||
Reference in New Issue
Block a user