From 809fa78d35f395375bdd431d8d7f5fb5e6d664b0 Mon Sep 17 00:00:00 2001 From: "kts of kettek (yan)" Date: Sat, 14 Aug 2021 13:48:04 -0700 Subject: [PATCH] Add WIP aedifex db --- index.js | 1 + plugins/srd-aedifex-router/errors.js | 44 +++++++++++++ plugins/srd-aedifex-router/gear.js | 22 +++++++ plugins/srd-aedifex-router/index.js | 63 ++++++++++++++++++ .../package-lock.json | 65 ++++++++++++++++++- .../package.json | 4 +- plugins/srd-aedifex-router/route.js | 56 ++++++++++++++++ plugins/srd-aedifex-router/specimen.js | 22 +++++++ plugins/srd-gear-router/index.js | 47 -------------- plugins/srd-gear-router/route.js | 32 --------- plugins/srd-router/package-lock.json | 18 +++++ views/tables.dot | 29 +++++---- 12 files changed, 308 insertions(+), 95 deletions(-) create mode 100644 plugins/srd-aedifex-router/errors.js create mode 100644 plugins/srd-aedifex-router/gear.js create mode 100644 plugins/srd-aedifex-router/index.js rename plugins/{srd-gear-router => srd-aedifex-router}/package-lock.json (87%) rename plugins/{srd-gear-router => srd-aedifex-router}/package.json (84%) create mode 100644 plugins/srd-aedifex-router/route.js create mode 100644 plugins/srd-aedifex-router/specimen.js delete mode 100644 plugins/srd-gear-router/index.js delete mode 100644 plugins/srd-gear-router/route.js diff --git a/index.js b/index.js index 634429f..97c6e17 100644 --- a/index.js +++ b/index.js @@ -78,6 +78,7 @@ try { console.log('...ok') plugins.push(plugin) } catch(err) { + console.error(err) if (err.code === 'MODULE_NOT_FOUND') { console.error('plugin', plugin_path, 'is not a valid module') } else { diff --git a/plugins/srd-aedifex-router/errors.js b/plugins/srd-aedifex-router/errors.js new file mode 100644 index 0000000..7eccb3b --- /dev/null +++ b/plugins/srd-aedifex-router/errors.js @@ -0,0 +1,44 @@ + +class AedifexError extends Error { + constructor(message) { + super(message) + this.name = 'AedifexError' + } +} + +class UnhandledTypeError extends AedifexError { + constructor(received) { + super(`unhandled aedifex type "${received}"`) + this.name = 'UnhandleTypeError' + } +} + +class IncorrectTypeError extends AedifexError { + constructor(expected, received) { + super(`expected "${expected}", received "${received}"`) + this.name = 'IncorrectTypeError' + } +} + +class IncorrectPropertyError extends AedifexError { + constructor(field, expected, received) { + super(`expected property "${field}" to be "${expected}", received type "${received}"`) + this.name = 'IncorrectPropertyError' + } +} + +class MismatchedVersionError extends AedifexError { + constructor(expected, received) { + super(`expected version "${expected}", received "${received}"`) + this.name = 'MismatchedVersionError' + } +} + +module.exports = { + AedifexError, + UnhandledTypeError, + IncorrectTypeError, + IncorrectPropertyError, + MismatchedVersionError, +} + diff --git a/plugins/srd-aedifex-router/gear.js b/plugins/srd-aedifex-router/gear.js new file mode 100644 index 0000000..d7d9671 --- /dev/null +++ b/plugins/srd-aedifex-router/gear.js @@ -0,0 +1,22 @@ +const semver = require('semver') + +const { IncorrectTypeError, IncorrectPropertyError, MismatchedVersionError } = require('./errors.js') + +function readGear(collection, v) { + if (v.type !== 'hord-gear') { + throw new IncorrectTypeError('hord-gear', v.type) + } + if (!Array.isArray(v.gear)) { + throw new IncorrectPropertyError('gear', typeof [], typeof v.gear) + } + if (!v.version || !semver.satisfies(v.version, '1.x')) { + throw new MismatchedVersionError('1.x', v.version) + } + for (let g of v.gear) { + collection.insert(g) + } +} + +module.exports = { + readGear, +} diff --git a/plugins/srd-aedifex-router/index.js b/plugins/srd-aedifex-router/index.js new file mode 100644 index 0000000..2a6cb6c --- /dev/null +++ b/plugins/srd-aedifex-router/index.js @@ -0,0 +1,63 @@ +const path = require('path') +const chokidar = require('chokidar') +const YAML = require('yaml') +const fs = require('fs') +const loki = require('lokijs') + +const { readSpecimens } = require('./specimen.js') +const { readGear } = require('./gear.js') + +const { UnhandledTypeError } = require('./errors.js') + +const refresh = async (plugin, app, db_dir) => { + let files = await fs.promises.readdir(path.join(db_dir)) + + let db = new loki('Hord') + let specimens = db.getCollection('specimens') || db.addCollection('specimens', {indices: ['family', 'name']}) + let gear = db.getCollection('gear') || db.addCollection('gear', {indices: ['type', 'name']}) + + for (let file of files) { + if (path.extname(file) === '.aedifex' || path.extname(file) === '.aed') { + plugin.log(`parsing aedifex file: "${path.join(db_dir, file)}"`) + let o = YAML.parse(await fs.promises.readFile(path.join(db_dir, file), { encoding: 'utf8' })) + try { + switch(o.type) { + case 'hord-specimens': + readSpecimens(specimens, o) + break; + case 'hord-gear': + readGear(gear, o) + break; + default: + throw new UnhandledTypeError(o.type) + break; + } + } catch(err) { + plugin.error(err) + } + } + } + + app.live = { + ...app.live, + db: db, + } +} + +module.exports = { + priority: 1, + load: async (plugin, app) => { + // Load up our DB. + const db_dir = path.resolve(path.join(app.config.srd, 'db')) + + await refresh(plugin, app, db_dir) + + const watcher = chokidar.watch(db_dir, {persistent: true}) + watcher.on('change', p => { + refresh(plugin, app, db_dir) + }) + plugin.log('watching', db_dir) + + app.express.use(require('./route.js')(plugin, app)) + }, +} diff --git a/plugins/srd-gear-router/package-lock.json b/plugins/srd-aedifex-router/package-lock.json similarity index 87% rename from plugins/srd-gear-router/package-lock.json rename to plugins/srd-aedifex-router/package-lock.json index 6b445a8..80d8411 100644 --- a/plugins/srd-gear-router/package-lock.json +++ b/plugins/srd-aedifex-router/package-lock.json @@ -1,5 +1,5 @@ { - "name": "srd-gear-router", + "name": "srd-aedifex-router", "version": "1.0.0", "lockfileVersion": 2, "requires": true, @@ -9,11 +9,13 @@ "license": "GPL-3.0", "dependencies": { "chokidar": "^3.5.1", + "lokijs": "^1.5.12", "markdown-it": "^12.0.6", "markdown-it-anchor": "^7.1.0", "markdown-it-attrs": "^4.0.0", "markdown-it-title": "^3.0.0", "memory-cache": "^0.2.0", + "semver": "^7.3.5", "yaml": "^1.10.2" } }, @@ -162,6 +164,22 @@ "uc.micro": "^1.0.1" } }, + "node_modules/lokijs": { + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.12.tgz", + "integrity": "sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/markdown-it": { "version": "12.0.6", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.6.tgz", @@ -241,6 +259,20 @@ "node": ">=8.10.0" } }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -257,6 +289,11 @@ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", @@ -370,6 +407,19 @@ "uc.micro": "^1.0.1" } }, + "lokijs": { + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.12.tgz", + "integrity": "sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, "markdown-it": { "version": "12.0.6", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.6.tgz", @@ -427,6 +477,14 @@ "picomatch": "^2.2.1" } }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -440,6 +498,11 @@ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", diff --git a/plugins/srd-gear-router/package.json b/plugins/srd-aedifex-router/package.json similarity index 84% rename from plugins/srd-gear-router/package.json rename to plugins/srd-aedifex-router/package.json index a11b6b6..d2d40ce 100644 --- a/plugins/srd-gear-router/package.json +++ b/plugins/srd-aedifex-router/package.json @@ -1,5 +1,5 @@ { - "name": "srd-gear-router", + "name": "srd-aedifex-router", "version": "1.0.0", "description": "", "main": "index.js", @@ -11,11 +11,13 @@ "license": "GPL-3.0", "dependencies": { "chokidar": "^3.5.1", + "lokijs": "^1.5.12", "markdown-it": "^12.0.6", "markdown-it-anchor": "^7.1.0", "markdown-it-attrs": "^4.0.0", "markdown-it-title": "^3.0.0", "memory-cache": "^0.2.0", + "semver": "^7.3.5", "yaml": "^1.10.2" } } diff --git a/plugins/srd-aedifex-router/route.js b/plugins/srd-aedifex-router/route.js new file mode 100644 index 0000000..1d02c42 --- /dev/null +++ b/plugins/srd-aedifex-router/route.js @@ -0,0 +1,56 @@ +const router = require('express').Router() +const fs = require('fs') +const path = require('path') + +module.exports = (plugin, app) => { + router.get(['/db/:collection', '/db/:collection/:type', '/db/:collection/:type/:name'], async function(req, res) { + let collection = app.live.db.getCollection(req.params.collection) + let results = [] + let error = '' + let errorCode = 0 + if (!collection) { + // TODO: 404 - collection missing + } else { + if (req.params.name) { + results = collection.find({type: req.params.type, name: req.params.name}) + if (results.length === 0) { + error = `No such entry "${req.params.name}"` + errorCode = 404 + } + } else if (req.params.type) { + results = collection.find({type: req.params.type}) + if (results.length === 0) { + error = `No such collection type "${req.params.type}"` + errorCode = 404 + } + } else { + results = collection.find({}) + if (results.length === 0) { + error = `Collection empty` + errorCode = 404 + } + } + } + //console.log(results, error, errorCode) + + let content + if (errorCode > 0) { + content = error + } else { + content = app.dot.tables({...req.params, results, type: req.params.type, name: req.params.name, collection: req.params.collection}) + } + + res.render('index', { + content, + menu: app.live.menu, + title: 'gear', + www_name: app.live.conf.www_name, + www_copyright: app.live.conf.www_copyright, + scripts: ['/js/gear.js'], + }) + }) + + plugin.log('added aedifex route') + + return router +} diff --git a/plugins/srd-aedifex-router/specimen.js b/plugins/srd-aedifex-router/specimen.js new file mode 100644 index 0000000..186bb88 --- /dev/null +++ b/plugins/srd-aedifex-router/specimen.js @@ -0,0 +1,22 @@ +const semver = require('semver') + +const { IncorrectTypeError, IncorrectPropertyError, MismatchedVersionError } = require('./errors.js') + +function readSpecimens(collection, v) { + if (v.type !== 'hord-specimens') { + throw new IncorrectTypeError('hord-specimens', v.type) + } + if (!Array.isArray(v.specimens)) { + throw new IncorrectPropertyError('specimens', typeof [], typeof v.specimens) + } + if (!v.version || !semver.satisfies(v.version, '1.x')) { + throw new MismatchedVersionError('1.x', v.version) + } + for (let s of v.specimens) { + collection.insert(s) + } +} + +module.exports = { + readSpecimens, +} diff --git a/plugins/srd-gear-router/index.js b/plugins/srd-gear-router/index.js deleted file mode 100644 index 614c1ad..0000000 --- a/plugins/srd-gear-router/index.js +++ /dev/null @@ -1,47 +0,0 @@ -const path = require('path') -const chokidar = require('chokidar') -const YAML = require('yaml') -const fs = require('fs') - -const refresh = async (app, db_dir) => { - const gear_path = path.join(db_dir, 'gear.yaml') - - let gear = {} - - YAML.parse(await fs.promises.readFile(gear_path, { encoding: 'utf8' })).forEach((v,i) => { - let type = 'untyped' - if (v.type) { - type = v.type+'s' - } - if (!gear[type]) { - gear[type] = [] - } - gear[type].push(v) - }) - - app.live = { - ...app.live, - db: { - ...app.live.db, - gear: gear, - }, - } -} - -module.exports = { - priority: 1, - load: async (plugin, app) => { - // Load up our DB. - const db_dir = path.resolve(path.join(app.config.srd, 'db')) - - await refresh(app, db_dir) - - const watcher = chokidar.watch(db_dir, {persistent: true}) - watcher.on('change', p => { - refresh(app, db_dir) - }) - plugin.log('watching', db_dir) - - app.express.use(require('./route.js')(plugin, app)) - }, -} diff --git a/plugins/srd-gear-router/route.js b/plugins/srd-gear-router/route.js deleted file mode 100644 index ca12774..0000000 --- a/plugins/srd-gear-router/route.js +++ /dev/null @@ -1,32 +0,0 @@ -const router = require('express').Router() -const fs = require('fs') -const path = require('path') - -module.exports = (plugin, app) => { - // gear, gear/type, gear/type/name - router.get(['/gear', '/gear/:type', '/gear/:type/:name'], async function(req, res) { - let entry = null - if (req.params.name) { - if (!app.live.db.gear[req.params.type]) { - // TODO: 404 - no such gear type - } else { - entry = app.live.db.gear[req.params.type].find(v=>v.name===req.params.name) - if (!entry) { - // TODO: 404 - no such gear by name - } - } - } - res.render('index', { - content: app.dot.tables({...req.params, db: app.live.db.gear, entry: entry}), - menu: app.live.menu, - title: 'gear', - www_name: app.live.conf.www_name, - www_copyright: app.live.conf.www_copyright, - scripts: ['/js/gear.js'], - }) - }) - - plugin.log('added gear route') - - return router -} diff --git a/plugins/srd-router/package-lock.json b/plugins/srd-router/package-lock.json index 8db282d..a7f6efb 100644 --- a/plugins/srd-router/package-lock.json +++ b/plugins/srd-router/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "markdown-it": "^12.0.6", "markdown-it-anchor": "^7.1.0", + "markdown-it-attrs": "^4.0.0", "markdown-it-title": "^3.0.0", "memory-cache": "^0.2.0" } @@ -59,6 +60,17 @@ "markdown-it": "*" } }, + "node_modules/markdown-it-attrs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.0.0.tgz", + "integrity": "sha512-uLjtdCmhhmL3BuZsReYkFxk74qKjj5ahe34teBpOCJ4hYZZl7/ftLyXWLowngC2moRkbLEvKwN/7TMwbhbHE/A==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "markdown-it": ">= 9.0.0 < 13.0.0" + } + }, "node_modules/markdown-it-title": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/markdown-it-title/-/markdown-it-title-3.0.0.tgz", @@ -117,6 +129,12 @@ "integrity": "sha512-loQggrwsIkkP7TOrESvmYkV2ikbQNNKhHcWyqC7/C2CmfHl1tkUizJJU8C5aGgg7J6oXVQJx17gk7i47tNn/lQ==", "requires": {} }, + "markdown-it-attrs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.0.0.tgz", + "integrity": "sha512-uLjtdCmhhmL3BuZsReYkFxk74qKjj5ahe34teBpOCJ4hYZZl7/ftLyXWLowngC2moRkbLEvKwN/7TMwbhbHE/A==", + "requires": {} + }, "markdown-it-title": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/markdown-it-title/-/markdown-it-title-3.0.0.tgz", diff --git a/views/tables.dot b/views/tables.dot index 1dd6553..1f344d8 100644 --- a/views/tables.dot +++ b/views/tables.dot @@ -1,6 +1,6 @@ {{##def.weapons_table_entry:item: - {{=item.name || ''}} + {{=item.name || ''}} {{=item.attack || ''}} {{=item.damage || ''}} {{=item.damagetype || ''}} @@ -79,9 +79,20 @@ #}} -{{? it.entry }} - {{#def.entry:it.entry || ''}} -{{?? !it.type }} +{{? it.results }} + {{#def.entry:it.results[0] || ''}} +

got results

+{{?? !it.name }} + {{? it.type === "weapon"}} +

Weapons

+ {{#def.weapons_table:it.results || ''}} + {{?? it.type === "consumable"}} +

Consumables

+ {{#def.consumables_table:it.results || ''}} + {{?? true }} + Bad type + {{?}} +{{?? true }}

Gear

{{? it.db.weapons }}

Weapons

@@ -92,14 +103,4 @@

Consumables

{{#def.consumables_table:it.db.consumables || ''}} {{?}} -{{?? true }} - {{? it.type === "weapons"}} -

Weapons

- {{#def.weapons_table:it.db.weapons || ''}} - {{?? it.type === "consumables"}} -

Consumables

- {{#def.consumables_table:it.db.consumables || ''}} - {{?? true }} - Bad type - {{?}} {{?}}