Absolute minimum prototype
This commit is contained in:
parent
8a6f4b44ec
commit
c0dc360579
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,7 @@
|
|||||||
|
# virtual-star custom
|
||||||
|
build/
|
||||||
|
|
||||||
|
# node boilerplate
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
|||||||
24
README.md
24
README.md
@ -1,2 +1,26 @@
|
|||||||
# virtual-star
|
# virtual-star
|
||||||
Static site builder for a blog site, for deployment to neocities or via included static-server docker container.
|
Static site builder for a blog site, for deployment to neocities or via included static-server docker container.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
- Clone this repository, and run `npm i`.
|
||||||
|
- Set up a `.env` file if desired.
|
||||||
|
|
||||||
|
### Configure
|
||||||
|
In your `.env` file, or as environment vars:
|
||||||
|
|
||||||
|
- `VS_DEBUG`: set to `true` to enable more logging, `false` otherwise (default: `false`).
|
||||||
|
- `VS_INPUT_DIR`: change the input directory (default: `content/`).
|
||||||
|
- `VS_OUTPUT_DIR`: change the output directory (default: `build/`).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Build
|
||||||
|
_Converts .md files in the input directory to .html files in the output directory._
|
||||||
|
|
||||||
|
- `npm run build`
|
||||||
|
|
||||||
|
### Serve
|
||||||
|
_Statically serves files in the output directory_
|
||||||
|
|
||||||
|
- `npm run serve`
|
||||||
|
|||||||
46
build.js
Normal file
46
build.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import Showdown from 'showdown';
|
||||||
|
import 'dotenv/config';
|
||||||
|
import { ENV } from './lib/env.js';
|
||||||
|
|
||||||
|
const converter = new Showdown.Converter();
|
||||||
|
|
||||||
|
let inputDir = 'content/';
|
||||||
|
if(ENV.getIsSet('VS_INPUT_DIR')) {
|
||||||
|
inputDir = ENV.getString('VS_INPUT_DIR');
|
||||||
|
}
|
||||||
|
|
||||||
|
let outputDir = 'build/';
|
||||||
|
if(ENV.getIsSet('VS_OUTPUT_DIR')) {
|
||||||
|
outputDir = ENV.getString('VS_OUTPUT_DIR');
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileEntities = fs.readdirSync(inputDir, {recursive: true, withFileTypes: true, encoding: 'utf8'});
|
||||||
|
|
||||||
|
fileEntities.forEach((fileEnt) => {
|
||||||
|
const filenameTokens = fileEnt.name.split('.');
|
||||||
|
const extension = filenameTokens[filenameTokens.length - 1];
|
||||||
|
|
||||||
|
if(extension === 'md') {
|
||||||
|
const fullPath = fileEnt.parentPath + fileEnt.name;
|
||||||
|
|
||||||
|
const content = fs.readFileSync(fullPath, {encoding: 'utf8'});
|
||||||
|
|
||||||
|
const converted = converter.makeHtml(content);
|
||||||
|
|
||||||
|
let outputFileName = "";
|
||||||
|
for(let i = 0; i < filenameTokens.length - 1; i++) {
|
||||||
|
outputFileName += filenameTokens[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFileName += '.html';
|
||||||
|
|
||||||
|
const trimmedPath = fileEnt.parentPath.replace(inputDir, "");
|
||||||
|
|
||||||
|
const outputPath = outputDir + trimmedPath + outputFileName;
|
||||||
|
|
||||||
|
fs.writeFileSync(outputPath, converted);
|
||||||
|
|
||||||
|
console.log(`Converted ${fullPath} -> ${outputPath}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
1
content/test.md
Normal file
1
content/test.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Here's a test!
|
||||||
17
lib/env.js
Normal file
17
lib/env.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export const ENV = {
|
||||||
|
getValue: function (key) {
|
||||||
|
return process.env[key];
|
||||||
|
},
|
||||||
|
getBoolean: function (key) {
|
||||||
|
return (this.getValue(key)?.toLowerCase?.() === 'true');
|
||||||
|
},
|
||||||
|
getNumber: function (key) {
|
||||||
|
return parseFloat(this.getValue(key));
|
||||||
|
},
|
||||||
|
getString: function (key) {
|
||||||
|
return this.getValue(key);
|
||||||
|
},
|
||||||
|
getIsSet: function (key) {
|
||||||
|
return (this.getValue(key) !== undefined);
|
||||||
|
},
|
||||||
|
};
|
||||||
164
package-lock.json
generated
Normal file
164
package-lock.json
generated
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
{
|
||||||
|
"name": "virtual-star",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "virtual-star",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"dotenv": "^16.4.7",
|
||||||
|
"serve-handler": "^6.1.6",
|
||||||
|
"showdown": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bytes": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/commander": {
|
||||||
|
"version": "9.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
|
||||||
|
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || >=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/content-disposition": {
|
||||||
|
"version": "0.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
|
||||||
|
"integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "16.4.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
|
||||||
|
"integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://dotenvx.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.33.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
|
||||||
|
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "2.1.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
|
||||||
|
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "~1.33.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-is-inside": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==",
|
||||||
|
"license": "(WTFPL OR MIT)"
|
||||||
|
},
|
||||||
|
"node_modules/path-to-regexp": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/range-parser": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/serve-handler": {
|
||||||
|
"version": "6.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz",
|
||||||
|
"integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.0.0",
|
||||||
|
"content-disposition": "0.5.2",
|
||||||
|
"mime-types": "2.1.18",
|
||||||
|
"minimatch": "3.1.2",
|
||||||
|
"path-is-inside": "1.0.2",
|
||||||
|
"path-to-regexp": "3.3.0",
|
||||||
|
"range-parser": "1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/showdown": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "^9.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"showdown": "bin/showdown.js"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://www.paypal.me/tiviesantos"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
package.json
Normal file
26
package.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "virtual-star",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "Static blog generator and simple server for node",
|
||||||
|
"homepage": "https://github.com/walcutt/virtual-star#readme",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/walcutt/virtual-star/issues"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/walcutt/virtual-star.git"
|
||||||
|
},
|
||||||
|
"license": "ISC",
|
||||||
|
"author": "walcutt",
|
||||||
|
"type": "module",
|
||||||
|
"main": "bundle.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node build.js",
|
||||||
|
"serve": "node serve.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dotenv": "^16.4.7",
|
||||||
|
"serve-handler": "^6.1.6",
|
||||||
|
"showdown": "^2.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
26
serve.js
Normal file
26
serve.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// based on the minimal demo from https://www.npmjs.com/package/serve
|
||||||
|
import handler from 'serve-handler';
|
||||||
|
import http from 'http';
|
||||||
|
import 'dotenv/config';
|
||||||
|
import { ENV } from './lib/env.js';
|
||||||
|
|
||||||
|
const isDebugEnabled = ENV.getBoolean('VS_DEBUG');
|
||||||
|
const hasOverrideDirectory = ENV.getIsSet('VS_OUTPUT_DIR');
|
||||||
|
const overrideDirectory = ENV.getString('VS_OUTPUT_DIR');
|
||||||
|
const defaultDirectory = 'build';
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
public: hasOverrideDirectory ? overrideDirectory : defaultDirectory,
|
||||||
|
directoryListing: isDebugEnabled,
|
||||||
|
};
|
||||||
|
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
return handler(req, res, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(3000, () => {
|
||||||
|
console.log('Running on port 3000');
|
||||||
|
if(isDebugEnabled) {
|
||||||
|
console.log(options);
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user