Skip to content
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
57 changes: 57 additions & 0 deletions packages/gatsby/src/utils/__tests__/node-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import {
processNodeManifests,
} from "../node-manifest"

function itWindows(name: string, fn: () => void): void {
return process.platform === `win32` ? it(name, fn) : xit(name, fn)
}

jest.mock(`fs-extra`, () => {
return {
ensureDir: jest.fn(),
Expand Down Expand Up @@ -342,4 +346,57 @@ describe(`processNodeManifests`, () => {
await testProcessNodeManifests()
process.env.NODE_ENV = `test`
})

itWindows(`replaces reserved Windows characters with a dash`, async () => {
const nodes = [
{ id: `1`, usePageContextId: true },
{ id: `2`, useOwnerNodeId: true },
{ id: `3`, useQueryTracking: true },
]
mockGetNodes(
new Map(nodes.map(node => [`${node.id}`, { id: `${node.id}` }]))
)

store.getState.mockImplementation(() => {
return {
...storeState,
pages: new Map([
[
`/test`,
{
path: `/test`,
context: { id: `1` },
},
],
[
`/test-2`,
{
path: `/test-2`,
context: { id: `2` },
},
],
]),
nodeManifests: [
{
pluginName: `test`,
node: { id: `1` },
// A manifest id containing all of the reserved windows characters that we check
// for and replace
manifestId: `\\*"<>/:?|`,
},
],
queries: {
byNode: new Map([
[`1`, new Set([`/test`, `/test-2`])],
[`2`, new Set([`/test`, `/test-2`])],
]),
},
}
})

await processNodeManifests()
const nodeManifestFileName = path.basename(fs.writeJSON.mock.calls[0][0])

expect(nodeManifestFileName).toEqual(`---------.json`)
})
})
22 changes: 21 additions & 1 deletion packages/gatsby/src/utils/node-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,33 @@ export async function processNodeManifest(

const gatsbySiteDirectory = store.getState().program.directory

let fileNameBase = inputManifest.manifestId

/**
* Windows has a handful of special/reserved characters that are not valid in a file path
* @reference https://superuser.com/questions/358855/what-characters-are-safe-in-cross-platform-file-names-for-linux-windows-and-os
*
* The two exceptions to the list linked above are
* - the colon that is part of the hard disk partition name at the beginning of a file path (i.e. C:)
* - backslashes. We don't want to replace backslashes because those are used to delineate what the actual file path is
*
* During local development, node manifests can be written to disk but are generally unused as they are only used
* for Content Sync which runs in Gatsby Cloud. Gatsby cloud is a Linux environment in which these special chars are valid in
* filepaths. To avoid errors on Windows, we replace all instances of the special chars in the filepath (with the exception of the
* hard disk partition name) with "-" to ensure that local Windows development setups do not break when attempting
* to write one of these manifests to disk.
*/
if (process.platform === `win32`) {
fileNameBase = fileNameBase.replace(/:|\/|\*|\?|"|<|>|\||\\/g, `-`)
}

// write out the manifest file
const manifestFilePath = path.join(
gatsbySiteDirectory,
`public`,
`__node-manifests`,
inputManifest.pluginName,
`${inputManifest.manifestId}.json`
`${fileNameBase}.json`
)

const manifestFileDir = path.dirname(manifestFilePath)
Expand Down