Skip to content

Commit 80c07e6

Browse files
MeLlamoPablowardpeet
authored andcommitted
feat(gatsby-transformer-yaml): support typeName (#13563)
see #7914 for json transformer
1 parent ea0b46e commit 80c07e6

File tree

3 files changed

+202
-9
lines changed

3 files changed

+202
-9
lines changed

packages/gatsby-transformer-yaml/README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,77 @@ Which would return:
164164
```
165165

166166
Please do **note** that `allLettersYaml` **will not** show up if you do not have any `.yaml` files.
167+
168+
## Configuration options
169+
170+
**`typeName`** [string|function][optional]
171+
172+
The default naming convention documented above can be changed with
173+
either a static string value (e.g. to be able to query all yaml with a
174+
simple query):
175+
176+
```javascript
177+
module.exports = {
178+
plugins: [
179+
{
180+
resolve: `gatsby-transformer-yaml`,
181+
options: {
182+
typeName: `Yaml`, // a fixed string
183+
},
184+
},
185+
],
186+
}
187+
```
188+
189+
```graphql
190+
{
191+
allYaml {
192+
edges {
193+
node {
194+
value
195+
}
196+
}
197+
}
198+
}
199+
```
200+
201+
or a function that receives the following arguments:
202+
203+
- `node`: the graphql node that is being processed, e.g. a File node with
204+
yaml content
205+
- `object`: a single object (either an item from an array or the whole yaml content)
206+
- `isArray`: boolean, true if `object` is part of an array
207+
208+
```yaml
209+
- level: info
210+
message: hurray
211+
- level: info
212+
message: it works
213+
- level: warning
214+
message: look out
215+
```
216+
217+
```javascript
218+
module.exports = {
219+
plugins: [
220+
{
221+
resolve: `gatsby-transformer-yaml`,
222+
options: {
223+
typeName: ({ node, object, isArray }) => object.level,
224+
},
225+
},
226+
],
227+
}
228+
```
229+
230+
```graphql
231+
{
232+
allInfo {
233+
edges {
234+
node {
235+
message
236+
}
237+
}
238+
}
239+
}
240+
```

packages/gatsby-transformer-yaml/src/__tests__/gatsby-node.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,114 @@ describe(`Process YAML nodes correctly`, () => {
6969
expect(createParentChildLink).toHaveBeenCalledTimes(1)
7070
})
7171
})
72+
73+
it(`correctly sets node type for array of objects`, () =>
74+
Promise.all(
75+
[
76+
{
77+
typeName: null,
78+
expectedNodeTypes: [`TestYaml`, `TestYaml`],
79+
},
80+
{
81+
typeName: `fixed`,
82+
expectedNodeTypes: [`fixed`, `fixed`],
83+
},
84+
{
85+
typeName: ({ node, object }) => object.funny,
86+
expectedNodeTypes: [`yup`, `nope`],
87+
},
88+
].map(
89+
async ({ typeName, expectedNodeTypes: [expectedOne, expectedTwo] }) => {
90+
const data = [
91+
{ id: `foo`, blue: true, funny: `yup` },
92+
{ blue: false, funny: `nope` },
93+
]
94+
95+
node.content = yaml.safeDump(data)
96+
node.dir = `${os.tmpdir()}/bar/`
97+
98+
const createNode = jest.fn()
99+
const createParentChildLink = jest.fn()
100+
const actions = { createNode, createParentChildLink }
101+
const createNodeId = jest.fn()
102+
createNodeId.mockReturnValue(`uuid-from-gatsby`)
103+
const createContentDigest = jest.fn().mockReturnValue(`contentDigest`)
104+
105+
return onCreateNode(
106+
{
107+
node,
108+
loadNodeContent,
109+
actions,
110+
createNodeId,
111+
createContentDigest,
112+
},
113+
{ typeName }
114+
).then(() => {
115+
expect(createNode).toBeCalledWith(
116+
expect.objectContaining({
117+
internal: expect.objectContaining({
118+
type: expectedOne,
119+
}),
120+
})
121+
)
122+
expect(createNode).toBeCalledWith(
123+
expect.objectContaining({
124+
internal: expect.objectContaining({
125+
type: expectedTwo,
126+
}),
127+
})
128+
)
129+
})
130+
}
131+
)
132+
))
133+
134+
it(`correctly sets node type for single object`, () =>
135+
Promise.all(
136+
[
137+
{
138+
typeName: null,
139+
expectedNodeType: `TestdirYaml`,
140+
},
141+
{
142+
typeName: `fixed`,
143+
expectedNodeType: `fixed`,
144+
},
145+
{
146+
typeName: ({ node, object }) => object.funny,
147+
expectedNodeType: `yup`,
148+
},
149+
].map(async ({ typeName, expectedNodeType }) => {
150+
const data = { id: `foo`, blue: true, funny: `yup` }
151+
152+
node.content = yaml.safeDump(data)
153+
node.dir = `${os.tmpdir()}/testdir/`
154+
155+
const createNode = jest.fn()
156+
const createParentChildLink = jest.fn()
157+
const actions = { createNode, createParentChildLink }
158+
const createNodeId = jest.fn()
159+
createNodeId.mockReturnValue(`uuid-from-gatsby`)
160+
const createContentDigest = jest.fn().mockReturnValue(`contentDigest`)
161+
162+
return onCreateNode(
163+
{
164+
node,
165+
loadNodeContent,
166+
actions,
167+
createNodeId,
168+
createContentDigest,
169+
},
170+
{ typeName }
171+
).then(() => {
172+
expect(createNode).toBeCalledWith(
173+
expect.objectContaining({
174+
internal: expect.objectContaining({
175+
type: expectedNodeType,
176+
}),
177+
})
178+
)
179+
})
180+
})
181+
))
72182
})

packages/gatsby-transformer-yaml/src/gatsby-node.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@ const jsYaml = require(`js-yaml`)
22
const _ = require(`lodash`)
33
const path = require(`path`)
44

5-
async function onCreateNode({
6-
node,
7-
actions,
8-
loadNodeContent,
9-
createNodeId,
10-
createContentDigest,
11-
}) {
5+
async function onCreateNode(
6+
{ node, actions, loadNodeContent, createNodeId, createContentDigest },
7+
pluginOptions
8+
) {
9+
function getType({ node, object, isArray }) {
10+
if (pluginOptions && _.isFunction(pluginOptions.typeName)) {
11+
return pluginOptions.typeName({ node, object, isArray })
12+
} else if (pluginOptions && _.isString(pluginOptions.typeName)) {
13+
return pluginOptions.typeName
14+
} else if (isArray) {
15+
return _.upperFirst(_.camelCase(`${node.name} Yaml`))
16+
} else {
17+
return _.upperFirst(_.camelCase(`${path.basename(node.dir)} Yaml`))
18+
}
19+
}
20+
1221
function transformObject(obj, id, type) {
1322
const yamlNode = {
1423
...obj,
@@ -38,14 +47,14 @@ async function onCreateNode({
3847
transformObject(
3948
obj,
4049
obj.id ? obj.id : createNodeId(`${node.id} [${i}] >>> YAML`),
41-
_.upperFirst(_.camelCase(`${node.name} Yaml`))
50+
getType({ node, object: obj, isArray: true })
4251
)
4352
})
4453
} else if (_.isPlainObject(parsedContent)) {
4554
transformObject(
4655
parsedContent,
4756
parsedContent.id ? parsedContent.id : createNodeId(`${node.id} >>> YAML`),
48-
_.upperFirst(_.camelCase(`${path.basename(node.dir)} Yaml`))
57+
getType({ node, object: parsedContent, isArray: false })
4958
)
5059
}
5160
}

0 commit comments

Comments
 (0)