Skip to content

Commit 3fb788d

Browse files
authored
remove transform default function, its dangerous (#88)
1 parent 3656b2a commit 3fb788d

4 files changed

Lines changed: 626 additions & 569 deletions

File tree

lib/index.js

Lines changed: 58 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const bindAllClass = require('es6bindall')
1414
// Anything that is not duplicated in the spike-records source will be clearly
1515
// explained and annotated here!
1616
class Contentful {
17-
constructor (opts) {
17+
constructor(opts) {
1818
Object.assign(this, validate(opts))
1919
// initialize the contentful api client
2020
this.client = contentful.createClient({
@@ -24,7 +24,7 @@ class Contentful {
2424
bindAllClass(this, ['apply', 'run'])
2525
}
2626

27-
apply (compiler) {
27+
apply(compiler) {
2828
this.util = new SpikeUtil(compiler.options)
2929
this.util.runAll(compiler, this.run)
3030
let templatePairs
@@ -36,10 +36,14 @@ class Contentful {
3636
templatePairs = this.contentTypes.reduce((m, model, idx) => {
3737
if (!model.template) return m
3838
if (!model.template.path) {
39-
throw new Error(`${model.name}.template must have a "path" property`)
39+
throw new Error(
40+
`${model.name}.template must have a "path" property`
41+
)
4042
}
4143
if (!model.template.output) {
42-
throw new Error(`${model.name}.template must have an "output" function`)
44+
throw new Error(
45+
`${model.name}.template must have an "output" function`
46+
)
4347
}
4448
m[model.template.path] = idx
4549
return m
@@ -55,8 +59,11 @@ class Contentful {
5559
const data = this.addDataTo.contentful[conf.name]
5660

5761
// add a reshape multi option to compile each template separately
58-
options.multi = data.map((d) => {
59-
return { locals: Object.assign({}, this.addDataTo, { item: d }), name: conf.template.output(d) }
62+
options.multi = data.map(d => {
63+
return {
64+
locals: Object.assign({}, this.addDataTo, { item: d }),
65+
name: conf.template.output(d)
66+
}
6067
})
6168
return options
6269
})
@@ -66,36 +73,47 @@ class Contentful {
6673
writeJson(compilation, this.json, this.addDataTo.contentful)
6774
}
6875

69-
this.contentTypes.filter((ct) => ct.json).map((ct) => {
70-
return writeJson(compilation, ct.json, this.addDataTo.contentful[ct.name])
76+
this.contentTypes.filter(ct => ct.json).map(ct => {
77+
return writeJson(
78+
compilation,
79+
ct.json,
80+
this.addDataTo.contentful[ct.name]
81+
)
7182
})
7283

7384
done()
7485
})
7586
}
7687

77-
run (compilation, done) {
88+
run(compilation, done) {
7889
// only pull data on the initial compile in watch mode
7990
if (this.addDataTo.contentful && !this.aggressiveRefresh) return done()
8091

81-
return W.reduce(this.contentTypes, (m, ct) => {
82-
let transformFn = ct.transform
83-
let options = Object.assign({
84-
content_type: ct.id,
85-
include: this.includeLevel
86-
}, ct.filters)
87-
88-
if (transformFn === true) transformFn = transform
89-
if (transformFn === false) transformFn = (x) => x
90-
91-
return W(this.client.getEntries(options))
92-
.then(response => {
93-
return W.map(response.items, (entry) => transformFn(entry))
94-
})
95-
.tap((res) => { m[ct.name] = res })
96-
.yield(m)
97-
}, {}).done((res) => {
98-
92+
return W.reduce(
93+
this.contentTypes,
94+
(m, ct) => {
95+
let transformFn = ct.transform
96+
let options = Object.assign(
97+
{
98+
content_type: ct.id,
99+
include: this.includeLevel
100+
},
101+
ct.filters
102+
)
103+
104+
if (transformFn === false) transformFn = x => x
105+
106+
return W(this.client.getEntries(options))
107+
.then(response => {
108+
return W.map(response.items, entry => transformFn(entry))
109+
})
110+
.tap(res => {
111+
m[ct.name] = res
112+
})
113+
.yield(m)
114+
},
115+
{}
116+
).done(res => {
99117
this.addDataTo = Object.assign(this.addDataTo, { contentful: res })
100118
done()
101119
}, done)
@@ -106,7 +124,7 @@ class Contentful {
106124
* Validate options
107125
* @private
108126
*/
109-
function validate (opts = {}) {
127+
function validate(opts = {}) {
110128
const schema = Joi.object().keys({
111129
accessToken: Joi.string().required(),
112130
spaceId: Joi.string().required(),
@@ -119,9 +137,15 @@ function validate (opts = {}) {
119137
name: Joi.string(),
120138
ordered: Joi.boolean().default(false),
121139
filters: Joi.object().keys({
122-
limit: Joi.number().integer().min(1).max(100).default(100)
140+
limit: Joi.number()
141+
.integer()
142+
.min(1)
143+
.max(100)
144+
.default(100)
123145
}),
124-
transform: Joi.alternatives().try(Joi.boolean(), Joi.func()).default(false),
146+
transform: Joi.alternatives()
147+
.try(Joi.boolean(), Joi.func())
148+
.default(false),
125149
json: Joi.string()
126150
})
127151
)
@@ -134,61 +158,13 @@ function validate (opts = {}) {
134158
object: { child: '!![spike-contentful constructor] option {{reason}}' }
135159
}
136160
})
137-
if (res.error) { throw new Error(res.error) }
138-
return res.value
139-
}
140-
141-
/**
142-
* Transform the Contentful response object to make it less messy
143-
* @private
144-
*/
145-
function transform (entry) {
146-
Object.assign(entry.fields, extractMeta(entry.sys))
147-
148-
return recursiveTransform(entry, 'fields')
149-
}
150-
151-
/**
152-
* Transform the Contentful response to remove the fields key and move the
153-
* data up one level.
154-
* @private
155-
*/
156-
function recursiveTransform (obj, key) {
157-
if (typeof obj !== 'object' || obj === null) {
158-
return obj
159-
}
160-
161-
if (Array.isArray(obj)) {
162-
return obj.map(o => recursiveTransform(o))
161+
if (res.error) {
162+
throw new Error(res.error)
163163
}
164-
165-
return Object.keys(obj).reduce((prev, curr) => {
166-
if (curr === key) {
167-
prev = recursiveTransform(obj[curr])
168-
} else if (curr === 'sys') {
169-
prev = extractMeta(obj[curr])
170-
} else {
171-
prev[curr] = recursiveTransform(obj[curr])
172-
}
173-
174-
return prev
175-
}, {})
176-
}
177-
178-
/**
179-
* Extracts specified meta properties from Contentful's sys object and
180-
* returns a new object
181-
* @private
182-
*/
183-
function extractMeta (sys) {
184-
const props = ['id', 'createdAt', 'updatedAt', 'contentType']
185-
return props.reduce((m, p) => {
186-
if (sys[p]) m[p] = sys[p] // include only defined fields
187-
return m
188-
}, {})
164+
return res.value
189165
}
190166

191-
function writeJson (compilation, filename, data) {
167+
function writeJson(compilation, filename, data) {
192168
const src = JSON.stringify(data, null, 2)
193169
compilation.assets[filename] = {
194170
source: () => src,
@@ -197,4 +173,3 @@ function writeJson (compilation, filename, data) {
197173
}
198174

199175
module.exports = Contentful
200-
module.exports.transform = transform

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@
99
},
1010
"bugs": "https://github.com/static-dev/spike-contentful/issues",
1111
"dependencies": {
12-
"contentful": "^4.5.0",
12+
"contentful": "^5.0.5",
1313
"es6bindall": "^0.0.9",
1414
"joi": "^10.6.0",
1515
"when": "^3.7.8"
1616
},
1717
"devDependencies": {
18-
"ava": "^0.21.0",
19-
"coveralls": "^2.13.1",
20-
"dotenv": "^4.0.0",
21-
"nyc": "^11.0.3",
22-
"reshape-standard": "^3.1.0",
23-
"rimraf": "^2.6.0",
18+
"ava": "^0.25.0",
19+
"coveralls": "^3.0.0",
20+
"dotenv": "^5.0.0",
21+
"nyc": "^11.4.1",
22+
"reshape-standard": "^3.3.0",
23+
"rimraf": "^2.6.2",
2424
"spike-core": "^2.2.0",
2525
"standard": "^10.0.3"
2626
},

0 commit comments

Comments
 (0)