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.
Files changed (160) hide show
  1. package/.dependency-cruiser.cjs +412 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  3. package/.github/workflows/ci.yml +24 -0
  4. package/.imdoneignore +13 -0
  5. package/.mocharc.json +10 -0
  6. package/.prettierrc +6 -0
  7. package/CHANGELOG.md +160 -0
  8. package/_index.md +7 -0
  9. package/_navbar.md +1 -0
  10. package/build.js +57 -0
  11. package/esm-migration.md +446 -0
  12. package/index.html +184 -0
  13. package/lib/FileProjectContext.js +13 -0
  14. package/lib/ProjectContext.js +43 -0
  15. package/lib/adapters/date-time.js +15 -0
  16. package/lib/adapters/environment.js +3 -0
  17. package/lib/adapters/file-gateway.js +154 -0
  18. package/lib/adapters/git-download.js +55 -0
  19. package/lib/adapters/index.js +9 -0
  20. package/lib/adapters/logger.js +136 -0
  21. package/lib/adapters/markdown.js +180 -0
  22. package/lib/adapters/parsers/DateLanguageParser.js +12 -0
  23. package/lib/adapters/parsers/content-transformer.js +116 -0
  24. package/lib/adapters/parsers/file/LocalFileParserFactory.js +36 -0
  25. package/lib/adapters/parsers/file/ReadStreamCodeParser.js +126 -0
  26. package/lib/adapters/parsers/file/ReadStreamMarkdownParser.js +17 -0
  27. package/lib/adapters/parsers/file/ReadStreamTaskParser.js +106 -0
  28. package/lib/adapters/parsers/file/index.js +4 -0
  29. package/lib/adapters/parsers/function-parser.js +25 -0
  30. package/lib/adapters/parsers/index.js +5 -0
  31. package/lib/adapters/parsers/task/CardContentParser.js +367 -0
  32. package/lib/adapters/parsers/task/CheckStyleTaskParser.js +28 -0
  33. package/lib/adapters/parsers/task/CodeStyleTaskParser.js +24 -0
  34. package/lib/adapters/parsers/task/HashStyleTaskParser.js +27 -0
  35. package/lib/adapters/parsers/task/MarkdownStyleTaskParser.js +24 -0
  36. package/lib/adapters/parsers/task/TaskParser.js +38 -0
  37. package/lib/adapters/parsers/task/index.js +6 -0
  38. package/lib/adapters/storage/config.js +44 -0
  39. package/lib/adapters/storage/index.js +2 -0
  40. package/lib/adapters/storage/tags.js +29 -0
  41. package/lib/adapters/yaml.js +9 -0
  42. package/lib/card.js +299 -0
  43. package/lib/checksum.js +22 -0
  44. package/lib/config.js +249 -0
  45. package/lib/constants.js +68 -0
  46. package/lib/context/ApplicationContext.js +35 -0
  47. package/lib/context/index.js +1 -0
  48. package/lib/default-settings.js +37 -0
  49. package/lib/domain/entities/View.js +23 -0
  50. package/lib/domain/entities/index.js +1 -0
  51. package/lib/domain/index.js +2 -0
  52. package/lib/domain/usecases/GetViewsUsecase.js +44 -0
  53. package/lib/domain/usecases/SaveViewUsecase.js +51 -0
  54. package/lib/domain/usecases/index.js +2 -0
  55. package/lib/file.js +1391 -0
  56. package/lib/get-tasks-to-modify.js +117 -0
  57. package/lib/languages.js +113 -0
  58. package/lib/list.js +56 -0
  59. package/lib/migrate-config.js +165 -0
  60. package/lib/mixins/index.js +2 -0
  61. package/lib/mixins/repo-fs-store.js +359 -0
  62. package/lib/mixins/repo-watched-fs-store.js +206 -0
  63. package/lib/plugins/archive-plugin.js +72 -0
  64. package/lib/plugins/default-board-actions-plugin.js +56 -0
  65. package/lib/plugins/default-board-properties-plugin.js +101 -0
  66. package/lib/plugins/default-plugins.js +7 -0
  67. package/lib/plugins/epic-plugin.js +177 -0
  68. package/lib/plugins/extension-plugin.js +94 -0
  69. package/lib/plugins/index.js +9 -0
  70. package/lib/plugins/persist-tags-plugin.js +14 -0
  71. package/lib/plugins/plugin-manager.js +458 -0
  72. package/lib/plugins/plugin-registry.js +57 -0
  73. package/lib/project-factory.js +42 -0
  74. package/lib/project.js +864 -0
  75. package/lib/repository.js +1514 -0
  76. package/lib/task.js +780 -0
  77. package/lib/tools.js +176 -0
  78. package/lib/usecases/actions.js +32 -0
  79. package/lib/usecases/get-imdone-url.js +6 -0
  80. package/lib/usecases/get-project-tags.js +7 -0
  81. package/lib/usecases/get-tasks-in-file.js +26 -0
  82. package/lib/usecases/index.js +4 -0
  83. package/package.json +2 -6
  84. package/scripts/delete-markdown-indexes.js +87 -0
  85. package/scripts/generate-index.js +35 -0
  86. package/scripts/index-markdown.js +55 -0
  87. package/tsconfig.json +15 -0
  88. package/types/FileProjectContext.d.ts +4 -0
  89. package/types/ProjectContext.d.ts +9 -0
  90. package/types/adapters/date-time.d.ts +2 -0
  91. package/types/adapters/environment.d.ts +1 -0
  92. package/types/adapters/file-gateway.d.ts +51 -0
  93. package/types/adapters/git-download.d.ts +1 -0
  94. package/types/adapters/index.d.ts +9 -0
  95. package/types/adapters/logger.d.ts +24 -0
  96. package/types/adapters/markdown.d.ts +13 -0
  97. package/types/adapters/parsers/DateLanguageParser.d.ts +1 -0
  98. package/types/adapters/parsers/content-transformer.d.ts +10 -0
  99. package/types/adapters/parsers/file/LocalFileParserFactory.d.ts +5 -0
  100. package/types/adapters/parsers/file/ReadStreamCodeParser.d.ts +13 -0
  101. package/types/adapters/parsers/file/ReadStreamMarkdownParser.d.ts +7 -0
  102. package/types/adapters/parsers/file/ReadStreamTaskParser.d.ts +19 -0
  103. package/types/adapters/parsers/file/index.d.ts +4 -0
  104. package/types/adapters/parsers/function-parser.d.ts +1 -0
  105. package/types/adapters/parsers/index.d.ts +5 -0
  106. package/types/adapters/parsers/task/CardContentParser.d.ts +45 -0
  107. package/types/adapters/parsers/task/CheckStyleTaskParser.d.ts +12 -0
  108. package/types/adapters/parsers/task/CodeStyleTaskParser.d.ts +14 -0
  109. package/types/adapters/parsers/task/HashStyleTaskParser.d.ts +13 -0
  110. package/types/adapters/parsers/task/MarkdownStyleTaskParser.d.ts +14 -0
  111. package/types/adapters/parsers/task/TaskParser.d.ts +7 -0
  112. package/types/adapters/parsers/task/index.d.ts +6 -0
  113. package/types/adapters/storage/config.d.ts +6 -0
  114. package/types/adapters/storage/index.d.ts +2 -0
  115. package/types/adapters/storage/tags.d.ts +3 -0
  116. package/types/adapters/yaml.d.ts +2 -0
  117. package/types/card.d.ts +166 -0
  118. package/types/checksum.d.ts +8 -0
  119. package/types/config.d.ts +61 -0
  120. package/types/constants.d.ts +46 -0
  121. package/types/context/ApplicationContext.d.ts +24 -0
  122. package/types/context/index.d.ts +1 -0
  123. package/types/default-settings.d.ts +2 -0
  124. package/types/domain/entities/FileProjectContext.d.ts +5 -0
  125. package/types/domain/entities/View.d.ts +17 -0
  126. package/types/domain/entities/index.d.ts +1 -0
  127. package/types/domain/index.d.ts +2 -0
  128. package/types/domain/usecases/GetViewsUsecase.d.ts +4 -0
  129. package/types/domain/usecases/SaveViewUsecase.d.ts +8 -0
  130. package/types/domain/usecases/index.d.ts +2 -0
  131. package/types/file.d.ts +344 -0
  132. package/types/get-tasks-to-modify.d.ts +3 -0
  133. package/types/index.d.ts +23 -0
  134. package/types/languages.d.ts +649 -0
  135. package/types/list.d.ts +30 -0
  136. package/types/migrate-config.d.ts +1 -0
  137. package/types/mixins/index.d.ts +2 -0
  138. package/types/mixins/repo-fs-store.d.ts +2 -0
  139. package/types/mixins/repo-watched-fs-store.d.ts +2 -0
  140. package/types/plugins/archive-plugin.d.ts +8 -0
  141. package/types/plugins/default-board-actions-plugin.d.ts +9 -0
  142. package/types/plugins/default-board-properties-plugin.d.ts +16 -0
  143. package/types/plugins/default-plugins.d.ts +6 -0
  144. package/types/plugins/epic-plugin.d.ts +19 -0
  145. package/types/plugins/extension-plugin.d.ts +15 -0
  146. package/types/plugins/index.d.ts +9 -0
  147. package/types/plugins/persist-tags-plugin.d.ts +4 -0
  148. package/types/plugins/plugin-manager.d.ts +68 -0
  149. package/types/plugins/plugin-registry.d.ts +1 -0
  150. package/types/project-factory.d.ts +14 -0
  151. package/types/project.d.ts +158 -0
  152. package/types/repository.d.ts +996 -0
  153. package/types/task.d.ts +202 -0
  154. package/types/tools.d.ts +29 -0
  155. package/types/usecases/actions.d.ts +7 -0
  156. package/types/usecases/get-imdone-url.d.ts +1 -0
  157. package/types/usecases/get-project-tags.d.ts +1 -0
  158. package/types/usecases/get-tasks-in-file.d.ts +4 -0
  159. package/types/usecases/index.d.ts +4 -0
  160. 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
+ }
@@ -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
+ }
@@ -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)