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/tools.js ADDED
@@ -0,0 +1,176 @@
1
+ import _isFunction from 'lodash.isfunction'
2
+ import _noop from 'lodash.noop'
3
+ import crypto from 'crypto'
4
+ import _path from 'path'
5
+ import { sort } from 'fast-sort'
6
+ import eol from 'eol'
7
+ import escapeRegExp from 'escape-string-regexp'
8
+
9
+ const max_bytes = 512
10
+
11
+ function isBinaryCheck(bytes, size) {
12
+ if (size === 0) return false
13
+
14
+ var suspicious_bytes = 0
15
+ var total_bytes = Math.min(size, max_bytes)
16
+
17
+ if (size >= 3 && bytes[0] == 0xef && bytes[1] == 0xbb && bytes[2] == 0xbf) {
18
+ // UTF-8 BOM. This isn't binary.
19
+ return false
20
+ }
21
+
22
+ for (var i = 0; i < total_bytes; i++) {
23
+ if (bytes[i] === 0) {
24
+ // NULL byte--it's binary!
25
+ return true
26
+ } else if (
27
+ (bytes[i] < 7 || bytes[i] > 14) &&
28
+ (bytes[i] < 32 || bytes[i] > 127)
29
+ ) {
30
+ // UTF-8 detection
31
+ if (bytes[i] > 191 && bytes[i] < 224 && i + 1 < total_bytes) {
32
+ i++
33
+ if (bytes[i] < 192) {
34
+ continue
35
+ }
36
+ } else if (bytes[i] > 223 && bytes[i] < 239 && i + 2 < total_bytes) {
37
+ i++
38
+ if (bytes[i] < 192 && bytes[i + 1] < 192) {
39
+ i++
40
+ continue
41
+ }
42
+ }
43
+ suspicious_bytes++
44
+ // Read at least 32 bytes before making a decision
45
+ if (i > 32 && (suspicious_bytes * 100) / total_bytes > 10) {
46
+ return true
47
+ }
48
+ }
49
+ }
50
+
51
+ if ((suspicious_bytes * 100) / total_bytes > 10) {
52
+ return true
53
+ }
54
+
55
+ return false
56
+ }
57
+
58
+ function deepEqual(a, b) {
59
+ if (a === b) return true; // Same reference
60
+
61
+ if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) {
62
+ return false; // Different types or one is null
63
+ }
64
+
65
+ if (Array.isArray(a) !== Array.isArray(b)) return false; // One is array, one is object
66
+
67
+ const keysA = Object.keys(a);
68
+ const keysB = Object.keys(b);
69
+ if (keysA.length !== keysB.length) return false; // Different number of keys
70
+
71
+ return keysA.every((key) => keysB.includes(key) && deepEqual(a[key], b[key]));
72
+ }
73
+
74
+ export const tools = {
75
+ union(...arrays) {
76
+ return [...new Set(arrays.flat())];
77
+ },
78
+ escapeRegExp(str) {
79
+ return escapeRegExp(str)
80
+ },
81
+ userHome() {
82
+ return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE
83
+ },
84
+ deepEqual,
85
+ /**
86
+ * Description
87
+ * @method user
88
+ * @return LogicalExpression
89
+ */
90
+ user() {
91
+ return process.env.USER || process.env.USERNAME
92
+ },
93
+
94
+ /**
95
+ * Description
96
+ * @method cb
97
+ * @param {} cb
98
+ * @return ConditionalExpression
99
+ */
100
+ cb(cb) {
101
+ return _isFunction(cb) ? cb : _noop
102
+ },
103
+
104
+ inMixinsNoop(cb) {
105
+ cb = this.cb(cb)
106
+ if (cb) return cb(new Error('Implemented in mixins'))
107
+ throw new Error('Implemented in mixins')
108
+ },
109
+
110
+ /**
111
+ * Description
112
+ * @method sha
113
+ * @param {} data
114
+ * @return CallExpression
115
+ */
116
+ sha: function (data) {
117
+ var shasum = crypto.createHash('sha1')
118
+ shasum.update(data)
119
+ return shasum.digest('hex')
120
+ },
121
+
122
+ /**
123
+ * Description
124
+ * @method format
125
+ * @param {} template
126
+ * @param {} col
127
+ * @return CallExpression
128
+ */
129
+ format: function (template, col) {
130
+ col =
131
+ typeof col === 'object' ? col : Array.prototype.slice.call(arguments, 2)
132
+
133
+ return template.replace(/\{\{|\}\}|\{(\w+)\}/g, function (m, n) {
134
+ if (m == '{{') {
135
+ return '{'
136
+ }
137
+ if (m == '}}') {
138
+ return '}'
139
+ }
140
+ return col[n]
141
+ })
142
+ },
143
+
144
+ isBinaryFile: function (fs, file, callback) {
145
+ fs.exists(file, function (exists) {
146
+ if (!exists) return callback(null, false)
147
+
148
+ fs.open(file, 'r', function (err, descriptor) {
149
+ if (err) return callback(err)
150
+ var bytes = new Buffer(max_bytes)
151
+ // Read the file with no encoding for raw buffer access.
152
+ fs.read(
153
+ descriptor,
154
+ bytes,
155
+ 0,
156
+ bytes.length,
157
+ 0,
158
+ function (err, size, bytes) {
159
+ fs.close(descriptor, function (err2) {
160
+ if (err || err2) return callback(err || err2)
161
+ return callback(null, isBinaryCheck(bytes, size))
162
+ })
163
+ }
164
+ )
165
+ })
166
+ })
167
+ },
168
+
169
+ isBinaryCheck: isBinaryCheck,
170
+ sortTasks(tasks) {
171
+ return sort(tasks).asc([u => u.order, u => u.text])
172
+ },
173
+ hasBlankLines(content) {
174
+ return new RegExp(`^\\s*${String(eol.auto)}`, 'gm').test(content)
175
+ },
176
+ }
@@ -0,0 +1,32 @@
1
+ import { createFileSystemProject } from '../project-factory.js';
2
+ import { load } from '../adapters/storage/config.js';
3
+ import { logger } from '../adapters/logger.js';
4
+
5
+ /**
6
+ * Initializes and returns a project instance.
7
+ * @param {string} projectPath - The path to the project.
8
+ * @param {string} configPath - The path to the configuration file.
9
+ * @returns {Promise<Object>} - The initialized project instance.
10
+ */
11
+ async function initializeProject(projectPath, configPath) {
12
+ const path = projectPath;
13
+ const config = await load(projectPath, configPath);
14
+ const project = createFileSystemProject({ path, config });
15
+ await project.init();
16
+ await project.toImdoneJSON();
17
+
18
+ return project;
19
+ }
20
+
21
+ export async function executeBoardAction({ projectPath, configPath, task, action }) {
22
+ const project = await initializeProject(projectPath, configPath);
23
+ const file = task && project.getFile(task.filePath);
24
+ const activeTask = file && task.line > -1 && file.getTaskAtLine(task.line);
25
+ await project.performBoardAction(action, activeTask);
26
+ }
27
+
28
+ export async function listAvailableActions(projectPath, configPath, plugin) {
29
+ const project = await initializeProject(projectPath, configPath);
30
+ logger.log('\nAvailable actions:');
31
+ logger.log(JSON.stringify(project.boardActions, null, 2));
32
+ }
@@ -0,0 +1,6 @@
1
+ // TODO Add a function that returns the imdone url for vscode and obsidian plugins
2
+ // <!--
3
+ // created:2025-01-11T20:20:08.348Z
4
+ // sid:wmr_a0ikOY39kInkmudPa
5
+ // order:-110
6
+ // -->
@@ -0,0 +1,7 @@
1
+ import { load } from '../adapters/storage/tags.js'
2
+ import { findImdonePath } from '../adapters/storage/config.js'
3
+
4
+ export async function getTags(filePath) {
5
+ const projectPath = await findImdonePath(filePath)
6
+ return await load(projectPath)
7
+ }
@@ -0,0 +1,26 @@
1
+ import { loadForFilePath } from '../adapters/storage/config.js';
2
+ import { getFileParser } from '../adapters/parsers/file/LocalFileParserFactory.js';
3
+ import { Readable } from 'node:stream';
4
+
5
+
6
+ export async function getTasks({filePath, content}) {
7
+ const config = await loadForFilePath(filePath)
8
+
9
+ const readStream = new Readable({
10
+ read() {
11
+ this.push(content);
12
+ this.push(null);
13
+ }
14
+ });
15
+
16
+ const parser = await getFileParser(filePath, config, readStream)
17
+
18
+ const tasks = []
19
+ let task = true
20
+ while (task) {
21
+ task = await parser.readTask()
22
+ if (task) tasks.push(task)
23
+ }
24
+ parser.close()
25
+ return tasks
26
+ }
@@ -0,0 +1,4 @@
1
+ export * from './actions.js';
2
+ export * from './get-imdone-url.js';
3
+ export * from './get-project-tags.js';
4
+ export * from './get-tasks-in-file.js';
package/package.json CHANGED
@@ -1,23 +1,19 @@
1
1
  {
2
2
  "name": "imdone-core",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "imdone-core",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/imdone/imdone-core.git"
8
8
  },
9
9
  "main": "lib/index.js",
10
- "module": "lib/index.js",
11
10
  "types": "types/index.d.ts",
12
- "files": [
13
- "dist"
14
- ],
15
11
  "type": "module",
16
12
  "bin": {
17
13
  "imdone-cli": "lib/cli.js"
18
14
  },
19
15
  "scripts": {
20
- "prepublishOnly": "npm run build:index && npm run build",
16
+ "prepublishOnly": "npm run build",
21
17
  "build": "npm run build:docs && npm run build:docs:index && npm run coverage && npm run build:index && npm run build:types",
22
18
  "build:docs": "doctoc --github --notitle README.md",
23
19
  "build:docs:index": "node scripts/index-markdown.js",
@@ -0,0 +1,87 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ // Get the current directory name in ESM
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ const sidebar = '_index.md';
10
+
11
+ function getMarkdownFiles(files = []) {
12
+ return files.filter(file => file.endsWith('.md') && file !== sidebar && file !== '_navbar.md');
13
+ }
14
+
15
+ function getFileLinks(files) {
16
+ return files.map(file => `- [${file.replace('.md', '')}](${file})`).join('\n');
17
+ }
18
+
19
+ function getSubDirLinks(files, directory) {
20
+ const subDirs = files.filter(file => fs.statSync(path.join(directory, file)).isDirectory());
21
+ const subDirsContainingMarkdown = subDirs.filter(subDir => fs.readdirSync(path.join(directory, subDir)).find(file => file.endsWith('.md')));
22
+ return subDirsContainingMarkdown.map(subDir => {
23
+ const resource = fs.readdirSync(path.join(directory, subDir)).find(file => file.toLowerCase() === 'readme.md')
24
+ ? 'README'
25
+ : sidebar;
26
+ return `- [:file_folder: **${subDir}**](${subDir}/${resource})`;
27
+ }).join('\n');
28
+ }
29
+
30
+ function getBreadCrumb(parentDir) {
31
+ const homeLink = '[:house: **Home**](/README)';
32
+ return parentDir ? `- ${homeLink}\n- [:arrow_heading_up: **Parent Directory**](${parentDir}${sidebar})` : '';
33
+ }
34
+
35
+ function createIndexes(directory, parentDir, title) {
36
+ const basename = path.basename(directory);
37
+ if (basename.startsWith('.')) {
38
+ return;
39
+ }
40
+
41
+ title = title || basename;
42
+
43
+ const files = fs.readdirSync(directory);
44
+ const markdownFiles = getMarkdownFiles(files);
45
+
46
+ if (markdownFiles.length > 0) {
47
+ const subDirLinks = getSubDirLinks(files, directory);
48
+ const fileLinks = getFileLinks(markdownFiles);
49
+ const breadcrumb = getBreadCrumb(parentDir);
50
+
51
+ fs.writeFileSync(path.join(directory, sidebar), `# ${title}\n${breadcrumb}\n${subDirLinks}\n${fileLinks}\n`);
52
+ }
53
+
54
+ files
55
+ .filter(file => fs.statSync(path.join(directory, file)).isDirectory())
56
+ .forEach(subDir => createIndexes(path.join(directory, subDir), parentDir ? path.join(parentDir, basename) + '/' : '/'));
57
+ }
58
+
59
+ createIndexes(process.cwd(), undefined, 'imdone-core');
60
+ console.log('Indexes created successfully!');
61
+
62
+ function deleteIndexFiles(dir) {
63
+ // Read the directory and filter for _index.md files
64
+ const files = fs.readdirSync(dir);
65
+
66
+ files.forEach(file => {
67
+ const filePath = path.join(dir, file);
68
+ const stat = fs.statSync(filePath);
69
+
70
+ // If it's a file and matches the _index.md pattern, delete it
71
+ if (stat.isFile() && file === '_index.md') {
72
+ console.log(`Deleting file: ${filePath}`);
73
+ fs.unlinkSync(filePath);
74
+ }
75
+
76
+ // If it's a directory, recurse
77
+ if (stat.isDirectory()) {
78
+ deleteIndexFiles(filePath);
79
+ }
80
+ });
81
+ }
82
+
83
+ // Path to your test directory
84
+ const testDirectory = path.join(__dirname, '..', 'test');
85
+
86
+ // Call the function to delete _index.md files
87
+ deleteIndexFiles(testDirectory);
@@ -0,0 +1,35 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ const LIB_DIR = './lib';
5
+
6
+ // Recursively generates index.js files
7
+ function generateIndexes(dir) {
8
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
9
+
10
+ const files = entries
11
+ .filter(entry => entry.isFile() && entry.name !== 'index.js' && entry.name !== 'cli.js' && entry.name.endsWith('.js'))
12
+ .map(entry => `export * from './${entry.name}';`);
13
+
14
+ const subdirs = entries
15
+ .filter(entry => entry.isDirectory() && entry.name !== '__tests__')
16
+ .map(entry => entry.name);
17
+
18
+ // Generate index.js in each subdirectory
19
+ subdirs.forEach(subdir => generateIndexes(path.join(dir, subdir)));
20
+
21
+ // Add namespace exports for subdirectories
22
+ const namespaceExports = subdirs.map(subdir => `export * as ${subdir} from './${subdir}/index.js';`);
23
+
24
+ // Write the index.js file
25
+ if (files.length || namespaceExports.length) {
26
+ const indexPath = path.join(dir, 'index.js');
27
+ const content = [...files, ...namespaceExports].join('\n') + '\n';
28
+ fs.writeFileSync(indexPath, content);
29
+ console.log(`Generated: ${indexPath}`);
30
+ }
31
+ }
32
+
33
+ // Run the script
34
+ generateIndexes(LIB_DIR);
35
+ console.log('✅ Index files generated successfully!');
@@ -0,0 +1,55 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ const sidebar = '_index.md';
5
+
6
+ function getMarkdownFiles(files = []) {
7
+ return files.filter(file => file.endsWith('.md') && file !== sidebar && file !== '_navbar.md');
8
+ }
9
+
10
+ function getFileLinks(files) {
11
+ return files.map(file => `- [${file.replace('.md', '')}](${file})`).join('\n');
12
+ }
13
+
14
+ function getSubDirLinks(files, directory) {
15
+ const subDirs = files.filter(file => fs.statSync(path.join(directory, file)).isDirectory());
16
+ const subDirsContainingMarkdown = subDirs.filter(subDir => fs.readdirSync(path.join(directory, subDir)).find(file => file.endsWith('.md')));
17
+ return subDirsContainingMarkdown.map(subDir => {
18
+ const resource = fs.readdirSync(path.join(directory, subDir)).find(file => file.toLowerCase() === 'readme.md')
19
+ ? 'README'
20
+ : sidebar;
21
+ return `- [:file_folder: **${subDir}**](${subDir}/${resource})`;
22
+ }).join('\n');
23
+ }
24
+
25
+ function getBreadCrumb(parentDir) {
26
+ const homeLink = '[:house: **Home**](/README)';
27
+ return parentDir ? `- ${homeLink}\n- [:arrow_heading_up: **Parent Directory**](${parentDir}${sidebar})` : '';
28
+ }
29
+
30
+ function createIndexes(directory, parentDir, title) {
31
+ const basename = path.basename(directory);
32
+ if (basename.startsWith('.') || basename === 'test') {
33
+ return;
34
+ }
35
+
36
+ title = title || basename;
37
+
38
+ const files = fs.readdirSync(directory);
39
+ const markdownFiles = getMarkdownFiles(files);
40
+
41
+ if (markdownFiles.length > 0) {
42
+ const subDirLinks = getSubDirLinks(files, directory);
43
+ const fileLinks = getFileLinks(markdownFiles);
44
+ const breadcrumb = getBreadCrumb(parentDir);
45
+
46
+ fs.writeFileSync(path.join(directory, sidebar), `# ${title}\n${breadcrumb}\n${subDirLinks}\n${fileLinks}\n`);
47
+ }
48
+
49
+ files
50
+ .filter(file => fs.statSync(path.join(directory, file)).isDirectory())
51
+ .forEach(subDir => createIndexes(path.join(directory, subDir), parentDir ? path.join(parentDir, basename) + '/' : '/'));
52
+ }
53
+
54
+ createIndexes(process.cwd(), undefined, 'imdone-core');
55
+ console.log('Indexes created successfully!');
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "declaration": true,
4
+ "emitDeclarationOnly": true,
5
+ "allowJs": true,
6
+ "outDir": "types",
7
+ "module": "NodeNext",
8
+ "moduleResolution": "NodeNext",
9
+ "target": "ESNext",
10
+ "esModuleInterop": true,
11
+ "strict": true
12
+ },
13
+ "include": ["lib/**/index.js"],
14
+ "exclude": ["node_modules", "__tests__"]
15
+ }
@@ -0,0 +1,4 @@
1
+ export class FileProjectContext {
2
+ getOrder(list: any, order: any): number | undefined;
3
+ getProject(): void;
4
+ }
@@ -0,0 +1,9 @@
1
+ export class ProjectContext extends FileProjectContext {
2
+ constructor(repo: any);
3
+ repo: any;
4
+ getOrder(list: any, order: any): any;
5
+ get config(): any;
6
+ toJSON(): null;
7
+ determineOrder(config: any, order: any, tasks: any): any;
8
+ }
9
+ import { FileProjectContext } from './FileProjectContext.js';
@@ -0,0 +1,2 @@
1
+ export function setNoDST(noDST: any): void;
2
+ export function getIsoDateWithOffset(date: any): string;
@@ -0,0 +1 @@
1
+ export function isDev(): boolean;
@@ -0,0 +1,51 @@
1
+ export function exists(path: any): Promise<false | _fs.Stats>;
2
+ export function statSync(path: any): _fs.Stats | undefined;
3
+ export function init(fileSystem?: typeof _fs): void;
4
+ export function existsSync(...args: any[]): boolean;
5
+ export function readFileSync(...args: any[]): string | Buffer<ArrayBufferLike>;
6
+ export function appendFileSync(...args: any[]): void;
7
+ export function writeFileSync(...args: any[]): void;
8
+ export function readdir(...args: any[]): Promise<_fs.Dirent[]>;
9
+ export function unlinkSync(...args: any[]): void;
10
+ export function readdirSyncRecursive(path: any): any[];
11
+ export function readdirSync(path: any): _fs.Dirent[];
12
+ export function sanitizeFileName(fileName: any, replaceSpacesWith: any): any;
13
+ export function preparePathForWriting(path: any, directory?: boolean): Promise<{
14
+ isFile: any;
15
+ isDirectory: any;
16
+ }>;
17
+ export function cp(src: any, dest: any, opts: any): Promise<void>;
18
+ export function rm(path: any, opts: any): Promise<void>;
19
+ export const sep: "/" | "\\";
20
+ export const stat: typeof _fs.promises.stat;
21
+ export const lstat: typeof _fs.promises.lstat;
22
+ export const lstatSync: _fs.StatSyncFn;
23
+ export const writeFile: typeof _fs.promises.writeFile;
24
+ export const unlink: typeof _fs.promises.unlink;
25
+ export const mkdir: typeof _fs.promises.mkdir;
26
+ export const readFile: typeof _fs.promises.readFile;
27
+ declare namespace _default {
28
+ export { cp };
29
+ export { rm };
30
+ export { exists };
31
+ export { stat };
32
+ export { lstat };
33
+ export { lstatSync };
34
+ export { readFileSync };
35
+ export { appendFileSync };
36
+ export { writeFileSync };
37
+ export { writeFile };
38
+ export { readdir };
39
+ export { unlink };
40
+ export { mkdir };
41
+ export { readFile };
42
+ export { readdirSyncRecursive };
43
+ export { readdirSync };
44
+ export { sanitizeFileName };
45
+ export { preparePathForWriting };
46
+ export { unlinkSync };
47
+ export { existsSync };
48
+ export { sep };
49
+ }
50
+ export default _default;
51
+ import _fs from 'fs';
@@ -0,0 +1 @@
1
+ export function downloadPlugin(repo: any, dest: any): Promise<void>;
@@ -0,0 +1,9 @@
1
+ export * from "./date-time.js";
2
+ export * from "./environment.js";
3
+ export * from "./file-gateway.js";
4
+ export * from "./git-download.js";
5
+ export * from "./logger.js";
6
+ export * from "./markdown.js";
7
+ export * from "./yaml.js";
8
+ export * as parsers from "./parsers/index.js";
9
+ export * as storage from "./storage/index.js";
@@ -0,0 +1,24 @@
1
+ export const logger: Logger;
2
+ declare class Logger {
3
+ level: number;
4
+ setLevel(level: any): this;
5
+ shouldLog(level: any): boolean;
6
+ formatMessage(args: any): any;
7
+ log(...args: any[]): void;
8
+ error(...args: any[]): void;
9
+ warn(...args: any[]): void;
10
+ info(...args: any[]): void;
11
+ debug(...args: any[]): void;
12
+ trace(...args: any[]): void;
13
+ time(label: any): void;
14
+ timeEnd(label: any): void;
15
+ }
16
+ export namespace LogLevel {
17
+ let ERROR: number;
18
+ let WARN: number;
19
+ let INFO: number;
20
+ let DEBUG: number;
21
+ let TRACE: number;
22
+ let NONE: number;
23
+ }
24
+ export {};
@@ -0,0 +1,13 @@
1
+ export function extractWikilinkTopics(markdown: any): string[];
2
+ export function _setPlatform(platform: any): void;
3
+ export function renderMarkdown(markdown: any, filePath: any): any;
4
+ export function removeMD(...args: any[]): any;
5
+ export const allEmoji: any;
6
+ declare namespace _default {
7
+ export { extractWikilinkTopics };
8
+ export { renderMarkdown };
9
+ export { removeMD };
10
+ export { _setPlatform };
11
+ export { allEmoji };
12
+ }
13
+ export default _default;
@@ -0,0 +1 @@
1
+ export function replaceDateLanguage(text: any, asDate?: boolean): any;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Interpolates the content with the provided data.
3
+ * @param {string} content - The content to interpolate.
4
+ * @param {object} data - The data to use for interpolation.
5
+ * @param {object} opts - The options for interpolation.
6
+ * @returns {object} - The interpolated content, whether there was interpolation, and error tokens.
7
+ */
8
+ export function interpolate(content: string, data: object, opts?: object): object;
9
+ export function encodeMarkdownLinks(content: any): any;
10
+ export function format(content: any, data: any, mustache: any): any;
@@ -0,0 +1,5 @@
1
+ export function getLang(config: any, filePath: any): any;
2
+ export function getLanguages(config: any): any;
3
+ export function getFileParser(filePath: any, config: any, readStream: any): Promise<ReadStreamMarkdownParser | ReadStreamCodeParser>;
4
+ import { ReadStreamMarkdownParser } from './ReadStreamMarkdownParser.js';
5
+ import { ReadStreamCodeParser } from './ReadStreamCodeParser.js';
@@ -0,0 +1,13 @@
1
+ export class ReadStreamCodeParser extends ReadStreamTaskParser {
2
+ constructor(readStream: any, filePath: any, lang: any, lists: any);
3
+ lists: any;
4
+ filePath: any;
5
+ lang: any;
6
+ taskParsers: CodeStyleTaskParser[];
7
+ init(): Promise<void>;
8
+ cards: any[] | undefined;
9
+ parseCards(code: any, tokens?: string[]): any[];
10
+ parseComments(code: any): any;
11
+ }
12
+ import { ReadStreamTaskParser } from './ReadStreamTaskParser.js';
13
+ import { CodeStyleTaskParser } from '../task/CodeStyleTaskParser.js';
@@ -0,0 +1,7 @@
1
+ export class ReadStreamMarkdownParser extends ReadStreamTaskParser {
2
+ constructor(readStream: any, config: any);
3
+ taskParsers: (HashStyleTaskParser | MarkdownStyleTaskParser)[];
4
+ }
5
+ import { ReadStreamTaskParser } from './ReadStreamTaskParser.js';
6
+ import { HashStyleTaskParser } from '../task/HashStyleTaskParser.js';
7
+ import { MarkdownStyleTaskParser } from '../task/MarkdownStyleTaskParser.js';
@@ -0,0 +1,19 @@
1
+ export class ReadStreamTaskParser {
2
+ constructor(readStream: any);
3
+ readStream: any;
4
+ task: any;
5
+ line: IteratorResult<string, any> | null;
6
+ taskParsers: any[];
7
+ lineNo: number;
8
+ blankLines: number;
9
+ readInterface: ReadLine.Interface;
10
+ readTask(): Promise<any>;
11
+ readLine(): Promise<IteratorResult<string, any>>;
12
+ isEndOfTask(line: any): boolean;
13
+ nextTask: any;
14
+ getTaskFromLine(line: any): undefined;
15
+ addLineToTask(line: any): void;
16
+ trimLinesToEndTask(): void;
17
+ close(): void;
18
+ }
19
+ import * as ReadLine from 'node:readline/promises';