-
Notifications
You must be signed in to change notification settings - Fork 5
/
publish.js
165 lines (159 loc) · 4.31 KB
/
publish.js
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import GitHub from './github'
import content from './content'
import parse from './parse'
import { utils } from './utils'
const uploadFiles = async files => {
if (!files) {
return []
}
const photos = []
for (let file of files) {
if (file.filename) {
const filename = content.mediaFilename(file)
const uploaded = await GitHub.uploadImage(filename, file)
if (uploaded) {
photos.push({ 'value': uploaded })
}
} else if (file.alt || file.value) {
photos.push(file)
} else {
photos.push({ 'value': file })
}
}
return photos
}
const handleUpdate = (body, parsed) => {
let updated = false
if (!body && !body.replace && !body.add && !body.delete) {
return
}
if (body.delete && Array.isArray(body.delete)) {
for (let key of body.delete) {
if (parsed[key]) {
updated = true
delete parsed[key]
}
}
return updated ? parsed : null
}
const updates = utils.removeEmpty(parse.fromJSON({
'type': parsed.type,
'properties': body.replace || body.add || body.delete
}))
if (!updates || Object.entries(updates).length <= 1) { // `updates` always has property 'type'
return
}
if (body.replace) {
return { ...parsed, ...updates }
} else {
for (let [key, value] of Object.entries(updates)) {
if (key == 'type' || key == 'photo') { // skip these properties
continue
}
if (body.add) {
updated = true
if (parsed[key]) {
parsed[key] = [ ...parsed[key], ...value ]
} else {
parsed[key] = value
}
} else if (body.delete && parsed[key] && Array.isArray(parsed[key])) {
// Only deletes here if the original value was an array
// Look for the specific item to delete from a potential list of values
for (let item of value) {
// Remove `item` from `parsed[key]` if it exists
if (parsed[key].includes(item)) {
updated = true
parsed[key].splice(parsed[key].indexOf(item), 1)
}
}
}
}
return updated ? parsed : null
}
}
const publish = {
handleUpdate: handleUpdate,
addContent: async (data, isJSON, clientId) => {
const parsed = isJSON ? parse.fromJSON(data) : parse.fromForm(data)
console.log('└─>', parsed)
if (parsed && parsed['like-of']) {
parsed.name = parsed.name || await parse.getPageTitle(parsed['like-of'])
}
if (parsed && parsed.photo) {
parse.photo = await uploadFiles(parsed.photo)
}
if (!utils.objectHasKeys(parsed)) {
return { 'error': 'nothing to add' }
}
const out = content.format(parsed, clientId)
if (!out || !out.filename || !out.formatted) {
return { 'error': 'could not parse data' }
}
const exists = await GitHub.getFile(out.filename)
if (exists) {
return { 'error': 'file exists' }
}
const filename = await GitHub.createFile(out.filename, out.formatted)
if (filename) {
return { 'filename': out.slug }
}
},
updateContent: async (url, body) => {
const filename = utils.urlToFilename(url)
if (!filename) {
return { 'error': 'invalid url' }
}
const exists = await GitHub.getFile(filename)
if (!exists) {
return { 'error': 'file does not exist' }
}
let parsed = parse.fromFrontMatter(exists.content)
if (!parsed) {
return { 'error': 'could not parse file' }
}
const updated = handleUpdate(body, parsed)
if (!updated) {
return { 'error': 'nothing to update' }
}
const out = content.format(updated)
if (!out || !out.filename || !out.formatted) {
return { 'error': 'could not parse data' }
}
const res = await GitHub.updateFile(filename, out.formatted, exists)
if (!res) {
return { 'error': 'file cannot be updated'}
}
return { 'filename': filename }
},
deleteContent: async (url, permanent) => {
if (!permanent) {
return publish.updateContent(url, {
'add': {
'deleted': [ 'true' ]
}
})
}
const filename = utils.urlToFilename(url)
if (!filename) {
return { 'error': 'invalid url' }
}
const exists = await GitHub.getFile(filename)
if (!exists) {
return { 'error': 'file does not exist' }
}
const res = await GitHub.deleteFile(filename, exists)
if (!res) {
return { 'error': 'file cannot be deleted' }
}
return { 'filename': filename }
},
undeleteContent: async (url) => {
// undelete supported even if `PERMANENT_DELETE` is true
// but only if file has the property `deleted`
return publish.updateContent(url, {
'delete': [ 'deleted' ]
})
}
}
export default publish