imdone-core 2.0.0 → 2.0.1
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/.dependency-cruiser.cjs +412 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- package/.github/workflows/ci.yml +24 -0
- package/.imdoneignore +13 -0
- package/.mocharc.json +10 -0
- package/.prettierrc +6 -0
- package/CHANGELOG.md +160 -0
- package/_index.md +7 -0
- package/_navbar.md +1 -0
- package/build.js +57 -0
- package/esm-migration.md +446 -0
- package/index.html +184 -0
- package/lib/FileProjectContext.js +13 -0
- package/lib/ProjectContext.js +43 -0
- package/lib/adapters/date-time.js +15 -0
- package/lib/adapters/environment.js +3 -0
- package/lib/adapters/file-gateway.js +154 -0
- package/lib/adapters/git-download.js +55 -0
- package/lib/adapters/index.js +9 -0
- package/lib/adapters/logger.js +136 -0
- package/lib/adapters/markdown.js +180 -0
- package/lib/adapters/parsers/DateLanguageParser.js +12 -0
- package/lib/adapters/parsers/content-transformer.js +116 -0
- package/lib/adapters/parsers/file/LocalFileParserFactory.js +36 -0
- package/lib/adapters/parsers/file/ReadStreamCodeParser.js +126 -0
- package/lib/adapters/parsers/file/ReadStreamMarkdownParser.js +17 -0
- package/lib/adapters/parsers/file/ReadStreamTaskParser.js +106 -0
- package/lib/adapters/parsers/file/index.js +4 -0
- package/lib/adapters/parsers/function-parser.js +25 -0
- package/lib/adapters/parsers/index.js +5 -0
- package/lib/adapters/parsers/task/CardContentParser.js +367 -0
- package/lib/adapters/parsers/task/CheckStyleTaskParser.js +28 -0
- package/lib/adapters/parsers/task/CodeStyleTaskParser.js +24 -0
- package/lib/adapters/parsers/task/HashStyleTaskParser.js +27 -0
- package/lib/adapters/parsers/task/MarkdownStyleTaskParser.js +24 -0
- package/lib/adapters/parsers/task/TaskParser.js +38 -0
- package/lib/adapters/parsers/task/index.js +6 -0
- package/lib/adapters/storage/config.js +44 -0
- package/lib/adapters/storage/index.js +2 -0
- package/lib/adapters/storage/tags.js +29 -0
- package/lib/adapters/yaml.js +9 -0
- package/lib/card.js +299 -0
- package/lib/checksum.js +22 -0
- package/lib/config.js +249 -0
- package/lib/constants.js +68 -0
- package/lib/context/ApplicationContext.js +35 -0
- package/lib/context/index.js +1 -0
- package/lib/default-settings.js +37 -0
- package/lib/domain/entities/View.js +23 -0
- package/lib/domain/entities/index.js +1 -0
- package/lib/domain/index.js +2 -0
- package/lib/domain/usecases/GetViewsUsecase.js +44 -0
- package/lib/domain/usecases/SaveViewUsecase.js +51 -0
- package/lib/domain/usecases/index.js +2 -0
- package/lib/file.js +1391 -0
- package/lib/get-tasks-to-modify.js +117 -0
- package/lib/languages.js +113 -0
- package/lib/list.js +56 -0
- package/lib/migrate-config.js +165 -0
- package/lib/mixins/index.js +2 -0
- package/lib/mixins/repo-fs-store.js +359 -0
- package/lib/mixins/repo-watched-fs-store.js +206 -0
- package/lib/plugins/archive-plugin.js +72 -0
- package/lib/plugins/default-board-actions-plugin.js +56 -0
- package/lib/plugins/default-board-properties-plugin.js +101 -0
- package/lib/plugins/default-plugins.js +7 -0
- package/lib/plugins/epic-plugin.js +177 -0
- package/lib/plugins/extension-plugin.js +94 -0
- package/lib/plugins/index.js +9 -0
- package/lib/plugins/persist-tags-plugin.js +14 -0
- package/lib/plugins/plugin-manager.js +458 -0
- package/lib/plugins/plugin-registry.js +57 -0
- package/lib/project-factory.js +42 -0
- package/lib/project.js +864 -0
- package/lib/repository.js +1514 -0
- package/lib/task.js +780 -0
- package/lib/tools.js +176 -0
- package/lib/usecases/actions.js +32 -0
- package/lib/usecases/get-imdone-url.js +6 -0
- package/lib/usecases/get-project-tags.js +7 -0
- package/lib/usecases/get-tasks-in-file.js +26 -0
- package/lib/usecases/index.js +4 -0
- package/package.json +2 -6
- package/scripts/delete-markdown-indexes.js +87 -0
- package/scripts/generate-index.js +35 -0
- package/scripts/index-markdown.js +55 -0
- package/tsconfig.json +15 -0
- package/types/FileProjectContext.d.ts +4 -0
- package/types/ProjectContext.d.ts +9 -0
- package/types/adapters/date-time.d.ts +2 -0
- package/types/adapters/environment.d.ts +1 -0
- package/types/adapters/file-gateway.d.ts +51 -0
- package/types/adapters/git-download.d.ts +1 -0
- package/types/adapters/index.d.ts +9 -0
- package/types/adapters/logger.d.ts +24 -0
- package/types/adapters/markdown.d.ts +13 -0
- package/types/adapters/parsers/DateLanguageParser.d.ts +1 -0
- package/types/adapters/parsers/content-transformer.d.ts +10 -0
- package/types/adapters/parsers/file/LocalFileParserFactory.d.ts +5 -0
- package/types/adapters/parsers/file/ReadStreamCodeParser.d.ts +13 -0
- package/types/adapters/parsers/file/ReadStreamMarkdownParser.d.ts +7 -0
- package/types/adapters/parsers/file/ReadStreamTaskParser.d.ts +19 -0
- package/types/adapters/parsers/file/index.d.ts +4 -0
- package/types/adapters/parsers/function-parser.d.ts +1 -0
- package/types/adapters/parsers/index.d.ts +5 -0
- package/types/adapters/parsers/task/CardContentParser.d.ts +45 -0
- package/types/adapters/parsers/task/CheckStyleTaskParser.d.ts +12 -0
- package/types/adapters/parsers/task/CodeStyleTaskParser.d.ts +14 -0
- package/types/adapters/parsers/task/HashStyleTaskParser.d.ts +13 -0
- package/types/adapters/parsers/task/MarkdownStyleTaskParser.d.ts +14 -0
- package/types/adapters/parsers/task/TaskParser.d.ts +7 -0
- package/types/adapters/parsers/task/index.d.ts +6 -0
- package/types/adapters/storage/config.d.ts +6 -0
- package/types/adapters/storage/index.d.ts +2 -0
- package/types/adapters/storage/tags.d.ts +3 -0
- package/types/adapters/yaml.d.ts +2 -0
- package/types/card.d.ts +166 -0
- package/types/checksum.d.ts +8 -0
- package/types/config.d.ts +61 -0
- package/types/constants.d.ts +46 -0
- package/types/context/ApplicationContext.d.ts +24 -0
- package/types/context/index.d.ts +1 -0
- package/types/default-settings.d.ts +2 -0
- package/types/domain/entities/FileProjectContext.d.ts +5 -0
- package/types/domain/entities/View.d.ts +17 -0
- package/types/domain/entities/index.d.ts +1 -0
- package/types/domain/index.d.ts +2 -0
- package/types/domain/usecases/GetViewsUsecase.d.ts +4 -0
- package/types/domain/usecases/SaveViewUsecase.d.ts +8 -0
- package/types/domain/usecases/index.d.ts +2 -0
- package/types/file.d.ts +344 -0
- package/types/get-tasks-to-modify.d.ts +3 -0
- package/types/index.d.ts +23 -0
- package/types/languages.d.ts +649 -0
- package/types/list.d.ts +30 -0
- package/types/migrate-config.d.ts +1 -0
- package/types/mixins/index.d.ts +2 -0
- package/types/mixins/repo-fs-store.d.ts +2 -0
- package/types/mixins/repo-watched-fs-store.d.ts +2 -0
- package/types/plugins/archive-plugin.d.ts +8 -0
- package/types/plugins/default-board-actions-plugin.d.ts +9 -0
- package/types/plugins/default-board-properties-plugin.d.ts +16 -0
- package/types/plugins/default-plugins.d.ts +6 -0
- package/types/plugins/epic-plugin.d.ts +19 -0
- package/types/plugins/extension-plugin.d.ts +15 -0
- package/types/plugins/index.d.ts +9 -0
- package/types/plugins/persist-tags-plugin.d.ts +4 -0
- package/types/plugins/plugin-manager.d.ts +68 -0
- package/types/plugins/plugin-registry.d.ts +1 -0
- package/types/project-factory.d.ts +14 -0
- package/types/project.d.ts +158 -0
- package/types/repository.d.ts +996 -0
- package/types/task.d.ts +202 -0
- package/types/tools.d.ts +29 -0
- package/types/usecases/actions.d.ts +7 -0
- package/types/usecases/get-imdone-url.d.ts +1 -0
- package/types/usecases/get-project-tags.d.ts +1 -0
- package/types/usecases/get-tasks-in-file.d.ts +4 -0
- package/types/usecases/index.d.ts +4 -0
- package/vitest.config.js +13 -0
package/lib/card.js
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { Task } from './task.js'
|
|
2
|
+
import _path from 'path'
|
|
3
|
+
import _pick from 'lodash.pick'
|
|
4
|
+
import _isFunction from 'lodash.isfunction'
|
|
5
|
+
import _isObject from 'lodash.isobject'
|
|
6
|
+
import _isEmpty from 'lodash.isempty'
|
|
7
|
+
import eol from 'eol'
|
|
8
|
+
import { getFunctionSignature } from './adapters/parsers/function-parser.js'
|
|
9
|
+
import { format, encodeMarkdownLinks, interpolate } from './adapters/parsers/content-transformer.js'
|
|
10
|
+
import { removeMD } from './adapters/markdown.js'
|
|
11
|
+
import { createRequire } from 'node:module';
|
|
12
|
+
import { logger } from './adapters/logger.js'
|
|
13
|
+
|
|
14
|
+
const require = createRequire(import.meta.url);
|
|
15
|
+
export const allEmoji = require("markdown-it-emoji/lib/data/full.json")
|
|
16
|
+
|
|
17
|
+
const CONTENT_TOKEN = '__CONTENT__'
|
|
18
|
+
const lf = String(eol.lf)
|
|
19
|
+
|
|
20
|
+
export function newCard(task, _project, dontParse) {
|
|
21
|
+
const project = _project
|
|
22
|
+
const pluginManager = _project && _project.pluginManager
|
|
23
|
+
|
|
24
|
+
class Card extends Task {
|
|
25
|
+
constructor(task, dontParse) {
|
|
26
|
+
super(project.config, task, dontParse)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get settings() {
|
|
30
|
+
return project.config.settings || {}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get maxLines() {
|
|
34
|
+
return project.config.maxLines
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get interpretedContent() {
|
|
38
|
+
return this.innerInterpretedContent || this.getTextAndDescription()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
set interpretedContent(value) {
|
|
42
|
+
this.innerInterpretedContent = value
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// TODO This should take an object of project level data and make it available to the card
|
|
46
|
+
// <!--
|
|
47
|
+
// order:-120
|
|
48
|
+
// -->
|
|
49
|
+
init(totals = project.totals) {
|
|
50
|
+
this.updateLastLine()
|
|
51
|
+
this.totals = totals
|
|
52
|
+
this.onTaskUpdate()
|
|
53
|
+
this.initProps()
|
|
54
|
+
this.initComputed()
|
|
55
|
+
this.initData()
|
|
56
|
+
this.initActions()
|
|
57
|
+
return this
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
onTaskUpdate() {
|
|
61
|
+
// TODO We should be mapping to the imdone-api task
|
|
62
|
+
// #imdone-1.45.0
|
|
63
|
+
// <!--
|
|
64
|
+
// order:-20
|
|
65
|
+
// -->
|
|
66
|
+
const interpretedContent = pluginManager.onTaskUpdate(this)
|
|
67
|
+
if (interpretedContent && interpretedContent.length > 0) {
|
|
68
|
+
this.interpretedContent = interpretedContent
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
initProps() {
|
|
73
|
+
const props = this?.settings?.cards?.props ?? {}
|
|
74
|
+
this.props = this.frontMatter.props
|
|
75
|
+
? { ...props, ...this.frontMatter.props }
|
|
76
|
+
: { ...props }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
initComputed() {
|
|
80
|
+
const computed = this?.settings?.cards?.computed ?? {}
|
|
81
|
+
this.computed = this.frontMatter.computed
|
|
82
|
+
? { ...computed, ...this.frontMatter.computed }
|
|
83
|
+
: { ...computed }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
initActions() {
|
|
87
|
+
this.links = []
|
|
88
|
+
if (!pluginManager) return
|
|
89
|
+
this.links = [...pluginManager.getCardActions(this)]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
get projectPath() {
|
|
93
|
+
return project.path
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get relPath() {
|
|
97
|
+
return this.source ? this.source.path : undefined
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get fullPath() {
|
|
101
|
+
return this.source ? _path.join(project.path, this.source.path) : undefined
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
get defaultData() {
|
|
105
|
+
return {
|
|
106
|
+
..._pick(
|
|
107
|
+
this,
|
|
108
|
+
...['beforeText',
|
|
109
|
+
'rawTask',
|
|
110
|
+
'id',
|
|
111
|
+
'text',
|
|
112
|
+
'progress',
|
|
113
|
+
'line',
|
|
114
|
+
'lastLine',
|
|
115
|
+
'list',
|
|
116
|
+
'source',
|
|
117
|
+
'due',
|
|
118
|
+
'created',
|
|
119
|
+
'started',
|
|
120
|
+
'completed',
|
|
121
|
+
'tags',
|
|
122
|
+
'context',
|
|
123
|
+
'meta',
|
|
124
|
+
'allTags',
|
|
125
|
+
'allContext',
|
|
126
|
+
'allMeta',
|
|
127
|
+
'metaKeys',
|
|
128
|
+
'content',
|
|
129
|
+
'filteredListName',
|
|
130
|
+
'interpretedContent',
|
|
131
|
+
'projectPath',
|
|
132
|
+
'relPath',
|
|
133
|
+
'fullPath',
|
|
134
|
+
'totals',
|
|
135
|
+
'topics'].sort()
|
|
136
|
+
),
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// TODO Add isInCodeFile property to card
|
|
141
|
+
// <!--
|
|
142
|
+
// order:-115
|
|
143
|
+
// -->
|
|
144
|
+
initData() {
|
|
145
|
+
const props = { ...this.props, content: CONTENT_TOKEN }
|
|
146
|
+
const computed = { ...this.computed }
|
|
147
|
+
const defaultData = this.defaultData
|
|
148
|
+
try {
|
|
149
|
+
for (let [key, value] of Object.entries(computed)) {
|
|
150
|
+
let computedValue = value.toString()
|
|
151
|
+
const computedProps = { ...props, ...computed, ...defaultData }
|
|
152
|
+
if (_isFunction(value) && !_isEmpty(props)) {
|
|
153
|
+
try {
|
|
154
|
+
// Call the computed function for a value
|
|
155
|
+
computedValue = value.call(computedProps)
|
|
156
|
+
} catch (e) {
|
|
157
|
+
logger.info(
|
|
158
|
+
`Unable to compute key: ${key} with value: ${computedValue}`,
|
|
159
|
+
e.message
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
try {
|
|
164
|
+
// Use template for the computed value
|
|
165
|
+
computedValue = interpolate(value, computedProps, { tags: ['${', '}'] })
|
|
166
|
+
} catch (e) {
|
|
167
|
+
logger.info(
|
|
168
|
+
`Unable to compute key: ${key} with value: ${computedValue}`,
|
|
169
|
+
e.message
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
computed[key] = computedValue
|
|
174
|
+
}
|
|
175
|
+
} catch (e) {
|
|
176
|
+
logger.error(e)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const pluginData = pluginManager
|
|
180
|
+
? { ...pluginManager.getCardProperties(defaultData) }
|
|
181
|
+
: {}
|
|
182
|
+
const data = {
|
|
183
|
+
...pluginData,
|
|
184
|
+
...props,
|
|
185
|
+
...computed,
|
|
186
|
+
...defaultData
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const keys = Object.keys(data).map((key) => {
|
|
190
|
+
const value = data[key]
|
|
191
|
+
if (_isFunction(value)) {
|
|
192
|
+
key = getFunctionSignature(value)
|
|
193
|
+
}
|
|
194
|
+
return key
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
keys.forEach((key) => {
|
|
198
|
+
const value = data[key]
|
|
199
|
+
if (_isObject(value) && !Array.isArray(value)) {
|
|
200
|
+
keys.push(...Object.keys(value).map((k) => `${key}.${k}`))
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
this.dataKeys = keys
|
|
204
|
+
|
|
205
|
+
this.data = { ...data }
|
|
206
|
+
this.updateDescriptionData()
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
updateDescriptionData() {
|
|
210
|
+
this.desc = this.getDescriptionData()
|
|
211
|
+
this.data = { ...this.data, ...this.desc }
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
getEncodedContent(content) {
|
|
215
|
+
const linkRegex = /\[([^[]+)\](\((.*)\))/gm
|
|
216
|
+
const plainDescription = removeMD(content.replace(linkRegex, '$3'), {
|
|
217
|
+
stripListLeaders: false,
|
|
218
|
+
}).replace(/:(\w+):/g, (match, p1) => {
|
|
219
|
+
return allEmoji[p1]
|
|
220
|
+
})
|
|
221
|
+
const encodedText = encodeURIComponent(plainDescription)
|
|
222
|
+
const encodedMD = encodeURIComponent(content)
|
|
223
|
+
content = content.replace(CONTENT_TOKEN, encodedText)
|
|
224
|
+
content = encodeMarkdownLinks(content)
|
|
225
|
+
return { encodedMD, encodedText, content }
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
formatContent(content, mustache) {
|
|
229
|
+
return this.getEncodedContent(this.format(content, mustache))
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
format(content, mustache) {
|
|
233
|
+
const projectData = project ? { ...project.data } : {}
|
|
234
|
+
const data = { ...this.data, ...projectData }
|
|
235
|
+
return format(content, data, mustache)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
getCardMarkdown() {
|
|
239
|
+
let taskMD = this.interpretedContent
|
|
240
|
+
.replace(/%%[\s\S]*?%%/g, '')
|
|
241
|
+
.replace(/<\!--\s*?-->/gs, '')
|
|
242
|
+
.trim()
|
|
243
|
+
const displayContent = []
|
|
244
|
+
const rawContent = []
|
|
245
|
+
const mdArray = eol.split(taskMD)
|
|
246
|
+
let titleFound = false
|
|
247
|
+
mdArray.forEach((line) => {
|
|
248
|
+
rawContent.push(line)
|
|
249
|
+
if (!titleFound && line === `${this.beforeText}${this.text}`) {
|
|
250
|
+
line = `<span class="imdone-card-title">${lf}${lf}${line}${lf}${lf}</span>${lf}`
|
|
251
|
+
titleFound = true
|
|
252
|
+
}
|
|
253
|
+
displayContent.push(line)
|
|
254
|
+
})
|
|
255
|
+
this.truncLines = titleFound ? this.maxLines + 5 : this.maxLines
|
|
256
|
+
const totalLines = displayContent.length
|
|
257
|
+
const markdown = displayContent.join(eol.lf)
|
|
258
|
+
const rawMarkdown = rawContent.join(eol.lf)
|
|
259
|
+
return { totalLines, markdown, rawMarkdown }
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
getHtml(content) {
|
|
263
|
+
const html = project.renderMarkdown(content, this.fullPath)
|
|
264
|
+
const mdArray = eol.split(content)
|
|
265
|
+
let truncHtml
|
|
266
|
+
if (mdArray.length > this.truncLines) {
|
|
267
|
+
mdArray.length = this.truncLines
|
|
268
|
+
truncHtml = project.renderMarkdown(mdArray.join(eol.lf), this.fullPath)
|
|
269
|
+
}
|
|
270
|
+
return { html, truncHtml }
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
getDescriptionData() {
|
|
274
|
+
const { markdown, rawMarkdown } = this.getCardMarkdown()
|
|
275
|
+
|
|
276
|
+
let { encodedText, encodedMD, content } = this.formatContent(
|
|
277
|
+
markdown,
|
|
278
|
+
true
|
|
279
|
+
)
|
|
280
|
+
const formattedRawMarkdown = this.formatContent(rawMarkdown, true).content
|
|
281
|
+
const { html, truncHtml } = this.getHtml(content)
|
|
282
|
+
const title = this.format(this.text, true)
|
|
283
|
+
return {
|
|
284
|
+
title,
|
|
285
|
+
html,
|
|
286
|
+
truncHtml,
|
|
287
|
+
encodedText,
|
|
288
|
+
encodedMD,
|
|
289
|
+
markdown: content,
|
|
290
|
+
rawMarkdown: formattedRawMarkdown,
|
|
291
|
+
htmlLength: html.length,
|
|
292
|
+
htmlTruncLength: truncHtml && truncHtml.length,
|
|
293
|
+
isOverMaxLines: truncHtml && truncHtml.length < html.length,
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return new Card(task, dontParse)
|
|
299
|
+
}
|
package/lib/checksum.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import { readFile } from 'fs/promises';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Compute a checksum for a given string or file.
|
|
6
|
+
* @param {string} input - The string or file path to hash.
|
|
7
|
+
* @param {string} algorithm - The hash algorithm to use (default: 'sha1').
|
|
8
|
+
* @param {boolean} isFile - Whether the input is a file path.
|
|
9
|
+
* @returns {Promise<string>} The computed checksum.
|
|
10
|
+
*/
|
|
11
|
+
export async function computeChecksum(input, algorithm = 'sha1', isFile = false) {
|
|
12
|
+
const hash = createHash(algorithm);
|
|
13
|
+
|
|
14
|
+
if (isFile) {
|
|
15
|
+
const fileBuffer = await readFile(input);
|
|
16
|
+
hash.update(fileBuffer);
|
|
17
|
+
} else {
|
|
18
|
+
hash.update(input);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return hash.digest('hex');
|
|
22
|
+
}
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Description
|
|
3
|
+
* @method Config
|
|
4
|
+
* @param {} opts
|
|
5
|
+
* @return
|
|
6
|
+
*/
|
|
7
|
+
const COLON = ':'
|
|
8
|
+
const DOUBLE_COLON = '::'
|
|
9
|
+
const META_SEPS = [COLON, DOUBLE_COLON]
|
|
10
|
+
|
|
11
|
+
const JOURNAL_TYPE = {
|
|
12
|
+
SINGLE_FILE: 'Single File',
|
|
13
|
+
FOLDER: 'Folder',
|
|
14
|
+
NEW_FILE: 'New File',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const DEFAULT_CONFIG = {
|
|
18
|
+
keepEmptyPriority: false,
|
|
19
|
+
code: {
|
|
20
|
+
include_lists: [
|
|
21
|
+
'TODO',
|
|
22
|
+
'DOING',
|
|
23
|
+
'DONE',
|
|
24
|
+
'PLANNING',
|
|
25
|
+
'FIXME',
|
|
26
|
+
'ARCHIVE',
|
|
27
|
+
'HACK',
|
|
28
|
+
'CHANGED',
|
|
29
|
+
'XXX',
|
|
30
|
+
'IDEA',
|
|
31
|
+
'NOTE',
|
|
32
|
+
'REVIEW',
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
lists: [
|
|
36
|
+
{
|
|
37
|
+
hidden: false,
|
|
38
|
+
name: 'TODO',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
hidden: false,
|
|
42
|
+
name: 'DOING',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
hidden: false,
|
|
46
|
+
name: 'DONE',
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class Config {
|
|
52
|
+
constructor(opts) {
|
|
53
|
+
Object.assign(this, opts)
|
|
54
|
+
if (!this.settings) this.settings = {}
|
|
55
|
+
if (!this.settings.views) this.settings.views = []
|
|
56
|
+
if (!this.settings.cards) this.settings.cards = {}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static DEFAULT_CONFIG = DEFAULT_CONFIG
|
|
60
|
+
static JOURNAL_TYPE = JOURNAL_TYPE
|
|
61
|
+
|
|
62
|
+
static newDefaultConfig(config = {}) {
|
|
63
|
+
return new Config(
|
|
64
|
+
{
|
|
65
|
+
...DEFAULT_CONFIG,
|
|
66
|
+
lists: [
|
|
67
|
+
...DEFAULT_CONFIG.lists
|
|
68
|
+
],
|
|
69
|
+
...config
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get cards () {
|
|
75
|
+
return this?.settings?.cards
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get defaultFilter() {
|
|
79
|
+
return this?.settings?.defaultFilter ?? ''
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
set defaultFilter(filter) {
|
|
83
|
+
this.settings.defaultFilter = filter
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get name() {
|
|
87
|
+
return this?.settings?.name ?? ''
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
set name(name) {
|
|
91
|
+
this.settings.name = name
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
includeList(name) {
|
|
95
|
+
return this?.code?.include_lists?.includes(name)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
ignoreList(name) {
|
|
99
|
+
const list = this?.lists?.find((list) => name === list.name)
|
|
100
|
+
return !list || (list && list.ignore)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
listExists(name) {
|
|
104
|
+
return this?.lists?.findIndex((list) => list.name === name) > -1
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
getDefaultList() {
|
|
108
|
+
return this?.cards?.defaultList ?? this.lists[0].name
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
getDoneList() {
|
|
112
|
+
const lists = structuredClone(this.lists).reverse().filter((list) => !list.filter)
|
|
113
|
+
return this?.cards?.doneList
|
|
114
|
+
|| lists?.find(list => /dene|completed|finished/i.test(list?.name ?? ''))?.name
|
|
115
|
+
|| lists[0]?.name
|
|
116
|
+
|| ''
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
getDoingList() {
|
|
120
|
+
const lists = structuredClone(this.lists).filter((list) => !list.filter)
|
|
121
|
+
.reverse()
|
|
122
|
+
return this?.cards?.doingList
|
|
123
|
+
|| lists?.find(list => /doing|progress/i.test(list?.name ?? ''))?.name
|
|
124
|
+
|| lists[1]?.name
|
|
125
|
+
|| ''
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
isAddNewCardsToTop() {
|
|
129
|
+
return this?.cards?.addNewCardsToTop ?? false
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
getNewCardSyntax() {
|
|
133
|
+
return this?.settings?.newCardSyntax?? 'MARKDOWN'
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
isMetaNewLine() {
|
|
137
|
+
return this?.cards?.metaNewLine ?? false
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
getTagPrefix() {
|
|
141
|
+
return this?.cards?.tagPrefix ?? '+'
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
getTaskPrefix() {
|
|
145
|
+
return this?.cards?.taskPrefix ?? '##'
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
isAddCheckBoxTasks() {
|
|
149
|
+
return this?.cards?.addCheckBoxTasks ?? false
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
isAddCompletedMeta() {
|
|
153
|
+
return this?.cards?.addCompletedMeta ?? false
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
get customCardTerminator() {
|
|
157
|
+
return this?.cards?.customCardTerminator
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
set customCardTerminator(terminator) {
|
|
161
|
+
this.settings.cards.customCardTerminator = terminator
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
get markdownOnly() {
|
|
165
|
+
return this?.settings?.markdownOnly
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
get views() {
|
|
169
|
+
return this?.settings?.views
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
get appendNewCardsTo() {
|
|
173
|
+
return this?.settings?.appendNewCardsTo ?? false
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
get ignoreFrontMatter() {
|
|
177
|
+
return this?.settings?.ignoreFrontMatter ?? false
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
get ignoreFrontMatterTags() {
|
|
181
|
+
return this?.settings?.ignoreFrontMatterTags ?? false
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
get journalPath() {
|
|
185
|
+
return this?.settings?.journalPath ?? ''
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
set journalPath(path) {
|
|
189
|
+
this.settings.journalPath = path
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
get journalTemplate() {
|
|
193
|
+
const template = this?.settings?.journalTemplate ?? ''
|
|
194
|
+
return template === 'null' ? '' : template || ''
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
get journalType() {
|
|
198
|
+
return this?.settings?.journalType ?? JOURNAL_TYPE.FOLDER
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
get journalFilePrefix() {
|
|
202
|
+
return this?.settings?.journalFilePrefix ?? ''
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
get journalFileSuffix() {
|
|
206
|
+
return this?.settings?.journalFileSuffix ?? ''
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
get replaceSpacesWith() {
|
|
210
|
+
return this?.settings?.replaceSpacesWith
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
get devMode() {
|
|
214
|
+
return this?.settings?.plugins?.devMode ?? false
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
get plugins() {
|
|
218
|
+
return this?.settings?.plugins ?? { devMode: this.devMode }
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
get orderMeta() {
|
|
222
|
+
return this?.cards?.orderMeta ?? false
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
get maxLines() {
|
|
226
|
+
return this?.cards?.maxLines ?? 1
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
get archiveFolder() {
|
|
230
|
+
return this?.cards?.archiveFolder ?? 'archive'
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
get archiveCompleted() {
|
|
234
|
+
return this?.cards?.archiveCompleted ?? false
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
get tokenPrefix() {
|
|
238
|
+
return this?.cards?.tokenPrefix ?? '#'
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
get doneList() {
|
|
242
|
+
return this.getDoneList()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
getMetaSep() {
|
|
246
|
+
const metaSep = this?.cards?.metaSep ?? COLON
|
|
247
|
+
return META_SEPS.includes(metaSep) ? metaSep : COLON
|
|
248
|
+
}
|
|
249
|
+
}
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import { Config } from './config.js'
|
|
3
|
+
|
|
4
|
+
var DEFAULT_IGNORE_PATHS = `
|
|
5
|
+
node_modules
|
|
6
|
+
bower_components
|
|
7
|
+
target
|
|
8
|
+
build
|
|
9
|
+
dist*
|
|
10
|
+
logs
|
|
11
|
+
flow-typed
|
|
12
|
+
.git
|
|
13
|
+
.svn
|
|
14
|
+
.hs
|
|
15
|
+
.npmignore
|
|
16
|
+
.obsidian
|
|
17
|
+
.imdone/templates
|
|
18
|
+
.imdone/tags.yml
|
|
19
|
+
`
|
|
20
|
+
var DEFAULT_IGNORE_EXTS = `
|
|
21
|
+
*.jpg
|
|
22
|
+
*.png
|
|
23
|
+
*.gif
|
|
24
|
+
*.swp
|
|
25
|
+
*.ttf
|
|
26
|
+
*.odf
|
|
27
|
+
*.pdf
|
|
28
|
+
*.doc*
|
|
29
|
+
*.xls*
|
|
30
|
+
*.ppt*
|
|
31
|
+
*.pps*
|
|
32
|
+
*.ppa*
|
|
33
|
+
*.pot*
|
|
34
|
+
`
|
|
35
|
+
|
|
36
|
+
const DEFAULT_IGNORE = `
|
|
37
|
+
${DEFAULT_IGNORE_PATHS}
|
|
38
|
+
${DEFAULT_IGNORE_EXTS}
|
|
39
|
+
`
|
|
40
|
+
const CONFIG_DIR = '.imdone'
|
|
41
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json')
|
|
42
|
+
const CONFIG_FILE_YML = path.join(CONFIG_DIR, 'config.yml')
|
|
43
|
+
const SORT_FILE = path.join(CONFIG_DIR, 'sort.json')
|
|
44
|
+
const TEMPLATES_DIR = path.join(CONFIG_DIR, 'templates')
|
|
45
|
+
const { JOURNAL_TYPE, DEFAULT_CONFIG } = Config
|
|
46
|
+
|
|
47
|
+
export const constants = {
|
|
48
|
+
JOURNAL_TYPE,
|
|
49
|
+
ASYNC_LIMIT: 512,
|
|
50
|
+
CONFIG_DIR,
|
|
51
|
+
CONFIG_FILE,
|
|
52
|
+
CONFIG_FILE_YML,
|
|
53
|
+
SORT_FILE,
|
|
54
|
+
TEMPLATES_DIR,
|
|
55
|
+
IGNORE_FILE: '.imdoneignore',
|
|
56
|
+
DEFAULT_FILE_PATTERN: '^(readme\\.md|home\\.md|readme\\.w+|home\\.w+)$',
|
|
57
|
+
DEFAULT_IGNORE,
|
|
58
|
+
DEFAULT_IGNORE_PATHS,
|
|
59
|
+
DEFAULT_IGNORE_EXTS,
|
|
60
|
+
ERRORS: {
|
|
61
|
+
NOT_A_FILE: 'file must be of type File',
|
|
62
|
+
CALLBACK_REQUIRED: 'Last paramter must be a callback function',
|
|
63
|
+
NO_CONTENT: 'File has no content',
|
|
64
|
+
LIST_NOT_FOUND: 'List not found',
|
|
65
|
+
TASK_NOT_FOUND: 'Task not found',
|
|
66
|
+
},
|
|
67
|
+
DEFAULT_CONFIG,
|
|
68
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Config } from '../config.js'
|
|
2
|
+
import { getAvailablePlugins } from '../plugins/plugin-registry.js';
|
|
3
|
+
|
|
4
|
+
class ApplicationContext {
|
|
5
|
+
constructor({
|
|
6
|
+
project,
|
|
7
|
+
repo,
|
|
8
|
+
projectContext,
|
|
9
|
+
projectReader,
|
|
10
|
+
projectPresenter,
|
|
11
|
+
}) {
|
|
12
|
+
this.project = project;
|
|
13
|
+
this.repo = repo;
|
|
14
|
+
this.projectContext = projectContext;
|
|
15
|
+
this.projectReader = projectReader;
|
|
16
|
+
this.projectPresenter = projectPresenter;
|
|
17
|
+
this.innerConfig = Config.newDefaultConfig()
|
|
18
|
+
this.pluginRegistry = { getAvailablePlugins }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
set config(config) {
|
|
22
|
+
this.innerConfig = config
|
|
23
|
+
this.repo && (this.repo.config = config)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get config() {
|
|
27
|
+
return this.repo?.config ?? this.innerConfig
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
const context = new ApplicationContext({})
|
|
32
|
+
|
|
33
|
+
export function appContext() {
|
|
34
|
+
return context
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ApplicationContext.js';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { loadYAML } from './adapters/yaml.js'
|
|
2
|
+
|
|
3
|
+
export const defaultSettingsString = `openIn: default #override
|
|
4
|
+
openCodeIn: default #override
|
|
5
|
+
journalType: New File
|
|
6
|
+
journalPath: imdone-tasks #override
|
|
7
|
+
appendNewCardsTo: imdone-tasks.md
|
|
8
|
+
newCardSyntax: HASHTAG #override
|
|
9
|
+
replaceSpacesWith: '-' #override
|
|
10
|
+
plugins:
|
|
11
|
+
devMode: false
|
|
12
|
+
cards:
|
|
13
|
+
colors: [] #override if
|
|
14
|
+
template: | # This is the template for new cards that are created in imdone
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
<!--
|
|
18
|
+
created:\${(new Date()).toISOString()}
|
|
19
|
+
-->
|
|
20
|
+
trackChanges: false #override
|
|
21
|
+
metaNewLine: false #override
|
|
22
|
+
addCompletedMeta: false #override
|
|
23
|
+
addCheckBoxTasks: false #override
|
|
24
|
+
doingList: DOING #override if
|
|
25
|
+
doneList: DONE #override if
|
|
26
|
+
tokenPrefix: '#' #override
|
|
27
|
+
taskPrefix: '##' #override
|
|
28
|
+
tagPrefix: '+' #override
|
|
29
|
+
metaSep: ':' #override
|
|
30
|
+
orderMeta: true
|
|
31
|
+
maxLines: 6 #override
|
|
32
|
+
addNewCardsToTop: true #override
|
|
33
|
+
showTagsAndMeta: true #override
|
|
34
|
+
journalTemplate: #override
|
|
35
|
+
markdownOnly: false #override
|
|
36
|
+
`
|
|
37
|
+
export const defaultSettings = loadYAML(defaultSettingsString)
|