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
	 walcutt
						walcutt