Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SLB-202: De-duplicate Gatsby queries #126

Merged
merged 15 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/website/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ public
styles.css
persisted-store

src/gatsby-fragments.js
autoload.mjs
6 changes: 6 additions & 0 deletions apps/website/gatsby-config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export default {
'gatsby-plugin-pnpm',
'gatsby-plugin-layout',
'gatsby-plugin-sharp',
{
resolve: '@amazeelabs/gatsby-plugin-operations',
options: {
operations: './node_modules/@custom/schema/build/operations.json',
},
},
{
resolve: '@amazeelabs/gatsby-source-silverback',
options: {
Expand Down
139 changes: 44 additions & 95 deletions apps/website/gatsby-node.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// TODO: re-add @ts-check when the issue with the type definitions is resolved.
import { Locale } from '@custom/schema';
import { graphqlQuery } from '@amazeelabs/gatsby-plugin-operations';
import { IndexPagesQuery, ListPagesQuery, Locale } from '@custom/schema';
import { cpSync } from 'fs';
import { resolve } from 'path';
import serve from 'serve-static';
Expand All @@ -17,11 +17,20 @@ export const onCreateWebpackConfig = ({ actions }) => {
});
};

/**
* @template T extends any
* @param {T | undefined | null} val
* @returns {val is T}
*/
Leksat marked this conversation as resolved.
Show resolved Hide resolved
function isDefined(val) {
return Boolean(val);
}

/**
*
* @type {import('gatsby').GatsbyNode['createPages']}
*/
export const createPages = async ({ actions, graphql }) => {
export const createPages = async ({ actions }) => {
// Rewrite file requests to Drupal.
actions.createRedirect({
fromPath: '/sites/default/files/*',
Expand All @@ -35,74 +44,60 @@ export const createPages = async ({ actions, graphql }) => {
statusCode: 200,
});

// TODO: Remove duplication of queries and fix typing.
/**
* @type {{data: import('@custom/schema')['IndexPagesQuery'], errors?: [string]}}
*/
// @ts-ignore
const settings = await graphql(`
query IndexPages {
websiteSettings {
homePage {
translations: _translations {
typeName: __typename
locale
id: _id
remoteId: _id
path
}
}
notFoundPage {
translations: _translations {
path
}
}
}
}
`);
// Run the query that lists all pages, both decap and Drupal.
const pages = await graphqlQuery(ListPagesQuery);

// Create a gatsby page for each of these pages.
pages.data?.allPages?.filter(isDefined).forEach(({ id, path, locale }) => {
const context = {
id,
locale,
};
actions.createPage({
path: path,
component: resolve(`./src/templates/page.tsx`),
context,
});
});

// Search for index page settings.
const settings = await graphqlQuery(IndexPagesQuery);

if (settings.errors) {
settings.errors.map((e) => console.error(e));
throw settings.errors;
}

if (settings.data?.websiteSettings?.homePage) {
/**
* @type {import('@amazeelabs/gatsby-source-silverback').SilverbackPageContext['localizations']}
*/
const frontPageLocalizations =
settings.data?.websiteSettings?.homePage.translations.map(
({ locale }) => ({
settings.data?.websiteSettings?.homePage.translations
?.filter(isDefined)
.map(({ locale }) => ({
path: `/${locale}`,
locale,
}),
);
})) || [];

settings.data?.websiteSettings?.homePage.translations.forEach(
({ locale, typeName, id, remoteId, path }) => {
settings.data?.websiteSettings?.homePage.translations
?.filter(isDefined)
.forEach(({ locale, id, path }) => {
// Create a page at the "front" path.
const frontPath =
frontPageLocalizations.length > 1 ? `/${locale}` : '/';
/**
* @type {import('@amazeelabs/gatsby-source-silverback').SilverbackPageContext}
*/
const context = {
typeName,
id,
remoteId,
locale,
localizations:
frontPageLocalizations.length > 1 ? frontPageLocalizations : [],
};
actions.createPage({
path: frontPath,
component: resolve(`./src/templates/drupal-page.tsx`),
component: resolve(`./src/templates/page.tsx`),
context,
});
// Delete the page at the original path.
actions.deletePage({
path,
component: resolve(`./src/templates/drupal-page.tsx`),
component: resolve(`./src/templates/page.tsx`),
});
// Create a redirect from the original path to the "front" path.
actions.createRedirect({
Expand All @@ -111,64 +106,18 @@ export const createPages = async ({ actions, graphql }) => {
isPermanent: true,
force: true,
});
},
);
});
}

// Remove 404 pages. We handle them in src/pages/404.tsx
settings.data?.websiteSettings?.notFoundPage?.translations.forEach(
({ path }) => {
settings.data?.websiteSettings?.notFoundPage?.translations
?.filter(isDefined)
.forEach(({ path }) => {
actions.deletePage({
path,
component: resolve(`./src/templates/drupal-page.tsx`),
component: resolve(`./src/templates/page.tsx`),
});
},
);

/**
* @type {{
* data?: {
* allDecapPage: {
* nodes: Array<{
* id: string;
* path: string;
* locale: string;
* }>
* }
* },
* errors?: any[];
* }}
*/
const decapPages = await graphql(`
query DecapPages {
allDecapPage {
nodes {
id
path
locale
}
}
}
`);

decapPages.data?.allDecapPage.nodes.forEach(({ id, path, locale }) => {
/**
* @type {import('@amazeelabs/gatsby-source-silverback').SilverbackPageContext}
*/
const context = {
typeName: 'DecapPage',
id,
remoteId: id,
locale,
// TODO: Handle decap localizations.
localizations: [],
};
actions.createPage({
path: path,
component: resolve(`./src/templates/decap-page.tsx`),
context,
});
});

// Broken Gatsby links will attempt to load page-data.json files, which don't exist
// and also should not be piped into the strangler function. Thats why they
Expand Down
6 changes: 4 additions & 2 deletions apps/website/image.mjs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import sizeOf from 'image-size';
import mime from 'mime-types';

// TODO: Move to shared package.
/**
* @param {string | undefined} source
*/
export function imageProps(source) {
// If its a decap image, process it.
// Otherwise, it comes from Drupal and
// already has all necessary props.
if (source.startsWith('/apps/decap')) {
if (source && source.startsWith('/apps/decap')) {
const relativeSource = source.substring(`/apps/decap`.length);
const dimensions = sizeOf(`node_modules/@custom/decap/${relativeSource}`);
const imageSrc = `${
Expand Down
6 changes: 3 additions & 3 deletions apps/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
"dependencies": {
"@amazeelabs/bridge-gatsby": "^1.2.7",
"@amazeelabs/cloudinary-responsive-image": "^1.6.15",
"@amazeelabs/gatsby-plugin-operations": "^1.1.0",
"@amazeelabs/gatsby-silverback-cloudinary": "^1.2.7",
"@amazeelabs/gatsby-source-silverback": "^1.13.7",
"@amazeelabs/gatsby-source-silverback": "^1.13.10",
"@amazeelabs/publisher": "^2.4.17",
"@amazeelabs/strangler-netlify": "^1.1.9",
"@custom/decap": "workspace:*",
Expand Down Expand Up @@ -38,9 +39,8 @@
},
"scripts": {
"test:static": "tsc --noEmit && eslint '**/*.{ts,tsx,js,jsx}' --ignore-path='./.gitignore'",
"prep": "pnpm run prep:styles && pnpm run prep:fragments",
"prep": "pnpm run prep:styles",
"prep:styles": "rm -f styles.css && cp node_modules/@custom/ui/build/styles.css styles.css",
"prep:fragments": "rm -rf src/gatsby-fragments.js && cp node_modules/@custom/schema/build/gatsby-fragments.js src/gatsby-fragments.js",
"build:gatsby": "pnpm build:dotenv && gatsby build",
"build:dotenv": "rm -rf .env && echo \"DRUPAL_EXTERNAL_URL='$DRUPAL_EXTERNAL_URL'\nDRUPAL_INTERNAL_URL='$DRUPAL_INTERNAL_URL'\" >> .env",
"rebuild": "gatsby build",
Expand Down
23 changes: 6 additions & 17 deletions apps/website/src/layouts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
import { SilverbackPageContext } from '@amazeelabs/gatsby-source-silverback';
import { graphql, useStaticQuery } from '@amazeelabs/gatsby-plugin-operations';
import { FrameQuery, registerExecutor } from '@custom/schema';
import { IntlProvider } from '@custom/ui/intl';
import { Frame } from '@custom/ui/routes/Frame';
import { graphql, useStaticQuery, WrapPageElementNodeArgs } from 'gatsby';
import React, { PropsWithChildren } from 'react';

export default function Layout({
children,
pageContext: { locale },
}: PropsWithChildren<
WrapPageElementNodeArgs<any, SilverbackPageContext>['props']
>) {
// TODO: Remove duplication of queries here.
const data = useStaticQuery<FrameQuery>(graphql`
query Frame {
mainNavigation: mainNavigations {
...Navigation
}
footerNavigation: footerNavigations {
...Navigation
}
}
`);
locale,
}: PropsWithChildren<{
locale: string;
}>) {
const data = useStaticQuery(graphql(FrameQuery));
registerExecutor(FrameQuery, data);
return (
<IntlProvider locale={locale || 'en'}>
Expand Down
19 changes: 4 additions & 15 deletions apps/website/src/pages/404.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
import { graphql } from '@amazeelabs/gatsby-plugin-operations';
import {
NotFoundPageQuery,
registerExecutor,
ViewPageQuery,
} from '@custom/schema';
import { Page } from '@custom/ui/routes/Page';
import { graphql, PageProps } from 'gatsby';
import { PageProps } from 'gatsby';
import React from 'react';

import {
LanguageNegotiator,
LanguageNegotiatorContent,
} from '../utils/language-negotiator';

export const query = graphql`
query NotFoundPage {
websiteSettings {
notFoundPage {
translations {
id
locale
...Page
}
}
}
}
`;
export const query = graphql(NotFoundPageQuery);

function isTruthy<T>(value: T | undefined | null): value is T {
return Boolean(value);
}

export default function Index({ data }: PageProps<NotFoundPageQuery>) {
export default function Index({ data }: PageProps<typeof query>) {
Leksat marked this conversation as resolved.
Show resolved Hide resolved
data.websiteSettings?.notFoundPage?.translations
?.filter(isTruthy)
.forEach(({ id, locale, ...page }) => {
Expand Down
62 changes: 0 additions & 62 deletions apps/website/src/templates/decap-page.tsx

This file was deleted.

Loading
Loading