Skip to content

Commit

Permalink
fix(gatsby-plugin-gatsby-cloud): Remove sibling detection code and re…
Browse files Browse the repository at this point in the history
…ly on match paths (#29610)

* Remove sibling detection code and rely on match paths

* Update snapshot

Co-authored-by: gatsbybot <mathews.kyle+gatsbybot@gmail.com>
  • Loading branch information
sidharthachatterjee and gatsbybot committed Feb 23, 2021
1 parent 308d418 commit 6016c26
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 175 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`create-redirects should assemble a redirects file 1`] = `"{\\"redirects\\":[{\\"fromPath\\":\\"/old-url\\",\\"toPath\\":\\"/new-url\\",\\"isPermanent\\":true},{\\"fromPath\\":\\"/url_that_is/not_pretty\\",\\"toPath\\":\\"/pretty/url\\",\\"statusCode\\":201}],\\"rewrites\\":[{\\"fromPath\\":\\"/path3/:level1/:level2\\",\\"toPath\\":\\"/path3/[level1]/[level2]/\\"},{\\"fromPath\\":\\"/url_that_is/ugly\\",\\"toPath\\":\\"/not_ugly/url\\"},{\\"fromPath\\":\\"/path2/*splatparam\\",\\"toPath\\":\\"/path2/[...splatparam]/\\"},{\\"fromPath\\":\\"/path4/:param1\\",\\"toPath\\":\\"/path4/[param1]/\\"},{\\"fromPath\\":\\"/path/*\\",\\"toPath\\":\\"/path/[...]/\\"}]}"`;
exports[`create-redirects should assemble a redirects file 1`] = `"{\\"redirects\\":[{\\"fromPath\\":\\"/old-url\\",\\"toPath\\":\\"/new-url\\",\\"isPermanent\\":true},{\\"fromPath\\":\\"/url_that_is/not_pretty\\",\\"toPath\\":\\"/pretty/url\\",\\"statusCode\\":201}],\\"rewrites\\":[{\\"fromPath\\":\\"/url_that_is/ugly\\",\\"toPath\\":\\"/not_ugly/url\\"},{\\"fromPath\\":\\"/path2/*splatparam\\",\\"toPath\\":\\"/path2/[...splatparam]/\\"},{\\"fromPath\\":\\"/path/*\\",\\"toPath\\":\\"/path/[...]/\\"},{\\"fromPath\\":\\"/path3/:level1/:level2\\",\\"toPath\\":\\"/path3/[level1]/[level2]/\\"},{\\"fromPath\\":\\"/path4/:param1\\",\\"toPath\\":\\"/path4/[param1]/\\"}]}"`;
22 changes: 0 additions & 22 deletions packages/gatsby-plugin-gatsby-cloud/src/__tests__/is-sibling.js

This file was deleted.

77 changes: 2 additions & 75 deletions packages/gatsby-plugin-gatsby-cloud/src/create-redirects.js
Original file line number Diff line number Diff line change
@@ -1,90 +1,17 @@
import { writeFile } from "fs-extra"
import { REDIRECTS_FILENAME } from "./constants"

/**
* Get all rewrites and sort them by most specific at the top
* code is based on @reach/router match utility (https://github.com/reach/router/blob/152aff2352bc62cefc932e1b536de9efde6b64a5/src/lib/utils.js#L224-L254)
*/

const paramRe = /^:(.+)/

const SEGMENT_POINTS = 4
const STATIC_POINTS = 3
const DYNAMIC_POINTS = 2
const SPLAT_PENALTY = 1
const ROOT_POINTS = 1

const isRootSegment = segment => segment === ``
const isDynamic = segment => paramRe.test(segment)
const isSplat = segment => segment === `*`

const rankRoute = (route, index) => {
const score = route.default
? 0
: segmentize(route).reduce((score, segment) => {
score += SEGMENT_POINTS
if (isRootSegment(segment)) score += ROOT_POINTS
else if (isDynamic(segment)) score += DYNAMIC_POINTS
else if (isSplat(segment)) score -= SEGMENT_POINTS + SPLAT_PENALTY
else score += STATIC_POINTS
return score
}, 0)
return { route, score, index }
}

const rankRoutes = routes =>
routes
.map(rankRoute)
.sort((a, b) =>
a.score < b.score ? 1 : a.score > b.score ? -1 : a.index - b.index
)

const segmentize = uri =>
uri
// strip starting/ending slashes
.replace(/(^\/+|\/+$)/g, ``)
.split(`/`)

/**
* rankRewrites
*
* We need to order rewrites in order of specificity because more specific rewrites have to be first in order.
* i.e. /url_that_is/ugly is more specific than /path4/:param1 even though both have 2 url segments
*/
const rankRewrites = rewrites => {
let sortedRewrites = []

const fromPaths = rewrites.map(({ fromPath }) => fromPath)
const rankedRoutes = rankRoutes(fromPaths)

for (let { route } of rankedRoutes) {
const rewrite = rewrites.find(rewrite => rewrite.fromPath === route)
if (rewrite) {
sortedRewrites.push(rewrite)
}
}

return sortedRewrites
}

export default async function writeRedirectsFile(
pluginData,
redirects,
rewrites,
siblingStaticPaths
rewrites
) {
const { publicFolder } = pluginData

if (!redirects.length && !rewrites.length) return null

// order rewrites based on priority
const rankedRewrites = rankRewrites(rewrites)

// Is it ok to pass through the data or should we format it so that we don't have dependencies
// between the redirects and rewrites formats? What are the chances those will change?
const FILE_PATH = publicFolder(REDIRECTS_FILENAME)
return writeFile(
FILE_PATH,
JSON.stringify({ redirects, rewrites: rankedRewrites, siblingStaticPaths })
)
return writeFile(FILE_PATH, JSON.stringify({ redirects, rewrites }))
}
67 changes: 35 additions & 32 deletions packages/gatsby-plugin-gatsby-cloud/src/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import WebpackAssetsManifest from "webpack-assets-manifest"
import makePluginData from "./plugin-data"
import buildHeadersProgram from "./build-headers-program"
import createRedirects from "./create-redirects"
import { isSibling } from "./is-sibling"
import { readJSON } from "fs-extra"
import { joinPath } from "gatsby-core-utils"
import { DEFAULT_OPTIONS, BUILD_HTML_STAGE, BUILD_CSS_STAGE } from "./constants"

let assetsManifest = {}
Expand Down Expand Up @@ -34,56 +35,58 @@ exports.onPostBuild = async (
const { redirects } = store.getState()

let rewrites = []
let siblingStaticPaths = []
if (pluginOptions.generateMatchPathRewrites) {
const { pages } = store.getState()
rewrites = Array.from(pages.values())
.filter(page => page.matchPath && page.matchPath !== page.path)
.map(page => {
const siblings = Array.from(pages.values())
.filter(maybeSiblingPage => {
if (maybeSiblingPage.matchPath) return false
const matchPathsFile = joinPath(
pluginData.program.directory,
`.cache`,
`match-paths.json`
)

return isSibling(page.matchPath, maybeSiblingPage.path)
})
.map(p => p.path)
const matchPaths = await readJSON(matchPathsFile)

siblingStaticPaths.push(...siblings)

return {
fromPath: page.matchPath,
toPath: page.path,
}
})
rewrites = matchPaths.map(({ matchPath, path }) => {
return {
fromPath: matchPath,
toPath: path,
}
})
}

await Promise.all([
buildHeadersProgram(pluginData, pluginOptions, reporter),
createRedirects(pluginData, redirects, rewrites, siblingStaticPaths),
createRedirects(pluginData, redirects, rewrites),
])
}

exports.pluginOptionsSchema = ({ Joi }) =>
Joi.object({
headers: Joi.object()
.pattern(/^/, Joi.array().items(Joi.string()))
.description(`Option to add headers for a filename`),
const MATCH_ALL_KEYS = /^/
const pluginOptionsSchema = function ({ Joi }) {
const headersSchema = Joi.object()
.pattern(MATCH_ALL_KEYS, Joi.array().items(Joi.string()))
.description(`Add more headers to specific pages`)

return Joi.object({
headers: headersSchema,
allPageHeaders: Joi.array()
.items(Joi.string())
.description(`Option to add headers for all files`),
.description(`Add more headers to all the pages`),
mergeSecurityHeaders: Joi.boolean().description(
`Option to include default Gatsby Cloud security headers (true by default)`
`When set to false, turns off the default security headers`
),
mergeLinkHeaders: Joi.boolean().description(
`Option to include default Gatsby Cloud link headers (true by default)`
`When set to false, turns off the default gatsby js headers`
),
mergeCachingHeaders: Joi.boolean().description(
`Option to include default Gatsby Cloud caching headers (true by default)`
`When set to false, turns off the default caching headers`
),
transformHeaders: Joi.function()
.arity(2)
.description(`Option to transform headers using a function`),
.maxArity(2)
.description(
`Transform function for manipulating headers under each path (e.g.sorting), etc. This should return an object of type: { key: Array<string> }`
),
generateMatchPathRewrites: Joi.boolean().description(
`Option to include redirect rules for client only paths (set to true by default)`
`When set to false, turns off automatic creation of redirect rules for client only paths`
),
})
}

exports.pluginOptionsSchema = pluginOptionsSchema
45 changes: 0 additions & 45 deletions packages/gatsby-plugin-gatsby-cloud/src/is-sibling.js

This file was deleted.

1 change: 1 addition & 0 deletions packages/gatsby-plugin-gatsby-cloud/src/plugin-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default function makePluginData(store, assetsManifest, pathPrefix) {
return {
pages,
manifest,
program,
pathPrefix,
publicFolder,
}
Expand Down

0 comments on commit 6016c26

Please sign in to comment.