From 7bfd7e1379f124ccb3c0315d6d5ac242d18dfb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E4=BA=91=E9=B9=A4?= Date: Sat, 7 Oct 2023 16:16:17 +0800 Subject: [PATCH] add index derective --- packages/server/src/utils/graphql/parser.ts | 106 +++++++++++--------- 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/packages/server/src/utils/graphql/parser.ts b/packages/server/src/utils/graphql/parser.ts index 2f8dce8b..848afb94 100644 --- a/packages/server/src/utils/graphql/parser.ts +++ b/packages/server/src/utils/graphql/parser.ts @@ -1,73 +1,89 @@ import { parse } from 'graphql/language'; +import { of } from 'rxjs'; export function parseToCreateModelGraphqls(graphql: string): Map { const modelGraphqlsMap = new Map(); - if (!graphql || graphql.length == 0) return modelGraphqlsMap + if (!graphql || graphql.length == 0) return modelGraphqlsMap const ast = parse(graphql); if (!ast || ast.definitions.length == 0) return modelGraphqlsMap; - const enumTypeDefinitionMap = new Map(); - const objectTypeDefinitionMap = new Map(); - - const definitions = ast.definitions; - definitions.forEach((definition: any) => { - const name = definition.name.value; - const kand = definition.kind; - const directives = definition.directives; - // currently only support createModel directive - if (definition.directives?.length > 0 && definition.directives[0].name.value == 'createModel') { - const modelGraphqls = []; - // iterate fields - definition.fields.forEach((field: any) => { - // parse object type - const objectTypeName = field.type?.name?.value; - if (objectTypeName){ - if (objectTypeDefinitionMap.get(objectTypeName)){ - modelGraphqls.push(objectTypeDefinitionMap.get(objectTypeName).loc.source.body.slice(objectTypeDefinitionMap.get(objectTypeName).loc.start, objectTypeDefinitionMap.get(objectTypeName).loc.end)); + const createModelCount = (graphql.match(/@createModel/g) || []).length + if (createModelCount < 2) { + const definitions = ast.definitions; + for (let index = 0; index < definitions.length; index++) { + const definition: any = definitions[index]; + const name = definition.name.value; + if (definition.directives?.length > 0 && definition.directives[0].name.value == 'createModel') { + modelGraphqlsMap.set(name, [graphql]); + break; + } + } + }else { + const enumTypeDefinitionMap = new Map(); + const objectTypeDefinitionMap = new Map(); + const definitions = ast.definitions; + definitions.forEach((definition: any) => { + const name = definition.name.value; + const kand = definition.kind; + const directives = definition.directives; + // currently only support createModel directive + if (definition.directives?.length > 0 && definition.directives[0].name.value == 'createModel') { + const modelGraphqls = []; + // iterate fields + definition.fields.forEach((field: any) => { + // parse object type + const objectTypeName = field.type?.name?.value; + if (objectTypeName) { + if (objectTypeDefinitionMap.get(objectTypeName)) { + modelGraphqls.push(objectTypeDefinitionMap.get(objectTypeName).loc.source.body.slice(objectTypeDefinitionMap.get(objectTypeName).loc.start, objectTypeDefinitionMap.get(objectTypeName).loc.end)); + } } - } - - // parse enum type - const enumTypeName = field.type?.type?.name?.value; - if (enumTypeName){ - if (enumTypeDefinitionMap.get(enumTypeName)){ - modelGraphqls.push(enumTypeDefinitionMap.get(enumTypeName).loc.source.body.slice(enumTypeDefinitionMap.get(enumTypeName).loc.start, enumTypeDefinitionMap.get(enumTypeName).loc.end)); + + // parse enum type + const enumTypeName = field.type?.type?.name?.value; + if (enumTypeName) { + if (enumTypeDefinitionMap.get(enumTypeName)) { + modelGraphqls.push(enumTypeDefinitionMap.get(enumTypeName).loc.source.body.slice(enumTypeDefinitionMap.get(enumTypeName).loc.start, enumTypeDefinitionMap.get(enumTypeName).loc.end)); + } } + }); + modelGraphqls.push(definition.loc.source.body.slice(definition.loc.start, definition.loc.end)); + modelGraphqlsMap.set(name, modelGraphqls); + } + + // build enum/object type definition map + if (kand == 'EnumTypeDefinition') { + enumTypeDefinitionMap.set(name, definition); + } else if (kand == 'ObjectTypeDefinition') { + if (directives?.length > 0 && directives[0].name.value == 'loadModel') { + objectTypeDefinitionMap.set(name, definition); } - }); - modelGraphqls.push(definition.loc.source.body.slice(definition.loc.start, definition.loc.end)); - modelGraphqlsMap.set(name, modelGraphqls); - } - - // build enum/object type definition map - if (kand == 'EnumTypeDefinition') { - enumTypeDefinitionMap.set(name, definition); - }else if (kand == 'ObjectTypeDefinition') { - if (directives?.length > 0 && directives[0].name.value == 'loadModel'){ - objectTypeDefinitionMap.set(name, definition); + } else { + // TODO: handle other kind + console.log(`unknown kind: ${kand}`); } - }else { - // TODO: handle other kind - console.log(`unknown kind: ${kand}`); - } - }); + }); + } + return modelGraphqlsMap; } export function generateLoadModelGraphqls(sourceGraphql: string, targetModel: string, modelStreamIdMap: Map): string[] { const loadModelGraphqls: string[] = []; const modelGraphqlsMap = parseToCreateModelGraphqls(sourceGraphql); - if (modelGraphqlsMap.size == 0 ) return []; + if (modelGraphqlsMap.size == 0) return []; const modelGraphqls = modelGraphqlsMap.get(targetModel); if (!modelGraphqls || modelGraphqls?.length == 0) return []; - const createModelGraphql = modelGraphqls.find((modelGraphql: string) => modelGraphql.includes(`type ${targetModel} @createModel`)); + const createModelGraphql = modelGraphqls.find((modelGraphql: string) => + modelGraphql.replace(/(\r\n|\n|\r|\s)/g, "").includes(`type${targetModel}@createModel`) + ); const ast = parse(createModelGraphql); const definitions = ast.definitions; - definitions?.forEach((definition: any)=>{ + definitions?.forEach((definition: any) => { definition?.fields?.forEach((field: any) => { if (field.type.kind == 'NamedType') { const typeName = field.type.name.value;