Skip to content

Commit

Permalink
enhance: directive extraction
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan committed Aug 16, 2024
1 parent 65452ab commit 0286437
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 144 deletions.
7 changes: 7 additions & 0 deletions .changeset/stale-weeks-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphql-tools/schema': patch
'@graphql-tools/merge': patch
'@graphql-tools/utils': patch
---

Improve directive extraction
8 changes: 6 additions & 2 deletions packages/merge/src/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ function applyExtensionObject(
obj: Maybe<{ extensions: Maybe<Readonly<Record<string, any>>> }>,
extensions: ExtensionsObject,
) {
if (!obj) {
if (!obj || !extensions || extensions === obj.extensions) {
return;
}
obj.extensions = mergeDeep([obj.extensions || {}, extensions || {}], false, true);
if (!obj.extensions) {
obj.extensions = extensions;
return;
}
obj.extensions = mergeDeep([obj.extensions, extensions], false, true);
}

export function applyExtensions(
Expand Down
7 changes: 1 addition & 6 deletions packages/schema/src/merge-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,7 @@ export function mergeSchemas(config: MergeSchemasConfig) {

if (config.schemas != null) {
for (const schema of config.schemas) {
extractedTypeDefs.push(
getDocumentNodeFromSchema(schema, {
...config,
pathToDirectivesInExtensions: ['NONEXISTENT'],
}),
);
extractedTypeDefs.push(getDocumentNodeFromSchema(schema));
extractedResolvers.push(getResolversFromSchema(schema));
extractedSchemaExtensions.push(extractExtensionsFromSchema(schema));
}
Expand Down
37 changes: 3 additions & 34 deletions packages/utils/src/get-directives.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,12 @@
import {
GraphQLEnumTypeConfig,
GraphQLEnumValue,
GraphQLEnumValueConfig,
GraphQLField,
GraphQLFieldConfig,
GraphQLInputField,
GraphQLInputFieldConfig,
GraphQLInputObjectTypeConfig,
GraphQLInterfaceTypeConfig,
GraphQLNamedType,
GraphQLObjectTypeConfig,
GraphQLScalarTypeConfig,
GraphQLSchema,
GraphQLSchemaConfig,
GraphQLUnionTypeConfig,
} from 'graphql';
import { getDirectiveExtensions } from './getDirectiveExtensions.js';
import { GraphQLSchema } from 'graphql';
import { DirectableObject, getDirectiveExtensions } from './getDirectiveExtensions.js';

export interface DirectiveAnnotation {
name: string;
args?: Record<string, any>;
}

export type DirectableGraphQLObject =
| GraphQLSchema
| GraphQLSchemaConfig
| GraphQLNamedType
| GraphQLObjectTypeConfig<any, any>
| GraphQLInterfaceTypeConfig<any, any>
| GraphQLUnionTypeConfig<any, any>
| GraphQLScalarTypeConfig<any, any>
| GraphQLEnumTypeConfig
| GraphQLEnumValue
| GraphQLEnumValueConfig
| GraphQLInputObjectTypeConfig
| GraphQLField<any, any>
| GraphQLInputField
| GraphQLFieldConfig<any, any>
| GraphQLInputFieldConfig;
export type DirectableGraphQLObject = DirectableObject;

export function getDirectivesInExtensions(
node: DirectableGraphQLObject,
Expand Down
69 changes: 40 additions & 29 deletions packages/utils/src/getDirectiveExtensions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ASTNode, DirectiveNode, GraphQLSchema } from 'graphql';
import { valueFromAST, valueFromASTUntyped } from 'graphql';
import { getArgumentValues } from './getArgumentValues.js';
import { memoize1 } from './memoize.js';

export type DirectableASTNode = ASTNode & { directives?: readonly DirectiveNode[] };
export type DirectableObject = {
Expand All @@ -25,6 +26,39 @@ export function getDirectiveExtensions<
TDirectiveAnnotationsMap[directiveName]
>;
} = {};

if (directableObj.extensions) {
let directivesInExtensions = directableObj.extensions;
for (const pathSegment of pathToDirectivesInExtensions) {
directivesInExtensions = directivesInExtensions?.[pathSegment];
}
if (directivesInExtensions != null) {
for (const directiveNameProp in directivesInExtensions) {
const directiveObjs = directivesInExtensions[directiveNameProp];
const directiveName = directiveNameProp as keyof TDirectiveAnnotationsMap;
if (Array.isArray(directiveObjs)) {
for (const directiveObj of directiveObjs) {
let existingDirectiveExtensions = directiveExtensions[directiveName];
if (!existingDirectiveExtensions) {
existingDirectiveExtensions = [];
directiveExtensions[directiveName] = existingDirectiveExtensions;
}
existingDirectiveExtensions.push(directiveObj);
}
} else {
let existingDirectiveExtensions = directiveExtensions[directiveName];
if (!existingDirectiveExtensions) {
existingDirectiveExtensions = [];
directiveExtensions[directiveName] = existingDirectiveExtensions;
}
existingDirectiveExtensions.push(directiveObjs);
}
}
}
}

const memoizedStringify = memoize1(obj => JSON.stringify(obj));

const astNodes: DirectableASTNode[] = [];
if (directableObj.astNode) {
astNodes.push(directableObj.astNode);
Expand Down Expand Up @@ -60,39 +94,16 @@ export function getDirectiveExtensions<
}
}
}
existingDirectiveExtensions.push(value);
}
}
}

if (directableObj.extensions) {
let directivesInExtensions = directableObj.extensions;
for (const pathSegment of pathToDirectivesInExtensions) {
directivesInExtensions = directivesInExtensions?.[pathSegment];
}
if (directivesInExtensions != null) {
for (const directiveNameProp in directivesInExtensions) {
const directiveObjs = directivesInExtensions[directiveNameProp];
const directiveName = directiveNameProp as keyof TDirectiveAnnotationsMap;
if (Array.isArray(directiveObjs)) {
for (const directiveObj of directiveObjs) {
let existingDirectiveExtensions = directiveExtensions[directiveName];
if (!existingDirectiveExtensions) {
existingDirectiveExtensions = [];
directiveExtensions[directiveName] = existingDirectiveExtensions;
}
existingDirectiveExtensions.push(directiveObj);
if (astNodes.length > 0 && existingDirectiveExtensions.length > 0) {
const valStr = memoizedStringify(value);
if (existingDirectiveExtensions.some(val => memoizedStringify(val) === valStr)) {
continue;
}
} else {
let existingDirectiveExtensions = directiveExtensions[directiveName];
if (!existingDirectiveExtensions) {
existingDirectiveExtensions = [];
directiveExtensions[directiveName] = existingDirectiveExtensions;
}
existingDirectiveExtensions.push(directiveObjs);
}
existingDirectiveExtensions.push(value);
}
}
}

return directiveExtensions;
}
Loading

0 comments on commit 0286437

Please sign in to comment.