feat(*): Modules export entities and fields (#5242)
This commit is contained in:
committed by
GitHub
parent
eeceec791c
commit
130cbc1f43
91
packages/modules-sdk/src/utils/clean-graphql-schema.ts
Normal file
91
packages/modules-sdk/src/utils/clean-graphql-schema.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { Kind, parse, print, visit } from "graphql"
|
||||
|
||||
export function cleanGraphQLSchema(schema: string): {
|
||||
schema: string
|
||||
notFound: Record<string, Record<string, string>>
|
||||
} {
|
||||
const extractTypeNameAndKind = (type) => {
|
||||
if (type.kind === Kind.NAMED_TYPE) {
|
||||
return [type.name.value, type.kind]
|
||||
}
|
||||
if (type.kind === Kind.NON_NULL_TYPE || type.kind === Kind.LIST_TYPE) {
|
||||
return extractTypeNameAndKind(type.type)
|
||||
}
|
||||
return [null, null]
|
||||
}
|
||||
|
||||
const ast = parse(schema)
|
||||
|
||||
const typeNames = new Set(["String", "Int", "Float", "Boolean", "ID"])
|
||||
const extendedTypes = new Set()
|
||||
|
||||
const kinds = [
|
||||
Kind.OBJECT_TYPE_DEFINITION,
|
||||
Kind.INTERFACE_TYPE_DEFINITION,
|
||||
Kind.ENUM_TYPE_DEFINITION,
|
||||
Kind.SCALAR_TYPE_DEFINITION,
|
||||
Kind.INPUT_OBJECT_TYPE_DEFINITION,
|
||||
Kind.UNION_TYPE_DEFINITION,
|
||||
]
|
||||
ast.definitions.forEach((def: any) => {
|
||||
if (kinds.includes(def.kind)) {
|
||||
typeNames.add(def.name.value)
|
||||
} else if (def.kind === Kind.OBJECT_TYPE_EXTENSION) {
|
||||
extendedTypes.add(def.name.value)
|
||||
}
|
||||
})
|
||||
|
||||
const nonExistingMap: Record<string, Record<string, string>> = {}
|
||||
const parentStack: string[] = []
|
||||
|
||||
/*
|
||||
Traverse the graph mapping all the entities + fields and removing the ones that don't exist.
|
||||
Extensions are not removed, but marked with a "__extended" key if the main entity doesn't exist. (example: Link modules injecting fields into another module)
|
||||
*/
|
||||
const cleanedAst = visit(ast, {
|
||||
ObjectTypeExtension: {
|
||||
enter(node) {
|
||||
const typeName = node.name.value
|
||||
|
||||
parentStack.push(typeName)
|
||||
if (!typeNames.has(typeName)) {
|
||||
nonExistingMap[typeName] ??= {}
|
||||
nonExistingMap[typeName]["__extended"] = ""
|
||||
return null
|
||||
}
|
||||
return
|
||||
},
|
||||
leave() {
|
||||
parentStack.pop()
|
||||
},
|
||||
},
|
||||
ObjectTypeDefinition: {
|
||||
enter(node) {
|
||||
parentStack.push(node.name.value)
|
||||
},
|
||||
leave() {
|
||||
parentStack.pop()
|
||||
},
|
||||
},
|
||||
FieldDefinition: {
|
||||
leave(node) {
|
||||
const [typeName, kind] = extractTypeNameAndKind(node.type)
|
||||
|
||||
if (!typeNames.has(typeName) && kind === Kind.NAMED_TYPE) {
|
||||
const currentParent = parentStack[parentStack.length - 1]
|
||||
|
||||
nonExistingMap[currentParent] ??= {}
|
||||
nonExistingMap[currentParent][node.name.value] = typeName
|
||||
return null
|
||||
}
|
||||
return
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Return the schema and the map of non existing entities and fields
|
||||
return {
|
||||
schema: print(cleanedAst),
|
||||
notFound: nonExistingMap,
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
export * from "./clean-graphql-schema"
|
||||
export * from "./get-fields-and-relations"
|
||||
export * from "./graphql-schema-to-fields"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user