-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathindex.js
More file actions
95 lines (82 loc) · 2.69 KB
/
index.js
File metadata and controls
95 lines (82 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const SpikeUtil = require('spike-util')
const W = require('when')
const node = require('when/node')
const Joi = require('joi')
const path = require('path')
const fs = require('fs')
const reshape = require('reshape')
const loader = require('reshape-loader')
const {SiteClient} = require('datocms-client')
const DatoLoader = require('datocms-client/lib/local/Loader')
const bindAllClass = require('es6bindall')
module.exports = class SpikeDatoCMS {
constructor (opts) {
Object.assign(this, this.validate(opts))
this.client = new DatoLoader(new SiteClient(opts.token))
bindAllClass(this, ['apply', 'run'])
}
apply (compiler) {
this.util = new SpikeUtil(compiler.options)
this.util.runAll(compiler, this.run)
// TODO: this pulls the incorrect loader context
compiler.plugin('compilation', (compilation) => {
compilation.plugin('normal-module-loader', (loaderContext) => {
this.loaderContext = loaderContext
})
})
compiler.plugin('emit', (compilation, done) => {
if (this.singlePages) {
W.map(this.singlePages(this.client.itemsRepo), (page) => {
return writeTemplate.call(this, compiler, compilation, page)
}).done(() => done(), done)
}
done()
})
}
run (compilation, done) {
return this.client.load().then(() => {
Object.assign(this.addDataTo, { dato: this.client.itemsRepo })
done()
})
}
/**
* Validate options
* @private
*/
validate (opts = {}) {
const schema = Joi.object().keys({
token: Joi.string().required(),
addDataTo: Joi.object().required(),
singlePages: Joi.func()
})
const res = Joi.validate(opts, schema, {
language: {
messages: { wrapArrays: false },
object: { child: '!![spike-datocms constructor] option {{reason}}' }
}
})
if (res.error) { throw new Error(res.error) }
return res.value
}
}
// TODO: get rid of this, put the templates through webpack
function writeTemplate (compiler, compilation, page) {
const filePath = path.join(compiler.options.context, page.template)
return node.call(fs.readFile.bind(fs), filePath, 'utf8')
.then((template) => {
const newLocals = Object.assign({}, this.addDataTo, page.locals)
const options = loader.parseOptions.call(this.loaderContext, this.util.getSpikeOptions().reshape, {})
// for any plugins that pull locals from the options
options.locals = newLocals
options.filename = filePath
return reshape(options)
.process(template)
.then((res) => {
const html = res.output(newLocals)
compilation.assets[page.output] = {
source: () => html,
size: () => html.length
}
})
})
}