imdone-core 1.54.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/cli.js +114 -0
- package/lib/index.js +23 -0
- package/package.json +48 -66
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -37
- package/.github/workflows/ci.yml +0 -24
- package/.imdoneignore +0 -12
- package/.mocharc.json +0 -10
- package/.prettierrc +0 -6
- package/CHANGELOG.md +0 -160
- package/_navbar.md +0 -1
- package/cli.js +0 -74
- package/index-markdown.js +0 -55
- package/index.html +0 -184
- package/index.js +0 -1
- package/lib/ProjectContext.js +0 -42
- package/lib/adapters/date-time.js +0 -20
- package/lib/adapters/file-gateway.js +0 -127
- package/lib/adapters/git-download.js +0 -35
- package/lib/adapters/markdown.js +0 -168
- package/lib/adapters/parsers/DateLanguageParser.js +0 -10
- package/lib/adapters/parsers/content-transformer.js +0 -111
- package/lib/adapters/parsers/file/LocalFileParserFactory.js +0 -37
- package/lib/adapters/parsers/file/ReadStreamCodeParser.js +0 -126
- package/lib/adapters/parsers/file/ReadStreamMarkdownParser.js +0 -17
- package/lib/adapters/parsers/file/ReadStreamTaskParser.js +0 -104
- package/lib/adapters/parsers/function-parser.js +0 -29
- package/lib/adapters/parsers/task/CardContentParser.js +0 -376
- package/lib/adapters/parsers/task/CheckStyleTaskParser.js +0 -28
- package/lib/adapters/parsers/task/CodeStyleTaskParser.js +0 -24
- package/lib/adapters/parsers/task/HashStyleTaskParser.js +0 -27
- package/lib/adapters/parsers/task/MarkdownStyleTaskParser.js +0 -24
- package/lib/adapters/parsers/task/TaskParser.js +0 -38
- package/lib/adapters/readers/FileSystemProjectReader.js +0 -45
- package/lib/adapters/storage/config.js +0 -49
- package/lib/adapters/storage/tags.js +0 -30
- package/lib/adapters/yaml.js +0 -6
- package/lib/card.js +0 -300
- package/lib/config.js +0 -214
- package/lib/constants.js +0 -97
- package/lib/context/ApplicationContext.js +0 -32
- package/lib/context/StreamingApplicationContext.js +0 -31
- package/lib/controlers/SaveViewController.js +0 -10
- package/lib/default-settings.js +0 -37
- package/lib/domain/entities/FileProjectContext.js +0 -10
- package/lib/domain/entities/View.js +0 -30
- package/lib/domain/usecases/GetViewsUsecase.js +0 -50
- package/lib/domain/usecases/OpenProjectUsecase.js +0 -13
- package/lib/domain/usecases/SaveViewUsecase.js +0 -57
- package/lib/file.js +0 -1395
- package/lib/languages.js +0 -114
- package/lib/list.js +0 -105
- package/lib/migrate-config.js +0 -165
- package/lib/mixins/repo-fs-store.js +0 -424
- package/lib/mixins/repo-watched-fs-store.js +0 -195
- package/lib/plugins/archive-plugin.js +0 -70
- package/lib/plugins/default-board-actions-plugin.js +0 -56
- package/lib/plugins/default-board-properties-plugin.js +0 -101
- package/lib/plugins/epic-plugin.js +0 -176
- package/lib/plugins/extension-plugin.js +0 -87
- package/lib/plugins/persist-tags-plugin.js +0 -13
- package/lib/plugins/plugin-manager.js +0 -421
- package/lib/plugins/plugin-registry.js +0 -61
- package/lib/project-factory.js +0 -45
- package/lib/project.js +0 -911
- package/lib/repository.js +0 -1746
- package/lib/task.js +0 -798
- package/lib/tools.js +0 -250
- package/lib/usecases/get-imdone-url.js +0 -6
- package/lib/usecases/get-project-tags.js +0 -16
- package/lib/usecases/get-tasks-in-file.js +0 -29
|
@@ -1,421 +0,0 @@
|
|
|
1
|
-
const Emitter = require('events')
|
|
2
|
-
const Plugin = require('imdone-api')
|
|
3
|
-
const _path = require('path')
|
|
4
|
-
const downloadRepo = require('../adapters/git-download')
|
|
5
|
-
const rimraf = require('rimraf')
|
|
6
|
-
const sane = require('sane')
|
|
7
|
-
const debounce = require('lodash.debounce')
|
|
8
|
-
const { exists, mkdir, readdir } = require('../adapters/file-gateway')
|
|
9
|
-
const appContext = require('../context/ApplicationContext')
|
|
10
|
-
|
|
11
|
-
module.exports = class PluginManager extends Emitter {
|
|
12
|
-
constructor(project) {
|
|
13
|
-
super()
|
|
14
|
-
this.project = project
|
|
15
|
-
this.defaultPlugins = [
|
|
16
|
-
'./persist-tags-plugin',
|
|
17
|
-
'./default-board-properties-plugin',
|
|
18
|
-
'./default-board-actions-plugin',
|
|
19
|
-
'./archive-plugin',
|
|
20
|
-
'./epic-plugin',
|
|
21
|
-
'./extension-plugin',
|
|
22
|
-
]
|
|
23
|
-
this.pluginsMap = {}
|
|
24
|
-
this.pluginPath = _path.join(project.path, '.imdone', 'plugins')
|
|
25
|
-
this.onDevChange = debounce(this.onDevChange.bind(this), 1000)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async startDevMode() {
|
|
29
|
-
if (this.project && this.project.config.devMode && !this.watcher) {
|
|
30
|
-
if (!(await exists(this.pluginPath)))
|
|
31
|
-
await mkdir(this.pluginPath)
|
|
32
|
-
this.watcher = sane(this.pluginPath, {
|
|
33
|
-
ignored(path) {
|
|
34
|
-
return /node_modules/.test(path)
|
|
35
|
-
},
|
|
36
|
-
})
|
|
37
|
-
this.watcher.on('change', (path, root, stat) => {
|
|
38
|
-
this.onDevChange()
|
|
39
|
-
})
|
|
40
|
-
this.watcher.on('add', (path, root, stat) => {
|
|
41
|
-
this.onDevChange()
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
stopDevMode() {
|
|
47
|
-
this.watcher && this.watcher.close()
|
|
48
|
-
this.watcher = null
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
initDevMode() {
|
|
52
|
-
if (!this.project.config.devMode) this.stopDevMode()
|
|
53
|
-
this.startDevMode()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async onDevChange() {
|
|
57
|
-
try {
|
|
58
|
-
await this.reloadPlugins()
|
|
59
|
-
this.emit('plugins-reloaded')
|
|
60
|
-
} catch {
|
|
61
|
-
console.error('Error reloading plugins.', err)
|
|
62
|
-
throw err
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async reloadPlugins() {
|
|
67
|
-
this.destroyPlugins()
|
|
68
|
-
await this.loadPlugins()
|
|
69
|
-
await this.startDevMode()
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async uninstallPlugin(pluginName) {
|
|
73
|
-
return new Promise((resolve, reject) => {
|
|
74
|
-
console.log('Preparing to uninstall plugin:', pluginName)
|
|
75
|
-
const pluginClassName = Object.keys(this.pluginsMap).find((key) => {
|
|
76
|
-
return this.getPlugin(key).info.name === pluginName
|
|
77
|
-
})
|
|
78
|
-
if (!pluginClassName) {
|
|
79
|
-
return reject(new Error('Unable to find plugin:' + pluginName))
|
|
80
|
-
}
|
|
81
|
-
const { info } = this.getPlugin(pluginClassName)
|
|
82
|
-
const { path } = info
|
|
83
|
-
// const pkg = { version, name }
|
|
84
|
-
console.log('Uninstalling:', info)
|
|
85
|
-
|
|
86
|
-
rimraf(path, (err) => {
|
|
87
|
-
if (err) return reject(err)
|
|
88
|
-
delete this.pluginsMap[pluginClassName]
|
|
89
|
-
this.emit('plugin-uninstalled', pluginName)
|
|
90
|
-
resolve()
|
|
91
|
-
})
|
|
92
|
-
})
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async installPlugin({ name, version }) {
|
|
96
|
-
if (!(await exists(this.pluginPath)))
|
|
97
|
-
await mkdir(this.pluginPath)
|
|
98
|
-
const installPath = _path.join(this.pluginPath, name)
|
|
99
|
-
await downloadRepo(version, installPath)
|
|
100
|
-
console.log(`Done installing ${name}`)
|
|
101
|
-
await this.loadPlugin(installPath)
|
|
102
|
-
this.emit('plugin-installed', name)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async loadPlugins() {
|
|
106
|
-
for (const pluginPath of this.defaultPlugins) {
|
|
107
|
-
await this.loadPlugin(pluginPath)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
await this.loadInstalledPlugins()
|
|
111
|
-
await this.loadPluginsNotInstalled()
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async loadInstalledPlugins() {
|
|
115
|
-
const path = await exists(this.pluginPath)
|
|
116
|
-
if (!path) {
|
|
117
|
-
await mkdir(this.pluginPath)
|
|
118
|
-
}
|
|
119
|
-
const paths = await readdir(this.pluginPath, { withFileTypes: true })
|
|
120
|
-
const pluginPaths = paths
|
|
121
|
-
.filter(
|
|
122
|
-
(entry) =>
|
|
123
|
-
entry.name !== 'node_modules' &&
|
|
124
|
-
(entry.isDirectory() || entry.isSymbolicLink())
|
|
125
|
-
)
|
|
126
|
-
.map((entry) => _path.join(this.pluginPath, entry.name))
|
|
127
|
-
|
|
128
|
-
for (const path of pluginPaths) {
|
|
129
|
-
await this.loadPlugin(path)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async loadPluginsNotInstalled() {
|
|
134
|
-
const availablePlugins = await appContext().pluginRegistry.getAvailablePlugins()
|
|
135
|
-
const configPluginNames = Object.keys(this.project.config.plugins)
|
|
136
|
-
if (!configPluginNames) return
|
|
137
|
-
const installedPluginNames = Object.keys(this.pluginsMap)
|
|
138
|
-
const pluginsNotInstalled = configPluginNames.filter(name => !installedPluginNames.includes(name))
|
|
139
|
-
for (const pluginName of pluginsNotInstalled) {
|
|
140
|
-
const plugin = availablePlugins.find(p => p.name === pluginName)
|
|
141
|
-
await this.installPlugin(plugin)
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async loadPlugin(path) {
|
|
146
|
-
console.log('Loading plugin: ', path)
|
|
147
|
-
try {
|
|
148
|
-
// eslint-disable-next-line
|
|
149
|
-
delete require.cache[require.resolve(path)]
|
|
150
|
-
// eslint-disable-next-line
|
|
151
|
-
const pluginClass = require(path)
|
|
152
|
-
const pluginInstance = await this.createPlugin(pluginClass, path)
|
|
153
|
-
if (pluginInstance.init) await pluginInstance.init()
|
|
154
|
-
} catch (e) {
|
|
155
|
-
console.error(`Error loading plugin at: ${path}`, e)
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
async createPlugin(pluginClass, path) {
|
|
160
|
-
if (!this.isPlugin(pluginClass))
|
|
161
|
-
throw new Error(`${pluginClass.name} is not a plugin`)
|
|
162
|
-
const name = pluginClass.name.toString()
|
|
163
|
-
const pluginInstance = new pluginClass(this.project)
|
|
164
|
-
let info = {}
|
|
165
|
-
try {
|
|
166
|
-
info = require(`${path}/package.json`)
|
|
167
|
-
delete info.dependencies
|
|
168
|
-
delete info.devDependencies
|
|
169
|
-
delete info.scripts
|
|
170
|
-
delete info.main
|
|
171
|
-
} catch (e) {
|
|
172
|
-
console.info('No info on plugin:', path)
|
|
173
|
-
} finally {
|
|
174
|
-
info.path = path
|
|
175
|
-
info.name = name
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
pluginInstance.getSettings = () => {
|
|
179
|
-
return this.getPluginSettings(info.name)
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
this.pluginsMap[name] = {
|
|
183
|
-
pluginInstance,
|
|
184
|
-
pluginClass,
|
|
185
|
-
info,
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return pluginInstance
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
destroyPlugins() {
|
|
192
|
-
this.stopDevMode()
|
|
193
|
-
this.eachPlugin(({ pluginInstance }) => {
|
|
194
|
-
try {
|
|
195
|
-
pluginInstance.destroy()
|
|
196
|
-
} catch (e) {
|
|
197
|
-
this.pluginError('destroy', pluginInstance, e)
|
|
198
|
-
}
|
|
199
|
-
})
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
isPlugin(pluginClass) {
|
|
203
|
-
return Object.getPrototypeOf(pluginClass).name === Plugin.name
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
eachPlugin(cb) {
|
|
207
|
-
Object.keys(this.pluginsMap).forEach((key) => {
|
|
208
|
-
cb(this.getPlugin(key))
|
|
209
|
-
})
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
async eachPluginAsync(cb) {
|
|
213
|
-
for (const key of Object.keys(this.pluginsMap)) {
|
|
214
|
-
await cb(this.getPlugin(key))
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
getPlugins() {
|
|
219
|
-
return Object.keys(this.pluginsMap).map((key) => {
|
|
220
|
-
const { info, pluginInstance } = this.getPlugin(key)
|
|
221
|
-
const schema = pluginInstance.getSettingsSchema()
|
|
222
|
-
if (schema) {
|
|
223
|
-
schema.id = info.name
|
|
224
|
-
schema.title = `${info.name} settings`
|
|
225
|
-
}
|
|
226
|
-
return { ...info, schema }
|
|
227
|
-
})
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
getPluginName(pluginInstance) {
|
|
231
|
-
return Object.keys(this.pluginsMap).find(
|
|
232
|
-
(pluginName) =>
|
|
233
|
-
this.getPlugin(pluginName).pluginInstance === pluginInstance
|
|
234
|
-
)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
getPluginInstance(name) {
|
|
238
|
-
const plugin = this.getPlugin(name)
|
|
239
|
-
if (!plugin) throw new Error(`Plugin ${name} not found`)
|
|
240
|
-
return plugin.pluginInstance
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
getPlugin(name) {
|
|
244
|
-
return this.pluginsMap[name]
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
getPluginSettings(name) {
|
|
248
|
-
return this.project.config.plugins[name] || {}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
pluginError(method, pluginInstance, error) {
|
|
252
|
-
console.warn(
|
|
253
|
-
`Plugin: ${this.getPluginName(
|
|
254
|
-
pluginInstance
|
|
255
|
-
)} threw an error on ${method}: `,
|
|
256
|
-
error
|
|
257
|
-
)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
async onBoardUpdate(lists) {
|
|
261
|
-
if (!lists || lists.length == 0) return
|
|
262
|
-
await this.eachPluginAsync(async ({ pluginInstance }) => {
|
|
263
|
-
// const timeLabel = `${this.getPluginName(pluginInstance)} onBoardUpdate time`
|
|
264
|
-
// console.time(timeLabel)
|
|
265
|
-
try {
|
|
266
|
-
await pluginInstance.onBoardUpdate(lists)
|
|
267
|
-
} catch (e) {
|
|
268
|
-
this.pluginError('onBoardUpdate', pluginInstance, e)
|
|
269
|
-
}
|
|
270
|
-
// console.timeEnd(timeLabel)
|
|
271
|
-
})
|
|
272
|
-
return lists
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
async onBeforeBoardUpdate() {
|
|
276
|
-
await this.eachPluginAsync(async ({ pluginInstance }) => {
|
|
277
|
-
try {
|
|
278
|
-
await pluginInstance.onBeforeBoardUpdate()
|
|
279
|
-
} catch (e) {
|
|
280
|
-
this.pluginError('onBeforeBoardUpdate', pluginInstance, e)
|
|
281
|
-
}
|
|
282
|
-
})
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
onTaskUpdate(task) {
|
|
286
|
-
this.eachPlugin(({ pluginInstance }) => {
|
|
287
|
-
try {
|
|
288
|
-
pluginInstance.onTaskUpdate(task)
|
|
289
|
-
} catch (e) {
|
|
290
|
-
this.pluginError('onTaskUpdate', pluginInstance, e)
|
|
291
|
-
}
|
|
292
|
-
})
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
async onTaskFound(task) {
|
|
296
|
-
await this.eachPluginAsync(async ({ pluginInstance }) => {
|
|
297
|
-
try {
|
|
298
|
-
if (pluginInstance.onTaskFound) await pluginInstance.onTaskFound(task)
|
|
299
|
-
} catch (e) {
|
|
300
|
-
this.pluginError('onTaskFound', pluginInstance, e)
|
|
301
|
-
}
|
|
302
|
-
})
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
async onBeforeAddTask({path, list, content, tags, contexts, meta, useCardTemplate}) {
|
|
306
|
-
await this.eachPluginAsync(async ({ pluginInstance }) => {
|
|
307
|
-
try {
|
|
308
|
-
const pluginMods = await pluginInstance.onBeforeAddTask({path, list, content, tags, contexts, meta, useCardTemplate})
|
|
309
|
-
path = pluginMods.path
|
|
310
|
-
content = pluginMods.content
|
|
311
|
-
tags = pluginMods.tags
|
|
312
|
-
contexts = pluginMods.contexts
|
|
313
|
-
meta = pluginMods.meta
|
|
314
|
-
} catch (e) {
|
|
315
|
-
this.pluginError('onBeforeAddTask', pluginInstance, e)
|
|
316
|
-
}
|
|
317
|
-
})
|
|
318
|
-
return {path, content, tags, contexts, meta}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
async onAfterDeleteTask(task) {
|
|
322
|
-
await this.eachPluginAsync(async ({ pluginInstance }) => {
|
|
323
|
-
try {
|
|
324
|
-
await pluginInstance.onAfterDeleteTask(task)
|
|
325
|
-
} catch (e) {
|
|
326
|
-
this.pluginError('onAfterDeleteTask', pluginInstance, e)
|
|
327
|
-
}
|
|
328
|
-
})
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
getCardProperties(props) {
|
|
332
|
-
let cardProps = {}
|
|
333
|
-
this.eachPlugin(({ pluginInstance }) => {
|
|
334
|
-
try {
|
|
335
|
-
cardProps = { ...cardProps, ...pluginInstance.getCardProperties(props) }
|
|
336
|
-
} catch (e) {
|
|
337
|
-
this.pluginError('getCardProperties', pluginInstance, e)
|
|
338
|
-
}
|
|
339
|
-
})
|
|
340
|
-
return cardProps
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// READY Make getBoardProperties async
|
|
344
|
-
// <!--
|
|
345
|
-
// order:-10
|
|
346
|
-
// -->
|
|
347
|
-
async getBoardProperties() {
|
|
348
|
-
let boardProps = {}
|
|
349
|
-
await this.eachPluginAsync(async ({ pluginInstance }) => {
|
|
350
|
-
try {
|
|
351
|
-
const pluginProps = pluginInstance.getBoardProperties ? await pluginInstance.getBoardProperties() : {}
|
|
352
|
-
boardProps = { ...boardProps, ...pluginProps }
|
|
353
|
-
} catch (e) {
|
|
354
|
-
this.pluginError('getBoardProperties', pluginInstance, e)
|
|
355
|
-
}
|
|
356
|
-
})
|
|
357
|
-
return boardProps
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
getCardActions(task) {
|
|
361
|
-
let cardLinks = []
|
|
362
|
-
this.eachPlugin(({ pluginInstance }) => {
|
|
363
|
-
try {
|
|
364
|
-
cardLinks = [
|
|
365
|
-
...cardLinks,
|
|
366
|
-
...pluginInstance.getCardActions(task).map((link, index) => {
|
|
367
|
-
return {
|
|
368
|
-
...link,
|
|
369
|
-
action: { plugin: this.getPluginName(pluginInstance), index },
|
|
370
|
-
}
|
|
371
|
-
}),
|
|
372
|
-
]
|
|
373
|
-
} catch (e) {
|
|
374
|
-
this.pluginError('getCardActions', pluginInstance, e)
|
|
375
|
-
}
|
|
376
|
-
})
|
|
377
|
-
return cardLinks
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
getBoardActions() {
|
|
381
|
-
let actions = []
|
|
382
|
-
this.eachPlugin(({ pluginInstance }) => {
|
|
383
|
-
try {
|
|
384
|
-
actions = [
|
|
385
|
-
...actions,
|
|
386
|
-
...pluginInstance.getBoardActions().map((item, index) => {
|
|
387
|
-
if (item.title) item.name = item.title
|
|
388
|
-
return {
|
|
389
|
-
...item,
|
|
390
|
-
plugin: this.getPluginName(pluginInstance),
|
|
391
|
-
index,
|
|
392
|
-
}
|
|
393
|
-
}),
|
|
394
|
-
]
|
|
395
|
-
} catch (e) {
|
|
396
|
-
this.pluginError('getBoardActions', pluginInstance, e)
|
|
397
|
-
}
|
|
398
|
-
})
|
|
399
|
-
return actions
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
performCardAction(action, task) {
|
|
403
|
-
const plugin = this.getPluginInstance(action.plugin)
|
|
404
|
-
try {
|
|
405
|
-
return plugin.getCardActions(task)[action.index].action()
|
|
406
|
-
} catch (e) {
|
|
407
|
-
this.pluginError('getCardActions', plugin, e)
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
async performBoardAction(action, task) {
|
|
412
|
-
const plugin = this.getPluginInstance(action.plugin)
|
|
413
|
-
try {
|
|
414
|
-
return action.index
|
|
415
|
-
? await plugin.getBoardActions()[action.index].action(task)
|
|
416
|
-
: await plugin.getBoardActions().find(a => a.title === action.title).action(task)
|
|
417
|
-
} catch (e) {
|
|
418
|
-
this.pluginError('getBoardActions', plugin, e)
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
renderMarkdown,
|
|
3
|
-
} = require('../adapters/markdown')
|
|
4
|
-
|
|
5
|
-
module.exports = {
|
|
6
|
-
|
|
7
|
-
getAvailablePlugins: async function () {
|
|
8
|
-
const response = await fetch('https://raw.githubusercontent.com/imdone/imdone-plugins/main/index.json')
|
|
9
|
-
const plugins = response.body
|
|
10
|
-
for (const plugin of plugins) {
|
|
11
|
-
plugin.content = renderMarkdown(await getReadmeContent(plugin))
|
|
12
|
-
}
|
|
13
|
-
return plugins
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async function getReadmeContent({version}) {
|
|
19
|
-
const response = await fetch(`https://api.github.com/repos/${version}/readme`)
|
|
20
|
-
const { content } = response.body
|
|
21
|
-
const buffer = Buffer.from(content, 'base64');
|
|
22
|
-
return buffer.toString('utf-8');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const https = require('https')
|
|
26
|
-
|
|
27
|
-
async function fetch(url, opts = { method: 'GET', headers: {} }) {
|
|
28
|
-
const { method, headers, body, debug = () => { } } = opts
|
|
29
|
-
if (body) headers['Content-Length'] = body.length
|
|
30
|
-
headers['Cache-Control'] = 'no-cache'; // Add Cache-Control header
|
|
31
|
-
url = new URL(url)
|
|
32
|
-
const port = url.protocol === 'https:' ? 443 : 80
|
|
33
|
-
const options = {
|
|
34
|
-
hostname: url.hostname,
|
|
35
|
-
port: port,
|
|
36
|
-
path: url.pathname,
|
|
37
|
-
method,
|
|
38
|
-
headers: {
|
|
39
|
-
'User-Agent': 'imdone',
|
|
40
|
-
...headers,
|
|
41
|
-
},
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
debug("Fetch request:", JSON.stringify({ method, url, body }))
|
|
45
|
-
|
|
46
|
-
return new Promise((resolve, reject) => {
|
|
47
|
-
let result = []
|
|
48
|
-
|
|
49
|
-
const req = https.request(options, (res) => {
|
|
50
|
-
res.on('data', (chunk) => result.push(chunk))
|
|
51
|
-
res.on('end', () => {
|
|
52
|
-
const data = Buffer.concat(result).toString()
|
|
53
|
-
debug("Fetch response:", JSON.stringify({ data, status: res.statusCode }))
|
|
54
|
-
resolve({ body: data && JSON.parse(data), status: res.statusCode })
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
req.on('error', reject)
|
|
58
|
-
if (body) req.write(body)
|
|
59
|
-
req.end()
|
|
60
|
-
})
|
|
61
|
-
}
|
package/lib/project-factory.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
const Repository = require('./repository')
|
|
2
|
-
const watchedFsStore = require('./mixins/repo-watched-fs-store')
|
|
3
|
-
const fsStore = require('./mixins/repo-fs-store')
|
|
4
|
-
const ProjectContext = require('./ProjectContext')
|
|
5
|
-
const Project = require('./project')
|
|
6
|
-
const context = require('./context/ApplicationContext')
|
|
7
|
-
|
|
8
|
-
function createFileSystemProject({
|
|
9
|
-
path,
|
|
10
|
-
config,
|
|
11
|
-
repo = fsStore(new Repository(path, config)),
|
|
12
|
-
loadInstalledPlugins,
|
|
13
|
-
loadPluginsNotInstalled
|
|
14
|
-
}) {
|
|
15
|
-
context().repo = repo
|
|
16
|
-
context().projectContext = new ProjectContext(repo)
|
|
17
|
-
context().project = new Project(repo)
|
|
18
|
-
if (loadInstalledPlugins) {
|
|
19
|
-
context().project.pluginManager.loadInstalledPlugins = loadInstalledPlugins
|
|
20
|
-
}
|
|
21
|
-
if (loadPluginsNotInstalled) {
|
|
22
|
-
context().project.pluginManager.loadPluginsNotInstalled = loadPluginsNotInstalled
|
|
23
|
-
}
|
|
24
|
-
return context().project
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
module.exports = {
|
|
28
|
-
createWatchedFileSystemProject: function({
|
|
29
|
-
path,
|
|
30
|
-
config,
|
|
31
|
-
repo = watchedFsStore(new Repository(path, config)),
|
|
32
|
-
loadInstalledPlugins,
|
|
33
|
-
loadPluginsNotInstalled
|
|
34
|
-
}) {
|
|
35
|
-
return createFileSystemProject({
|
|
36
|
-
path,
|
|
37
|
-
config,
|
|
38
|
-
repo,
|
|
39
|
-
loadInstalledPlugins,
|
|
40
|
-
loadPluginsNotInstalled
|
|
41
|
-
})
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
createFileSystemProject
|
|
45
|
-
}
|