Skip to content

Commit

Permalink
feat(gatsby-source-wordpress): MediaItem.excludeFieldNames / auto exc…
Browse files Browse the repository at this point in the history
…lude interface types that have no fields (#37062) (#37085)

Co-authored-by: Tyler Barnes <[email protected]>
  • Loading branch information
LekoArts and TylerBarnes authored Nov 23, 2022
1 parent 1f92e69 commit 2bc5902
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,6 @@ Array [
Object {
"fields": Array [
"avatar",
"databaseId",
"id",
"name",
"url",
Expand Down Expand Up @@ -1424,7 +1423,6 @@ Array [
"modifiedGmt",
"slug",
"status",
"template",
"uri",
"nodeType",
"parent",
Expand Down Expand Up @@ -5575,7 +5573,6 @@ Array [
"sourceUrl",
"srcSet",
"status",
"template",
"title",
"uri",
"nodeType",
Expand Down Expand Up @@ -6005,12 +6002,6 @@ Array [
],
"name": "WpNodeWithRevisionsToContentNodeConnectionEdge",
},
Object {
"fields": Array [
"template",
],
"name": "WpNodeWithTemplate",
},
Object {
"fields": Array [
"title",
Expand Down
1 change: 1 addition & 0 deletions integration-tests/gatsby-source-wordpress/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ require(`dotenv`).config({
console.log(`Sourcing data from ` + process.env.WPGRAPHQL_URL)

const mediaItemTypeSettings = {
excludeFieldNames: [`template`],
localFile: {
excludeByMimeTypes: ["video/mp4"],
/**
Expand Down
21 changes: 21 additions & 0 deletions packages/gatsby-source-wordpress/docs/plugin-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
- [type.\_\_all.beforeChangeNode](#type__allbeforechangenode)
- [type.RootQuery](#typerootquery)
- [type.MediaItem](#typemediaitem)
- [type.MediaItem.excludeFieldNames](#typemediaitemexcludefieldnames)
- [type.MediaItem.placeholderSizeName](#typemediaitemplaceholdersizename)
- [type.MediaItem.createFileNodes](#typemediaitemcreatefilenodes)
- [type.MediaItem.lazyNodes](#typemediaitemlazynodes)
Expand Down Expand Up @@ -1230,6 +1231,26 @@ A special type which is applied to any non-node root fields that are ingested an

**Field type**: `Object`

#### type.MediaItem.excludeFieldNames

Excludes fields on the MediaItem type by field name.

**Field type**: `Array`

```js
{
resolve: `gatsby-source-wordpress`,
options: {
type: {
MediaItem: {
excludeFieldNames: [`dateGmt`, `parent`],
},
},
},
}

```

#### type.MediaItem.placeholderSizeName

This option allows you to choose the placeholder size used in the new Gatsby image service (currently in ALPHA/BETA) for the small placeholder image. Please make this image size very small for better performance. 20px or smaller width is recommended. To use, create a new image size in WP and name it "gatsby-image-placeholder" (or the name that you pass to this option) and that new size will be used automatically for placeholder images in the Gatsby build.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
fieldOfTypeWasFetched,
getTypeSettingsByType,
filterTypeDefinition,
getTypesThatImplementInterfaceType,
} from "./helpers"

const unionType = typeBuilderApi => {
Expand Down Expand Up @@ -47,38 +48,24 @@ const unionType = typeBuilderApi => {
}

const interfaceType = typeBuilderApi => {
const { type, schema, gatsbyNodeTypes, fieldAliases, fieldBlacklist } =
typeBuilderApi
const { type, schema } = typeBuilderApi

const state = store.getState()
const { ingestibles, typeMap } = state.remoteSchema
const { ingestibles } = state.remoteSchema
const { nodeInterfaceTypes } = ingestibles

const allTypes = typeMap.values()

const implementingTypes = Array.from(allTypes)
.filter(
({ interfaces }) =>
interfaces &&
// find types that implement this interface type
interfaces.find(singleInterface => singleInterface.name === type.name)
)
.map(type => typeMap.get(type.name))
.filter(
type =>
type.kind !== `UNION` ||
// if this is a union type, make sure the union type has one or more member types, otherwise schema customization will throw an error
(!!type.possibleTypes && !!type.possibleTypes.length)
)
const implementingTypes = getTypesThatImplementInterfaceType(type)

const transformedFields = transformFields({
parentInterfacesImplementingTypes: implementingTypes,
parentType: type,
fields: type.fields,
gatsbyNodeTypes,
fieldAliases,
fieldBlacklist,
})

if (!transformedFields) {
return null
}

let typeDef = {
name: buildTypeName(type.name),
fields: transformedFields,
Expand Down Expand Up @@ -144,7 +131,11 @@ const objectType = typeBuilderApi => {
.filter(interfaceType => {
const interfaceTypeSettings = getTypeSettingsByType(interfaceType)

return !interfaceTypeSettings.exclude && fieldOfTypeWasFetched(type)
return (
!interfaceTypeSettings.exclude &&
fieldOfTypeWasFetched(type) &&
fieldOfTypeWasFetched(interfaceType)
)
})
.map(({ name }) => buildTypeName(name))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,38 @@ export const fieldOfTypeWasFetched = type => {
return typeWasFetched
}

const implementingTypeCache = new Map()

export const getTypesThatImplementInterfaceType = type => {
if (implementingTypeCache.has(type.name)) {
return implementingTypeCache.get(type.name)
}

const state = store.getState()
const { typeMap } = state.remoteSchema

const allTypes = typeMap.values()

const implementingTypes = Array.from(allTypes)
.filter(
({ interfaces }) =>
interfaces &&
// find types that implement this interface type
interfaces.find(singleInterface => singleInterface.name === type.name)
)
.map(type => typeMap.get(type.name))
.filter(
type =>
type.kind !== `UNION` ||
// if this is a union type, make sure the union type has one or more member types, otherwise schema customization will throw an error
(!!type.possibleTypes && !!type.possibleTypes.length)
)

implementingTypeCache.set(type.name, implementingTypes)

return implementingTypes
}

const supportedScalars = [
`Int`,
`Float`,
Expand All @@ -84,7 +116,7 @@ export const typeIsASupportedScalar = type => {
return supportedScalars.includes(findTypeName(type))
}

const typeSettingCache = {}
const typeSettingCache = new Map()

// retrieves plugin settings for the provided type
export const getTypeSettingsByType = type => {
Expand All @@ -94,7 +126,11 @@ export const getTypeSettingsByType = type => {

const typeName = findTypeName(type)

const cachedTypeSettings = typeSettingCache[typeName]
if (!typeName) {
return {}
}

const cachedTypeSettings = typeSettingCache.get(typeName)

if (cachedTypeSettings) {
return cachedTypeSettings
Expand All @@ -116,12 +152,12 @@ export const getTypeSettingsByType = type => {
if (typeSettings) {
const mergedSettings = merge(__allTypeSetting, typeSettings)

typeSettingCache[typeName] = mergedSettings
typeSettingCache.set(typeName, mergedSettings)

return mergedSettings
}

typeSettingCache[typeName] = __allTypeSetting
typeSettingCache.set(typeName, __allTypeSetting)

return __allTypeSetting
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ const customizeSchema = async ({ actions, schema, store: gatsbyStore }) => {
break
case `SCALAR`:
/**
* custom scalar types aren't imlemented currently.
* @todo make this hookable so sub-plugins or plugin options can add custom scalar support.
* custom scalar types aren't supported.
*/
break
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { fieldTransformers } from "./field-transformers"
import { getGatsbyNodeTypeNames } from "../../source-nodes/fetch-nodes/fetch-nodes"
import store from "~/store"

import {
Expand Down Expand Up @@ -88,19 +89,19 @@ const excludeField = ({
* with proper node linking and type namespacing
* also filters out unusable fields and types
*/

export const transformFields = ({
fields,
fieldAliases,
fieldBlacklist,
parentType,
parentInterfacesImplementingTypes,
gatsbyNodeTypes,
}) => {
if (!fields || !fields.length) {
return null
}

const gatsbyNodeTypes = getGatsbyNodeTypeNames()

const { fieldAliases, fieldBlacklist } = store.getState().remoteSchema

const parentTypeSettings = getTypeSettingsByType(parentType)

const parentInterfacesImplementingTypeSettings =
Expand Down Expand Up @@ -197,5 +198,9 @@ export const transformFields = ({
return fieldsObject
}, {})

if (!Object.keys(transformedFields).length) {
return null
}

return transformedFields
}
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,20 @@ When using this option, be sure to gitignore the wordpress-cache directory in th
`),
}),
MediaItem: Joi.object({
excludeFieldNames: Joi.array()
.items(Joi.string())
.allow(null)
.allow(false)
.description(`Excludes fields on the MediaItem type by field name.`)
.meta({
example: wrapOptions(`
type: {
MediaItem: {
excludeFieldNames: [\`dateGmt\`, \`parent\`],
},
},
`),
}),
placeholderSizeName: Joi.string()
.default(`gatsby-image-placeholder`)
.description(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import {
findTypeName,
findTypeKind,
} from "~/steps/create-schema-customization/helpers"
import { fieldIsExcludedOnParentType } from "~/steps/ingest-remote-schema/is-excluded"
import {
fieldIsExcludedOnParentType,
fieldIsExcludedOnAll,
} from "~/steps/ingest-remote-schema/is-excluded"
import { returnAliasedFieldName } from "~/steps/create-schema-customization/transform-fields"

export const transformInlineFragments = ({
Expand Down Expand Up @@ -539,11 +542,12 @@ const transformFields = ({
?.filter(
field =>
!fieldIsExcludedOnParentType({
pluginOptions,
field,
parentType,
mainType,
parentField,
}) &&
!fieldIsExcludedOnAll({
pluginOptions,
field,
})
)
.map(field => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import store from "~/store"
import { typeIsExcluded } from "~/steps/ingest-remote-schema/is-excluded"
import { typeIsABuiltInScalar } from "../create-schema-customization/helpers"
import { findTypeName } from "~/steps/create-schema-customization/helpers"
import {
findTypeName,
getTypesThatImplementInterfaceType,
} from "~/steps/create-schema-customization/helpers"
import { transformFields } from "~/steps/create-schema-customization/transform-fields"
import { getPersistentCache } from "~/utils/cache"

const identifyAndStoreIngestableFieldsAndTypes = async () => {
Expand Down Expand Up @@ -46,6 +50,23 @@ const identifyAndStoreIngestableFieldsAndTypes = async () => {
continue
}

if (!interfaceType.fields) {
continue
}

const typesThatImplementInterface =
getTypesThatImplementInterfaceType(interfaceType)

const shouldSkipInterfaceType = !transformFields({
fields: interfaceType.fields,
parentType: interfaceType,
parentInterfacesImplementingTypes: typesThatImplementInterface,
})

if (shouldSkipInterfaceType && interfaceType.name !== `Node`) {
continue
}

store.dispatch.remoteSchema.addFetchedType(interfaceType)

if (interfaceType.fields) {
Expand Down
Loading

0 comments on commit 2bc5902

Please sign in to comment.