Skip to content

Commit

Permalink
Redis fixin' + some small cleanup (#308)
Browse files Browse the repository at this point in the history
  • Loading branch information
tjheffner authored Jan 2, 2024
1 parent 5f184e2 commit 50f5283
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 64 deletions.
37 changes: 11 additions & 26 deletions generator-templates/query/query.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { drupalClient } from '@/lib/drupal/drupalClient'
import { queries } from '.'
import { Node{{pascalCase name}} } from '@/types/drupal/node'
import { {{pascalCase name}} } from '@/types/formatted/{{pascalCase name}}'
import { RESOURCE_TYPES } from '@/lib/constants/resourceTypes'
import { ExpandedStaticPropsContext } from '@/lib/drupal/staticProps'
import {
entityBaseFields,
fetchSingleEntityOrPreview,
} from '@/lib/drupal/query'

// Define the query params for fetching node--{{snakeCase name}}.
export const params: QueryParams<null> = () => {
Expand All @@ -27,23 +32,11 @@ export type {{pascalCase name}}DataOpts = {
export const data: QueryData<{{pascalCase name}}DataOpts, Node{{pascalCase name}}> = async (
opts
): Promise<Node{{pascalCase name}}> => {
const entity = opts?.context?.preview
? // need to use getResourceFromContext for unpublished revisions
await drupalClient.getResourceFromContext<Node{{pascalCase name}}>(
'node--{{snakeCase name}}',
opts.context,
{
params: params().getQueryObject(),
}
)
: // otherwise just lookup by uuid
await drupalClient.getResource<Node{{pascalCase name}}>(
'node--{{snakeCase name}}',
opts.id,
{
params: params().getQueryObject(),
}
)
const entity = (await fetchSingleEntityOrPreview(
opts,
RESOURCE_TYPES.{{constantCase name}},
params
)) as Node{{pascalCase name}}

return entity
}
Expand All @@ -52,14 +45,6 @@ export const formatter: QueryFormatter<Node{{pascalCase name}}, {{pascalCase nam
entity: Node{{pascalCase name}}
) => {
return {
id: entity.id,
entityId: entity.drupal_internal__nid,
entityPath: entity.path.alias,
type: entity.type,
published: entity.status,
moderationState: entity.moderation_state,
title: entity.title,
metatags: entity.metatag,
breadcrumbs: entity.breadcrumbs
...entityBaseFields(entity)
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"build:preview": "yarn build:env-loader && node ./scripts/yarn/build:preview.js",
"build:sitemap": "yarn build:env-loader & node ./scripts/yarn/build:sitemap.js",
"start": "yarn build:env-loader && node ./scripts/yarn/start.js",
"export": "yarn build:env-loader && node ./scripts/yarn/export.js",
"export": "yarn build:env-loader && node ./scripts/yarn/export.js --USE_REDIS",
"export:serve": "http-server out -p 8001",
"redis": "docker run --name next-redis -p 6379:6379 -d redis",
"redis:cli": "docker exec -it next-redis redis-cli",
Expand Down
3 changes: 3 additions & 0 deletions packages/env-loader/src/cli-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ const configureAdditionalHelpText = (

/**
* Parses CLI options from the command line into an object.
*
* See https://www.npmjs.com/package/commander#common-option-types-boolean-and-value
*/
export const getCliOptions = (scriptName: string): EnvVars => {
const program = new Command()
Expand All @@ -78,6 +80,7 @@ export const getCliOptions = (scriptName: string): EnvVars => {
.option('--DRUPAL_CLIENT_SECRET <secret>', 'Drupal client secret')
.option('--DRUPAL_PREVIEW_SECRET <secret>', 'Drupal preview secret')
.option('--DRUPAL_SITE_ID <id>', 'Drupal site ID')
.option('--USE_REDIS', 'Enable redis')
.option('--REDIS_URL <url>', 'Redis URL')
.option('--SITE_URL <url>', 'Origin used for generated absolute paths')

Expand Down
15 changes: 11 additions & 4 deletions plopfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ module.exports = function (plop) {
templateFile: 'generator-templates/type/formatted.hbs',
},
// Strings can be added to print a comment in the terminal.
'You will need to manually import & add your query to src/data/queries/index.ts',
'Be sure to also run `yarn test:u` to update test snapshots for your new query!',
'You will need to do a few steps manually:',
'- Import & add your query to src/data/queries/index.ts',
'- Add your resource type to src/lib/constants/resourceTypes.ts',
'- Update the mock.json with correct data',
'- Run `yarn test:u` to update test snapshots for your new query!',
],
})

Expand Down Expand Up @@ -101,8 +104,11 @@ module.exports = function (plop) {
path: 'src/types/formatted/{{camelCase name}}.ts',
templateFile: 'generator-templates/type/formatted.hbs',
},
'You will need to manually import & add your query to src/data/queries/index.ts',
'Be sure to also run `yarn test:u` to update test snapshots for your new query!',
'You will need to do a few steps manually:',
'- Import & add your query to src/data/queries/index.ts',
'- Add your resource type to src/lib/constants/resourceTypes.ts',
'- Update the mock.json with correct data',
'- Run `yarn test:u` to update test snapshots for your new query!',
// Create react component + test files for new Page type.
{
type: 'add',
Expand All @@ -124,6 +130,7 @@ module.exports = function (plop) {
path: 'playwright/tests/{{camelCase name}}.spec.js',
templateFile: 'generator-templates/component/playwright.hbs',
},
'To render your new page type, update [[...slug]].tsx',
],
})

Expand Down
3 changes: 2 additions & 1 deletion src/data/queries/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
entityBaseFields,
fetchSingleEntityOrPreview,
} from '@/lib/drupal/query'
import { RESOURCE_TYPES } from '@/lib/constants/resourceTypes'

export const params: QueryParams<null> = () => {
return queries
Expand All @@ -37,7 +38,7 @@ export const data: QueryData<EventDataOpts, NodeEvent> = async (
): Promise<NodeEvent> => {
const entity = (await fetchSingleEntityOrPreview(
opts,
'node--event',
RESOURCE_TYPES.EVENT,
params
)) as NodeEvent

Expand Down
11 changes: 3 additions & 8 deletions src/data/queries/headerFooter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ export type RawHeaderFooterData = {
headerMegaMenu: HeaderMegaMenu
}

// Define the query params for fetching footer menu data.
export const params: QueryParams<null> = () => {
return queries.getParams().addFields('menu_items', ['title,url'])
}

// Define the query params for fetching header megamenu data. Include referenced promo block data, if present
// Define extra equery params for fetching header megamenu data. Include referenced promo block data, if present
export const megaMenuParams: QueryParams<null> = () => {
return queries
.getParams()
Expand All @@ -30,8 +25,8 @@ export const megaMenuParams: QueryParams<null> = () => {

export const data: QueryData<null, RawHeaderFooterData> = async () => {
// Gather data from the different menus for the headerFooter data object
const footerColumns = await getMenu('va-gov-footer', params)
const footerBottomRail = await getMenu('footer-bottom-rail', params)
const footerColumns = await getMenu('va-gov-footer')
const footerBottomRail = await getMenu('footer-bottom-rail')
const headerMegaMenu: HeaderMegaMenu = await getMenu(
'header-megamenu',
megaMenuParams
Expand Down
3 changes: 2 additions & 1 deletion src/data/queries/newsStory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
entityBaseFields,
fetchSingleEntityOrPreview,
} from '@/lib/drupal/query'
import { RESOURCE_TYPES } from '@/lib/constants/resourceTypes'

// Define the query params for fetching node--news_story.
export const params: QueryParams<null> = () => {
Expand All @@ -33,7 +34,7 @@ export const data: QueryData<NewsStoryDataOpts, NodeNewsStory> = async (
): Promise<NodeNewsStory> => {
const entity = (await fetchSingleEntityOrPreview(
opts,
'node--news_story',
RESOURCE_TYPES.STORY,
params
)) as NodeNewsStory

Expand Down
18 changes: 4 additions & 14 deletions src/data/queries/storyListing.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { QueryData, QueryFormatter, QueryParams } from 'next-drupal-query'
import { drupalClient } from '@/lib/drupal/drupalClient'
import { queries } from '.'
import { NodeStoryListing, NodeNewsStory } from '@/types/drupal/node'
import { Menu } from '@/types/drupal/menu'
import { StoryListing } from '@/types/formatted/storyListing'
import { DrupalJsonApiParams } from 'drupal-jsonapi-params'
import { buildSideNavDataFromMenu } from '@/lib/drupal/facilitySideNav'
import { ListingPageDataOpts } from '@/lib/drupal/listingPages'
import { RESOURCE_TYPES } from '@/lib/constants/resourceTypes'
Expand All @@ -14,6 +12,7 @@ import {
fetchSingleResourceCollectionPage,
entityBaseFields,
fetchSingleEntityOrPreview,
getMenu,
} from '@/lib/drupal/query'

const PAGE_SIZE = PAGE_SIZES[RESOURCE_TYPES.STORY_LISTING]
Expand Down Expand Up @@ -45,7 +44,7 @@ export const data: QueryData<ListingPageDataOpts, StoryListingData> = async (
) => {
const entity = (await fetchSingleEntityOrPreview(
opts,
'node--story_listing',
RESOURCE_TYPES.STORY_LISTING,
params
)) as NodeStoryListing

Expand All @@ -67,19 +66,10 @@ export const data: QueryData<ListingPageDataOpts, StoryListingData> = async (
PAGE_SIZE
)

// Fetch facility menu (sidebar navigation)
const menuOpts = {
params: new DrupalJsonApiParams()
.addFields('menu_items', ['title,url'])
.getQueryObject(),
}

// Fetch the menu name dynamically off of the field_office reference
// We may want to make our own version of this method, a la staticPathResources
const menu = await drupalClient.getMenu(
const menu = await getMenu(
entity.field_office.field_system_menu.resourceIdObjMeta
.drupal_internal__target_id,
menuOpts
.drupal_internal__target_id
)

return {
Expand Down
5 changes: 4 additions & 1 deletion src/lib/drupal/drupalClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export const drupalClient = new DrupalClient(baseUrl, {
clientId: process.env.DRUPAL_CLIENT_ID,
clientSecret: process.env.DRUPAL_CLIENT_SECRET,
},
// cache: redisCache(createRedisClient(process.env.REDIS_URL)),
// Generally use cache for `yarn export` as it generates all pages
cache: process.env.USE_REDIS
? redisCache(createRedisClient(process.env.REDIS_URL))
: null,
previewSecret: process.env.DRUPAL_PREVIEW_SECRET,
})
23 changes: 15 additions & 8 deletions src/lib/drupal/query.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { DrupalJsonApiParams } from 'drupal-jsonapi-params'
import { PHASE_PRODUCTION_BUILD } from 'next/constants'
import { JsonApiResponse } from 'next-drupal'
import { QueryParams } from 'next-drupal-query'
import { queries } from '@/data/queries'
import { ResourceType } from '@/lib/constants/resourceTypes'
import { drupalClient } from '@/lib/drupal/drupalClient'
import { QueryParams } from 'next-drupal-query'
import { NodeTypes } from '@/types/drupal/node'
import { PublishedEntity } from '@/types/formatted/publishedEntity'

Expand Down Expand Up @@ -91,20 +93,25 @@ export async function fetchAndConcatAllResourceCollectionPages<T>(
}
}

// Fetch drupal menu resource with cache
export async function getMenu(name: string, params: QueryParams<null>) {
// Fetch drupal menu resource with cache.
export async function getMenu(name: string, params?: QueryParams<null>) {
const defaultMenuParams = queries
.getParams()
.addFields('menu_items', ['title,url'])
.getQueryObject()

const menu = await drupalClient.getMenu(name, {
params: params().getQueryObject(),
params: params ? params().getQueryObject() : defaultMenuParams,

// Cache resource during build, not dev.
// withCache: process.env.NEXT_PHASE === PHASE_PRODUCTION_BUILD,
// cacheKey: `menu:${name}`,
withCache: process.env.NEXT_PHASE === PHASE_PRODUCTION_BUILD,
cacheKey: `menu:${name}`,
})

return menu
}

// Consistent handler to fetch a node entity from a normal route or a preview route
// Consistent handler to fetch a node entity from a normal route or a preview route.
export async function fetchSingleEntityOrPreview(opts, type, params) {
const entity = opts?.context?.preview
? // need to use getResourceFromContext for unpublished revisions
Expand All @@ -119,7 +126,7 @@ export async function fetchSingleEntityOrPreview(opts, type, params) {
return entity
}

// Helper function to return a consistent set of base fields for resources
// Helper function to return a consistent set of base fields for resources.
export const entityBaseFields = (entity: NodeTypes): PublishedEntity => {
return {
id: entity.id,
Expand Down

0 comments on commit 50f5283

Please sign in to comment.