This commit is contained in:
lowlighter
2022-01-21 20:39:51 -05:00
7 changed files with 146 additions and 0 deletions

View File

@@ -84,12 +84,16 @@ export default async function metadata({log = true, diff = false} = {}) {
return {plugins:Plugins, templates:Templates, packaged, descriptor}
}
/**Metadata extractor for inputs */
metadata.inputs = {}
/**Metadata extractor for templates */
metadata.plugin = async function({__plugins, __templates, name, logger}) {
try {
//Load meta descriptor
const raw = `${await fs.promises.readFile(path.join(__plugins, name, "metadata.yml"), "utf-8")}`
const {inputs, ...meta} = yaml.load(raw)
Object.assign(metadata.inputs, inputs)
//category
if (!categories.includes(meta.category))
@@ -345,6 +349,8 @@ metadata.plugin = async function({__plugins, __templates, name, logger}) {
cell.push(`⏩ Inherits <code>${o.inherits}</code><br>`)
if (o.global)
cell.push("⏭️ Global option<br>")
if (/^(?:[Ff]alse|[Oo]ff|[Nn]o|0)$/.test(o.preset))
cell.push("⏯️ Cannot be preset<br>")
if (o.testing)
cell.push("🔧 For development<br>")
if (!Object.keys(previous?.inputs ?? {}).includes(option))

View File

@@ -0,0 +1,70 @@
//Imports
import fs from "fs/promises"
import yaml from "js-yaml"
import fetch from "node-fetch"
import metadata from "./metadata.mjs"
/**Presets parser */
export default async function presets(list, {log = true, core = null} = {}) {
//Init
const {plugins} = await metadata({log:false})
const {"config.presets":files} = plugins.core.inputs({q:{"config.presets":list}, account:"bypass"})
const logger = log ? console.debug : () => null
const allowed = Object.entries(metadata.inputs).filter(([_, {type, preset}]) => (type !== "token")&&(!/^(?:[Ff]alse|[Oo]ff|[Nn]o|0)$/.test(preset))).map(([key]) => key)
const env = core ? "action" : "web"
const options = {}
//Load presets
for (const file of files) {
try {
//Load and parse preset
logger(`metrics/presets > loading ${file}`)
let text = ""
if (file.startsWith("@")) {
logger(`metrics/presets > ${file} seems to be predefined preset, fetching`)
text = await fetch(`https://raw.githubusercontent.com/lowlighter/metrics/presets/${file.substring(1)}/preset.yaml`).then(response => response.text())
}
else if (file.startsWith("https://")) {
logger(`metrics/presets > ${file} seems to be an url, fetching`)
text = await fetch(file).then(response => response.text())
}
else if (env === "action") {
logger(`metrics/presets > ${file} seems to be a local file, reading`)
text = `${await fs.readFile(file)}`
}
else {
logger(`metrics/presets > ${file} cannot be loaded in current environment ${env}, skipping`)
continue
}
const {schema, with:inputs} = yaml.load(text)
logger(`metrics/presets > ${file} preset schema is ${schema}`)
//Evaluate preset
switch (`${schema}`) {
case "draft":{
for (let [key, value] of Object.entries(inputs)) {
if (!allowed.includes(key)) {
logger(`metrics/presets > ${key} is specified but is not allowed in preset, skipping`)
continue
}
if (env === "web")
key = metadata.to.query(key)
if (key in options)
logger(`metrics/presets > ${key} was already specified by another preset, overwriting`)
options[key] = value
}
break
}
default:
throw new Error(`unsupported preset schema: ${schema}`)
}
}
//Handle errors
catch (error) {
if (env === "action")
console.log(`::warning::skipping preset ${file}: ${error.message}`)
logger(`metrics/presets > an error occured while loading preset ${file} (${error}), ignoring`)
}
}
return options
}

View File

@@ -8,6 +8,7 @@ import cache from "memory-cache"
import util from "util"
import mocks from "../../../tests/mocks/index.mjs"
import metrics from "../metrics/index.mjs"
import presets from "../metrics/presets.mjs"
import setup from "../metrics/setup.mjs"
/**App */
@@ -252,6 +253,10 @@ export default async function({mock, nosettings} = {}) {
//Render
const q = req.query
console.debug(`metrics/app/${login} > ${util.inspect(q, {depth:Infinity, maxStringLength:256})}`)
if ((q["config.presets"])&&(conf.settings.extras?.presets ?? conf.settings.extras?.default ?? false)) {
console.debug(`metrics/app/${login} > presets have been specified, loading them`)
Object.assign(q, await presets(q["config.presets"]))
}
const {rendered, mime} = await metrics({login, q}, {
graphql,
rest,

View File

@@ -27,6 +27,7 @@
},
"extras": {
"default": false, "//": "Default extras state (advised to let 'false' unless in debug mode)",
"presets": false, "//": "Allow use of 'config.presets' option",
"css": false, "//": "Allow use of 'extras.css' option",
"js": false, "//": "Allow use of 'extras.js' option",
"features": false, "//": "Enable extra features (advised to let 'false' on web instances)"