Skip to content

Commit

Permalink
fix(gatsby-core-utils): make createContentDigest deterministic (#19832)
Browse files Browse the repository at this point in the history
* always return a string

* convert content-digest to node-object-hash

* remove array sort

* update snapshots

* use crypto for primitives

* fix snapshots
  • Loading branch information
wardpeet authored and GatsbyJS Bot committed Nov 29, 2019
1 parent f92cb9c commit cb6d0e2
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 35 deletions.
3 changes: 2 additions & 1 deletion packages/gatsby-core-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
],
"types": "index.d.ts",
"dependencies": {
"ci-info": "2.0.0"
"ci-info": "2.0.0",
"node-object-hash": "^2.0.0"
},
"devDependencies": {
"@babel/cli": "^7.7.4",
Expand Down

This file was deleted.

54 changes: 51 additions & 3 deletions packages/gatsby-core-utils/src/__tests__/create-content-digest.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,66 @@ const createContentDigest = require(`../create-content-digest`)

describe(`Create content digest`, () => {
it(`returns the content digest when the input is a string`, () => {
const input = JSON.stringify({ id: 1 })
const input = `this is a string`

const contentDigest = createContentDigest(input)

expect(contentDigest).toMatchSnapshot()
expect(typeof contentDigest).toEqual(`string`)
expect(contentDigest).toMatchInlineSnapshot(
`"b37e16c620c055cf8207b999e3270e9b"`
)
})

it(`returns the content digest when the input is a non string`, () => {
const input = { id: 1 }

const contentDigest = createContentDigest(input)

expect(contentDigest).toMatchSnapshot()
expect(typeof contentDigest).toEqual(`string`)
expect(contentDigest).toMatchInlineSnapshot(
`"db1aa405ee004296a31f04620bbb8e28"`
)
})

it(`returns a deterministic hash from an object`, () => {
const input = {
id: `12345`,
args: {
arg1: `test`,
arg2: `test2`,
arg3: [1, 2],
},
}
const input2 = {
args: {
arg2: `test2`,
arg1: `test`,
arg3: [1, 2],
},
id: `12345`,
}

expect(createContentDigest(input)).toEqual(createContentDigest(input2))
})

it(`shouldn't threat arrays as deterministic by default`, () => {
const input = {
id: `12345`,
args: {
arg1: `test`,
arg2: `test2`,
arg3: [2, 1],
},
}
const input2 = {
args: {
arg2: `test2`,
arg1: `test`,
arg3: [1, 2],
},
id: `12345`,
}

expect(createContentDigest(input)).not.toEqual(createContentDigest(input2))
})
})
28 changes: 23 additions & 5 deletions packages/gatsby-core-utils/src/create-content-digest.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
const crypto = require(`crypto`)
const objectHash = require(`node-object-hash`)

const hasher = objectHash({
coerce: false,
alg: `md5`,
enc: `hex`,
sort: {
map: true,
object: true,
array: false,
set: false,
},
})

const hashPrimitive = input =>
crypto
.createHash(`md5`)
.update(input)
.digest(`hex`)

/**
* @type {import('../index').createContentDigest}
*/
const createContentDigest = input => {
const content = typeof input !== `string` ? JSON.stringify(input) : input
if (typeof input === `object`) {
return hasher.hash(input)
}

return crypto
.createHash(`md5`)
.update(content)
.digest(`hex`)
return hashPrimitive(input)
}

module.exports = createContentDigest
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Object {
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAACXBIWXMAAAPoAAAD6AG1e1JrAAABk0lEQVQ4y7VUy07DMBDsf9IDhcauaVM4IajUIuALOFRI/R24wB8AgkpInJKI9ME5zDi24rx5HjZKvOP17Hg2neh8nNjo8CGESGL7sbpwMvrlaepriF4J3dQLMlsXvzbVFCKHLJ3J8+5PRxqlF0OzleFLkSG7Xrp4faiyRaI/Lgs13QhNVB5uCUyUTDyUloidvkjezvyMEB8B4uZkqAHCiR44bYtCcecSirD5XQDmIGzVjOrEiJo4fhvY2jWTG3C6g/TLmZ+8VwEJekWy20+loUSzA5kDp15BKJmXhmD6Iqcjtep5eSArk0ZQPPpqPNAaWiBpbKt0pLgEU2xuIOewTh7rmFWFRH9/M78uaG8yNuox4oYbbrQEhaI4HKEh7mvfS2OE98WR0r6P26zj2ofW5rWowlzY2WduAQxZ14odmNZuMWA0h6wo5pplDxj+MrgnqDM3W32E/QYNxaxN2f7ztNx6qWUCOC3H+F/Y35EU2XCw3QkGhBrHX/WXLbwG4wewoAwMst84t/0jH4ZG36DFLv9m7E/1HjvIa/canAAAAABJRU5ErkJggg==",
"height": 100,
"originalName": undefined,
"src": "/static/1234/59dbf/test.png",
"srcSet": "/static/1234/59dbf/test.png 1x",
"src": "/static/1234/a2779/test.png",
"srcSet": "/static/1234/a2779/test.png 1x",
"tracedSVG": undefined,
"width": 100,
}
Expand All @@ -28,15 +28,15 @@ Object {
"aspectRatio": 1,
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAACXBIWXMAAAPoAAAD6AG1e1JrAAABk0lEQVQ4y7VUy07DMBDsf9IDhcauaVM4IajUIuALOFRI/R24wB8AgkpInJKI9ME5zDi24rx5HjZKvOP17Hg2neh8nNjo8CGESGL7sbpwMvrlaepriF4J3dQLMlsXvzbVFCKHLJ3J8+5PRxqlF0OzleFLkSG7Xrp4faiyRaI/Lgs13QhNVB5uCUyUTDyUloidvkjezvyMEB8B4uZkqAHCiR44bYtCcecSirD5XQDmIGzVjOrEiJo4fhvY2jWTG3C6g/TLmZ+8VwEJekWy20+loUSzA5kDp15BKJmXhmD6Iqcjtep5eSArk0ZQPPpqPNAaWiBpbKt0pLgEU2xuIOewTh7rmFWFRH9/M78uaG8yNuox4oYbbrQEhaI4HKEh7mvfS2OE98WR0r6P26zj2ofW5rWowlzY2WduAQxZ14odmNZuMWA0h6wo5pplDxj+MrgnqDM3W32E/QYNxaxN2f7ztNx6qWUCOC3H+F/Y35EU2XCw3QkGhBrHX/WXLbwG4wewoAwMst84t/0jH4ZG36DFLv9m7E/1HjvIa/canAAAAABJRU5ErkJggg==",
"density": 72,
"originalImg": "/static/1234/59dbf/test.png",
"originalImg": "/static/1234/a2779/test.png",
"originalName": undefined,
"presentationHeight": 100,
"presentationWidth": 100,
"sizes": "(max-width: 100px) 100vw, 100px",
"src": "/static/1234/59dbf/test.png",
"srcSet": "/static/1234/51d83/test.png 25w,
/static/1234/851fc/test.png 50w,
/static/1234/59dbf/test.png 100w",
"src": "/static/1234/a2779/test.png",
"srcSet": "/static/1234/2d2c2/test.png 25w,
/static/1234/84325/test.png 50w,
/static/1234/a2779/test.png 100w",
"srcSetType": "image/png",
"tracedSVG": undefined,
}
Expand All @@ -47,13 +47,13 @@ Object {
"aspectRatio": 1,
"base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsSAAALEgHS3X78AAABKklEQVQ4y8WUy07DMBBFrwMpr4aybjepUeqIFd/CAgmJsuIHgWXVL+Gx4C3xCdQJnpm0UDJNAQnVuouMM8dzY4+DcoA/C/8Fe9bv4ABMMpQOZc5yFPqfwEUQY499jHoY9/BsKQyTRTNMyzu8WAwTbBnI2DY438XbPr0qFsFCvlrkMTERYFgRL3HYUvh5OMdpQqkbBtPC9NDiINQPCZM6LGVvUzIpwNch4V5EGxHS/DeYtjfHZbcyXB8yGfaPimcafLEMHqmw2L5OsWkUUuY6Ee5V28WUP25TXjwPS3iWUFnfcFQPFna98rlmSGL4IOZucQvgT76Po53qeOTYTtp4qpFKe/qM29PhJsVVl3SXsluntLfS7rPvn10MP1Aau+lKBuA9I/kV/AyW6gNTIWTuA/r8lQAAAABJRU5ErkJggg==",
"density": 72,
"originalImg": "/static/1234/c0399/test.png",
"originalImg": "/static/1234/c616f/test.png",
"originalName": undefined,
"presentationHeight": 100,
"presentationWidth": 100,
"sizes": "(max-width: 100px) 100vw, 100px",
"src": "/static/1234/c0399/test.png",
"srcSet": "/static/1234/c0399/test.png 100w",
"src": "/static/1234/c616f/test.png",
"srcSet": "/static/1234/c616f/test.png 100w",
"srcSetType": "image/png",
"tracedSVG": undefined,
}
Expand Down Expand Up @@ -88,8 +88,8 @@ Object {
"base64": undefined,
"height": 100,
"originalName": undefined,
"src": "/static/1234/c0399/test.png",
"srcSet": "/static/1234/c0399/test.png 1x",
"src": "/static/1234/c616f/test.png",
"srcSet": "/static/1234/c616f/test.png 1x",
"tracedSVG": "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'%3e%3cpath%20d='M41%2024c-18%207-24%2029-11%2043%2015%2017%2044%208%2046-15%201-19-17-34-35-28'%20fill='red'%20fill-rule='evenodd'/%3e%3c/svg%3e",
"width": 100,
}
Expand All @@ -100,15 +100,15 @@ Object {
"aspectRatio": 1,
"base64": undefined,
"density": 72,
"originalImg": "/static/1234/c0399/test.png",
"originalImg": "/static/1234/c616f/test.png",
"originalName": undefined,
"presentationHeight": 100,
"presentationWidth": 100,
"sizes": "(max-width: 100px) 100vw, 100px",
"src": "/static/1234/c0399/test.png",
"srcSet": "/static/1234/0f0dc/test.png 25w,
/static/1234/bc08f/test.png 50w,
/static/1234/c0399/test.png 100w",
"src": "/static/1234/c616f/test.png",
"srcSet": "/static/1234/db86b/test.png 25w,
/static/1234/356f1/test.png 50w,
/static/1234/c616f/test.png 100w",
"srcSetType": "image/png",
"tracedSVG": "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'%3e%3cpath%20d='M41%2024c-18%207-24%2029-11%2043%2015%2017%2044%208%2046-15%201-19-17-34-35-28'%20fill='red'%20fill-rule='evenodd'/%3e%3c/svg%3e",
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Array [
"internal": Object {
"content": "Where oh where is my little pony?
",
"contentDigest": "26a9a60af333645b5ca69261c7d9aa53",
"contentDigest": "d041434d15cb094fcf097bfd9e45347b",
"type": "MarkdownRemark",
},
"parent": "whatever",
Expand All @@ -40,7 +40,7 @@ Array [
"internal": Object {
"content": "Where oh where is my little pony?
",
"contentDigest": "26a9a60af333645b5ca69261c7d9aa53",
"contentDigest": "d041434d15cb094fcf097bfd9e45347b",
"type": "MarkdownRemark",
},
"parent": "whatever",
Expand Down Expand Up @@ -94,7 +94,7 @@ Sed eu gravida mauris. Suspendisse potenti. Praesent sit amet egestas mi, sed he
Sed bibendum sem iaculis, pellentesque leo sed, imperdiet ante. Sed consequat mattis dui nec pretium. Donec vel consectetur est. Nam sagittis, libero vitae pretium pharetra, velit est dignissim erat, at cursus quam massa vitae ligula. Suspendisse potenti. In hac habitasse platea dictumst. Donec sit amet finibus justo. Mauris ante dolor, pulvinar vitae feugiat eu, rhoncus nec diam. In ut accumsan diam, faucibus fringilla odio. Nunc id ultricies turpis. Quisque justo quam, tristique sit amet interdum quis, facilisis at mi. Fusce porttitor vel sem ut condimentum. Praesent at libero congue, vulputate elit ut, rhoncus erat.
",
"contentDigest": "024ff0e6141e2121fe04090114c7535a",
"contentDigest": "c3e139c39e6d1b57492467150598f53c",
"type": "MarkdownRemark",
},
"parent": "whatever",
Expand Down Expand Up @@ -144,7 +144,7 @@ Sed eu gravida mauris. Suspendisse potenti. Praesent sit amet egestas mi, sed he
Sed bibendum sem iaculis, pellentesque leo sed, imperdiet ante. Sed consequat mattis dui nec pretium. Donec vel consectetur est. Nam sagittis, libero vitae pretium pharetra, velit est dignissim erat, at cursus quam massa vitae ligula. Suspendisse potenti. In hac habitasse platea dictumst. Donec sit amet finibus justo. Mauris ante dolor, pulvinar vitae feugiat eu, rhoncus nec diam. In ut accumsan diam, faucibus fringilla odio. Nunc id ultricies turpis. Quisque justo quam, tristique sit amet interdum quis, facilisis at mi. Fusce porttitor vel sem ut condimentum. Praesent at libero congue, vulputate elit ut, rhoncus erat.
",
"contentDigest": "024ff0e6141e2121fe04090114c7535a",
"contentDigest": "c3e139c39e6d1b57492467150598f53c",
"type": "MarkdownRemark",
},
"parent": "whatever",
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15723,6 +15723,11 @@ node-notifier@^5.4.2:
shellwords "^0.1.1"
which "^1.3.0"

node-object-hash@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/node-object-hash/-/node-object-hash-2.0.0.tgz#9971fcdb7d254f05016bd9ccf508352bee11116b"
integrity sha512-VZR0zroAusy1ETZMZiGeLkdu50LGjG5U1KHZqTruqtTyQ2wfWhHG2Ow4nsUbfTFGlaREgNHcCWoM/OzEm6p+NQ==

node-plop@=0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/node-plop/-/node-plop-0.9.0.tgz#d24796c9b5f37441308cfb3184f574dca0355aa6"
Expand Down

0 comments on commit cb6d0e2

Please sign in to comment.