imdone-core 2.0.11 → 2.0.13

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/.env ADDED
@@ -0,0 +1,6 @@
1
+
2
+ # Jira environment variables
3
+
4
+ # JIRA_AUTH_BASIC=true # Set to false to use Bearer token auth.
5
+ # JIRA_USERNAME="<your jira username>" # e.g. your email address. Not needed if using Bearer token auth.
6
+ # JIRA_TOKEN="<your personal access token>"
package/.imdoneignore CHANGED
@@ -11,3 +11,4 @@ imdone-export.json
11
11
  .imdone/templates
12
12
  .imdone
13
13
  notes/archive
14
+ _lib
@@ -1,5 +1,3 @@
1
- import { info, error as consoleError, warn as consoleWarn } from 'console'
2
-
3
1
  // Log levels with numeric values for comparison
4
2
  const LogLevel = {
5
3
  ERROR: 0,
@@ -10,7 +8,7 @@ const LogLevel = {
10
8
  NONE: -1 // Use this to disable all logging
11
9
  }
12
10
 
13
- function getCallerInfo() {
11
+ export function getCallerInfo() {
14
12
  const err = new Error();
15
13
  const stack = err.stack?.split('\n');
16
14
 
@@ -47,10 +45,13 @@ function getCallerInfo() {
47
45
  return {};
48
46
  }
49
47
 
48
+ const DEFAULT_LOG_LEVEL = LogLevel.WARN;
49
+ const DEFAULT_LOG_LEVEL_NAME = Object.keys(LogLevel).find(key => LogLevel[key] === DEFAULT_LOG_LEVEL);
50
+
50
51
  class Logger {
51
52
  constructor() {
52
53
  // Default log level
53
- this.level = LogLevel.INFO
54
+ this.level = DEFAULT_LOG_LEVEL
54
55
  }
55
56
 
56
57
  // Setter for log level
@@ -60,7 +61,8 @@ class Logger {
60
61
  } else if (typeof level === 'number' && level >= -1 && level <= 4) {
61
62
  this.level = level
62
63
  } else {
63
- consoleWarn(`Invalid log level: ${level}. Using default INFO level.`)
64
+ this.level = DEFAULT_LOG_LEVEL
65
+ console.warn(`Invalid log level: ${level}. Using default ${DEFAULT_LOG_LEVEL_NAME} level.`)
64
66
  }
65
67
  return this
66
68
  }
@@ -85,37 +87,37 @@ class Logger {
85
87
 
86
88
  log(...args) {
87
89
  if (this.shouldLog(LogLevel.INFO)) {
88
- info(...this.formatMessage(args));
90
+ console.log(...this.formatMessage(args));
89
91
  }
90
92
  }
91
93
 
92
94
  error(...args) {
93
95
  if (this.shouldLog(LogLevel.ERROR)) {
94
- consoleError(...this.formatMessage(args));
96
+ console.error(...this.formatMessage(args));
95
97
  }
96
98
  }
97
99
 
98
100
  warn(...args) {
99
101
  if (this.shouldLog(LogLevel.WARN)) {
100
- consoleWarn(...this.formatMessage(args));
102
+ console.warn(...this.formatMessage(args));
101
103
  }
102
104
  }
103
105
 
104
106
  info(...args) {
105
107
  if (this.shouldLog(LogLevel.INFO)) {
106
- info(...this.formatMessage(args));
108
+ console.info(...this.formatMessage(args));
107
109
  }
108
110
  }
109
111
 
110
112
  debug(...args) {
111
113
  if (this.shouldLog(LogLevel.DEBUG)) {
112
- info(`[DEBUG]`, ...this.formatMessage(args));
114
+ console.debug(`[DEBUG]`, ...this.formatMessage(args));
113
115
  }
114
116
  }
115
117
 
116
118
  trace(...args) {
117
119
  if (this.shouldLog(LogLevel.TRACE)) {
118
- info(`[TRACE]`, ...this.formatMessage(args));
120
+ console.trace(`[TRACE]`, ...this.formatMessage(args));
119
121
  }
120
122
  }
121
123
 
package/lib/config.js CHANGED
@@ -141,6 +141,10 @@ export class Config {
141
141
  return this?.cards?.tagPrefix ?? '+'
142
142
  }
143
143
 
144
+ getCommentTagsOnly() {
145
+ return this?.cards?.commentTagsOnly ?? false
146
+ }
147
+
144
148
  getTaskPrefix() {
145
149
  return this?.cards?.taskPrefix ?? '##'
146
150
  }
@@ -18,6 +18,7 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
18
18
  const _init = repo.init
19
19
  let initializing = false
20
20
  let refreshing = false
21
+ let watcherPaused = false
21
22
 
22
23
  function ready() {
23
24
  return !initializing && !refreshing
@@ -30,6 +31,30 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
30
31
  }
31
32
  }
32
33
 
34
+ // Add function to pause the watcher
35
+ repo.pauseWatcher = async function() {
36
+ if (repo.watcher && !watcherPaused) {
37
+ logger.info('Pausing file watcher for:', repo.path)
38
+ await repo.watcher.close()
39
+ watcherPaused = true
40
+ repo.emit('watcher.paused')
41
+ return true
42
+ }
43
+ return false
44
+ }
45
+
46
+ // Add function to unpause the watcher
47
+ repo.unpauseWatcher = async function() {
48
+ if (watcherPaused) {
49
+ logger.info('Unpausing file watcher for:', repo.path)
50
+ await repo.initWatcher()
51
+ watcherPaused = false
52
+ repo.emit('watcher.resumed')
53
+ return true
54
+ }
55
+ return false
56
+ }
57
+
33
58
  // READY Refactor init to async/await
34
59
  // #esm-migration #important
35
60
  // <!--
@@ -69,7 +94,10 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
69
94
  refreshing = true
70
95
  try {
71
96
  const files = await _refresh.call(repo)
72
- await repo.initWatcher()
97
+ // Only initialize watcher if it's not paused
98
+ if (!watcherPaused) {
99
+ await repo.initWatcher()
100
+ }
73
101
  refreshing = false
74
102
  return files
75
103
  } catch (err) {
@@ -108,6 +136,11 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
108
136
  // defer:2025-03-18
109
137
  // -->
110
138
  repo.initWatcher = async () => {
139
+ // Close existing watcher if it exists
140
+ if (repo.watcher) {
141
+ await repo.watcher.close()
142
+ }
143
+
111
144
  return new Promise(async (resolve, reject) => {
112
145
  logger.log('initializing watcher for:', repo.path)
113
146
  repo.watcher = chokidar.watch(repo.path, {
@@ -1,7 +1,6 @@
1
1
  export * from './archive-plugin.js';
2
2
  export * from './default-board-actions-plugin.js';
3
3
  export * from './default-board-properties-plugin.js';
4
- export * from './default-plugins.js';
5
4
  export * from './epic-plugin.js';
6
5
  export * from './extension-plugin.js';
7
6
  export * from './persist-tags-plugin.js';
package/lib/task.js CHANGED
@@ -188,6 +188,10 @@ export class Task {
188
188
  getTagPrefix () {
189
189
  return this.config?.getTagPrefix()
190
190
  }
191
+
192
+ getCommentTagsOnly () {
193
+ return this.config?.getCommentTagsOnly()
194
+ }
191
195
 
192
196
  static addToLastCommentInContent (content, toAdd, newLine) {
193
197
  // BACKLOG respect padding of task prefix for list items
@@ -315,14 +319,16 @@ export class Task {
315
319
  'gmiu'
316
320
  )
317
321
  }
318
- static getTags (text, prefix = '+') {
322
+ static getTags (text, prefix = '+', commentTagsOnly = false) {
319
323
  const tags = [];
320
324
  const codePositions = Task.getMarkdownCodePositions(text);
321
325
  const linkLabelPositions = Task.getMarkdownLinkLabelPositions(text);
326
+ const commentPositions = Task.getCommentPositions(text);
322
327
  let result;
323
328
  const re = Task.getTagRegexp(prefix);
324
329
 
325
330
  while ((result = re.exec(text)) !== null) {
331
+ if (commentTagsOnly && !Task.isResultInComment(commentPositions, result.index)) continue;
326
332
  if (Task.isResultInMarkdownCode(codePositions, result.index)) continue;
327
333
  if (Task.isResultInMarkdownLinkLabel(linkLabelPositions, result.index)) continue;
328
334
  const tag = result[2];
@@ -349,6 +355,22 @@ export class Task {
349
355
  return linkLabelPositions.some(pos => index >= pos.start && index < pos.end);
350
356
  };
351
357
 
358
+ static getCommentPositions (text) {
359
+ const positions = [];
360
+ const re = /<!--[\s\S]*?-->/g;
361
+ let match;
362
+
363
+ while ((match = re.exec(text)) !== null) {
364
+ positions.push({ start: match.index, end: re.lastIndex });
365
+ }
366
+
367
+ return positions;
368
+ }
369
+
370
+ static isResultInComment (commentPositions, index) {
371
+ return commentPositions.some(pos => index >= pos.start && index < pos.end);
372
+ }
373
+
352
374
  static ContextRegExp = new RegExp(
353
375
  `(^|\\s)@([${Task.AnyLanguageGroup}${Task.EmojiGroup}]+)`,
354
376
  'gmiu'
@@ -567,7 +589,7 @@ export class Task {
567
589
  }
568
590
 
569
591
  parseTodoTxt () {
570
- this.tags = Task.getTags(this.getRawTextAndDescription(), this.getTagPrefix())
592
+ this.tags = Task.getTags(this.getRawTextAndDescription(), this.getTagPrefix(), this.getCommentTagsOnly())
571
593
  this.context = Task.getContext(this.getRawTextAndDescription())
572
594
  this.meta = Task.getMetaData(this.config, this)
573
595
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imdone-core",
3
- "version": "2.0.11",
3
+ "version": "2.0.13",
4
4
  "description": "imdone-core",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,7 +22,7 @@
22
22
  "coverage": "vitest --run --coverage",
23
23
  "link": "npm link ../imdone-api",
24
24
  "pre-commit": "npm run build:docs && npm run build:docs:index && npm run build:index && npm run build:types",
25
- "test": "vitest --run",
25
+ "test": "npm run coverage",
26
26
  "test-ci": "vitest --run",
27
27
  "serve": "npx docsify-cli serve",
28
28
  "prepare": "husky"
@@ -1,3 +1,14 @@
1
+ export function getCallerInfo(): {
2
+ functionName?: undefined;
3
+ file?: undefined;
4
+ line?: undefined;
5
+ column?: undefined;
6
+ } | {
7
+ functionName: string;
8
+ file: string;
9
+ line: number;
10
+ column: number;
11
+ };
1
12
  export const logger: Logger;
2
13
  declare class Logger {
3
14
  level: number;
package/types/card.d.ts CHANGED
@@ -158,6 +158,7 @@ export function newCard(task: any, _project: any, dontParse: any): {
158
158
  expand: boolean;
159
159
  };
160
160
  getTagPrefix(): any;
161
+ getCommentTagsOnly(): any;
161
162
  addToLastCommentInContent(content: any, toAdd: any, newLine: any): string;
162
163
  getCheckedData(): {
163
164
  pad: number;
package/types/config.d.ts CHANGED
@@ -32,6 +32,7 @@ export class Config {
32
32
  getNewCardSyntax(): any;
33
33
  isMetaNewLine(): any;
34
34
  getTagPrefix(): any;
35
+ getCommentTagsOnly(): any;
35
36
  getTaskPrefix(): any;
36
37
  isAddCheckBoxTasks(): any;
37
38
  isAddCompletedMeta(): any;
package/types/file.d.ts CHANGED
@@ -256,6 +256,7 @@ export class File extends Emitter<[never]> {
256
256
  expand: boolean;
257
257
  };
258
258
  getTagPrefix(): any;
259
+ getCommentTagsOnly(): any;
259
260
  addToLastCommentInContent(content: any, toAdd: any, newLine: any): string;
260
261
  getCheckedData(): {
261
262
  pad: number;
@@ -1,7 +1,6 @@
1
1
  export * from "./archive-plugin.js";
2
2
  export * from "./default-board-actions-plugin.js";
3
3
  export * from "./default-board-properties-plugin.js";
4
- export * from "./default-plugins.js";
5
4
  export * from "./epic-plugin.js";
6
5
  export * from "./extension-plugin.js";
7
6
  export * from "./persist-tags-plugin.js";
package/types/task.d.ts CHANGED
@@ -18,12 +18,17 @@ export class Task {
18
18
  static AnyLanguageGroup: string;
19
19
  static EmojiGroup: string;
20
20
  static getTagRegexp(prefix?: string): RegExp;
21
- static getTags(text: any, prefix?: string): string[];
21
+ static getTags(text: any, prefix?: string, commentTagsOnly?: boolean): string[];
22
22
  static getMarkdownLinkLabelPositions(text: any): {
23
23
  start: number;
24
24
  end: number;
25
25
  }[];
26
26
  static isResultInMarkdownLinkLabel(linkLabelPositions: any, index: any): any;
27
+ static getCommentPositions(text: any): {
28
+ start: number;
29
+ end: number;
30
+ }[];
31
+ static isResultInComment(commentPositions: any, index: any): any;
27
32
  static ContextRegExp: RegExp;
28
33
  static getContext(text: any): string[];
29
34
  static MetaRegExp: RegExp;
@@ -124,6 +129,7 @@ export class Task {
124
129
  expand: boolean;
125
130
  };
126
131
  getTagPrefix(): any;
132
+ getCommentTagsOnly(): any;
127
133
  addToLastCommentInContent(content: any, toAdd: any, newLine: any): string;
128
134
  getCheckedData(): {
129
135
  pad: number;
package/vitest.config.js CHANGED
@@ -8,6 +8,8 @@ export default defineConfig({
8
8
  reporter: ["text"], // Ensure text output is included
9
9
  clean: false,
10
10
  reportOnFailure: true,
11
+ include: ['lib'], // Only include files from src/
12
+ exclude: ['_lib', 'lib/**/index.*']
11
13
  },
12
14
  },
13
15
  });
@@ -1,7 +0,0 @@
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
-