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

chore(gatsby-plugin-fastify): Misc cleanup #85

Merged
merged 3 commits into from
Oct 8, 2021
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
5 changes: 5 additions & 0 deletions .changeset/lazy-ears-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gatsby-plugin-fastify": patch
---

chore(gatsby-plugin-fastify): Misc cleanup and typing improvements
7 changes: 3 additions & 4 deletions packages/gatsby-plugin-fastify/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,9 @@ dist
.DS_Store

#build files
/index.js
/utils.js
/serve.js
/plugins
/gatsby
/utils
/serve.js
/gatsby-*.js
/*.d.ts
/cli.js
3 changes: 2 additions & 1 deletion packages/gatsby-plugin-fastify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,19 @@
},
"dependencies": {
"@babel/runtime": "^7.15.4",
"fs-extra": "^10.0.0",
"open": "^8.2.1",
"picomatch": "^2.3.0",
"yargs": "^17.2.1"
},
"devDependencies": {
"@babel/cli": "^7.15.7",
"@babel/core": "^7.15.5",
"@types/fs-extra": "^9.0.13",
"@types/node": "^14.17.20",
"babel-preset-gatsby-package": "^1.14.0",
"cross-env": "^7.0.3",
"fastify": "^3.22.0",
"fastify-caching": "^6.1.0",
"fastify-compress": "^3.6.0",
"fastify-plugin": "^3.0.0",
"fastify-static": "^4.2.4",
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-plugin-fastify/src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env node

import { setConfig, ConfigKeyEnum, getServerConfg } from "./utils";
import { setConfig, ConfigKeyEnum, getServerConfig } from "./utils/config";
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { gatsbyServer } from "./serve";
Expand Down Expand Up @@ -43,7 +43,7 @@ yargs(hideBin(process.argv))
(_yargs) => {},
(argv) => {
setConfig(ConfigKeyEnum.CLI, argv as any);
setConfig(ConfigKeyEnum.SERVER, getServerConfg());
setConfig(ConfigKeyEnum.SERVER, getServerConfig());

gatsbyServer();
},
Expand Down
54 changes: 29 additions & 25 deletions packages/gatsby-plugin-fastify/src/gatsby-node.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,49 @@
import fs from "fs";
import type { GatsbyReduxStore } from "gatsby/dist/redux";
import type { PathConfig } from "./plugins/clientPaths";
import { existsSync, mkdir, writeJSON } from "fs-extra";

import type { GatsbyServerFeatureOptions } from "./plugins/gatsby";
import type { GatsbyNodeServerConfig } from "./utils";
import type { PluginOptionsSchemaJoi } from "gatsby-plugin-utils";
import type { GatsbyNodeServerConfig } from "./utils/config";
import type { GatsbyNode } from "gatsby";

export type GatsbyApiInput = { pathPrefix: string; store: GatsbyReduxStore };
import { makePluginData } from "./utils/plugin-data";
import { getFunctionManifest } from "./gatsby/functionsManifest";
import { CONFIG_FILE_NAME, PATH_TO_CACHE } from "./utils/constants";
import { getClientSideRoutes } from "./gatsby/clientSideRoutes";

export function onPostBuild(
{ store, pathPrefix }: GatsbyApiInput,
export const onPostBuild: GatsbyNode["onPostBuild"] = async (
{ store, pathPrefix, reporter },
pluginOptions: GatsbyServerFeatureOptions,
) {
const { pages, redirects } = store.getState();

const p: PathConfig[] = [];
for (const page of pages.values()) {
p.push({
matchPath: page.matchPath,
path: page.path,
});
}
) => {
const { redirects } = store.getState();

const pluginData = await makePluginData(store, pathPrefix);

const functions = await getFunctionManifest(pluginData);
const clientSideRoutes = await getClientSideRoutes(pluginData);

// @ts-ignore
delete pluginOptions.plugins;

const config: GatsbyNodeServerConfig = {
...pluginOptions,
paths: p,
clientSideRoutes,
redirects,
prefix: pathPrefix,
functions,
};

if (!fs.existsSync("public/")) {
fs.mkdirSync("public/");
if (!existsSync(PATH_TO_CACHE)) {
await mkdir(PATH_TO_CACHE);
}

fs.writeFileSync("public/gatsby-plugin-node.json", JSON.stringify(config, null, 2));
}
try {
await writeJSON(pluginData.configFolder(CONFIG_FILE_NAME), config, { spaces: 2 });
} catch (e) {
reporter.error("Error writing config file.", e, "gatsby-plugin-fastify");
}
};

export function pluginOptionsSchema({ Joi }: { Joi: PluginOptionsSchemaJoi }) {
export const pluginOptionsSchema: GatsbyNode["pluginOptionsSchema"] = ({ Joi }) => {
return Joi.object({
compression: Joi.boolean().default(true),
});
}
};
21 changes: 21 additions & 0 deletions packages/gatsby-plugin-fastify/src/gatsby/clientSideRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { PathConfig } from "../plugins/clientPaths";
import type { PluginData } from "../utils/plugin-data";

export type NoUndefinedField<T> = { [P in keyof T]-?: NoUndefinedField<NonNullable<T[P]>> };

export async function getClientSideRoutes(pageData: PluginData) {
const { pages } = pageData;

const routes: NoUndefinedField<PathConfig>[] = [];

for (const page of pages.values()) {
if (page?.matchPath) {
routes.push({
matchPath: page.matchPath,
path: page.path,
});
}
}

return routes;
}
22 changes: 22 additions & 0 deletions packages/gatsby-plugin-fastify/src/gatsby/functionsManifest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { existsSync, readJSON } from "fs-extra";
import { IGatsbyFunction } from "gatsby/dist/redux/types";
import { PluginData } from "../utils/plugin-data";

export async function getFunctionManifest(pluginData: PluginData): Promise<IGatsbyFunction[]> {
const { functionsFolder } = pluginData;
const compiledFunctionsDir = functionsFolder();
let functions: IGatsbyFunction[] = [];

if (!existsSync(compiledFunctionsDir)) {
console.error("Unable to find function mainfest @ ", compiledFunctionsDir);
return functions;
}

try {
functions = await readJSON(functionsFolder(`manifest.json`), `utf-8`);
} catch (e) {
// ignore
}

return functions;
}
13 changes: 6 additions & 7 deletions packages/gatsby-plugin-fastify/src/plugins/clientPaths.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import path from "path";

import type { FastifyPluginAsync } from "fastify";
import type { NoUndefinedField } from "../gatsby/clientSideRoutes";

export type PathConfig = {
matchPath: string | undefined;
path: string;
};

export const handleClientOnlyPaths: FastifyPluginAsync<{
paths: PathConfig[];
paths: NoUndefinedField<PathConfig>[];
}> = async (fastify, { paths }) => {
for (const p of paths) {
if (p?.matchPath) {
console.info("Registering client-only route: ", p.path);
console.info("Registering client-only route: ", p.path);

fastify.get(p.matchPath, (_req, reply) => {
reply.sendFile("index.html", path.resolve("./public", p.path.replace("/", "")));
});
}
fastify.get(p.matchPath, (_req, reply) => {
reply.sendFile("index.html", path.resolve("./public", p.path.replace("/", "")));
});
}
};
75 changes: 25 additions & 50 deletions packages/gatsby-plugin-fastify/src/plugins/functions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import path from "path";
import fs from "fs";
import { existsSync } from "fs-extra";
import { IGatsbyFunction } from "gatsby/dist/redux/types";
import type { FastifyPluginAsync, FastifyReply, FastifyRequest } from "fastify";

const PATH_TO_FUNCTIONS = "./.cache/functions/";
import { PATH_TO_FUNCTIONS } from "../utils/constants";

export type GatsbyFunctionHandler = (
req: FastifyRequest,
Expand All @@ -15,7 +14,7 @@ async function getFunctionToExec({
}: IGatsbyFunction): Promise<GatsbyFunctionHandler | null> {
const funcImportAbsPath = path.resolve(PATH_TO_FUNCTIONS, relativeCompiledFilePath);

if (!fs.existsSync(funcImportAbsPath)) {
if (!existsSync(funcImportAbsPath)) {
console.error("Unable to find function to import @ ", funcImportAbsPath);
return null;
}
Expand All @@ -33,52 +32,28 @@ async function getFunctionHandler(routeConfig: IGatsbyFunction) {
return execFunction;
}

function getFunctionManifest(): IGatsbyFunction[] {
const compiledFunctionsDir = path.resolve(`.cache`, `functions`);
let functions: IGatsbyFunction[] = [];

if (!fs.existsSync(compiledFunctionsDir)) {
console.error("Unable to find funciton mainfest @ ", compiledFunctionsDir);
return functions;
}

try {
functions = JSON.parse(
fs.readFileSync(path.join(compiledFunctionsDir, `manifest.json`), `utf-8`),
);
} catch (e) {
// ignore
}

return functions;
}

export const handleFunctions: FastifyPluginAsync<{ prefix: string }> = async (
fastify,
{ prefix },
) => {
const functions = getFunctionManifest();

if (functions?.length > 0) {
for (const funcConfig of functions) {
const fnToExecute = await getFunctionHandler(funcConfig);

if (fnToExecute) {
console.info("Registering function: ", prefix + funcConfig.functionRoute);
fastify.all(funcConfig.functionRoute, {
handler: async function (req, reply) {
try {
await Promise.resolve(fnToExecute(req, reply));
} catch (e) {
console.error(e);
// Don't send the error if that would cause another error.
if (!reply.sent) {
reply.code(500).send("Error executing Gatsby Funciton.");
export const handleFunctions: FastifyPluginAsync<{ prefix: string; functions: IGatsbyFunction[] }> =
async (fastify, { prefix, functions }) => {
if (functions?.length > 0) {
for (const funcConfig of functions) {
const fnToExecute = await getFunctionHandler(funcConfig);

if (fnToExecute) {
console.info("Registering function: ", prefix + funcConfig.functionRoute);
fastify.all(funcConfig.functionRoute, {
handler: async function (req, reply) {
try {
await Promise.resolve(fnToExecute(req, reply));
} catch (e) {
console.error(e);
// Don't send the error if that would cause another error.
if (!reply.sent) {
reply.code(500).send("Error executing Gatsby Funciton.");
}
}
}
},
});
},
});
}
}
}
}
};
};
12 changes: 7 additions & 5 deletions packages/gatsby-plugin-fastify/src/plugins/gatsby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { handleClientOnlyPaths } from "./clientPaths";
import { handleFunctions } from "./functions";
import { handleRedirects } from "./redirects";
import { handleStatic } from "./static";
import { getConfig } from "../utils";
import { getConfig } from "../utils/config";

import fastifyCompress from "fastify-compress";
import type { FastifyPluginAsync } from "fastify";
import type { PluginOptions } from "gatsby";

export type GatsbyServerFeatureOptions = {
export interface GatsbyServerFeatureOptions extends PluginOptions {
compression: boolean;
};
}

export const serveGatsby: FastifyPluginAsync<GatsbyServerFeatureOptions> = async (fastify) => {
//@ts-ignore
Expand All @@ -23,7 +24,7 @@ export const serveGatsby: FastifyPluginAsync<GatsbyServerFeatureOptions> = async
console.info("Starting server with config: ", serverConfig);
}

const { paths, redirects, compression } = serverConfig;
const { clientSideRoutes, redirects, compression, functions } = serverConfig;

// Optimizations
if (compression) {
Expand All @@ -34,6 +35,7 @@ export const serveGatsby: FastifyPluginAsync<GatsbyServerFeatureOptions> = async
// Gatsby Functions
await fastify.register(handleFunctions, {
prefix: "/api/",
functions,
});
// Gatsby Static

Expand All @@ -42,7 +44,7 @@ export const serveGatsby: FastifyPluginAsync<GatsbyServerFeatureOptions> = async
// Gatsby Client Only Routes

await fastify.register(handleClientOnlyPaths, {
paths,
paths: clientSideRoutes,
});

// Gatsby Redirects
Expand Down
2 changes: 1 addition & 1 deletion packages/gatsby-plugin-fastify/src/serve.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { serveGatsby } from "./plugins/gatsby";
import Fastify from "fastify";
import { getConfig } from "./utils";
import { getConfig } from "./utils/config";
import open from "open";

export function gatsbyServer() {
Expand Down
Loading