Added settings API.

main
BurnyLlama 2023-08-04 19:51:08 +02:00
parent 7415e9d529
commit 7a7b894bd5
6 changed files with 355 additions and 232 deletions

4
.gitignore vendored
View File

@ -130,4 +130,8 @@ dist
.yarn/install-state.gz .yarn/install-state.gz
.pnp.* .pnp.*
# Project-related files
config.yml
src/_settings.scss
src/main.scss
out/ out/

View File

@ -1,21 +1,66 @@
import sass from "sass" import sass from "sass"
import fs from "fs" import fs from "fs"
import { log } from "console"
import YAML from "yaml"
import parseTemplate from "./parseTemplate.js"
const { css } = sass.compile( export default function buildNebulosa(debug) {
"./src/main.scss", log("Generating Nebulosa CSS...")
{ style: "compressed" }
)
const now = new Date() log("Reading config...")
.toISOString() if (!fs.existsSync("./config.yml")) {
.replace(/\.\S+/g, "") log("No config file found!")
.replace(/:/g, ".") log("Copying 'example-config.yml' to 'config.yml'...")
.replace(/T/g, "_") fs.copyFileSync("./example-config.yml", "config.yml")
}
const config = YAML.parse(fs.readFileSync("./config.yml").toString())
if (!fs.existsSync("./out")) log("Reading templates...")
fs.mkdirSync("./out") const templateFiles = fs.readdirSync("./src/templates")
const templates = templateFiles.map(
fileName => {
return {
fileName,
content: fs.readFileSync(`./src/templates/${fileName}`).toString()
}
}
)
fs.writeFileSync( log("Executing templates...")
`./out/${now}.css`, templates.forEach(
"/* Generated using Nebulosa CSS. https://git.qwik.space/BurnyLlama/nebulosa-css */\n" + css template => {
) const compiledTemplate = parseTemplate(template.content, config)
fs.writeFileSync(`./src/${template.fileName}`, compiledTemplate)
}
)
log("Compiling SCSS...")
const { css } = sass.compile(
"./src/main.scss",
{ style: "compressed" }
)
const now = new Date()
.toISOString()
.replace(/\.\S+/g, "")
.replace(/:/g, ".")
.replace(/T/g, "_")
const outFileName = debug ? "./out/main.css" : `./out/${now}.css`
if (!fs.existsSync("./out"))
fs.mkdirSync("./out")
log("Writing file...")
fs.writeFileSync(
outFileName,
"/* Generated using Nebulosa CSS. https://git.qwik.space/BurnyLlama/nebulosa-css */\n" + css
)
log(`Saved config file to ./out/${now}.css`)
}
// If the file is run directly from the commandline, build Nebulosa.
if (import.meta.url === `file://${process.argv[0]}`) {
buildNebulosa(false)
}

45
dev.js
View File

@ -2,7 +2,7 @@ import chokidar from "chokidar"
import express from "express" import express from "express"
import fs from "fs" import fs from "fs"
import njk from "nunjucks" import njk from "nunjucks"
import sass from "sass" import buildNebulosa from "./build.js"
const server = express() const server = express()
@ -17,35 +17,24 @@ njk.configure(
} }
) )
chokidar.watch("./src").on("change", () => { // Do an initial build of Nebulosa, then watch for changes...
console.log("Detected changes in SCSS! Recompiling...") buildNebulosa(true)
chokidar
.watch(["./src", "./config.yml", "./example-config.yml"])
.on(
"change",
() => {
console.log("Detected changes in SCSS or config! Recompiling...")
try { try {
const { css } = sass.compile( buildNebulosa(true)
"./src/main.scss", console.log("Saved!")
{ } catch (error) {
sourceMap: false, console.log("Error while compiling!")
alertColor: true, console.error(error)
style: "compressed"
} }
) }
)
console.log("Compile done! Saving changes...")
if (!fs.existsSync("./out"))
fs.mkdirSync("./out")
fs.writeFileSync(
"./out/main.css",
css
)
console.log("Saved!")
} catch (error) {
console.log("Error while compiling!")
console.error(error)
}
})
server.use("/assets", express.static("./out")) server.use("/assets", express.static("./out"))

View File

@ -20,7 +20,8 @@
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
"express": "^4.18.2", "express": "^4.18.2",
"nunjucks": "^3.2.3", "nunjucks": "^3.2.3",
"sass": "^1.58.3" "sass": "^1.58.3",
"yaml": "^2.3.1"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.35.0" "eslint": "^8.35.0"

69
parseTemplate.js Normal file
View File

@ -0,0 +1,69 @@
import { log, error } from "console"
/**
* Flattens an object into a 1 level deep object.
* { a: { b: 1, c: 2 } } --> { "a.b": 1, "a.c": 2 }
* @param {Object} object
* @return {Object}
*/
function flattenObject(object) {
let finalObject = {}
for (const key in object) {
// Skip if key isn't own.
if (!Object.prototype.hasOwnProperty.call(object, key))
continue
if (typeof object[key] === "object" && object[key] !== null) {
const flattenedObject = flattenObject(object[key])
for (const innerKey in flattenedObject) {
// Skip if key isn't own.
if (!Object.prototype.hasOwnProperty.call(flattenedObject, innerKey))
continue
finalObject[`${key}.${innerKey}`] = flattenedObject[innerKey]
}
} else {
finalObject[key] = object[key]
}
}
return finalObject
}
export default function parseTemplate(template, data) {
const flattenedData = flattenObject(data)
log("Loaded config:")
return template
// Syntax: {{ variableName }}
// Does: Inserts a variable, if it exists.
.replace(
/{{\s*(.+)\s*}}/gm,
(match, variableName) => {
if (flattenedData[variableName] === undefined || flattenedData[variableName] === null) {
error(`Error: ${variableName} is not defined!`)
process.exit(1)
}
log(`${variableName} = ${flattenedData[variableName]}`)
return flattenedData[variableName]
}
)
// Syntax:
// {% if variableName %}
// <code to include>
// {% endif %}
// Does: includes <code to include> if variableName exists and is true.
.replace(
/^{%\s*if\s*(.+)\s*%}$([\s\S]*?)^{%\s*endif\s*%}$/gm,
(match, variableName, codeBlock) => {
if (flattenedData[variableName] === undefined || flattenedData[variableName] === null) {
error(`Error: ${variableName} is not defined!`)
process.exit(1)
}
log(`${variableName} = ${flattenedData[variableName]}`)
return flattenedData[variableName] ? codeBlock : ""
}
)
}

File diff suppressed because it is too large Load Diff