imdone-core 2.3.4 → 2.4.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 2.3.5
2
+
3
+ - Incorporate newly added watched files into repository state before emitting `file.update`, so live board consumers can render the new task without a reload or restart.
4
+
1
5
  ## 2.3.3
2
6
 
3
7
  - Update `adm-zip` to `0.6.0` to address a high-severity ZIP parsing memory allocation vulnerability.
package/lib/index.js CHANGED
@@ -12,6 +12,7 @@ export * from './get-tasks-to-modify.js';
12
12
  export * from './languages.js';
13
13
  export * from './list.js';
14
14
  export * from './migrate-config.js';
15
+ export * from './monquery.js';
15
16
  export * from './omit.js';
16
17
  export * from './project-factory.js';
17
18
  export * from './project.js';
@@ -190,18 +190,20 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
190
190
  .on('add', trackWatcherEvent(async function (path, stat) {
191
191
  logger.log('Watcher received add event for file: ' + path)
192
192
  if (stat.isDirectory()) return
193
- let file = repo.getFile(path)
193
+ const relativePath = repo.getRelativePath(path)
194
+ let file = repo.getFile(relativePath)
194
195
  if (file === undefined) {
195
196
  log('Creating file: ' + path)
196
197
  file = new File({
197
198
  repoId: repo.getId(),
198
- filePath: path,
199
+ filePath: relativePath,
199
200
  languages: repo.languages,
200
201
  project: repo.project,
201
202
  })
202
203
  }
203
204
 
204
- stat = await repo.fileOK()
205
+ stat = await repo.fileOK(relativePath)
206
+ if (!stat) return
205
207
  log('fileOK returned: ' + JSON.stringify(stat))
206
208
  if (stat.mtime <= file.getModifiedTime()) {
207
209
  return log('File update already applied. Change ignored for file: ' + path)
@@ -0,0 +1,120 @@
1
+ // Derived from imdone/node-monquery 0.2.2, originally visionmedia/node-monquery.
2
+ // Retained under the MIT license used by both projects.
3
+ import assert from 'node:assert'
4
+
5
+ export function compile(node) {
6
+ switch (node.type) {
7
+ case 'field': {
8
+ const value = node.cmp
9
+ ? { [`$${node.cmp}`]: node.value }
10
+ : node.value
11
+ return { [node.name]: value }
12
+ }
13
+ case 'op':
14
+ return {
15
+ [`$${node.op}`]: [compile(node.left), compile(node.right)],
16
+ }
17
+ default:
18
+ return undefined
19
+ }
20
+ }
21
+
22
+ function comparison(value) {
23
+ switch (value) {
24
+ case '>': return 'gt'
25
+ case '<': return 'lt'
26
+ case '<=': return 'lte'
27
+ case '>=': return 'gte'
28
+ case '!=': return 'ne'
29
+ default: return null
30
+ }
31
+ }
32
+
33
+ function numeric(value) {
34
+ return !Number.isNaN(Number.parseFloat(value))
35
+ }
36
+
37
+ function quoted(value) {
38
+ return value[0] === "'" || value[0] === '"'
39
+ }
40
+
41
+ function pattern(value) {
42
+ const escaped = value
43
+ .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
44
+ .replace(/-/g, '\\x2d')
45
+ .replace(/\\\*/g, '.*')
46
+ return new RegExp(`^${escaped}$`)
47
+ }
48
+
49
+ function coerce(value) {
50
+ if (typeof value !== 'string') return value
51
+ if (value[0] === '/') return new RegExp(value.slice(1, -1))
52
+ if (value === 'true' || value === 'yes') return true
53
+ if (value === 'false' || value === 'no') return false
54
+ if (quoted(value)) return value.replace(/^['"]|['"]$/g, '')
55
+ if (value.includes('*')) return pattern(value)
56
+ return value
57
+ }
58
+
59
+ export function parse(input) {
60
+ let source = `(${input.trim()})`
61
+
62
+ const requireSyntax = (condition, message) => {
63
+ if (condition) return
64
+ assert.fail(`${message} near \`${source.slice(0, 10)}\``)
65
+ }
66
+
67
+ const field = () => {
68
+ const nameMatch = source.match(/^([-.\w]+)/)
69
+ if (!nameMatch) return undefined
70
+
71
+ const name = nameMatch[0]
72
+ source = source.slice(name.length)
73
+ const valueMatch = source.match(/ *([:><!=]*) *([-*\w.]+|".*?"|'.*?'|\/(.*)\/) */)
74
+ let value = true
75
+ let operator = null
76
+ if (valueMatch) {
77
+ source = source.slice(valueMatch[0].length)
78
+ value = valueMatch[2]
79
+ operator = comparison(valueMatch[1])
80
+ if (numeric(value)) value = Number.parseFloat(value)
81
+ }
82
+
83
+ return {
84
+ type: 'field',
85
+ name,
86
+ value: coerce(value),
87
+ ...(operator ? { cmp: operator } : {}),
88
+ }
89
+ }
90
+
91
+ const expression = () => {
92
+ requireSyntax(source[0] === '(', "missing opening '('")
93
+ source = source.slice(1)
94
+ const node = binaryOperation()
95
+ requireSyntax(source[0] === ')', "missing closing ')'")
96
+ source = source.slice(1)
97
+ return node
98
+ }
99
+
100
+ const primary = () => field() || expression()
101
+
102
+ const binaryOperation = () => {
103
+ const left = primary()
104
+ const operatorMatch = source.match(/^ *(OR|AND) */i)
105
+ if (!operatorMatch) return left
106
+ source = source.slice(operatorMatch[0].length)
107
+ return {
108
+ type: 'op',
109
+ op: operatorMatch[1].toLowerCase(),
110
+ left,
111
+ right: binaryOperation(),
112
+ }
113
+ }
114
+
115
+ return expression()
116
+ }
117
+
118
+ export default function monquery(input) {
119
+ return compile(parse(input))
120
+ }
package/lib/repository.js CHANGED
@@ -23,7 +23,7 @@ import { constants } from './constants.js'
23
23
  import debug from 'debug'
24
24
  const log = debug('imdone-core:Repository')
25
25
  import { List } from './list.js'
26
- import monquery from 'monquery'
26
+ import monquery from './monquery.js'
27
27
  import sift from 'sift'
28
28
  import { sort } from 'fast-sort'
29
29
  import JSONfns from 'json-fns'
@@ -988,7 +988,7 @@ export class Repository extends Emitter {
988
988
  if (!file.updated) return file
989
989
 
990
990
  await this.extractTasks(file)
991
- await this.addFile()
991
+ await this.addFile(file)
992
992
 
993
993
  return file
994
994
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imdone-core",
3
- "version": "2.3.4",
3
+ "version": "2.4.0",
4
4
  "description": "imdone-core",
5
5
  "repository": {
6
6
  "type": "git",
@@ -84,7 +84,6 @@
84
84
  "markdown-it-emoji": "^2.0.0",
85
85
  "markdown-it-mark": "^3.0.1",
86
86
  "moment": "^2.29.1",
87
- "monquery": "https://github.com/imdone/node-monquery/archive/refs/tags/0.2.2.tar.gz",
88
87
  "multilang-extract-comments": "^0.4.0",
89
88
  "open": "^9.1.0",
90
89
  "ora": "^8.2.0",
package/types/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export * from "./get-tasks-to-modify.js";
12
12
  export * from "./languages.js";
13
13
  export * from "./list.js";
14
14
  export * from "./migrate-config.js";
15
+ export * from "./monquery.js";
15
16
  export * from "./omit.js";
16
17
  export * from "./project-factory.js";
17
18
  export * from "./project.js";
@@ -0,0 +1,3 @@
1
+ export function compile(node: any): any;
2
+ export function parse(input: any): any;
3
+ export default function monquery(input: any): any;