1
0

New query rendering engine with handlebars

This commit is contained in:
Zef Hemel 2022-04-28 11:55:38 +02:00
parent 0182a587e4
commit 9ef30d1f49
24 changed files with 2560 additions and 112 deletions

317
package-lock.json generated
View File

@ -11,6 +11,9 @@
"workspaces": [
"packages/*"
],
"dependencies": {
"handlebars": "^4.7.7"
},
"devDependencies": {
"@parcel/core": "2.3.2",
"@parcel/packager-raw-url": "2.3.2",
@ -21,6 +24,7 @@
"@parcel/validator-typescript": "2.3.2",
"parcel": "2.3.2",
"prettier": "^2.5.1",
"ts-node": "^10.7.0",
"typescript": "^4.6.2"
}
},
@ -763,6 +767,27 @@
"w3c-keyname": "^2.2.4"
}
},
"node_modules/@cspotcode/source-map-consumer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
"integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
"devOptional": true,
"engines": {
"node": ">= 12"
}
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz",
"integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==",
"devOptional": true,
"dependencies": {
"@cspotcode/source-map-consumer": "0.8.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@fortawesome/fontawesome-common-types": {
"version": "0.3.0",
"hasInstallScript": true,
@ -2356,6 +2381,30 @@
"node": ">=10.13.0"
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
"devOptional": true
},
"node_modules/@tsconfig/node12": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
"devOptional": true
},
"node_modules/@tsconfig/node14": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
"devOptional": true
},
"node_modules/@tsconfig/node16": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
"devOptional": true
},
"node_modules/@types/babel__core": {
"version": "7.1.19",
"license": "MIT",
@ -2818,6 +2867,12 @@
"readable-stream": "^2.0.6"
}
},
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"devOptional": true
},
"node_modules/argparse": {
"version": "1.0.10",
"license": "MIT",
@ -3601,6 +3656,12 @@
"node": ">=10"
}
},
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"devOptional": true
},
"node_modules/crelt": {
"version": "1.0.5",
"license": "MIT"
@ -3927,6 +3988,15 @@
"wrappy": "1"
}
},
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"devOptional": true,
"engines": {
"node": ">=0.3.1"
}
},
"node_modules/diff-sequences": {
"version": "27.5.1",
"license": "MIT",
@ -4842,6 +4912,26 @@
"version": "4.2.10",
"license": "ISC"
},
"node_modules/handlebars": {
"version": "4.7.7",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
"integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
"dependencies": {
"minimist": "^1.2.5",
"neo-async": "^2.6.0",
"source-map": "^0.6.1",
"wordwrap": "^1.0.0"
},
"bin": {
"handlebars": "bin/handlebars"
},
"engines": {
"node": ">=0.4.7"
},
"optionalDependencies": {
"uglify-js": "^3.1.4"
}
},
"node_modules/has": {
"version": "1.0.3",
"license": "MIT",
@ -6716,6 +6806,12 @@
"semver": "bin/semver.js"
}
},
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"devOptional": true
},
"node_modules/makeerror": {
"version": "1.0.12",
"license": "BSD-3-Clause",
@ -6946,6 +7042,11 @@
"node": ">= 0.6"
}
},
"node_modules/neo-async": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
"node_modules/node-abi": {
"version": "3.15.0",
"license": "MIT",
@ -9098,6 +9199,58 @@
"node": ">=8"
}
},
"node_modules/ts-node": {
"version": "10.7.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz",
"integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==",
"devOptional": true,
"dependencies": {
"@cspotcode/source-map-support": "0.7.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.0",
"yn": "3.1.1"
},
"bin": {
"ts-node": "dist/bin.js",
"ts-node-cwd": "dist/bin-cwd.js",
"ts-node-esm": "dist/bin-esm.js",
"ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js"
},
"peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@types/node": "*",
"typescript": ">=2.7"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"@swc/wasm": {
"optional": true
}
}
},
"node_modules/ts-node/node_modules/acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"devOptional": true,
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
"license": "Apache-2.0",
@ -9188,6 +9341,18 @@
"version": "1.0.6",
"license": "MIT"
},
"node_modules/uglify-js": {
"version": "3.15.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.4.tgz",
"integrity": "sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==",
"optional": true,
"bin": {
"uglifyjs": "bin/uglifyjs"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/unbox-primitive": {
"version": "1.0.1",
"dev": true,
@ -9316,6 +9481,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"devOptional": true
},
"node_modules/v8-to-istanbul": {
"version": "8.1.1",
"license": "ISC",
@ -9516,6 +9687,11 @@
"node": ">=0.10.0"
}
},
"node_modules/wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
},
"node_modules/wrap-ansi": {
"version": "7.0.0",
"license": "MIT",
@ -9663,6 +9839,15 @@
"node": ">=8"
}
},
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"devOptional": true,
"engines": {
"node": ">=6"
}
},
"packages/common": {
"name": "@silverbulletmd/common",
"version": "0.0.1",
@ -10382,6 +10567,21 @@
"w3c-keyname": "^2.2.4"
}
},
"@cspotcode/source-map-consumer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
"integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
"devOptional": true
},
"@cspotcode/source-map-support": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz",
"integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==",
"devOptional": true,
"requires": {
"@cspotcode/source-map-consumer": "0.8.0"
}
},
"@fortawesome/fontawesome-common-types": {
"version": "0.3.0"
},
@ -11461,6 +11661,30 @@
"version": "0.2.0",
"dev": true
},
"@tsconfig/node10": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
"devOptional": true
},
"@tsconfig/node12": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
"devOptional": true
},
"@tsconfig/node14": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
"devOptional": true
},
"@tsconfig/node16": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
"devOptional": true
},
"@types/babel__core": {
"version": "7.1.19",
"requires": {
@ -11809,6 +12033,12 @@
"readable-stream": "^2.0.6"
}
},
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"devOptional": true
},
"argparse": {
"version": "1.0.10",
"requires": {
@ -12284,6 +12514,12 @@
"yaml": "^1.10.0"
}
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"devOptional": true
},
"crelt": {
"version": "1.0.5"
},
@ -12479,6 +12715,12 @@
"wrappy": "1"
}
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"devOptional": true
},
"diff-sequences": {
"version": "27.5.1"
},
@ -13055,6 +13297,18 @@
"graceful-fs": {
"version": "4.2.10"
},
"handlebars": {
"version": "4.7.7",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
"integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
"requires": {
"minimist": "^1.2.5",
"neo-async": "^2.6.0",
"source-map": "^0.6.1",
"uglify-js": "^3.1.4",
"wordwrap": "^1.0.0"
}
},
"has": {
"version": "1.0.3",
"requires": {
@ -14189,6 +14443,12 @@
}
}
},
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"devOptional": true
},
"makeerror": {
"version": "1.0.12",
"requires": {
@ -14327,6 +14587,11 @@
"negotiator": {
"version": "0.6.3"
},
"neo-async": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
"node-abi": {
"version": "3.15.0",
"requires": {
@ -15598,6 +15863,35 @@
"punycode": "^2.1.1"
}
},
"ts-node": {
"version": "10.7.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz",
"integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==",
"devOptional": true,
"requires": {
"@cspotcode/source-map-support": "0.7.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.0",
"yn": "3.1.1"
},
"dependencies": {
"acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"devOptional": true
}
}
},
"tunnel-agent": {
"version": "0.6.0",
"requires": {
@ -15647,6 +15941,12 @@
"uc.micro": {
"version": "1.0.6"
},
"uglify-js": {
"version": "3.15.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.4.tgz",
"integrity": "sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==",
"optional": true
},
"unbox-primitive": {
"version": "1.0.1",
"dev": true,
@ -15731,6 +16031,12 @@
"version": "2.3.0",
"dev": true
},
"v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"devOptional": true
},
"v8-to-istanbul": {
"version": "8.1.1",
"requires": {
@ -15861,6 +16167,11 @@
"word-wrap": {
"version": "1.2.3"
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
},
"wrap-ansi": {
"version": "7.0.0",
"requires": {
@ -15947,6 +16258,12 @@
},
"yargs-parser": {
"version": "21.0.1"
},
"yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"devOptional": true
}
}
}

View File

@ -7,7 +7,7 @@
"@lezer/common": "https://github.com/zefhemel/common.git#046c880d1fcab713cadad327a5b7d8bb5de6522c"
},
"scripts": {
"watch": "rm -rf .parcel-cache && parcel watch --no-hmr packages/{web,server,plugos} desktop",
"watch": "rm -rf .parcel-cache && parcel watch --no-hmr packages/{web,server,plugos,plugs} desktop",
"clean": "rm -rf .parcel-cache packages/*/dist",
"build": "parcel build packages/{web,server,plugos}",
"plugs": "cd packages/plugs && npm run watch",
@ -25,9 +25,13 @@
"@parcel/validator-typescript": "2.3.2",
"parcel": "2.3.2",
"prettier": "^2.5.1",
"ts-node": "^10.7.0",
"typescript": "^4.6.2"
},
"workspaces": [
"packages/*"
]
],
"dependencies": {
"handlebars": "^4.7.7"
}
}

View File

@ -4,4 +4,4 @@
// Candidate modules for this are larger modules
// When adding a module to this list, also manually add it to sandbox_worker.ts
export const preloadModules = ["@lezer/lr", "yaml"];
export const preloadModules = ["@lezer/lr", "yaml", "handlebars"];

View File

@ -41,6 +41,7 @@ self.syscall = async (name: string, ...args: any[]) => {
const preloadedModules: { [key: string]: any } = {
"@lezer/lr": require("@lezer/lr"),
yaml: require("yaml"),
handlebars: require("handlebars/dist/handlebars"),
};
// for (const moduleName of preloadModules) {
// preloadedModules[moduleName] = require(moduleName);

View File

@ -0,0 +1,468 @@
var $hVExJ$jestglobals = require("@jest/globals");
var $hVExJ$lezerlr = require("@lezer/lr");
function $255163dfff8c42fb$export$6dd7a1b2f91e0e12(tree) {
if (!tree.children) return;
for (let child of tree.children){
if (child.parent) // Already added parent pointers before
return;
child.parent = tree;
$255163dfff8c42fb$export$6dd7a1b2f91e0e12(child);
}
}
function $255163dfff8c42fb$export$7bbc263cafa7dd78(tree) {
delete tree.parent;
if (!tree.children) return;
for (let child of tree.children)$255163dfff8c42fb$export$7bbc263cafa7dd78(child);
}
function $255163dfff8c42fb$export$6dcbc6776594ee95(tree, matchFn) {
let node = tree.parent;
while(node){
if (matchFn(node)) return node;
node = node.parent;
}
return null;
}
function $255163dfff8c42fb$export$dddeb721bf64f8df(tree, nodeType) {
return $255163dfff8c42fb$export$b86407c733c9fe3(tree, (n)=>n.type === nodeType
);
}
function $255163dfff8c42fb$export$b86407c733c9fe3(tree, matchFn) {
if (matchFn(tree)) return [
tree
];
let results = [];
if (tree.children) for (let child of tree.children)results = [
...results,
...$255163dfff8c42fb$export$b86407c733c9fe3(child, matchFn)
];
return results;
}
function $255163dfff8c42fb$export$90b8ac453fa63932(tree, substituteFn) {
if (tree.children) {
let children = tree.children.slice();
for (let child of children){
let subst = substituteFn(child);
if (subst !== undefined) {
let pos = tree.children.indexOf(child);
if (subst) tree.children.splice(pos, 1, subst);
else // null = delete
tree.children.splice(pos, 1);
} else $255163dfff8c42fb$export$90b8ac453fa63932(child, substituteFn);
}
}
}
function $255163dfff8c42fb$export$4d49acedd23f9b0a(tree, matchFn) {
return $255163dfff8c42fb$export$b86407c733c9fe3(tree, matchFn)[0];
}
function $255163dfff8c42fb$export$80a8b4335833eeeb(tree, nodeType) {
return $255163dfff8c42fb$export$b86407c733c9fe3(tree, (n)=>n.type === nodeType
)[0];
}
function $255163dfff8c42fb$export$a41716fb83443983(tree, pos) {
if (pos < tree.from || pos > tree.to) return null;
if (!tree.children) return tree;
for (let child of tree.children){
let n = $255163dfff8c42fb$export$a41716fb83443983(child, pos);
if (n && n.text !== undefined) // Got a text node, let's return its parent
return tree;
else if (n) // Got it
return n;
}
return null;
}
function $255163dfff8c42fb$export$f21c5276b1e9847a(tree) {
let pieces = [];
if (tree.text !== undefined) return tree.text;
for (let child of tree.children)pieces.push($255163dfff8c42fb$export$f21c5276b1e9847a(child));
return pieces.join("");
}
function $88d466d5aaf7a497$export$87cc1c28aef74af1(text, n, offset = 0) {
let children = [];
let nodeText;
let child = n.firstChild;
while(child){
children.push($88d466d5aaf7a497$export$87cc1c28aef74af1(text, child));
child = child.nextSibling;
}
if (children.length === 0) children = [
{
from: n.from + offset,
to: n.to + offset,
text: text.substring(n.from, n.to)
},
];
else {
let newChildren = [];
let index = n.from;
for (let child of children){
let s = text.substring(index, child.from);
if (s) newChildren.push({
from: index + offset,
to: child.from + offset,
text: s
});
newChildren.push(child);
index = child.to;
}
let s = text.substring(index, n.to);
if (s) newChildren.push({
from: index + offset,
to: n.to + offset,
text: s
});
children = newChildren;
}
let result = {
type: n.name,
from: n.from + offset,
to: n.to + offset
};
if (children.length > 0) result.children = children;
if (nodeText) result.text = nodeText;
return result;
}
function $88d466d5aaf7a497$export$98e6a39c04603d36(language, text) {
let tree = $88d466d5aaf7a497$export$87cc1c28aef74af1(text, language.parser.parse(text).topNode);
// replaceNodesMatching(tree, (n): MarkdownTree | undefined | null => {
// if (n.type === "FencedCode") {
// let infoN = findNodeMatching(n, (n) => n.type === "CodeInfo");
// let language = infoN!.children![0].text;
// let textN = findNodeMatching(n, (n) => n.type === "CodeText");
// let text = textN!.children![0].text!;
//
// console.log(language, text);
// switch (language) {
// case "yaml":
// let parsed = StreamLanguage.define(yaml).parser.parse(text);
// let subTree = treeToAST(text, parsed.topNode, n.from);
// // console.log(JSON.stringify(subTree, null, 2));
// subTree.type = "yaml";
// return subTree;
// }
// }
// return;
// });
return tree;
}
const $d85524f23de2149a$export$8f49e4af10703ce3 = $hVExJ$lezerlr.LRParser.deserialize({
version: 13,
states: "&fOVQPOOOmQQO'#C^QOQPOOOtQPO'#C`OyQQO'#CkO!OQPO'#CmO!TQPO'#CnO!YQPO'#CoOOQO'#Cp'#CpO!_QQO,58xO!fQQO'#CcO#TQQO'#CaOOQO'#Ca'#CaOOQO,58z,58zO#lQPO,59VOOQO,59X,59XO#qQQO'#D`OOQO,59Y,59YOOQO,59Z,59ZOOQO-E6n-E6nO$YQQO,58}OtQPO,58|O$qQQO1G.qO%]QPO'#CrO%bQQO,59zOOQO'#Cg'#CgOOQO'#Ci'#CiO$YQQO'#CjOOQO'#Cd'#CdOOQO1G.i1G.iOOQO1G.h1G.hOOQO'#Cl'#ClOOQO7+$]7+$]OOQO,59^,59^OOQO-E6p-E6pO%yQPO'#C|O&RQPO,59UO$YQQO'#CqO&WQPO,59hOOQO1G.p1G.pOOQO,59],59]OOQO-E6o-E6o",
stateData: "&`~OiOS~ORPO~OjRO|SO!QTO!RUO!TVO~OgQX~P[ORYO~O}^O~OX_O~OR`O~OYbO~OgQa~P[OkdOsdOtdOudOvdOwdOxdOydOzdO~O{eOgTXjTX|TX!QTX!RTX!TTX~ORfO~OqgOg!SXj!SX|!SX!Q!SX!R!SX!T!SX~OXlOYlO[lOliOmiOnjOokO~O!OoO!PoOg_ij_i|_i!Q_i!R_i!T_i~ORqO~OqgOg!Saj!Sa|!Sa!Q!Sa!R!Sa!T!Sa~OquOrpX~OrwO~OquOrpa~O",
goto: "#d!TPP!UP!X!]!`!c!iPP!rP!r!r!X!w!X!X!X!z#Q#WPPPPPPPPP#^PPPPPPPPPPPPPPPPP#aRQOTWPXR]RR[RQZRRneQmdQskRxuVldkuRpfQXPRcXQvsRyvQh`RrhRtkRaU",
nodeNames: "⚠ Program Query Name WhereClause LogicalExpr AndExpr FilterExpr Value Number String Bool Regex Null List OrderClause Order LimitClause SelectClause RenderClause",
maxTerm: 51,
skippedNodes: [
0
],
repeatNodeCount: 3,
tokenData: "Ap~R}X^$Opq$Oqr$srs%W|}%r}!O%w!P!Q&Y!Q!['P!^!_'X!_!`'f!`!a's!c!}%w!}#O(Q#P#Q(V#R#S%w#T#U([#U#V*q#V#W%w#W#X+m#X#Y%w#Y#Z-i#Z#]%w#]#^/y#^#`%w#`#a0u#a#b%w#b#c3Y#c#d5U#d#f%w#f#g7i#g#h:e#h#i=a#i#k%w#k#l?]#l#o%w#y#z$O$f$g$O#BY#BZ$O$IS$I_$O$Ip$Iq%W$Iq$Ir%W$I|$JO$O$JT$JU$O$KV$KW$O&FU&FV$O~$TYi~X^$Opq$O#y#z$O$f$g$O#BY#BZ$O$IS$I_$O$I|$JO$O$JT$JU$O$KV$KW$O&FU&FV$O~$vP!_!`$y~%OPu~#r#s%R~%WOy~~%ZUOr%Wrs%ms$Ip%W$Ip$Iq%m$Iq$Ir%m$Ir~%W~%rOY~~%wOq~P%|SRP}!O%w!c!}%w#R#S%w#T#o%w~&_V[~OY&YZ]&Y^!P&Y!P!Q&t!Q#O&Y#O#P&y#P~&Y~&yO[~~&|PO~&Y~'UPX~!Q!['P~'^Pk~!_!`'a~'fOs~~'kPt~#r#s'n~'sOx~~'xPw~!_!`'{~(QOv~~(VOo~~([Or~R(aWRP}!O%w!c!}%w#R#S%w#T#b%w#b#c(y#c#g%w#g#h)u#h#o%wR)OURP}!O%w!c!}%w#R#S%w#T#W%w#W#X)b#X#o%wR)iS{QRP}!O%w!c!}%w#R#S%w#T#o%wR)zURP}!O%w!c!}%w#R#S%w#T#V%w#V#W*^#W#o%wR*eS!PQRP}!O%w!c!}%w#R#S%w#T#o%wR*vURP}!O%w!c!}%w#R#S%w#T#m%w#m#n+Y#n#o%wR+aS}QRP}!O%w!c!}%w#R#S%w#T#o%wR+rURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y,U#Y#o%wR,ZURP}!O%w!c!}%w#R#S%w#T#g%w#g#h,m#h#o%wR,rURP}!O%w!c!}%w#R#S%w#T#V%w#V#W-U#W#o%wR-]S!OQRP}!O%w!c!}%w#R#S%w#T#o%wR-nTRP}!O%w!c!}%w#R#S%w#T#U-}#U#o%wR.SURP}!O%w!c!}%w#R#S%w#T#`%w#`#a.f#a#o%wR.kURP}!O%w!c!}%w#R#S%w#T#g%w#g#h.}#h#o%wR/SURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y/f#Y#o%wR/mSmQRP}!O%w!c!}%w#R#S%w#T#o%wR0OURP}!O%w!c!}%w#R#S%w#T#b%w#b#c0b#c#o%wR0iSzQRP}!O%w!c!}%w#R#S%w#T#o%wR0zURP}!O%w!c!}%w#R#S%w#T#]%w#]#^1^#^#o%wR1cURP}!O%w!c!}%w#R#S%w#T#a%w#a#b1u#b#o%wR1zURP}!O%w!c!}%w#R#S%w#T#]%w#]#^2^#^#o%wR2cURP}!O%w!c!}%w#R#S%w#T#h%w#h#i2u#i#o%wR2|S!QQRP}!O%w!c!}%w#R#S%w#T#o%wR3_URP}!O%w!c!}%w#R#S%w#T#i%w#i#j3q#j#o%wR3vURP}!O%w!c!}%w#R#S%w#T#`%w#`#a4Y#a#o%wR4_URP}!O%w!c!}%w#R#S%w#T#`%w#`#a4q#a#o%wR4xSnQRP}!O%w!c!}%w#R#S%w#T#o%wR5ZURP}!O%w!c!}%w#R#S%w#T#f%w#f#g5m#g#o%wR5rURP}!O%w!c!}%w#R#S%w#T#W%w#W#X6U#X#o%wR6ZURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y6m#Y#o%wR6rURP}!O%w!c!}%w#R#S%w#T#f%w#f#g7U#g#o%wR7]S|QRP}!O%w!c!}%w#R#S%w#T#o%wR7nURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y8Q#Y#o%wR8VURP}!O%w!c!}%w#R#S%w#T#b%w#b#c8i#c#o%wR8nURP}!O%w!c!}%w#R#S%w#T#W%w#W#X9Q#X#o%wR9VURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y9i#Y#o%wR9nURP}!O%w!c!}%w#R#S%w#T#f%w#f#g:Q#g#o%wR:XS!TQRP}!O%w!c!}%w#R#S%w#T#o%wR:jURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y:|#Y#o%wR;RURP}!O%w!c!}%w#R#S%w#T#`%w#`#a;e#a#o%wR;jURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y;|#Y#o%wR<RURP}!O%w!c!}%w#R#S%w#T#V%w#V#W<e#W#o%wR<jURP}!O%w!c!}%w#R#S%w#T#h%w#h#i<|#i#o%wR=TS!RQRP}!O%w!c!}%w#R#S%w#T#o%wR=fURP}!O%w!c!}%w#R#S%w#T#f%w#f#g=x#g#o%wR=}URP}!O%w!c!}%w#R#S%w#T#i%w#i#j>a#j#o%wR>fURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y>x#Y#o%wR?PSlQRP}!O%w!c!}%w#R#S%w#T#o%wR?bURP}!O%w!c!}%w#R#S%w#T#[%w#[#]?t#]#o%wR?yURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y@]#Y#o%wR@bURP}!O%w!c!}%w#R#S%w#T#f%w#f#g@t#g#o%wR@yURP}!O%w!c!}%w#R#S%w#T#X%w#X#YA]#Y#o%wRAdSjQRP}!O%w!c!}%w#R#S%w#T#o%w",
tokenizers: [
0,
1
],
topRules: {
"Program": [
0,
1
]
},
tokenPrec: 0
});
const $4ba3510c824e3aea$export$c5be9092dbf465c = self.syscall;
async function $2780e5830b4782c9$export$c3455d2d4767a60b(unfiltered = false) {
return $4ba3510c824e3aea$export$c5be9092dbf465c("space.listPages", unfiltered);
}
async function $2780e5830b4782c9$export$126f79da5c357ad(name) {
return $4ba3510c824e3aea$export$c5be9092dbf465c("space.readPage", name);
}
async function $2780e5830b4782c9$export$7ed3b3f07f54e00c(name, text) {
return $4ba3510c824e3aea$export$c5be9092dbf465c("space.writePage", name, text);
}
async function $2780e5830b4782c9$export$2e9858c25869c949(name) {
return $4ba3510c824e3aea$export$c5be9092dbf465c("space.deletePage", name);
}
function $9072202279b76d33$export$1e8473eaf75b0d10(query) {
let n1 = $88d466d5aaf7a497$export$87cc1c28aef74af1(query, $d85524f23de2149a$export$8f49e4af10703ce3.parse(query).topNode);
// Clean the tree a bit
$255163dfff8c42fb$export$90b8ac453fa63932(n1, (n)=>{
if (!n.type) {
let trimmed = n.text.trim();
if (!trimmed) return null;
n.text = trimmed;
}
});
// console.log("Parsed", JSON.stringify(n, null, 2));
let queryNode = n1.children[0];
let parsedQuery = {
table: queryNode.children[0].children[0].text,
filter: []
};
let orderByNode = $255163dfff8c42fb$export$80a8b4335833eeeb(queryNode, "OrderClause");
if (orderByNode) {
let nameNode = $255163dfff8c42fb$export$80a8b4335833eeeb(orderByNode, "Name");
parsedQuery.orderBy = nameNode.children[0].text;
let orderNode = $255163dfff8c42fb$export$80a8b4335833eeeb(orderByNode, "Order");
parsedQuery.orderDesc = orderNode ? orderNode.children[0].text === "desc" : false;
}
let limitNode = $255163dfff8c42fb$export$80a8b4335833eeeb(queryNode, "LimitClause");
if (limitNode) {
let nameNode = $255163dfff8c42fb$export$80a8b4335833eeeb(limitNode, "Number");
parsedQuery.limit = $9072202279b76d33$var$valueNodeToVal(nameNode);
}
let filterNodes = $255163dfff8c42fb$export$dddeb721bf64f8df(queryNode, "FilterExpr");
for (let filterNode of filterNodes){
let val = undefined;
let valNode = filterNode.children[2].children[0];
val = $9072202279b76d33$var$valueNodeToVal(valNode);
let f = {
prop: filterNode.children[0].children[0].text,
op: filterNode.children[1].text,
value: val
};
parsedQuery.filter.push(f);
}
let selectNode = $255163dfff8c42fb$export$80a8b4335833eeeb(queryNode, "SelectClause");
if (selectNode) {
// console.log("Select node", JSON.stringify(selectNode));
parsedQuery.select = [];
$255163dfff8c42fb$export$dddeb721bf64f8df(selectNode, "Name").forEach((t)=>{
parsedQuery.select.push(t.children[0].text);
});
// let nameNode = findNodeOfType(selectNode, "Number");
// parsedQuery.limit = +nameNode!.children![0].text!;
}
let renderNode = $255163dfff8c42fb$export$80a8b4335833eeeb(queryNode, "RenderClause");
if (renderNode) {
let renderNameNode = $255163dfff8c42fb$export$80a8b4335833eeeb(renderNode, "String");
parsedQuery.render = $9072202279b76d33$var$valueNodeToVal(renderNameNode);
}
// console.log(JSON.stringify(queryNode, null, 2));
return parsedQuery;
}
function $9072202279b76d33$var$valueNodeToVal(valNode) {
switch(valNode.type){
case "Number":
return +valNode.children[0].text;
case "Bool":
return valNode.children[0].text === "true";
case "Null":
return null;
case "Name":
return valNode.children[0].text;
case "Regex":
let val = valNode.children[0].text;
return val.substring(1, val.length - 1);
case "String":
let stringVal = valNode.children[0].text;
return stringVal.substring(1, stringVal.length - 1);
case "List":
return $255163dfff8c42fb$export$dddeb721bf64f8df(valNode, "Value").map((t)=>$9072202279b76d33$var$valueNodeToVal(t.children[0])
);
}
}
function $9072202279b76d33$export$5884dae03c64f759(parsedQuery, records) {
let resultRecords = [];
if (parsedQuery.filter.length === 0) resultRecords = records.slice();
else recordLoop: for (let record of records){
const recordAny = record;
for (let { op: op , prop: prop , value: value } of parsedQuery.filter)switch(op){
case "=":
if (!(recordAny[prop] == value)) continue recordLoop;
break;
case "!=":
if (!(recordAny[prop] != value)) continue recordLoop;
break;
case "<":
if (!(recordAny[prop] < value)) continue recordLoop;
break;
case "<=":
if (!(recordAny[prop] <= value)) continue recordLoop;
break;
case ">":
if (!(recordAny[prop] > value)) continue recordLoop;
break;
case ">=":
if (!(recordAny[prop] >= value)) continue recordLoop;
break;
case "=~":
// TODO: Cache regexps somehow
if (!new RegExp(value).exec(recordAny[prop])) continue recordLoop;
break;
case "!=~":
if (new RegExp(value).exec(recordAny[prop])) continue recordLoop;
break;
case "in":
if (!value.includes(recordAny[prop])) continue recordLoop;
break;
}
resultRecords.push(recordAny);
}
// Now the sorting
if (parsedQuery.orderBy) resultRecords = resultRecords.sort((a, b)=>{
const orderBy = parsedQuery.orderBy;
const orderDesc = parsedQuery.orderDesc;
if (a[orderBy] === b[orderBy]) return 0;
if (a[orderBy] < b[orderBy]) return orderDesc ? 1 : -1;
else return orderDesc ? -1 : 1;
});
if (parsedQuery.limit) resultRecords = resultRecords.slice(0, parsedQuery.limit);
if (parsedQuery.select) resultRecords = resultRecords.map((rec)=>{
let newRec = {
};
for (let k of parsedQuery.select)newRec[k] = rec[k];
return newRec;
});
return resultRecords;
}
async function $9072202279b76d33$var$renderQuery(parsedQuery, data) {
if (parsedQuery.render) {
let { text: templateText } = await $2780e5830b4782c9$export$126f79da5c357ad(parsedQuery.render);
// let template = Handlebars.compile(templateText);
}
}
$hVExJ$jestglobals.test("Test parser", ()=>{
let parsedBasicQuery = $9072202279b76d33$export$1e8473eaf75b0d10(`page`);
$hVExJ$jestglobals.expect(parsedBasicQuery.table).toBe("page");
let parsedQuery1 = $9072202279b76d33$export$1e8473eaf75b0d10(`task where completed = false and dueDate <= "{{today}}" order by dueDate desc limit 5`);
$hVExJ$jestglobals.expect(parsedQuery1.table).toBe("task");
$hVExJ$jestglobals.expect(parsedQuery1.orderBy).toBe("dueDate");
$hVExJ$jestglobals.expect(parsedQuery1.orderDesc).toBe(true);
$hVExJ$jestglobals.expect(parsedQuery1.limit).toBe(5);
$hVExJ$jestglobals.expect(parsedQuery1.filter.length).toBe(2);
$hVExJ$jestglobals.expect(parsedQuery1.filter[0]).toStrictEqual({
op: "=",
prop: "completed",
value: false
});
$hVExJ$jestglobals.expect(parsedQuery1.filter[1]).toStrictEqual({
op: "<=",
prop: "dueDate",
value: "{{today}}"
});
let parsedQuery2 = $9072202279b76d33$export$1e8473eaf75b0d10(`page where name =~ /interview\\/.*/"`);
$hVExJ$jestglobals.expect(parsedQuery2.table).toBe("page");
$hVExJ$jestglobals.expect(parsedQuery2.filter.length).toBe(1);
$hVExJ$jestglobals.expect(parsedQuery2.filter[0]).toStrictEqual({
op: "=~",
prop: "name",
value: "interview\\/.*"
});
let parsedQuery3 = $9072202279b76d33$export$1e8473eaf75b0d10(`page where something != null`);
$hVExJ$jestglobals.expect(parsedQuery3.table).toBe("page");
$hVExJ$jestglobals.expect(parsedQuery3.filter.length).toBe(1);
$hVExJ$jestglobals.expect(parsedQuery3.filter[0]).toStrictEqual({
op: "!=",
prop: "something",
value: null
});
$hVExJ$jestglobals.expect($9072202279b76d33$export$1e8473eaf75b0d10(`page select name`).select).toStrictEqual([
"name"
]);
$hVExJ$jestglobals.expect($9072202279b76d33$export$1e8473eaf75b0d10(`page select name, age`).select).toStrictEqual([
"name",
"age",
]);
$hVExJ$jestglobals.expect($9072202279b76d33$export$1e8473eaf75b0d10(`gh-events where type in ["PushEvent", "somethingElse"]`)).toStrictEqual({
table: "gh-events",
filter: [
{
op: "in",
prop: "type",
value: [
"PushEvent",
"somethingElse"
]
},
]
});
$hVExJ$jestglobals.expect($9072202279b76d33$export$1e8473eaf75b0d10(`something render "template/table"`)).toStrictEqual({
table: "something",
filter: [],
render: "template/table"
});
});
$hVExJ$jestglobals.test("Test performing the queries", ()=>{
let data = [
{
name: "interview/My Interview",
lastModified: 1
},
{
name: "interview/My Interview 2",
lastModified: 2
},
{
name: "Pete",
age: 38
},
{
name: "Angie",
age: 28
},
];
$hVExJ$jestglobals.expect($9072202279b76d33$export$5884dae03c64f759($9072202279b76d33$export$1e8473eaf75b0d10(`page where name =~ /interview\\/.*/`), data)).toStrictEqual([
{
name: "interview/My Interview",
lastModified: 1
},
{
name: "interview/My Interview 2",
lastModified: 2
},
]);
$hVExJ$jestglobals.expect($9072202279b76d33$export$5884dae03c64f759($9072202279b76d33$export$1e8473eaf75b0d10(`page where name =~ /interview\\/.*/ order by lastModified`), data)).toStrictEqual([
{
name: "interview/My Interview",
lastModified: 1
},
{
name: "interview/My Interview 2",
lastModified: 2
},
]);
$hVExJ$jestglobals.expect($9072202279b76d33$export$5884dae03c64f759($9072202279b76d33$export$1e8473eaf75b0d10(`page where name =~ /interview\\/.*/ order by lastModified desc`), data)).toStrictEqual([
{
name: "interview/My Interview 2",
lastModified: 2
},
{
name: "interview/My Interview",
lastModified: 1
},
]);
$hVExJ$jestglobals.expect($9072202279b76d33$export$5884dae03c64f759($9072202279b76d33$export$1e8473eaf75b0d10(`page where age > 30`), data)).toStrictEqual([
{
name: "Pete",
age: 38
},
]);
$hVExJ$jestglobals.expect($9072202279b76d33$export$5884dae03c64f759($9072202279b76d33$export$1e8473eaf75b0d10(`page where age > 28 and age < 38`), data)).toStrictEqual([]);
$hVExJ$jestglobals.expect($9072202279b76d33$export$5884dae03c64f759($9072202279b76d33$export$1e8473eaf75b0d10(`page where age > 30 select name`), data)).toStrictEqual([
{
name: "Pete"
}
]);
$hVExJ$jestglobals.expect($9072202279b76d33$export$5884dae03c64f759($9072202279b76d33$export$1e8473eaf75b0d10(`page where name in ["Pete"] select name`), data)).toStrictEqual([
{
name: "Pete"
}
]);
});
//# sourceMappingURL=engine.test.js.map

File diff suppressed because one or more lines are too long

View File

@ -59,7 +59,7 @@ export async function indexItems({ name, tree }: IndexTreeEvent) {
export async function queryProvider({
query,
}: QueryProviderEvent): Promise<string> {
}: QueryProviderEvent): Promise<any[]> {
let allItems: Item[] = [];
for (let { key, page, value } of await scanPrefixGlobal("it:")) {
let [, pos] = key.split(":");
@ -69,10 +69,5 @@ export async function queryProvider({
pos: +pos,
});
}
let markdownItems = applyQuery(query, allItems).map(
(item) =>
`* [[${item.page}@${item.pos}]] ${item.name}` +
(item.nested ? "\n " + item.nested : "")
);
return markdownItems.join("\n");
return applyQuery(query, allItems);
}

View File

@ -65,9 +65,8 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
export async function pageQueryProvider({
query,
}: QueryProviderEvent): Promise<string> {
}: QueryProviderEvent): Promise<any[]> {
let allPages = await listPages();
if (query.select) {
let allPageMap: Map<string, any> = new Map(
allPages.map((pm) => [pm.name, pm])
);
@ -80,29 +79,21 @@ export async function pageQueryProvider({
}
}
allPages = [...allPageMap.values()];
return jsonToMDTable(applyQuery(query, allPages), (k, v) =>
k === "name" ? `[[${v}]]` : v
);
} else {
return applyQuery(query, allPages)
.map((pageMeta: PageMeta) => `* [[${pageMeta.name}]]`)
.join("\n");
}
return applyQuery(query, allPages);
}
export async function linkQueryProvider({
query,
pageName,
}: QueryProviderEvent): Promise<string> {
}: QueryProviderEvent): Promise<any[]> {
let uniqueLinks = new Set<string>();
for (let { value: name } of await scanPrefixGlobal(`pl:${pageName}:`)) {
uniqueLinks.add(name);
}
let markdownLinks = applyQuery(
return applyQuery(
query,
[...uniqueLinks].map((l) => ({ name: l }))
).map((pageMeta) => `* [[${pageMeta.name}]]`);
return markdownLinks.join("\n");
);
}
export async function deletePage() {

View File

@ -0,0 +1,6 @@
name: github
functions:
test:
path: ./github.ts:queryEvents
events:
- query:gh-events

View File

@ -0,0 +1,84 @@
import { applyQuery, QueryProviderEvent, renderQuery } from "../query/engine";
import { jsonToMDTable } from "../query/util";
type GithubEvent = {
id: string;
type: string;
actor: GithubUser;
repo: GithubRepo;
created_at: string;
payload: any;
org: GithubOrg;
};
type GithubUser = {
id: number;
login: string;
display_login: string;
url: string;
};
type GithubRepo = {
id: number;
name: string;
url: string;
};
type GithubOrg = {
id: number;
login: string;
url: string;
};
type ExposedEvent = {
id: string;
type: string;
username: string;
repo: string;
};
async function listEvents(username: string): Promise<GithubEvent[]> {
let events = await fetch(`https://api.github.com/users/${username}/events`);
return await events.json();
}
async function listIssues(filter: string): Promise<any[]> {
let issues = await fetch(
`https://api.github.com/issues?q=${encodeURIComponent(filter)}`
);
return await issues.json();
}
function mapEvent(event: GithubEvent): any {
// console.log("Event", event);
return {
...event.payload,
id: event.id,
type: event.type,
username: event.actor.login,
repo: event.repo.name,
date: event.created_at.split("T")[0],
};
}
export async function queryEvents({
query,
}: QueryProviderEvent): Promise<any[]> {
let usernameFilter = query.filter.find((f) => f.prop === "username");
if (!usernameFilter) {
throw Error("No 'username' filter specified, this is mandatory");
}
let username = usernameFilter.value;
let allEvents = (await listEvents(username)).map(mapEvent);
return applyQuery(query, allEvents);
}
// export async function queryIssues({
// query,
// }: QueryProviderEvent): Promise<string> {
// let filter = query.filter.find((f) => f.prop === "filter");
// if (!filter) {
// throw Error("No 'filter' specified, this is mandatory");
// }
// let username = filter.value;
// }

View File

@ -5,6 +5,9 @@ import { parseMarkdown } from "@silverbulletmd/plugos-silverbullet-syscall/markd
import { extractMeta } from "../query/data";
import { niceDate } from "../core/dates";
import { Post } from "@mattermost/types/lib/posts";
import { ServerChannel } from "@mattermost/types/lib/channels";
import { UserProfile } from "@mattermost/types/lib/users";
import { Team } from "@mattermost/types/lib/teams";
type AugmentedPost = Post & {
// Dates we can use to filter
@ -25,6 +28,7 @@ function mattermostDesktopUrlForPost(
type MattermostConfig = {
url: string;
token: string;
defaultTeam: string;
};
async function getConfig(): Promise<MattermostConfig> {
@ -46,11 +50,49 @@ function augmentPost(post: AugmentedPost) {
}
}
class CachingClient4 {
constructor(public client: Client4) {}
private channelCache = new Map<string, ServerChannel>();
async getChannelCached(channelId: string): Promise<ServerChannel> {
let channel = this.channelCache.get(channelId);
if (channel) {
return channel;
}
channel = await this.client.getChannel(channelId);
this.channelCache.set(channelId, channel!);
return channel!;
}
private teamCache = new Map<string, Team>();
async getTeamCached(teamId: string): Promise<Team> {
let team = this.teamCache.get(teamId);
if (team) {
return team;
}
team = await this.client.getTeam(teamId);
this.teamCache.set(teamId, team!);
return team!;
}
private userCache = new Map<string, UserProfile>();
async getUserCached(userId: string): Promise<UserProfile> {
let user = this.userCache.get(userId);
if (user) {
return user;
}
user = await this.client.getUser(userId);
this.userCache.set(userId, user!);
return user!;
}
}
export async function savedPostsQueryProvider({
query,
}: QueryProviderEvent): Promise<string> {
}: QueryProviderEvent): Promise<any[]> {
let config = await getConfig();
let client = new Client4();
let cachingClient = new CachingClient4(client);
client.setUrl(config.url);
client.setToken(config.token);
let me = await client.getMe();
@ -61,20 +103,22 @@ export async function savedPostsQueryProvider({
augmentPost(post);
savedPosts.push(post);
}
let savedPostsMd = [];
let resultSavedPosts = [];
savedPosts = applyQuery(query, savedPosts);
for (let savedPost of savedPosts) {
let channel = await client.getChannel(savedPost.channel_id);
let team = await client.getTeam(channel.team_id);
savedPostsMd.push(
`@${(await client.getUser(savedPost.user_id)).username} [${
savedPost.createdAt
}](${mattermostDesktopUrlForPost(
client.url,
team.name,
savedPost.id
)}):\n> ${savedPost.message.substring(0, 1000).replaceAll(/\n/g, "\n> ")}`
);
let channel = await cachingClient.getChannelCached(savedPost.channel_id);
let teamName = config.defaultTeam;
if (channel.team_id) {
let team = await cachingClient.getTeamCached(channel.team_id);
teamName = team.name;
}
return savedPostsMd.join("\n\n");
resultSavedPosts.push({
...savedPost,
user: await cachingClient.getUserCached(savedPost.user_id),
channel: channel,
teamName: teamName,
url: mattermostDesktopUrlForPost(client.url, teamName, savedPost.id),
});
}
return resultSavedPosts;
}

1427
packages/plugs/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,12 +8,28 @@
"license": "MIT",
"scripts": {
"generate": "lezer-generator query/query.grammar -o query/parse-query.js",
"watch": "plugos-bundle -w --dist dist --exclude @lezer/lr yaml -- */*.plug.yaml",
"build": "plugos-bundle --dist dist --exclude @lezer/lr yaml -- */*.plug.yaml"
"watch": "plugos-bundle -w --dist dist --exclude @lezer/lr yaml handlebars -- */*.plug.yaml",
"build": "plugos-bundle --dist dist --exclude @lezer/lr yaml handlebars -- */*.plug.yaml",
"test": "jest build/test"
},
"files": [
"dist"
],
"targets": {
"test": {
"source": [
"query/engine.test.ts"
],
"outputFormat": "commonjs",
"isLibrary": true,
"context": "node",
"includeNodeModules": [
"@silverbulletmd/common",
"@silverbulletmd/plugos-silverbullet-syscall"
],
"distDir": "build/test"
}
},
"dependencies": {
"@jest/globals": "^27.5.1",
"@lezer/generator": "^0.15.4",

View File

@ -9,6 +9,12 @@ functions:
updatePlugs:
path: ./plugmanager.ts:updatePlugs
env: server
check:
path: "./plugmanager.ts:checkCommand"
command:
name: "Plug: Check"
mac: "Cmd-Alt-c"
key: "Ctrl-Alt-c"
compile:
path: "./plugmanager.ts:compileCommand"
command:

View File

@ -36,7 +36,18 @@ export async function compileCommand() {
);
console.log("Wrote this plug", manifest);
await hideBhs();
// Important not to await!
await reloadPlugs();
} catch (e: any) {
await showBhs(e.message);
// console.error("Got this error from compiler", e.message);
}
}
export async function checkCommand() {
let text = await getText();
try {
await compileDefinition(text);
await hideBhs();
reloadPlugs();
} catch (e: any) {
await showBhs(e.message);

View File

@ -86,7 +86,7 @@ export function extractMeta(parseTree: ParseTree, remove = false): any {
export async function queryProvider({
query,
}: QueryProviderEvent): Promise<string> {
}: QueryProviderEvent): Promise<any[]> {
let allData: any[] = [];
for (let { key, page, value } of await scanPrefixGlobal("data:")) {
let [, pos] = key.split("@");
@ -96,6 +96,5 @@ export async function queryProvider({
pos: +pos,
});
}
let resultData = applyQuery(query, allData);
return jsonToMDTable(resultData);
return applyQuery(query, allData);
}

View File

@ -47,6 +47,25 @@ test("Test parser", () => {
"name",
"age",
]);
expect(
parseQuery(`gh-events where type in ["PushEvent", "somethingElse"]`)
).toStrictEqual({
table: "gh-events",
filter: [
{
op: "in",
prop: "type",
value: ["PushEvent", "somethingElse"],
},
],
});
expect(parseQuery(`something render "template/table"`)).toStrictEqual({
table: "something",
filter: [],
render: "template/table",
});
});
test("Test performing the queries", () => {
@ -92,4 +111,8 @@ test("Test performing the queries", () => {
expect(
applyQuery(parseQuery(`page where age > 30 select name`), data)
).toStrictEqual([{ name: "Pete" }]);
expect(
applyQuery(parseQuery(`page where name in ["Pete"] select name`), data)
).toStrictEqual([{ name: "Pete" }]);
});

View File

@ -1,8 +1,17 @@
import { collectNodesOfType, findNodeOfType, replaceNodesMatching } from "@silverbulletmd/common/tree";
import {
collectNodesOfType,
findNodeOfType,
ParseTree,
replaceNodesMatching,
} from "@silverbulletmd/common/tree";
import { lezerToParseTree } from "@silverbulletmd/common/parse_tree";
import Handlebars from "handlebars";
import YAML from "yaml";
// @ts-ignore
import { parser } from "./parse-query";
import { readPage } from "@silverbulletmd/plugos-silverbullet-syscall/space";
import { niceDate } from "../core/dates";
export type QueryProviderEvent = {
query: ParsedQuery;
@ -22,6 +31,7 @@ export type ParsedQuery = {
limit?: number;
filter: Filter[];
select?: string[];
render?: string;
};
export function parseQuery(query: string): ParsedQuery {
@ -56,34 +66,14 @@ export function parseQuery(query: string): ParsedQuery {
let limitNode = findNodeOfType(queryNode, "LimitClause");
if (limitNode) {
let nameNode = findNodeOfType(limitNode, "Number");
parsedQuery.limit = +nameNode!.children![0].text!;
parsedQuery.limit = valueNodeToVal(nameNode!);
}
let filterNodes = collectNodesOfType(queryNode, "FilterExpr");
for (let filterNode of filterNodes) {
let val: any = undefined;
let valNode = filterNode.children![2].children![0];
switch (valNode.type) {
case "Number":
val = valNode.children![0].text!;
break;
case "Bool":
val = valNode.children![0].text! === "true";
break;
case "Null":
val = null;
break;
case "Name":
val = valNode.children![0].text!;
break;
case "Regex":
val = valNode.children![0].text!;
val = val.substring(1, val.length - 1);
break;
case "String":
val = valNode.children![0].text!;
val = val.substring(1, val.length - 1);
break;
}
val = valueNodeToVal(valNode);
let f: Filter = {
prop: filterNode.children![0].children![0].text!,
op: filterNode.children![1].text!,
@ -93,7 +83,7 @@ export function parseQuery(query: string): ParsedQuery {
}
let selectNode = findNodeOfType(queryNode, "SelectClause");
if (selectNode) {
console.log("Select node", JSON.stringify(selectNode));
// console.log("Select node", JSON.stringify(selectNode));
parsedQuery.select = [];
collectNodesOfType(selectNode, "Name").forEach((t) => {
parsedQuery.select!.push(t.children![0].text!);
@ -102,10 +92,39 @@ export function parseQuery(query: string): ParsedQuery {
// parsedQuery.limit = +nameNode!.children![0].text!;
}
let renderNode = findNodeOfType(queryNode, "RenderClause");
if (renderNode) {
let renderNameNode = findNodeOfType(renderNode, "String");
parsedQuery.render = valueNodeToVal(renderNameNode!);
}
// console.log(JSON.stringify(queryNode, null, 2));
return parsedQuery;
}
function valueNodeToVal(valNode: ParseTree): any {
switch (valNode.type) {
case "Number":
return +valNode.children![0].text!;
case "Bool":
return valNode.children![0].text! === "true";
case "Null":
return null;
case "Name":
return valNode.children![0].text!;
case "Regex":
let val = valNode.children![0].text!;
return val.substring(1, val.length - 1);
case "String":
let stringVal = valNode.children![0].text!;
return stringVal.substring(1, stringVal.length - 1);
case "List":
return collectNodesOfType(valNode, "Value").map((t) =>
valueNodeToVal(t.children![0])
);
}
}
export function applyQuery<T>(parsedQuery: ParsedQuery, records: T[]): T[] {
let resultRecords: any[] = [];
if (parsedQuery.filter.length === 0) {
@ -156,6 +175,11 @@ export function applyQuery<T>(parsedQuery: ParsedQuery, records: T[]): T[] {
continue recordLoop;
}
break;
case "in":
if (!value.includes(recordAny[prop])) {
continue recordLoop;
}
break;
}
}
resultRecords.push(recordAny);
@ -191,3 +215,33 @@ export function applyQuery<T>(parsedQuery: ParsedQuery, records: T[]): T[] {
}
return resultRecords;
}
export async function renderQuery(
parsedQuery: ParsedQuery,
data: any[]
): Promise<string> {
if (parsedQuery.render) {
Handlebars.registerHelper("json", (v) => JSON.stringify(v));
Handlebars.registerHelper("niceDate", (ts) => niceDate(new Date(ts)));
Handlebars.registerHelper("yaml", (v, prefix) => {
if (typeof prefix === "string") {
let yaml = YAML.stringify(v)
.split("\n")
.join("\n" + prefix)
.trim();
if (Array.isArray(v)) {
return "\n" + prefix + yaml;
} else {
return yaml;
}
} else {
return YAML.stringify(v).trim();
}
});
let { text: templateText } = await readPage(parsedQuery.render);
let template = Handlebars.compile(templateText, { noEscape: true });
return template(data);
}
return "ERROR";
}

View File

@ -11,9 +11,9 @@ import {
writePage,
} from "@silverbulletmd/plugos-silverbullet-syscall/space";
import { invokeFunction } from "@silverbulletmd/plugos-silverbullet-syscall/system";
import { parseQuery } from "./engine";
import { parseQuery, renderQuery } from "./engine";
import { replaceTemplateVars } from "../core/template";
import { queryRegex, removeQueries } from "./util";
import { jsonToMDTable, queryRegex, removeQueries } from "./util";
import { dispatch } from "@plugos/plugos-syscall/event";
import { replaceAsync } from "../lib/util";
import { parseMarkdown } from "@silverbulletmd/plugos-silverbullet-syscall/markdown";
@ -57,7 +57,12 @@ export async function updateMaterializedQueriesOnPage(pageName: string) {
if (results.length === 0) {
return `${startQuery}\n${endQuery}`;
} else if (results.length === 1) {
return `${startQuery}\n${results[0]}\n${endQuery}`;
if (parsedQuery.render) {
let rendered = await renderQuery(parsedQuery, results[0]);
return `${startQuery}\n${rendered.trim()}\n${endQuery}`;
} else {
return `${startQuery}\n${jsonToMDTable(results[0])}\n${endQuery}`;
}
} else {
console.error("Too many query results", results);
return fullMatch;

View File

@ -1,21 +1,16 @@
// This file was generated by lezer-generator. You probably shouldn't edit it.
import { LRParser } from "@lezer/lr";
import {LRParser} from "@lezer/lr"
export const parser = LRParser.deserialize({
version: 13,
states:
"%WOVQPOOO[QQO'#C^QOQPOOOmQPO'#C`OrQQO'#CjOwQPO'#ClO|QPO'#CmOOQO'#Cn'#CnO!RQQO,58xO!dQPO'#CcO#OQQO'#CaOOQO'#Ca'#CaOOQO,58z,58zO#dQPO,59UOOQO,59W,59WO#iQQO'#DWOOQO,59X,59XOOQO-E6l-E6lO#}QQO,58}OmQPO,58|O$cQQO1G.pO$zQPO'#CoO%PQQO,59rOOQO'#Cg'#CgOOQO'#Ci'#CiOOQO'#Cd'#CdOOQO1G.i1G.iOOQO1G.h1G.hOOQO'#Ck'#CkOOQO7+$[7+$[OOQO,59Z,59ZOOQO-E6m-E6m",
stateData:
"%e~OfOS~ORPO~OgROtSOxTOyUOdQX~ORXO~Ou]O~OX^O~OR_O~OgROtSOxTOyUOdQa~OhbOlbOmbOnbOobOpbOqbOrbO~OscOdTXgTXtTXxTXyTX~ORdO~O{eOdzXgzXtzXxzXyzX~OXiOYiO[iOigOjgOkhO~OvlOwlOd^ig^it^ix^iy^i~ORnO~O{eOdzagzatzaxzayza~O",
goto: "!y{PP|P!P!T!W!Z!aPP!dP!d!P!g!P!P!j!pPPPPPPPPPPPPPPPPPPPPPP!vRQOTVPWR[RRZRQYRRkcRjbRibRmdQWPRaWQf_RofR`U",
nodeNames:
"⚠ Program Query Name WhereClause LogicalExpr AndExpr FilterExpr Value Number String Bool Regex Null OrderClause Order LimitClause SelectClause",
maxTerm: 43,
states: "&fOVQPOOOmQQO'#C^QOQPOOOtQPO'#C`OyQQO'#CkO!OQPO'#CmO!TQPO'#CnO!YQPO'#CoOOQO'#Cp'#CpO!_QQO,58xO!fQQO'#CcO#TQQO'#CaOOQO'#Ca'#CaOOQO,58z,58zO#lQPO,59VOOQO,59X,59XO#qQQO'#D`OOQO,59Y,59YOOQO,59Z,59ZOOQO-E6n-E6nO$YQQO,58}OtQPO,58|O$qQQO1G.qO%]QPO'#CrO%bQQO,59zOOQO'#Cg'#CgOOQO'#Ci'#CiO$YQQO'#CjOOQO'#Cd'#CdOOQO1G.i1G.iOOQO1G.h1G.hOOQO'#Cl'#ClOOQO7+$]7+$]OOQO,59^,59^OOQO-E6p-E6pO%yQPO'#C|O&RQPO,59UO$YQQO'#CqO&WQPO,59hOOQO1G.p1G.pOOQO,59],59]OOQO-E6o-E6o",
stateData: "&`~OiOS~ORPO~OjRO|SO!QTO!RUO!TVO~OgQX~P[ORYO~O}^O~OX_O~OR`O~OYbO~OgQa~P[OkdOsdOtdOudOvdOwdOxdOydOzdO~O{eOgTXjTX|TX!QTX!RTX!TTX~ORfO~OqgOg!SXj!SX|!SX!Q!SX!R!SX!T!SX~OXlOYlO[lOliOmiOnjOokO~O!OoO!PoOg_ij_i|_i!Q_i!R_i!T_i~ORqO~OqgOg!Saj!Sa|!Sa!Q!Sa!R!Sa!T!Sa~OquOrpX~OrwO~OquOrpa~O",
goto: "#d!TPP!UP!X!]!`!c!iPP!rP!r!r!X!w!X!X!X!z#Q#WPPPPPPPPP#^PPPPPPPPPPPPPPPPP#aRQOTWPXR]RR[RQZRRneQmdQskRxuVldkuRpfQXPRcXQvsRyvQh`RrhRtkRaU",
nodeNames: "⚠ Program Query Name WhereClause LogicalExpr AndExpr FilterExpr Value Number String Bool Regex Null List OrderClause Order LimitClause SelectClause RenderClause",
maxTerm: 51,
skippedNodes: [0],
repeatNodeCount: 2,
tokenData:
"=_~RxX^#opq#oqr$drs$w|}%c}!O%h!P!Q%y!Q![&p!^!_&x!_!`'V!`!a'd!c!}%h#R#S%h#T#U'q#U#V*W#V#W%h#W#X+S#X#Y%h#Y#Z-O#Z#`%h#`#a/`#a#b%h#b#c1s#c#d3o#d#g%h#g#h6S#h#i9O#i#k%h#k#l:z#l#o%h#y#z#o$f$g#o#BY#BZ#o$IS$I_#o$Ip$Iq$w$Iq$Ir$w$I|$JO#o$JT$JU#o$KV$KW#o&FU&FV#o~#tYf~X^#opq#o#y#z#o$f$g#o#BY#BZ#o$IS$I_#o$I|$JO#o$JT$JU#o$KV$KW#o&FU&FV#o~$gP!_!`$j~$oPn~#r#s$r~$wOr~~$zUOr$wrs%^s$Ip$w$Ip$Iq%^$Iq$Ir%^$Ir~$w~%cOY~~%hO{~P%mSRP}!O%h!c!}%h#R#S%h#T#o%h~&OV[~OY%yZ]%y^!P%y!P!Q&e!Q#O%y#O#P&j#P~%y~&jO[~~&mPO~%y~&uPX~!Q![&p~&}Ph~!_!`'Q~'VOl~~'[Pm~#r#s'_~'dOq~~'iPp~!_!`'l~'qOo~R'vWRP}!O%h!c!}%h#R#S%h#T#b%h#b#c(`#c#g%h#g#h)[#h#o%hR(eURP}!O%h!c!}%h#R#S%h#T#W%h#W#X(w#X#o%hR)OSsQRP}!O%h!c!}%h#R#S%h#T#o%hR)aURP}!O%h!c!}%h#R#S%h#T#V%h#V#W)s#W#o%hR)zSwQRP}!O%h!c!}%h#R#S%h#T#o%hR*]URP}!O%h!c!}%h#R#S%h#T#m%h#m#n*o#n#o%hR*vSuQRP}!O%h!c!}%h#R#S%h#T#o%hR+XURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y+k#Y#o%hR+pURP}!O%h!c!}%h#R#S%h#T#g%h#g#h,S#h#o%hR,XURP}!O%h!c!}%h#R#S%h#T#V%h#V#W,k#W#o%hR,rSvQRP}!O%h!c!}%h#R#S%h#T#o%hR-TTRP}!O%h!c!}%h#R#S%h#T#U-d#U#o%hR-iURP}!O%h!c!}%h#R#S%h#T#`%h#`#a-{#a#o%hR.QURP}!O%h!c!}%h#R#S%h#T#g%h#g#h.d#h#o%hR.iURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y.{#Y#o%hR/SSjQRP}!O%h!c!}%h#R#S%h#T#o%hR/eURP}!O%h!c!}%h#R#S%h#T#]%h#]#^/w#^#o%hR/|URP}!O%h!c!}%h#R#S%h#T#a%h#a#b0`#b#o%hR0eURP}!O%h!c!}%h#R#S%h#T#]%h#]#^0w#^#o%hR0|URP}!O%h!c!}%h#R#S%h#T#h%h#h#i1`#i#o%hR1gSxQRP}!O%h!c!}%h#R#S%h#T#o%hR1xURP}!O%h!c!}%h#R#S%h#T#i%h#i#j2[#j#o%hR2aURP}!O%h!c!}%h#R#S%h#T#`%h#`#a2s#a#o%hR2xURP}!O%h!c!}%h#R#S%h#T#`%h#`#a3[#a#o%hR3cSkQRP}!O%h!c!}%h#R#S%h#T#o%hR3tURP}!O%h!c!}%h#R#S%h#T#f%h#f#g4W#g#o%hR4]URP}!O%h!c!}%h#R#S%h#T#W%h#W#X4o#X#o%hR4tURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y5W#Y#o%hR5]URP}!O%h!c!}%h#R#S%h#T#f%h#f#g5o#g#o%hR5vStQRP}!O%h!c!}%h#R#S%h#T#o%hR6XURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y6k#Y#o%hR6pURP}!O%h!c!}%h#R#S%h#T#`%h#`#a7S#a#o%hR7XURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y7k#Y#o%hR7pURP}!O%h!c!}%h#R#S%h#T#V%h#V#W8S#W#o%hR8XURP}!O%h!c!}%h#R#S%h#T#h%h#h#i8k#i#o%hR8rSyQRP}!O%h!c!}%h#R#S%h#T#o%hR9TURP}!O%h!c!}%h#R#S%h#T#f%h#f#g9g#g#o%hR9lURP}!O%h!c!}%h#R#S%h#T#i%h#i#j:O#j#o%hR:TURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y:g#Y#o%hR:nSiQRP}!O%h!c!}%h#R#S%h#T#o%hR;PURP}!O%h!c!}%h#R#S%h#T#[%h#[#];c#]#o%hR;hURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y;z#Y#o%hR<PURP}!O%h!c!}%h#R#S%h#T#f%h#f#g<c#g#o%hR<hURP}!O%h!c!}%h#R#S%h#T#X%h#X#Y<z#Y#o%hR=RSgQRP}!O%h!c!}%h#R#S%h#T#o%h",
repeatNodeCount: 3,
tokenData: "Ap~R}X^$Opq$Oqr$srs%W|}%r}!O%w!P!Q&Y!Q!['P!^!_'X!_!`'f!`!a's!c!}%w!}#O(Q#P#Q(V#R#S%w#T#U([#U#V*q#V#W%w#W#X+m#X#Y%w#Y#Z-i#Z#]%w#]#^/y#^#`%w#`#a0u#a#b%w#b#c3Y#c#d5U#d#f%w#f#g7i#g#h:e#h#i=a#i#k%w#k#l?]#l#o%w#y#z$O$f$g$O#BY#BZ$O$IS$I_$O$Ip$Iq%W$Iq$Ir%W$I|$JO$O$JT$JU$O$KV$KW$O&FU&FV$O~$TYi~X^$Opq$O#y#z$O$f$g$O#BY#BZ$O$IS$I_$O$I|$JO$O$JT$JU$O$KV$KW$O&FU&FV$O~$vP!_!`$y~%OPu~#r#s%R~%WOy~~%ZUOr%Wrs%ms$Ip%W$Ip$Iq%m$Iq$Ir%m$Ir~%W~%rOY~~%wOq~P%|SRP}!O%w!c!}%w#R#S%w#T#o%w~&_V[~OY&YZ]&Y^!P&Y!P!Q&t!Q#O&Y#O#P&y#P~&Y~&yO[~~&|PO~&Y~'UPX~!Q!['P~'^Pk~!_!`'a~'fOs~~'kPt~#r#s'n~'sOx~~'xPw~!_!`'{~(QOv~~(VOo~~([Or~R(aWRP}!O%w!c!}%w#R#S%w#T#b%w#b#c(y#c#g%w#g#h)u#h#o%wR)OURP}!O%w!c!}%w#R#S%w#T#W%w#W#X)b#X#o%wR)iS{QRP}!O%w!c!}%w#R#S%w#T#o%wR)zURP}!O%w!c!}%w#R#S%w#T#V%w#V#W*^#W#o%wR*eS!PQRP}!O%w!c!}%w#R#S%w#T#o%wR*vURP}!O%w!c!}%w#R#S%w#T#m%w#m#n+Y#n#o%wR+aS}QRP}!O%w!c!}%w#R#S%w#T#o%wR+rURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y,U#Y#o%wR,ZURP}!O%w!c!}%w#R#S%w#T#g%w#g#h,m#h#o%wR,rURP}!O%w!c!}%w#R#S%w#T#V%w#V#W-U#W#o%wR-]S!OQRP}!O%w!c!}%w#R#S%w#T#o%wR-nTRP}!O%w!c!}%w#R#S%w#T#U-}#U#o%wR.SURP}!O%w!c!}%w#R#S%w#T#`%w#`#a.f#a#o%wR.kURP}!O%w!c!}%w#R#S%w#T#g%w#g#h.}#h#o%wR/SURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y/f#Y#o%wR/mSmQRP}!O%w!c!}%w#R#S%w#T#o%wR0OURP}!O%w!c!}%w#R#S%w#T#b%w#b#c0b#c#o%wR0iSzQRP}!O%w!c!}%w#R#S%w#T#o%wR0zURP}!O%w!c!}%w#R#S%w#T#]%w#]#^1^#^#o%wR1cURP}!O%w!c!}%w#R#S%w#T#a%w#a#b1u#b#o%wR1zURP}!O%w!c!}%w#R#S%w#T#]%w#]#^2^#^#o%wR2cURP}!O%w!c!}%w#R#S%w#T#h%w#h#i2u#i#o%wR2|S!QQRP}!O%w!c!}%w#R#S%w#T#o%wR3_URP}!O%w!c!}%w#R#S%w#T#i%w#i#j3q#j#o%wR3vURP}!O%w!c!}%w#R#S%w#T#`%w#`#a4Y#a#o%wR4_URP}!O%w!c!}%w#R#S%w#T#`%w#`#a4q#a#o%wR4xSnQRP}!O%w!c!}%w#R#S%w#T#o%wR5ZURP}!O%w!c!}%w#R#S%w#T#f%w#f#g5m#g#o%wR5rURP}!O%w!c!}%w#R#S%w#T#W%w#W#X6U#X#o%wR6ZURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y6m#Y#o%wR6rURP}!O%w!c!}%w#R#S%w#T#f%w#f#g7U#g#o%wR7]S|QRP}!O%w!c!}%w#R#S%w#T#o%wR7nURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y8Q#Y#o%wR8VURP}!O%w!c!}%w#R#S%w#T#b%w#b#c8i#c#o%wR8nURP}!O%w!c!}%w#R#S%w#T#W%w#W#X9Q#X#o%wR9VURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y9i#Y#o%wR9nURP}!O%w!c!}%w#R#S%w#T#f%w#f#g:Q#g#o%wR:XS!TQRP}!O%w!c!}%w#R#S%w#T#o%wR:jURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y:|#Y#o%wR;RURP}!O%w!c!}%w#R#S%w#T#`%w#`#a;e#a#o%wR;jURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y;|#Y#o%wR<RURP}!O%w!c!}%w#R#S%w#T#V%w#V#W<e#W#o%wR<jURP}!O%w!c!}%w#R#S%w#T#h%w#h#i<|#i#o%wR=TS!RQRP}!O%w!c!}%w#R#S%w#T#o%wR=fURP}!O%w!c!}%w#R#S%w#T#f%w#f#g=x#g#o%wR=}URP}!O%w!c!}%w#R#S%w#T#i%w#i#j>a#j#o%wR>fURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y>x#Y#o%wR?PSlQRP}!O%w!c!}%w#R#S%w#T#o%wR?bURP}!O%w!c!}%w#R#S%w#T#[%w#[#]?t#]#o%wR?yURP}!O%w!c!}%w#R#S%w#T#X%w#X#Y@]#Y#o%wR@bURP}!O%w!c!}%w#R#S%w#T#f%w#f#g@t#g#o%wR@yURP}!O%w!c!}%w#R#S%w#T#X%w#X#YA]#Y#o%wRAdSjQRP}!O%w!c!}%w#R#S%w#T#o%w",
tokenizers: [0, 1],
topRules: { Program: [0, 1] },
tokenPrec: 0,
});
topRules: {"Program":[0,1]},
tokenPrec: 0
})

View File

@ -13,7 +13,9 @@ export const
Bool = 11,
Regex = 12,
Null = 13,
OrderClause = 14,
Order = 15,
LimitClause = 16,
SelectClause = 17
List = 14,
OrderClause = 15,
Order = 16,
LimitClause = 17,
SelectClause = 18,
RenderClause = 19

View File

@ -3,7 +3,7 @@
@top Program { Query }
Query {
Name ( WhereClause | OrderClause | LimitClause | SelectClause )*
Name ( WhereClause | OrderClause | LimitClause | SelectClause | RenderClause )*
}
commaSep<content> { content ("," content)* }
@ -12,12 +12,13 @@ WhereClause { "where" LogicalExpr }
OrderClause { "order" "by" Name Order? }
LimitClause { "limit" Number }
SelectClause { "select" commaSep<Name> }
RenderClause { "render" String }
Order {
"desc" | "asc"
}
Value { Number | String | Bool | Regex | Null }
Value { Number | String | Bool | Regex | Null | List }
LogicalExpr { AndExpr | FilterExpr }
@ -32,8 +33,11 @@ FilterExpr {
| Name ">" Value
| Name "=~" Value
| Name "!=~" Value
| Name "in" Value
}
List { "[" commaSep<Value> "]" }
@skip { space }

View File

@ -25,7 +25,7 @@ import {
renderToText,
} from "@silverbulletmd/common/tree";
import { removeQueries } from "../query/util";
import { applyQuery, QueryProviderEvent } from "../query/engine";
import { applyQuery, QueryProviderEvent, renderQuery } from "../query/engine";
import { niceDate } from "../core/dates";
export type Task = {
@ -195,7 +195,7 @@ export async function postponeCommand() {
export async function queryProvider({
query,
}: QueryProviderEvent): Promise<string> {
}: QueryProviderEvent): Promise<Task[]> {
let allTasks: Task[] = [];
for (let { key, page, value } of await scanPrefixGlobal("task:")) {
let [, pos] = key.split(":");
@ -205,10 +205,5 @@ export async function queryProvider({
pos: pos,
});
}
let markdownTasks = applyQuery(query, allTasks).map(
(t) =>
`* [${t.done ? "x" : " "}] [[${t.page}@${t.pos}]] ${t.name}` +
(t.nested ? "\n " + t.nested : "")
);
return markdownTasks.join("\n");
return applyQuery(query, allTasks);
}

View File

@ -10,7 +10,7 @@
"silverbullet": "./dist/server.js"
},
"scripts": {
"start": "nodemon -w dist dist/server.js ../../pages"
"start": "nodemon -w dist --exec 'node --enable-source-maps dist/server.js ../../pages'"
},
"targets": {
"server": {