From 14babb3521bd29e75be30aefa38da5f282a752eb Mon Sep 17 00:00:00 2001 From: Dustin Schau Date: Mon, 12 Feb 2018 15:55:23 -0600 Subject: [PATCH] fix: prevent invalid graphql field names from being created (#3994) * fix: prevent invalid graphql field names from being created Note: This will currently transform (for example) `/*` into `_` so I'm not quite sure what the best course of action is to replace that Fixes #3487; Fixes #2925 * chore: revert yarn lock change * test: simplify tests * fix: dasherize after leading underscore --- .../gatsby/src/schema/__tests__/create-key.js | 26 +++++++++++++++++++ packages/gatsby/src/schema/create-key.js | 11 ++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 packages/gatsby/src/schema/__tests__/create-key.js diff --git a/packages/gatsby/src/schema/__tests__/create-key.js b/packages/gatsby/src/schema/__tests__/create-key.js new file mode 100644 index 0000000000000..da6484dda1888 --- /dev/null +++ b/packages/gatsby/src/schema/__tests__/create-key.js @@ -0,0 +1,26 @@ +const createKey = require(`../create-key`) + +describe(`createKey`, () => { + it(`leaves valid strings as is`, () => { + ;[`01234`, `validstring`, `_hello`, `_`].forEach(input => { + expect(createKey(input)).toBe(input) + }) + }) + + it(`replaces invalid characters`, () => { + ;[ + [`/hello`, `_hello`], + [`~/path/to/some/module`, `_-path-to-some-module`], + [`/*`, `_-`], + [`/*.js`, `_--js`], + ].forEach(([input, output]) => { + expect(createKey(input)).toBe(output) + }) + }) + + it(`does not generate same key for different input`, () => { + ;[[`/*.js`, `*js`]].forEach(([one, two]) => { + expect(createKey(one)).not.toBe(createKey(two)) + }) + }) +}) diff --git a/packages/gatsby/src/schema/create-key.js b/packages/gatsby/src/schema/create-key.js index 77d43f5e5c241..4cb78499f5552 100644 --- a/packages/gatsby/src/schema/create-key.js +++ b/packages/gatsby/src/schema/create-key.js @@ -1,6 +1,6 @@ // @flow const invariant = require(`invariant`) -const regex = new RegExp(`[^a-zA-Z0-9_]`, `g`) +const nonAlphaNumericExpr = new RegExp(`[^a-zA-Z0-9_]`, `g`) /** * GraphQL field names must be a string and cannot contain anything other than @@ -14,5 +14,12 @@ module.exports = (key: string): string => { `Graphql field name (key) is not a string -> ${key}` ) - return key.replace(regex, `_`) + const replaced = key.replace(nonAlphaNumericExpr, `_`) + + // key is invalid; normalize with a leading underscore and dasherize rest + if (replaced.match(/^__/)) { + return replaced.replace(/_/g, (char, index) => (index === 0 ? `_` : `-`)) + } + + return replaced }