Skip to content

Commit

Permalink
Accept onWarning callback as a parameter (#171)
Browse files Browse the repository at this point in the history
* Accept onWarning callback as a parameter

* Added changeset

Co-authored-by: Neeraj Joseph <njoseph@poppulo.com>
  • Loading branch information
joseph-neeraj and njoseph-poppulo committed Nov 21, 2022
1 parent c2be0c5 commit 5169495
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/loud-hairs-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@n1ru4l/graphql-public-schema-filter": minor
---

accept an onWarning callback as parameter to the buildPublicSchema function
21 changes: 21 additions & 0 deletions src/public-schema-filter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,27 @@ it("can be called", () => {
);
});

it("uses the onWarning callback when provided", () => {
const source = /* GraphQL */ `
type User {
id: ID!
login: String!
}
type Query {
me: User @public
}
`;

const schema = buildSchema(source);

const onWarning = jest.fn();
lib.buildPublicSchema({ schema, onWarning });

expect(onWarning).toHaveBeenCalled();

});

it("does not expose the public directive", () => {
const source = /* GraphQL */ `
type User {
Expand Down
13 changes: 8 additions & 5 deletions src/public-schema-filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,20 @@ export type BuildPublicSchemaParameter = {
schema: GraphQLSchema;
/** Overwrite this function for customizing how fields are determined as public. Uses `defaultIsPublic` per default. */
isPublic?: typeof defaultIsPublic;
/** Callback to be invoked when schema filtering encounters conflicts that would result in an invalid schema. */
onWarning?: (message: string) => void;
};

/**
* Maps the input schema to a public schema that only includes types and fields that are marked as public.
* Conflicts that would result in an invalid schema, will be printed to the console.
* Conflicts that would result in an invalid schema, will be printed to the console. This can be overriden by the onWarning parameter.
* The implementation tries to construct a valid schema by automatically hiding invalid constructs (such as empty ObjectTypes or fields whose return type is not public).
*/
export const buildPublicSchema = (
params: BuildPublicSchemaParameter
): GraphQLSchema => {
const isPublic = params.isPublic ?? defaultIsPublic;
const onWarningCallback = params.onWarning ?? logWarning;
const publicTypeNames: Set<string> = new Set(builtInTypes);
const publicFieldReturnTypes: Map<string, string> = new Map();
const publicFieldArguments: Map<string, Set<string>> = new Map();
Expand Down Expand Up @@ -175,7 +178,7 @@ export const buildPublicSchema = (
for (let unionTypeMember of types) {
if (!publicTypeNames.has(unionTypeMember.name)) {
publicTypeNames.delete(unionType.name);
logWarning(
onWarningCallback(
`[public-introspection-filter] Type "${unionTypeMember.name}" is not marked as public.\n` +
` -> The union "${unionType}" will not be marked as visible.`
);
Expand All @@ -188,7 +191,7 @@ export const buildPublicSchema = (
for (let interfaceName of implementedInterfaces) {
if (!publicTypeNames.has(interfaceName)) {
publicTypeNames.delete(type);
logWarning(
onWarningCallback(
`[public-introspection-filter] Interface "${interfaceName}" is not marked as public.\n` +
` -> The type "${type}" which implements the interface will not be marked as visible.`
);
Expand All @@ -199,7 +202,7 @@ export const buildPublicSchema = (
// check availability of fields
for (let [fieldPath, returnType] of publicFieldReturnTypes) {
if (!publicTypeNames.has(returnType)) {
logWarning(
onWarningCallback(
`[public-introspection-filter] Type "${returnType}" is not marked as public.\n` +
` -> The field "${fieldPath}" will not be marked as visible.`
);
Expand All @@ -214,7 +217,7 @@ export const buildPublicSchema = (
for (let [fieldPath, inputTypes] of publicFieldArgumentTypes) {
for (let inputType of inputTypes) {
if (!publicTypeNames.has(inputType)) {
logWarning(
onWarningCallback(
`[public-introspection-filter] Input Type "${inputType}" is not marked as public.\n` +
` -> The field "${fieldPath}" will not be marked as visible.`
);
Expand Down

0 comments on commit 5169495

Please sign in to comment.