Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

graphql-field-mask

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphql-field-mask - npm Package Compare versions

Comparing version 0.1.3 to 0.1.4

CHANGELOG.md

12

lib/fieldMaskPathsFromResolveInfo.d.ts

@@ -1,2 +0,2 @@

import { FragmentDefinitionNode, GraphQLAbstractType, GraphQLField, GraphQLObjectType, GraphQLResolveInfo, GraphQLSchema, InlineFragmentNode } from "graphql";
import { FieldNode, FragmentDefinitionNode, GraphQLAbstractType, GraphQLField, GraphQLObjectType, GraphQLResolveInfo, GraphQLScalarType, GraphQLSchema, InlineFragmentNode } from "graphql";
export declare type GetFieldNameFunc = (field: GraphQLField<any, any>, type: GraphQLObjectType, schema: GraphQLSchema) => string | null;

@@ -9,2 +9,7 @@ export declare type GetAbstractTypeFieldMaskPathsFunc = (info: {

}, getFieldMaskPaths: () => string[]) => string[];
export declare type GetCustomScalarTypeFieldMaskPathsFunc = (path: string, info: {
node: FieldNode;
type: GraphQLScalarType;
field: GraphQLField<any, any>;
}) => string[];
export declare type FieldMaskPathsFromResolveInfoOptions = {

@@ -22,2 +27,7 @@ /**

getAbstractTypeFieldMaskPaths?: GetAbstractTypeFieldMaskPathsFunc;
/**
* Determine field mask paths in custom scalar type.
* By default, it returns only the field name of the scalar type.
*/
getCustomScalarFieldMaskPaths?: GetCustomScalarTypeFieldMaskPathsFunc;
};

@@ -24,0 +34,0 @@ /**

@@ -5,2 +5,3 @@ "use strict";

const graphql_1 = require("graphql");
const defaultScalarTypeNames = new Set(["Int", "Float", "String", "Boolean", "ID"]);
/**

@@ -46,2 +47,3 @@ * Create field mask paths from `GraphQLResolveInfo`.

}
const fieldType = (0, graphql_1.getNamedType)(field.type);
if (selection.selectionSet) {

@@ -52,2 +54,7 @@ const childTypename = (0, graphql_1.getNamedType)(field.type).name;

}
else if (fieldType instanceof graphql_1.GraphQLScalarType &&
!defaultScalarTypeNames.has(fieldType.name) &&
opts.getCustomScalarFieldMaskPaths) {
fields.push(...opts.getCustomScalarFieldMaskPaths(fieldName, { field, type: fieldType, node: selection }));
}
else {

@@ -78,2 +85,5 @@ fields.push(fieldName);

}
default: {
throw new Error("unreachable");
}
}

@@ -80,0 +90,0 @@ const fragmentType = getType(fragmentTypename, schema);

@@ -1,2 +0,2 @@

import { FragmentDefinitionNode, GraphQLAbstractType, GraphQLField, GraphQLObjectType, GraphQLResolveInfo, GraphQLSchema, InlineFragmentNode } from "graphql";
import { FieldNode, FragmentDefinitionNode, GraphQLAbstractType, GraphQLField, GraphQLObjectType, GraphQLResolveInfo, GraphQLScalarType, GraphQLSchema, InlineFragmentNode } from "graphql";
export declare type GetFieldNameFunc = (field: GraphQLField<any, any>, type: GraphQLObjectType, schema: GraphQLSchema) => string | null;

@@ -9,2 +9,7 @@ export declare type GetAbstractTypeFieldMaskPathsFunc = (info: {

}, getFieldMaskPaths: () => string[]) => string[];
export declare type GetCustomScalarTypeFieldMaskPathsFunc = (path: string, info: {
node: FieldNode;
type: GraphQLScalarType;
field: GraphQLField<any, any>;
}) => string[];
export declare type FieldMaskPathsFromResolveInfoOptions = {

@@ -22,2 +27,7 @@ /**

getAbstractTypeFieldMaskPaths?: GetAbstractTypeFieldMaskPathsFunc;
/**
* Determine field mask paths in custom scalar type.
* By default, it returns only the field name of the scalar type.
*/
getCustomScalarFieldMaskPaths?: GetCustomScalarTypeFieldMaskPathsFunc;
};

@@ -24,0 +34,0 @@ /**

@@ -1,2 +0,3 @@

import { getNamedType, GraphQLObjectType, isAbstractType, } from "graphql";
import { getNamedType, GraphQLObjectType, GraphQLScalarType, isAbstractType, } from "graphql";
const defaultScalarTypeNames = new Set(["Int", "Float", "String", "Boolean", "ID"]);
/**

@@ -41,2 +42,3 @@ * Create field mask paths from `GraphQLResolveInfo`.

}
const fieldType = getNamedType(field.type);
if (selection.selectionSet) {

@@ -47,2 +49,7 @@ const childTypename = getNamedType(field.type).name;

}
else if (fieldType instanceof GraphQLScalarType &&
!defaultScalarTypeNames.has(fieldType.name) &&
opts.getCustomScalarFieldMaskPaths) {
fields.push(...opts.getCustomScalarFieldMaskPaths(fieldName, { field, type: fieldType, node: selection }));
}
else {

@@ -73,2 +80,5 @@ fields.push(fieldName);

}
default: {
throw new Error("unreachable");
}
}

@@ -75,0 +85,0 @@ const fragmentType = getType(fragmentTypename, schema);

12

package.json
{
"name": "graphql-field-mask",
"version": "0.1.3",
"version": "0.1.4",
"description": "google.protobuf.FieldMask from GraphQL query",

@@ -17,3 +17,3 @@ "sideEffects": false,

],
"repository": "https://github.com/izumin5210/graphql-field-mask",
"repository": "https://github.com/proto-graphql/graphql-field-mask",
"author": "izumin5210 <m@izum.in>",

@@ -29,3 +29,3 @@ "license": "MIT",

"peerDependencies": {
"graphql": "^15.0.0"
"graphql": "^15.0.0 || ^16.0.0"
},

@@ -35,3 +35,7 @@ "devDependencies": {

"frolint": "^2.8.2",
"graphql": "^15.6.1",
"graphql": "link:./node_modules/graphql-16.x",
"graphql-15.0.0": "npm:graphql@15.0.0",
"graphql-15.x": "npm:graphql@15.x",
"graphql-16.0.0": "npm:graphql@16.0.0",
"graphql-16.x": "npm:graphql@16.x",
"jest": "^27.3.1",

@@ -38,0 +42,0 @@ "ts-jest": "^27.0.7",

# graphql-field-mask
[![CI](https://github.com/izumin5210/graphql-field-mask/actions/workflows/ci.yml/badge.svg)](https://github.com/izumin5210/graphql-field-mask/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/izumin5210/graphql-field-mask/badge.svg?branch=main)](https://coveralls.io/github/izumin5210/graphql-field-mask?branch=main)
[![CI](https://github.com/proto-graphql/graphql-field-mask/actions/workflows/ci.yml/badge.svg)](https://github.com/proto-graphql/graphql-field-mask/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/proto-graphql/graphql-field-mask/badge.svg?branch=main)](https://coveralls.io/github/proto-graphql/graphql-field-mask?branch=main)
[![npm](https://img.shields.io/npm/v/graphql-field-mask)](https://www.npmjs.com/package/graphql-field-mask)
[![LICENSE](https://img.shields.io/github/license/izumin5210/graphql-field-mask)](./LICENSE)
[![LICENSE](https://img.shields.io/github/license/proto-graphql/graphql-field-mask)](./LICENSE)

@@ -31,2 +31,23 @@ `google.protobuf.FieldMask` from GraphQL query

### With custom scalar
```ts
import { fieldMaskPathsFromResolveInfo, GetCustomScalarFieldMaskPaths } from "graphql-field-mask";
const getCustomScalarFieldMaskPaths: GetCustomScalarFieldMaskPaths = (fieldName, info) => {
switch (info.type.name) {
case 'Date':
return ['year', 'month', 'day'].map(c => `${fieldName}.${c}`);
// ...
}
};
resolve(_source, _args, ctx, info) {
const paths = fieldMaskPathsFromResolveInfo("User", info, { getCustomScalarFieldMaskPaths });
const mask = new FieldMask().setPathsList(paths);
// ...
}
```
### Convert to snake case

@@ -73,1 +94,5 @@

```
## Author
- [Masayuki Izumi (@izumin5210)](https://github.com/izumin5210)
import {
extendSchema,
graphql,

@@ -10,2 +11,3 @@ GraphQLInt,

GraphQLUnionType,
parse,
} from "graphql";

@@ -27,7 +29,7 @@ import { fieldMaskPathsFromResolveInfo, GetFieldNameFunc } from "./fieldMaskPathsFromResolveInfo";

targetField: {
type: GraphQLNonNull(GraphQLString),
type: new GraphQLNonNull(GraphQLString),
extensions: { fieldMask: { fieldName: "target_field" } } as FieldMaskExtensions,
},
otherField: {
type: GraphQLNonNull(GraphQLString),
type: new GraphQLNonNull(GraphQLString),
},

@@ -59,3 +61,7 @@ },

const fetchObject1 = jest.fn().mockReturnValue({ targetField: "target field", otherField: "other field" });
const result = await graphql(schema, "{ object1 { targetField, otherField } }", undefined, { fetchObject1 });
const result = await graphql({
schema,
source: "{ object1 { targetField, otherField } }",
contextValue: { fetchObject1 },
});

@@ -80,3 +86,7 @@ expect(result.errors).toBeUndefined();

const fetchObject1 = jest.fn().mockReturnValue({ targetField: "target field", otherField: "other field" });
const result = await graphql(schema, "{ object1 { targetField, otherField } }", undefined, { fetchObject1 });
const result = await graphql({
schema,
source: "{ object1 { targetField, otherField } }",
contextValue: { fetchObject1 },
});

@@ -93,3 +103,7 @@ expect(result.errors).toBeUndefined();

const fetchObject1 = jest.fn().mockReturnValue({ targetField: "target field" });
const result = await graphql(schema, "{ object1 { aliasedField: targetField } }", undefined, { fetchObject1 });
const result = await graphql({
schema,
source: "{ object1 { aliasedField: targetField } }",
contextValue: { fetchObject1 },
});

@@ -106,3 +120,7 @@ expect(result.errors).toBeUndefined();

const fetchObject1 = jest.fn().mockReturnValue({ targetField: "target field" });
const result = await graphql(schema, "{ object1 { __typename, targetField } }", undefined, { fetchObject1 });
const result = await graphql({
schema,
source: "{ object1 { __typename, targetField } }",
contextValue: { fetchObject1 },
});

@@ -119,5 +137,5 @@ expect(result.errors).toBeUndefined();

const fetchObject1 = jest.fn().mockReturnValue({ targetField: "target field", otherField: "other field" });
const result = await graphql(
const result = await graphql({
schema,
`
source: `
query {

@@ -133,5 +151,4 @@ object1 {

`,
undefined,
{ fetchObject1 }
);
contextValue: { fetchObject1 },
});

@@ -148,5 +165,5 @@ expect(result.errors).toBeUndefined();

const fetchObject1 = jest.fn().mockReturnValue({ targetField: "target field", otherField: "other field" });
const result = await graphql(
const result = await graphql({
schema,
`
source: `
query {

@@ -161,5 +178,4 @@ object1 {

`,
undefined,
{ fetchObject1 }
);
contextValue: { fetchObject1 },
});

@@ -176,5 +192,5 @@ expect(result.errors).toBeUndefined();

const fetchObject1 = jest.fn().mockReturnValue({ targetField: "target field", otherField: "other field" });
const result = await graphql(
const result = await graphql({
schema,
`
source: `
query {

@@ -189,5 +205,4 @@ object1 {

`,
undefined,
{ fetchObject1 }
);
contextValue: { fetchObject1 },
});

@@ -206,3 +221,3 @@ expect(result.errors).toBeUndefined();

parentField: { type: GraphQLInt },
object1: { type: GraphQLNonNull(object1Type) },
object1: { type: new GraphQLNonNull(object1Type) },
},

@@ -223,8 +238,7 @@ });

.mockReturnValue({ parentField: 1, object1: { targetField: "target field", otherField: "other field" } });
const result = await graphql(
const result = await graphql({
schema,
"{ parent { parentField, object1 { targetField, otherField } } }",
undefined,
{ fetchParent }
);
source: "{ parent { parentField, object1 { targetField, otherField } } }",
contextValue: { fetchParent },
});

@@ -239,2 +253,51 @@ expect(result.errors).toBeUndefined();

describe("with custom scalar", () => {
it("returns field mask paths with getCustomScalarFieldMaskPath result", async () => {
let schema = createSchema({
queryFields: {
object1: {
type: object1Type,
resolve(_source, _args, ctx, info) {
return ctx.fetchObject1(
fieldMaskPathsFromResolveInfo("Object1", info, {
getCustomScalarFieldMaskPaths: (path, info) => {
if (info.type.name === "Date") return ["year", "month", "day"].map((c) => `${path}.${c}`);
throw new Error(`unkonwn scalar type: ${info.type.name}`);
},
})
);
},
},
},
});
schema = extendSchema(
schema,
parse(`
scalar Date
extend type Object1 { date: Date! }
`)
);
const fetchObject1 = jest
.fn()
.mockReturnValue({ targetField: "target field", otherField: "other field", date: "2021-11-01" });
const result = await graphql({
schema,
source: `query { object1 { targetField, otherField, date } }`,
contextValue: { fetchObject1 },
});
expect(result.errors).toBeUndefined();
expect(result.data).toEqual({
object1: { targetField: "target field", otherField: "other field", date: "2021-11-01" },
});
expect(fetchObject1.mock.calls[0][0]).toEqual([
"targetField",
"otherField",
"date.year",
"date.month",
"date.day",
]);
});
});
describe("with union type", () => {

@@ -260,5 +323,5 @@ const object2Type = new GraphQLObjectType({ name: "Object2", fields: { field2: { type: GraphQLString } } });

.mockReturnValue({ __typename: "Object1", targetField: "target field", otherField: "other field" });
const result = await graphql(
const result = await graphql({
schema,
`
source: `
{

@@ -277,5 +340,4 @@ union {

`,
undefined,
{ fetchUnion }
);
contextValue: { fetchUnion },
});
expect(result.errors).toBeUndefined();

@@ -310,3 +372,3 @@ expect(result.data).toEqual({ union: { otherField: "other field", targetField: "target field" } });

`;
const result = await graphql(schema, query, undefined, { fetchUnion });
const result = await graphql({ schema, source: query, contextValue: { fetchUnion } });
expect(result.errors).toBeUndefined();

@@ -329,3 +391,3 @@ expect(result.data).toEqual({ union: { otherField: "other field", targetField: "target field" } });

union: {
type: GraphQLNonNull(unionType),
type: new GraphQLNonNull(unionType),
extensions: { fieldMaskPathPrefix: { Object1: "object1", Object2: "object2" } },

@@ -366,3 +428,3 @@ },

.mockReturnValue({ union: { __typename: "Object1", targetField: "target field", otherField: "other field" } });
const result = await graphql(schema, query, undefined, { fetchParent });
const result = await graphql({ schema, source: query, contextValue: { fetchParent } });
expect(result.errors).toBeUndefined();

@@ -383,3 +445,3 @@ expect(result.data).toEqual({ parent: { union: { otherField: "other field", targetField: "target field" } } });

// eslint-disable-next-line dot-notation
const prefix = info.field.extensions?.["fieldMaskPathPrefix"][info.concreteType.name];
const prefix = (info.field.extensions as any)?.["fieldMaskPathPrefix"][info.concreteType.name];
return getFieldMaskPaths().map((p) => `${prefix}.${p}`);

@@ -396,3 +458,3 @@ },

.mockReturnValue({ union: { __typename: "Object1", targetField: "target field", otherField: "other field" } });
const result = await graphql(schema, query, undefined, { fetchParent });
const result = await graphql({ schema, source: query, contextValue: { fetchParent } });
expect(result.errors).toBeUndefined();

@@ -424,3 +486,3 @@ expect(result.data).toEqual({ parent: { union: { otherField: "other field", targetField: "target field" } } });

// eslint-disable-next-line dot-notation
const prefix = info.field.extensions?.["fieldMaskPathPrefix"][info.concreteType.name];
const prefix = (info.field.extensions as any)?.["fieldMaskPathPrefix"][info.concreteType.name];
return getFieldMaskPaths().map((p) => `${prefix}.${p}`);

@@ -437,3 +499,3 @@ },

.mockReturnValue({ union: { __typename: "Object1", targetField: "target field", otherField: "other field" } });
const result = await graphql(schema, query, undefined, { fetchParent });
const result = await graphql({ schema, source: query, contextValue: { fetchParent } });
expect(result.errors).toBeUndefined();

@@ -455,3 +517,3 @@ expect(result.data).toEqual({ parent: { union: { otherField: "other field", targetField: "target field" } } });

object1: {
type: GraphQLNonNull(object1Type),
type: new GraphQLNonNull(object1Type),
resolve(_source, _args, ctx, info) {

@@ -474,4 +536,6 @@ return ctx.fetchObject1(fieldMaskPathsFromResolveInfo("Object1", info));

const fetchObject1 = jest.fn().mockReturnValue({ targetField: "target field", otherField: "other field" });
const result = await graphql(schema, "{ parent { object1 { targetField otherField } } }", undefined, {
fetchObject1,
const result = await graphql({
schema,
source: "{ parent { object1 { targetField otherField } } }",
contextValue: { fetchObject1 },
});

@@ -496,3 +560,7 @@ expect(result.errors).toBeUndefined();

const fetchObject1 = jest.fn().mockReturnValue({ targetField: "target field", otherField: "other field" });
const result = await graphql(schema, "{ object1 { targetField, otherField } }", undefined, { fetchObject1 });
const result = await graphql({
schema,
source: "{ object1 { targetField, otherField } }",
contextValue: { fetchObject1 },
});

@@ -499,0 +567,0 @@ expect(result.errors).toHaveLength(1);

@@ -10,2 +10,3 @@ import {

GraphQLResolveInfo,
GraphQLScalarType,
GraphQLSchema,

@@ -32,2 +33,13 @@ InlineFragmentNode,

export type GetCustomScalarTypeFieldMaskPathsFunc = (
path: string,
info: {
node: FieldNode;
type: GraphQLScalarType;
field: GraphQLField<any, any>;
}
) => string[];
const defaultScalarTypeNames = new Set(["Int", "Float", "String", "Boolean", "ID"]);
export type FieldMaskPathsFromResolveInfoOptions = {

@@ -45,2 +57,7 @@ /**

getAbstractTypeFieldMaskPaths?: GetAbstractTypeFieldMaskPathsFunc;
/**
* Determine field mask paths in custom scalar type.
* By default, it returns only the field name of the scalar type.
*/
getCustomScalarFieldMaskPaths?: GetCustomScalarTypeFieldMaskPathsFunc;
};

@@ -110,2 +127,3 @@

}
const fieldType = getNamedType(field.type);
if (selection.selectionSet) {

@@ -115,2 +133,8 @@ const childTypename = getNamedType(field.type).name;

fields.push(...childFields.map((field) => `${fieldName}.${field}`));
} else if (
fieldType instanceof GraphQLScalarType &&
!defaultScalarTypeNames.has(fieldType.name) &&
opts.getCustomScalarFieldMaskPaths
) {
fields.push(...opts.getCustomScalarFieldMaskPaths(fieldName, { field, type: fieldType, node: selection }));
} else {

@@ -141,2 +165,5 @@ fields.push(fieldName);

}
default: {
throw new Error("unreachable");
}
}

@@ -143,0 +170,0 @@ const fragmentType = getType(fragmentTypename, schema);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc