imdone-core 1.54.10 → 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 (163) hide show
  1. package/.dependency-cruiser.cjs +412 -0
  2. package/.github/workflows/ci.yml +2 -2
  3. package/.imdoneignore +2 -1
  4. package/README.md +2 -2
  5. package/_index.md +7 -0
  6. package/build.js +57 -0
  7. package/esm-migration.md +446 -0
  8. package/lib/FileProjectContext.js +13 -0
  9. package/lib/ProjectContext.js +19 -18
  10. package/lib/adapters/date-time.js +3 -8
  11. package/lib/adapters/environment.js +3 -0
  12. package/lib/adapters/file-gateway.js +133 -106
  13. package/lib/adapters/git-download.js +36 -16
  14. package/lib/adapters/index.js +9 -0
  15. package/lib/adapters/logger.js +136 -0
  16. package/lib/adapters/markdown.js +31 -19
  17. package/lib/adapters/parsers/DateLanguageParser.js +11 -9
  18. package/lib/adapters/parsers/content-transformer.js +35 -30
  19. package/lib/adapters/parsers/file/LocalFileParserFactory.js +8 -9
  20. package/lib/adapters/parsers/file/ReadStreamCodeParser.js +8 -8
  21. package/lib/adapters/parsers/file/ReadStreamMarkdownParser.js +4 -4
  22. package/lib/adapters/parsers/file/ReadStreamTaskParser.js +5 -3
  23. package/lib/adapters/parsers/file/index.js +4 -0
  24. package/lib/adapters/parsers/function-parser.js +1 -5
  25. package/lib/adapters/parsers/index.js +5 -0
  26. package/lib/adapters/parsers/task/CardContentParser.js +23 -32
  27. package/lib/adapters/parsers/task/CheckStyleTaskParser.js +2 -2
  28. package/lib/adapters/parsers/task/CodeStyleTaskParser.js +2 -2
  29. package/lib/adapters/parsers/task/HashStyleTaskParser.js +3 -3
  30. package/lib/adapters/parsers/task/MarkdownStyleTaskParser.js +2 -2
  31. package/lib/adapters/parsers/task/TaskParser.js +1 -1
  32. package/lib/adapters/parsers/task/index.js +6 -0
  33. package/lib/adapters/storage/config.js +15 -20
  34. package/lib/adapters/storage/index.js +2 -0
  35. package/lib/adapters/storage/tags.js +11 -12
  36. package/lib/adapters/yaml.js +8 -5
  37. package/lib/card.js +25 -26
  38. package/lib/checksum.js +22 -0
  39. package/lib/cli.js +114 -0
  40. package/lib/config.js +106 -71
  41. package/lib/constants.js +21 -50
  42. package/lib/context/ApplicationContext.js +7 -4
  43. package/lib/context/index.js +1 -0
  44. package/lib/default-settings.js +3 -3
  45. package/lib/domain/entities/View.js +4 -11
  46. package/lib/domain/entities/index.js +1 -0
  47. package/lib/domain/index.js +2 -0
  48. package/lib/domain/usecases/GetViewsUsecase.js +6 -12
  49. package/lib/domain/usecases/SaveViewUsecase.js +8 -14
  50. package/lib/domain/usecases/index.js +2 -0
  51. package/lib/file.js +1158 -1162
  52. package/lib/get-tasks-to-modify.js +117 -0
  53. package/lib/index.js +23 -0
  54. package/lib/languages.js +4 -5
  55. package/lib/list.js +46 -95
  56. package/lib/migrate-config.js +5 -5
  57. package/lib/mixins/index.js +2 -0
  58. package/lib/mixins/repo-fs-store.js +224 -289
  59. package/lib/mixins/repo-watched-fs-store.js +158 -147
  60. package/lib/plugins/archive-plugin.js +10 -8
  61. package/lib/plugins/default-board-actions-plugin.js +2 -2
  62. package/lib/plugins/default-board-properties-plugin.js +7 -7
  63. package/lib/plugins/default-plugins.js +7 -0
  64. package/lib/plugins/epic-plugin.js +6 -5
  65. package/lib/plugins/extension-plugin.js +24 -17
  66. package/lib/plugins/index.js +9 -0
  67. package/lib/plugins/persist-tags-plugin.js +4 -3
  68. package/lib/plugins/plugin-manager.js +89 -52
  69. package/lib/plugins/plugin-registry.js +12 -16
  70. package/lib/project-factory.js +21 -24
  71. package/lib/project.js +97 -144
  72. package/lib/repository.js +1323 -1555
  73. package/lib/task.js +562 -580
  74. package/lib/tools.js +39 -113
  75. package/lib/usecases/actions.js +32 -0
  76. package/lib/usecases/get-project-tags.js +3 -12
  77. package/lib/usecases/get-tasks-in-file.js +4 -7
  78. package/lib/usecases/index.js +4 -0
  79. package/package.json +44 -66
  80. package/scripts/delete-markdown-indexes.js +87 -0
  81. package/scripts/generate-index.js +35 -0
  82. package/{index-markdown.js → scripts/index-markdown.js} +7 -7
  83. package/tsconfig.json +15 -0
  84. package/types/FileProjectContext.d.ts +4 -0
  85. package/types/ProjectContext.d.ts +9 -0
  86. package/types/adapters/date-time.d.ts +2 -0
  87. package/types/adapters/environment.d.ts +1 -0
  88. package/types/adapters/file-gateway.d.ts +51 -0
  89. package/types/adapters/git-download.d.ts +1 -0
  90. package/types/adapters/index.d.ts +9 -0
  91. package/types/adapters/logger.d.ts +24 -0
  92. package/types/adapters/markdown.d.ts +13 -0
  93. package/types/adapters/parsers/DateLanguageParser.d.ts +1 -0
  94. package/types/adapters/parsers/content-transformer.d.ts +10 -0
  95. package/types/adapters/parsers/file/LocalFileParserFactory.d.ts +5 -0
  96. package/types/adapters/parsers/file/ReadStreamCodeParser.d.ts +13 -0
  97. package/types/adapters/parsers/file/ReadStreamMarkdownParser.d.ts +7 -0
  98. package/types/adapters/parsers/file/ReadStreamTaskParser.d.ts +19 -0
  99. package/types/adapters/parsers/file/index.d.ts +4 -0
  100. package/types/adapters/parsers/function-parser.d.ts +1 -0
  101. package/types/adapters/parsers/index.d.ts +5 -0
  102. package/types/adapters/parsers/task/CardContentParser.d.ts +45 -0
  103. package/types/adapters/parsers/task/CheckStyleTaskParser.d.ts +12 -0
  104. package/types/adapters/parsers/task/CodeStyleTaskParser.d.ts +14 -0
  105. package/types/adapters/parsers/task/HashStyleTaskParser.d.ts +13 -0
  106. package/types/adapters/parsers/task/MarkdownStyleTaskParser.d.ts +14 -0
  107. package/types/adapters/parsers/task/TaskParser.d.ts +7 -0
  108. package/types/adapters/parsers/task/index.d.ts +6 -0
  109. package/types/adapters/storage/config.d.ts +6 -0
  110. package/types/adapters/storage/index.d.ts +2 -0
  111. package/types/adapters/storage/tags.d.ts +3 -0
  112. package/types/adapters/yaml.d.ts +2 -0
  113. package/types/card.d.ts +166 -0
  114. package/types/checksum.d.ts +8 -0
  115. package/types/config.d.ts +61 -0
  116. package/types/constants.d.ts +46 -0
  117. package/types/context/ApplicationContext.d.ts +24 -0
  118. package/types/context/index.d.ts +1 -0
  119. package/types/default-settings.d.ts +2 -0
  120. package/types/domain/entities/FileProjectContext.d.ts +5 -0
  121. package/types/domain/entities/View.d.ts +17 -0
  122. package/types/domain/entities/index.d.ts +1 -0
  123. package/types/domain/index.d.ts +2 -0
  124. package/types/domain/usecases/GetViewsUsecase.d.ts +4 -0
  125. package/types/domain/usecases/SaveViewUsecase.d.ts +8 -0
  126. package/types/domain/usecases/index.d.ts +2 -0
  127. package/types/file.d.ts +344 -0
  128. package/types/get-tasks-to-modify.d.ts +3 -0
  129. package/types/index.d.ts +23 -0
  130. package/types/languages.d.ts +649 -0
  131. package/types/list.d.ts +30 -0
  132. package/types/migrate-config.d.ts +1 -0
  133. package/types/mixins/index.d.ts +2 -0
  134. package/types/mixins/repo-fs-store.d.ts +2 -0
  135. package/types/mixins/repo-watched-fs-store.d.ts +2 -0
  136. package/types/plugins/archive-plugin.d.ts +8 -0
  137. package/types/plugins/default-board-actions-plugin.d.ts +9 -0
  138. package/types/plugins/default-board-properties-plugin.d.ts +16 -0
  139. package/types/plugins/default-plugins.d.ts +6 -0
  140. package/types/plugins/epic-plugin.d.ts +19 -0
  141. package/types/plugins/extension-plugin.d.ts +15 -0
  142. package/types/plugins/index.d.ts +9 -0
  143. package/types/plugins/persist-tags-plugin.d.ts +4 -0
  144. package/types/plugins/plugin-manager.d.ts +68 -0
  145. package/types/plugins/plugin-registry.d.ts +1 -0
  146. package/types/project-factory.d.ts +14 -0
  147. package/types/project.d.ts +158 -0
  148. package/types/repository.d.ts +996 -0
  149. package/types/task.d.ts +202 -0
  150. package/types/tools.d.ts +29 -0
  151. package/types/usecases/actions.d.ts +7 -0
  152. package/types/usecases/get-imdone-url.d.ts +1 -0
  153. package/types/usecases/get-project-tags.d.ts +1 -0
  154. package/types/usecases/get-tasks-in-file.d.ts +4 -0
  155. package/types/usecases/index.d.ts +4 -0
  156. package/vitest.config.js +13 -0
  157. package/cli.js +0 -74
  158. package/index.js +0 -1
  159. package/lib/adapters/readers/FileSystemProjectReader.js +0 -45
  160. package/lib/context/StreamingApplicationContext.js +0 -31
  161. package/lib/controlers/SaveViewController.js +0 -10
  162. package/lib/domain/entities/FileProjectContext.js +0 -10
  163. package/lib/domain/usecases/OpenProjectUsecase.js +0 -13
@@ -1,194 +1,205 @@
1
- 'use strict'
2
-
3
- var fsStore = require('./repo-fs-store'),
4
- log = require('debug')('imdone-mixins:repo-watched-fs-store'),
5
- File = require('../file'),
6
- constants = require('../constants'),
7
- sane = require('sane')
8
-
9
- module.exports = mixin
1
+ import { fileSystemStoreMixin } from './repo-fs-store.js'
2
+ import debug from 'debug'
3
+ const log = debug('imdone-mixins:repo-watched-fs-store')
4
+ import { File } from '../file.js'
5
+ import { constants } from '../constants.js'
6
+ import chokidar from 'chokidar'
7
+ import realFs from 'fs'
8
+ import { logger } from '../adapters/logger.js'
10
9
 
11
10
  // BACKLOG Only emit file.update if the file checksum has changed
12
11
  // <!--
13
12
  // order:-650
14
13
  // -->
15
- function mixin(repo, fs = require('fs')) {
16
- repo = fsStore(repo, fs)
17
- var _refresh = repo.refresh
18
- var _destroy = repo.destroy
19
- var _init = repo.init
20
- var initializing = false
14
+ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
15
+ repo = fileSystemStoreMixin(repo, fs)
16
+ const _refresh = repo.refresh
17
+ const _destroy = repo.destroy
18
+ const _init = repo.init
19
+ let initializing = false
20
+ let refreshing = false
21
+
22
+ function ready() {
23
+ return !initializing && !refreshing
24
+ }
21
25
 
22
- repo.init = function (cb) {
26
+ async function waitForReady() {
27
+ while (!ready()) {
28
+ logger.log('Waiting for repo to be ready:', repo.path)
29
+ await new Promise(resolve => setTimeout(resolve, 500))
30
+ }
31
+ }
32
+
33
+ // READY Refactor init to async/await
34
+ // #esm-migration #important
35
+ // <!--
36
+ // order:-310
37
+ // -->
38
+ repo.init = async function () {
23
39
  if (initializing) {
24
- const err = new Error("Can't initialize repo while it's initializing.")
25
- console.error(err.message)
26
- return cb ? cb(err) : null
40
+ throw new Error("Can't initialize repo while it's initializing.")
27
41
  }
28
42
  log('Initializing repo:', repo.path)
29
43
  initializing = true
30
- _init.call(repo, function (err, files) {
31
- if (err) {
32
- console.error(`Error initializing repo: ${err.message}`)
33
- initializing = false
34
- return cb ? cb(err) : null
35
- }
36
- repo.initWatcher(() => {
37
- initializing = false
38
- if (cb) cb(err, files)
39
- })
40
- })
44
+ try {
45
+ const files = await _init.call(repo)
46
+ await repo.initWatcher()
47
+ repo.emit('watching', { ok: true, lists: repo.getLists() })
48
+ initializing = false
49
+ return files
50
+ } catch (err) {
51
+ initializing = false
52
+ throw new Error(`Error initializing repo: ${repo.path}`, { cause: err })
53
+ }
41
54
  }
42
55
 
43
- repo.destroy = function () {
44
- if (repo.watcher) repo.watcher.close()
45
- _destroy.apply(repo)
56
+ repo.destroy = async function () {
57
+ if (repo.watcher) await repo.watcher.close()
58
+ await _destroy.apply(repo)
46
59
  }
47
60
 
48
- repo.refresh = function (cb) {
49
- if (initializing) {
50
- return cb ? cb('already initializing') : null
61
+ // READY Refactor refresh to async/await
62
+ // #esm-migration #important
63
+ // <!--
64
+ // order:-330
65
+ // -->
66
+ repo.refresh = async function () {
67
+ await waitForReady()
68
+ log('Refreshing repo:', repo.path)
69
+ refreshing = true
70
+ try {
71
+ const files = await _refresh.call(repo)
72
+ await repo.initWatcher()
73
+ refreshing = false
74
+ return files
75
+ } catch (err) {
76
+ refreshing = false
77
+ throw new Error(`Error refreshing repo: ${repo.path}`, { cause: err })
51
78
  }
52
- console.info('Initializing repo:', repo.path)
53
- initializing = true
54
- if (repo.watcher) repo.watcher.close()
55
- _refresh.call(repo, function (err, files) {
56
- if (err) {
57
- initializing = false
58
- return cb ? cb(err) : null
59
- }
60
- repo.initWatcher(() => {
61
- initializing = false
62
- return cb ? cb(err, files) : null
63
- })
64
- })
79
+
65
80
  }
66
81
 
67
- var _isImdoneConfig = function (path) {
82
+ function _isImdoneConfig(path) {
68
83
  return path === constants.CONFIG_FILE_YML
69
84
  }
70
85
 
71
- var _isImdoneIgnore = function (path) {
86
+ function _isImdoneIgnore(path) {
72
87
  return path === constants.IGNORE_FILE
73
88
  }
74
89
 
75
- const onConfigChange = function (file) {
76
- console.info('Loading config. Observed a change to:', file)
90
+ async function onConfigChange(file) {
91
+ logger.info('Loading config. Observed a change to:', file)
77
92
  const label = `Refresh repo: ${repo.path}`
78
- console.time(label)
79
- repo.refresh((err, files) => {
80
- if (err) console.error('Error refreshing repo', err)
81
- console.timeEnd(label)
93
+ logger.time(label)
94
+ try {
95
+ await repo.refresh()
82
96
  repo.emitConfigUpdate(file, repo.config)
83
- })
97
+ } finally {
98
+ logger.timeEnd(label)
99
+ }
84
100
  }
85
101
 
86
102
  const onIgnoreChange = onConfigChange
87
103
 
88
- repo.initWatcher = function (cb) {
89
- console.log('initializing watcher for:', repo.path)
90
- repo.watcher = sane(repo.path, {
91
- dot: true,
92
- ignored(file) {
93
- if (!initializing && _isImdoneConfig(file)) {
94
- onConfigChange(file)
95
- }
96
-
97
- if (!initializing && _isImdoneIgnore(file)) {
98
- onIgnoreChange(file)
99
- }
100
-
101
- const ignore = !repo.shouldInclude(file)
102
- if (!ignore || /^.*\.(jpg|gif|pdf|png)$/i.test(file)) {
103
- repo.addFilePath(file)
104
- }
105
- return ignore
106
- },
107
- })
108
-
109
- repo.watcher
110
- .on('error', (err) => {
111
- console.error('Error in watcher')
112
- console.error(err)
113
- cb(err)
114
- })
115
- .on('ready', () => {
116
- console.log('watcher ready for:', repo.path)
117
- initializing = false
118
- cb()
119
- })
120
- .on('add', function (path, root, stat) {
121
- console.log('Watcher received add event for file: ' + path)
122
- if (stat.isDirectory()) return
123
- var file = repo.getFile(path)
124
- if (file === undefined) {
125
- log('Creating file: ' + path)
126
- file = new File({
127
- repoId: repo.getId(),
128
- filePath: path,
129
- languages: repo.languages,
130
- project: repo.project,
131
- })
104
+ // READY Refactor initWatcher to async/await
105
+ // #esm-migration #important
106
+ // <!--
107
+ // order:-320
108
+ // defer:2025-03-18
109
+ // -->
110
+ repo.initWatcher = async () => {
111
+ return new Promise(async (resolve, reject) => {
112
+ logger.log('initializing watcher for:', repo.path)
113
+ repo.watcher = chokidar.watch(repo.path, {
114
+ persistent: true,
115
+ usePolling: false,
116
+ alwaysStat: true,
117
+ awaitWriteFinish: true,
118
+ atomic: true,
119
+ ignoreInitial: true,
120
+ ignored: (file) => {
121
+ const ignored = !repo.shouldInclude(file)
122
+ if (ignored) logger.log('Ignoring file:', file)
123
+ return ignored
132
124
  }
125
+ }).on('error', (err) => {
126
+ logger.error('Error in watcher')
127
+ logger.error(err)
128
+ repo.emit('watch.error', err)
129
+ reject(err)
130
+ })
131
+ .on('ready', () => {
132
+ logger.log('watcher ready for:', repo.path)
133
+ initializing = false
134
+ resolve()
135
+ })
136
+ .on('add', async function (path, stat) {
137
+ logger.log('Watcher received add event for file: ' + path)
138
+ if (stat.isDirectory()) return
139
+ let file = repo.getFile(path)
140
+ if (file === undefined) {
141
+ log('Creating file: ' + path)
142
+ file = new File({
143
+ repoId: repo.getId(),
144
+ filePath: path,
145
+ languages: repo.languages,
146
+ project: repo.project,
147
+ })
148
+ }
133
149
 
134
- repo.fileOK(file, function (err, stat) {
150
+ stat = await repo.fileOK()
135
151
  log('fileOK returned: ' + JSON.stringify(stat))
136
- if (err || !stat) return
137
152
  if (stat.mtime <= file.getModifiedTime()) {
138
153
  return log('File update already applied. Change ignored for file: ' + path)
139
154
  }
140
155
  log('Reading file: ' + path)
141
- repo.readFile(file, function (err, file) {
142
- repo.emitFileUpdate(file)
143
- })
156
+ file = await repo.readFile(file)
157
+ repo.emi('watch.add', file)
158
+ repo.emitFileUpdate(file)
144
159
  })
145
- })
146
- .on('change', function (path, root, stat) {
147
- console.log(
148
- `Watcher received change event for file: ${path} repoPath: ${repo.path}`,
149
- stat.mtime
150
- )
151
- if (!path || stat.isDirectory()) return
152
- var file = repo.getFile(path) || path
153
- const isFile = File.isFile(file)
154
- // BACKLOG ## Handle the case where the file is not in the repo
155
- // #urgent #1.12.0
156
- // <!--
157
- // order:-660
158
- // -->
159
- if (isFile && stat.mtime <= file.getModifiedTime()) {
160
- // console.log("File update already applied. Change ignored.")
161
- return
162
- }
163
- if (_isImdoneConfig(path)) return onConfigChange(path)
164
- if (_isImdoneIgnore(path)) return onIgnoreChange(path)
165
-
166
- repo.fileOK((file && file.path) || path, function (err, ok) {
167
- if (err) {
168
- console.error('Error processing ignore on path: ', path, err)
160
+ .on('change', async function (path, stat) {
161
+ logger.log(
162
+ `Watcher received change event for file: ${path} repoPath: ${repo.path}`,
163
+ stat.mtime
164
+ )
165
+ if (!path || stat.isDirectory()) return
166
+ var file = repo.getFile(path) || path
167
+ const isFile = File.isFile(file)
168
+ // BACKLOG ## Handle the case where the file is not in the repo
169
+ // #urgent #1.12.0
170
+ // <!--
171
+ // order:-660
172
+ // -->
173
+ if (isFile && stat.mtime <= file.getModifiedTime()) {
174
+ // logger.log("File update already applied. Change ignored.")
169
175
  return
170
176
  }
177
+ if (_isImdoneConfig(path)) return onConfigChange(path)
178
+ if (_isImdoneIgnore(path)) return onIgnoreChange(path)
179
+
180
+ const ok = await repo.fileOK((file && file.path) || path)
171
181
  if (!ok) return
172
182
  log('Reading file: ' + path)
173
183
  if (!isFile) file = repo.getFile(path)
174
- repo.readFile(file, function (err, file) {
175
- repo.emitFileUpdate(file)
176
- })
184
+ file = await repo.readFile(file)
185
+ repo.emit('watch.change', file)
186
+ repo.emitFileUpdate(file)
177
187
  })
178
- })
179
- .on('delete', function (path) {
180
- log('Watcher received unlink event for file: ' + path)
181
- repo.removeFilePath(path)
182
- var file = new File({
183
- repoId: repo.getId(),
184
- filePath: path,
185
- languages: repo.languages,
186
- project: repo.project,
188
+ .on('delete', async function (path) {
189
+ log('Watcher received unlink event for file: ' + path)
190
+ repo.removeFilePath(path)
191
+ var file = new File({
192
+ repoId: repo.getId(),
193
+ filePath: path,
194
+ languages: repo.languages,
195
+ project: repo.project,
196
+ })
197
+ log('Removing file: ' + path)
198
+ repo.removeFile(file)
199
+ repo.emit('watch.delete', file)
200
+ repo.emitFileUpdate(file, true)
187
201
  })
188
- log('Removing file: ' + path)
189
- repo.removeFile(file)
190
- repo.emitFileUpdate(file, true)
191
- })
202
+ });
192
203
  }
193
204
 
194
205
  return repo
@@ -1,8 +1,8 @@
1
- const Plugin = require('imdone-api')
2
- const path = require('path')
3
- const { getRawTask } = require('../adapters/parsers/task/CardContentParser')
1
+ import Plugin from 'imdone-api'
2
+ import path from 'path'
3
+ import { getRawTask } from '../adapters/parsers/task/CardContentParser.js'
4
4
 
5
- module.exports = class ArchivePlugin extends Plugin {
5
+ export default class ArchivePlugin extends Plugin {
6
6
  constructor(project) {
7
7
  super(project)
8
8
  }
@@ -29,7 +29,9 @@ module.exports = class ArchivePlugin extends Plugin {
29
29
  if (messageUser) this.project.snackBar({message: `Archiving ${cards.length} card(s)...`})
30
30
  }
31
31
 
32
- cards.forEach(card => this.archiveTask(card))
32
+ for (const card of cards) {
33
+ await this.archiveTask(card)
34
+ }
33
35
 
34
36
  if (messageUser) this.project.snackBar({message: ` Done archiving ${cards.length} card(s). Deleting original(s)...`})
35
37
  await this.project.deleteTasks(cards)
@@ -39,7 +41,7 @@ module.exports = class ArchivePlugin extends Plugin {
39
41
 
40
42
  }
41
43
 
42
- archiveTask (task, config = this.config) {
44
+ async archiveTask (task, config = this.config) {
43
45
  const archiveFolder = config.archiveFolder
44
46
  const fileDir = path.dirname(task.relPath)
45
47
 
@@ -63,8 +65,8 @@ module.exports = class ArchivePlugin extends Plugin {
63
65
  const taskStart = getRawTask({tokenPrefix, beforeText, list, text: ''})
64
66
  const taskContent = `${taskStart} ${content}\n\n\n`
65
67
 
66
- this.fileGateway.preparePathForWriting(newPath)
67
- this.fileGateway.appendFileSync(newPath, taskContent)
68
+ await this.fileGateway.preparePathForWriting(newPath)
69
+ await this.fileGateway.appendFileSync(newPath, taskContent)
68
70
  }
69
71
 
70
72
  }
@@ -1,6 +1,6 @@
1
- const Plugin = require('imdone-api')
1
+ import Plugin from 'imdone-api'
2
2
 
3
- module.exports = class DefaultBoardActionsPlugin extends Plugin {
3
+ export default class DefaultBoardActionsPlugin extends Plugin {
4
4
  constructor(project) {
5
5
  super(project)
6
6
  }
@@ -1,6 +1,6 @@
1
- const Plugin = require('imdone-api')
2
- const {getIsoDateWithOffset} = require('../adapters/date-time')
3
- const path = require('path')
1
+ import Plugin from 'imdone-api'
2
+ import { getIsoDateWithOffset } from '../adapters/date-time.js'
3
+ import path from 'path'
4
4
 
5
5
  const simpleTemplate = '\n<!--\ncreated:${timestamp}\n-->\n'
6
6
 
@@ -13,7 +13,7 @@ function flattenObject(object) {
13
13
  }, {});
14
14
  }
15
15
 
16
- module.exports = class DefaultBoardPropertiesPlugin extends Plugin {
16
+ export default class DefaultBoardPropertiesPlugin extends Plugin {
17
17
  constructor(project) {
18
18
  super(project)
19
19
  this.templates = {}
@@ -66,11 +66,11 @@ module.exports = class DefaultBoardPropertiesPlugin extends Plugin {
66
66
 
67
67
 
68
68
  async getTemplates() {
69
- const { preparePathForWriting, readdir, readFile, stat } = this.project.fileGateway;
69
+ const { preparePathForWriting, readdir, readFile, stat, exists } = this.project.fileGateway;
70
70
  const templateDir = path.join(this.project.configDir, 'templates');
71
71
  const githubDir = path.join(this.project.path, '.github');
72
72
 
73
- preparePathForWriting(templateDir);
73
+ await preparePathForWriting(templateDir, true);
74
74
 
75
75
  const readMarkdownFiles = async (dir, prefix = '') => {
76
76
  const files = await readdir(dir);
@@ -92,7 +92,7 @@ module.exports = class DefaultBoardPropertiesPlugin extends Plugin {
92
92
  };
93
93
 
94
94
  const templatesFromTemplateDir = await readMarkdownFiles(templateDir);
95
- const templatesFromGithubDir = await stat(githubDir)
95
+ const templatesFromGithubDir = await exists(githubDir)
96
96
  ? await readMarkdownFiles(githubDir, 'github_')
97
97
  : {};
98
98
 
@@ -0,0 +1,7 @@
1
+ export * as ArchivePlugin from './archive-plugin.js'
2
+ export * as DefaultBoardActionsPlugin from './default-board-actions-plugin.js'
3
+ export * as DefaultBoardPropertiesPlugin from './default-board-properties-plugin.js'
4
+ export * as EpicPlugin from './epic-plugin.js'
5
+ export * as PersistTagsPlugin from './persist-tags-plugin.js'
6
+ export * as ExtensionPlugin from './extension-plugin.js'
7
+
@@ -1,4 +1,5 @@
1
- const Plugin = require('imdone-api')
1
+ import Plugin from 'imdone-api'
2
+ import { logger } from '../adapters/logger.js'
2
3
 
3
4
  function getIsEpicMeta(task) {
4
5
  return task.allMeta && task.allMeta['is-epic'] && task.allMeta['is-epic'][0]
@@ -8,7 +9,7 @@ function getEpicMeta(task) {
8
9
  return task.allMeta && task.allMeta['epic'] && task.allMeta['epic'][0]
9
10
  }
10
11
 
11
- module.exports = class EpicPlugin extends Plugin {
12
+ export default class EpicPlugin extends Plugin {
12
13
  constructor(project) {
13
14
  super(project)
14
15
  this.epics = {}
@@ -20,13 +21,13 @@ module.exports = class EpicPlugin extends Plugin {
20
21
 
21
22
  onBoardUpdate(lists) {
22
23
  // this html is getting initialized before onBoardUpdate
23
- console.log(
24
+ logger.log(
24
25
  `${this.project.name} epics found:`,
25
26
  Object.keys(this.epics).length
26
27
  )
27
- console.time(`${this.project.name} Epic updates`)
28
+ logger.time(`${this.project.name} Epic updates`)
28
29
  this.updateCardMD(lists)
29
- console.timeEnd(`${this.project.name} Epic updates`)
30
+ logger.timeEnd(`${this.project.name} Epic updates`)
30
31
  }
31
32
 
32
33
  onTaskUpdate(task) {
@@ -1,31 +1,39 @@
1
- const Plugin = require('imdone-api')
2
- const _path = require('path')
3
- const { statSync } = require('fs')
1
+ import Plugin from 'imdone-api'
2
+ import _path from 'path'
3
+ import { exists } from '../adapters/file-gateway.js'
4
+ import { createRequire } from 'node:module';
5
+ import { logger } from '../adapters/logger.js';
4
6
 
5
- module.exports = class ExtensionPlugin extends Plugin {
7
+ const require = createRequire(import.meta.url);
8
+ const url = new URL(import.meta.url)
9
+ const __dirname = _path.dirname(url.pathname)
10
+
11
+ export default class ExtensionPlugin extends Plugin {
6
12
  constructor(project) {
7
13
  super(project)
8
- console.log('loading extensions')
14
+ logger.log('loading extensions')
9
15
  this.configDir = _path.join(project.path, '.imdone')
16
+ }
10
17
 
11
- this.cardActionsFunction = this.loadExtensionModule(
18
+ async init() {
19
+ this.cardActionsFunction = await this.loadExtensionModule(
12
20
  () => [],
13
21
  'actions',
14
22
  'card'
15
23
  )
16
- this.boardActionsFunction = this.loadExtensionModule(
24
+ this.boardActionsFunction = await this.loadExtensionModule(
17
25
  () => [],
18
26
  'actions',
19
27
  'board'
20
28
  )
21
- this.cardPropertiesFunction = this.loadExtensionModule(
29
+ this.cardPropertiesFunction = await this.loadExtensionModule(
22
30
  () => {
23
31
  return {}
24
32
  },
25
33
  'properties',
26
34
  'card'
27
35
  )
28
- this.boardPropertiesFunction = this.loadExtensionModule(
36
+ this.boardPropertiesFunction = await this.loadExtensionModule(
29
37
  () => {
30
38
  return {}
31
39
  },
@@ -33,7 +41,6 @@ module.exports = class ExtensionPlugin extends Plugin {
33
41
  'board'
34
42
  )
35
43
  }
36
-
37
44
  getCardProperties(task) {
38
45
  return this.cardPropertiesFunction(task)
39
46
  }
@@ -57,26 +64,26 @@ module.exports = class ExtensionPlugin extends Plugin {
57
64
  }
58
65
 
59
66
  getConfigPath(relativePath) {
60
- return _path.join(this.configDir, ...relativePath)
67
+ return _path.resolve(_path.join(this.configDir, ...relativePath) + '.js')
61
68
  }
62
69
 
63
- loadExtensionModule(_default, ...path) {
70
+ async loadExtensionModule(_default, ...path) {
64
71
  let extension = _default
65
72
  const extensionPath = this.getConfigPath(path)
66
73
  try {
67
- statSync(extensionPath + '.js')
68
- delete require.cache[require.resolve(extensionPath)]
74
+ await exists(extensionPath)
75
+ delete require.cache[extensionPath]
69
76
  extension = require(extensionPath)
70
77
  } catch (e) {
71
78
  if (e.code === 'ENOENT') {
72
- console.log('No extension found at:', extensionPath)
79
+ logger.log('No extension found at:', extensionPath)
73
80
  } else {
74
- console.error(e)
81
+ logger.warn('Error loading extension:', e.message)
75
82
  }
76
83
  }
77
84
 
78
85
  if (typeof extension !== 'function') {
79
- console.warn(
86
+ logger.warn(
80
87
  `${extensionPath} does not export a function. Using default empty function. ${_default.toString()}`
81
88
  )
82
89
  extension = _default
@@ -0,0 +1,9 @@
1
+ export * from './archive-plugin.js';
2
+ export * from './default-board-actions-plugin.js';
3
+ export * from './default-board-properties-plugin.js';
4
+ export * from './default-plugins.js';
5
+ export * from './epic-plugin.js';
6
+ export * from './extension-plugin.js';
7
+ export * from './persist-tags-plugin.js';
8
+ export * from './plugin-manager.js';
9
+ export * from './plugin-registry.js';
@@ -1,7 +1,8 @@
1
- const Plugin = require('imdone-api')
2
- const { save } = require('../adapters/storage/tags.js')
1
+ import Plugin from 'imdone-api'
2
+ import { save } from '../adapters/storage/tags.js'
3
3
 
4
- module.exports = class PersistTagsPlugin extends Plugin {
4
+ export default class PersistTagsPlugin extends Plugin {
5
+
5
6
  constructor(project) {
6
7
  super(project)
7
8
  }