From 91a9f780576ddfdbac24acebada0ce862a451960 Mon Sep 17 00:00:00 2001 From: James King Date: Sun, 10 Jan 2021 19:49:32 +0000 Subject: [PATCH] feat!: Initial moving to single humble SSG script rather than npm scripts --- README.md | 2 +- favicon.config.js | 34 +- humble.config.ts | 10 + nodemon.json | 2 +- package-lock.json | 980 ++++++++++++++++++++++------ package.json | 16 +- {templates => partials}/footer.html | 0 {templates => partials}/head.html | 0 {templates => partials}/meta.html | 0 {templates => partials}/nav.html | 0 scripts/findInDir.ts | 12 +- scripts/generateChangelog.ts | 50 +- scripts/generatePages.ts | 116 ++-- scripts/generateSitemap.ts | 240 +++---- scripts/generateThoughts.ts | 220 ++++--- scripts/humble.ts | 78 +++ 16 files changed, 1241 insertions(+), 519 deletions(-) create mode 100644 humble.config.ts rename {templates => partials}/footer.html (100%) rename {templates => partials}/head.html (100%) rename {templates => partials}/meta.html (100%) rename {templates => partials}/nav.html (100%) create mode 100755 scripts/humble.ts diff --git a/README.md b/README.md index 791f37d..4c25bbd 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ SSGs are amazing, if you want a full-fledged site. But if you just want to dumb ## What -This repo simply looks for any `{template_name.html}` in the body of the `pages/page_name.html`, and replaces it with the content of `templates/template_name.html`, and writes it to `public/page_name.html` with that new content. +This repo simply looks for any `{template_name.html}` in the body of the `pages/page_name.html`, and replaces it with the content of `partials/template_name.html`, and writes it to `public/page_name.html` with that new content. It also does a few other little things, like looking for `{page}` and replacing it with the `page_name` (for uses like `class="home"` and setting the ``). diff --git a/favicon.config.js b/favicon.config.js index 876c172..4dc69a2 100644 --- a/favicon.config.js +++ b/favicon.config.js @@ -1,23 +1,23 @@ module.exports = { - input: "./assets/images/favicon.png", // Required. override cli options. - output: "./public", // Required. override cli options. - template: "./templates/meta.html", // Default is the same as output, default name is meta.html. + input: './assets/images/favicon.png', // Required. override cli options. + output: './public', // Required. override cli options. + template: './partials/meta.html', // Default is the same as output, default name is meta.html. config: { - path: "/", // Path for overriding default icons path. `string` - appName: "ripixel", // Your application's name. `string` + path: '/', // Path for overriding default icons path. `string` + appName: 'ripixel', // Your application's name. `string` appDescription: "I'm James King, and I make things for the web", // Your application's description. `string` - developerName: "James King", // Your (or your developer's) name. `string` - developerURL: "https://www.ripixel.co.uk", // Your (or your developer's) URL. `string` - dir: "auto", // Primary text direction for name, short_name, and description - lang: "en-US", // Primary language for name and short_name - background: "#FF9100", // Background colour for flattened icons. `string` - theme_color: "#FF9100", // Theme color user for example in Android's task switcher. `string` - appleStatusBarStyle: "black-translucent", // Style for Apple status bar: "black-translucent", "default", "black". `string` - display: "standalone", // Preferred display mode: "fullscreen", "standalone", "minimal-ui" or "browser". `string` - orientation: "any", // Default orientation: "any", "natural", "portrait" or "landscape". `string` - scope: "/", // set of URLs that the browser considers within your app - start_url: "/", // Start URL when launching the application from a device. `string` - version: "1.0", // Your application's version string. `string` + developerName: 'James King', // Your (or your developer's) name. `string` + developerURL: 'https://www.ripixel.co.uk', // Your (or your developer's) URL. `string` + dir: 'auto', // Primary text direction for name, short_name, and description + lang: 'en-US', // Primary language for name and short_name + background: '#FF9100', // Background colour for flattened icons. `string` + theme_color: '#FF9100', // Theme color user for example in Android's task switcher. `string` + appleStatusBarStyle: 'black-translucent', // Style for Apple status bar: "black-translucent", "default", "black". `string` + display: 'standalone', // Preferred display mode: "fullscreen", "standalone", "minimal-ui" or "browser". `string` + orientation: 'any', // Default orientation: "any", "natural", "portrait" or "landscape". `string` + scope: '/', // set of URLs that the browser considers within your app + start_url: '/', // Start URL when launching the application from a device. `string` + version: '1.0', // Your application's version string. `string` logging: false, // Print logs to console? `boolean` pixel_art: false, // Keeps pixels "sharp" when scaling up, for pixel art. Only supported in offline mode. loadManifestWithCredentials: false, // Browsers don't send cookies when fetching a manifest, enable this to fix that. `boolean` diff --git a/humble.config.ts b/humble.config.ts new file mode 100644 index 0000000..b8dd6f5 --- /dev/null +++ b/humble.config.ts @@ -0,0 +1,10 @@ +export const config = { + rootDir: './', + pagesDir: 'pages', + partialsDir: 'partials', + outDir: 'public', + cssDir: 'assets/styles', + imagesDir: 'assets/images', + nodeModulesDir: 'node_modules', + generateFavicons: true, // optional +}; diff --git a/nodemon.json b/nodemon.json index 8efa6c7..7f6e418 100644 --- a/nodemon.json +++ b/nodemon.json @@ -2,7 +2,7 @@ "watch": [ "pages", "assets", - "templates", + "partials", "thoughts" ], "ext": "html,css,md", diff --git a/package-lock.json b/package-lock.json index cec1aca..0893d12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -593,6 +593,15 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", "dev": true }, + "@samverschueren/stream-to-observable": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz", + "integrity": "sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -822,6 +831,16 @@ "debug": "4" } }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { "version": "6.12.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", @@ -843,6 +862,12 @@ "string-width": "^2.0.0" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", @@ -876,6 +901,12 @@ "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", "dev": true }, + "any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true + }, "anymatch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", @@ -1492,6 +1523,12 @@ } } }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, "cli-boxes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", @@ -1536,36 +1573,59 @@ "colors": "1.0.3" } }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" }, "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" } } } }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", @@ -3000,6 +3060,12 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -3030,6 +3096,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "env-variable": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz", @@ -3493,52 +3568,83 @@ "dev": true }, "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", + "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", "dev": true, "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "dependencies": { "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "get-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", "dev": true }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "mimic-fn": "^2.1.0" } }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -3925,6 +4031,31 @@ "uuid": "^3.0.0", "winston": "^3.0.0", "ws": "^7.2.3" + }, + "dependencies": { + "fs-extra": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.23.1.tgz", + "integrity": "sha1-ZhHbpq3yq43Jxp+rN83fiBgVfj0=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + } } }, "flat-arguments": { @@ -4047,29 +4178,6 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "dev": true }, - "fs-extra": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.23.1.tgz", - "integrity": "sha1-ZhHbpq3yq43Jxp+rN83fiBgVfj0=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, "fs-minipass": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", @@ -4857,6 +4965,12 @@ "debug": "4" } }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, "husky": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz", @@ -5143,6 +5257,15 @@ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "requires": { + "symbol-observable": "^1.1.0" + } + }, "is-path-inside": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", @@ -5549,67 +5672,439 @@ "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", "dev": true }, - "load-bmfont": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.0.tgz", - "integrity": "sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==", + "listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", "dev": true, "requires": { - "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^2.9.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" + "@samverschueren/stream-to-observable": "^0.3.0", + "is-observable": "^1.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.5.0", + "listr-verbose-renderer": "^0.5.0", + "p-map": "^2.0.0", + "rxjs": "^6.3.3" }, "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true } } }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^2.3.0", + "strip-ansi": "^3.0.1" }, "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", "dev": true - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "^1.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + }, + "dependencies": { + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + } + } + }, + "listr2": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.3.tgz", + "integrity": "sha512-vUb80S2dSUi8YxXahO8/I/s29GqnOL8ozgHVLjfWQXa03BNEeS1TpBLjh2ruaqq5ufx46BRGvfymdBSuoXET5w==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "figures": "^3.2.0", + "indent-string": "^4.0.0", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.3", + "through": "^2.3.8" + }, + "dependencies": { + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rxjs": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", + "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "load-bmfont": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.0.tgz", + "integrity": "sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==", + "dev": true, + "requires": { + "buffer-equal": "0.0.1", + "mime": "^1.3.4", + "parse-bmfont-ascii": "^1.0.3", + "parse-bmfont-binary": "^1.0.5", + "parse-bmfont-xml": "^1.1.4", + "phin": "^2.9.1", + "xhr": "^2.0.1", + "xtend": "^4.0.0" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + } + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, @@ -5817,6 +6312,17 @@ "chalk": "^2.0.1" } }, + "log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + } + }, "logform": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", @@ -6774,12 +7280,20 @@ "dev": true }, "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { - "path-key": "^2.0.0" + "path-key": "^3.0.0" + }, + "dependencies": { + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + } } }, "npmlog": { @@ -6948,6 +7462,12 @@ "p-limit": "^2.0.0" } }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -8301,6 +8821,76 @@ "dev": true, "requires": { "yargs": "^14.2" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "yargs-parser": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } } }, "showdown-highlight": { @@ -9011,6 +9601,12 @@ } } }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -9117,6 +9713,65 @@ "dev": true, "requires": { "execa": "^0.7.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } } }, "text-extensions": { @@ -9423,6 +10078,12 @@ } } }, + "uninstall": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/uninstall/-/uninstall-0.0.0.tgz", + "integrity": "sha1-ED5uN+nFLshXVCzSWQI9ccej+ys=", + "dev": true + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -9816,25 +10477,28 @@ "dev": true }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" }, "dependencies": { - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "ansi-regex": "^3.0.0" } } } @@ -9962,56 +10626,6 @@ "@babel/runtime": "^7.9.2" } }, - "yargs": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.1" - }, - "dependencies": { - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } - } - }, - "yargs-parser": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - } - } - }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index a6331ae..e473ec7 100644 --- a/package.json +++ b/package.json @@ -5,15 +5,8 @@ "main": "index.js", "scripts": { "dev": "nodemon", - "build": "mkdir -p ./public && npm run build:css && npm run build:favicons && NODE_ENV=production npm run build:pages && npm run build:images && NODE_ENV=production npm run build:thoughts && npm run build:sitemap && npm run build:changelog", - "build:dev": "mkdir -p ./public && npm run build:css && NODE_ENV=development npm run build:pages && npm run build:images && NODE_ENV=development npm run build:thoughts", - "build:pages": "ts-node ./scripts/generatePages", - "build:css": "cleancss -o ./public/styles.min.css ./assets/styles/*.css", - "build:favicons": "favicons-generate", - "build:images": "cp -R ./assets/images/. ./public/", - "build:sitemap": "ts-node ./scripts/generateSitemap", - "build:changelog": "ts-node ./scripts/generateChangelog", - "build:thoughts": "mkdir -p ./public/thoughts && ts-node ./scripts/generateThoughts", + "build": "ts-node ./scripts/humble.ts", + "build:dev": "NODE_ENV=development ts-node ./scripts/humble.ts", "lint": "eslint \"scripts/**/*{.js,.ts}\"", "lint:ci": "eslint \"scripts/**/*{.js,.ts}\" --format junit -o reports/eslint/results.xml", "release": "standard-version -m 'chore(release): %s [skip ci]'", @@ -37,12 +30,16 @@ "@typescript-eslint/parser": "^3.2.0", "clean-css-cli": "^4.3.0", "date-fns": "^2.13.0", + "enquirer": "^2.3.6", "eslint": "^7.2.0", "eslint-config-prettier": "^6.11.0", "eslint-plugin-prettier": "^3.1.3", + "execa": "^5.0.0", "favicons-generate": "0.0.15", "firebase-tools": "^8.2.0", "husky": "^4.2.5", + "listr": "^0.14.3", + "listr2": "^3.2.3", "nodemon": "^2.0.3", "prettier": "^2.0.5", "pretty-quick": "^2.0.1", @@ -51,6 +48,7 @@ "standard-version": "^8.0.1", "ts-node": "^8.10.1", "typescript": "^3.8.3", + "uninstall": "0.0.0", "xml-js": "^1.6.11" }, "husky": { diff --git a/templates/footer.html b/partials/footer.html similarity index 100% rename from templates/footer.html rename to partials/footer.html diff --git a/templates/head.html b/partials/head.html similarity index 100% rename from templates/head.html rename to partials/head.html diff --git a/templates/meta.html b/partials/meta.html similarity index 100% rename from templates/meta.html rename to partials/meta.html diff --git a/templates/nav.html b/partials/nav.html similarity index 100% rename from templates/nav.html rename to partials/nav.html diff --git a/scripts/findInDir.ts b/scripts/findInDir.ts index 7040163..dc5cdc8 100644 --- a/scripts/findInDir.ts +++ b/scripts/findInDir.ts @@ -1,12 +1,12 @@ import * as fs from 'fs'; import * as path from 'path'; -export const findInDir = (startPath: string, filter: string): string[] => { - console.log( - `Finding files in directory '${startPath}' containing '${filter}'` - ); +const findInDir = (startPath: string, filter: string): string[] => { + // console.log( + // `Finding files in directory '${startPath}' containing '${filter}'` + // ); if (!fs.existsSync(startPath)) { - console.error('no dir ' + startPath); + // console.error('no dir ' + startPath); return []; } @@ -22,7 +22,7 @@ export const findInDir = (startPath: string, filter: string): string[] => { } } - console.log(`Found ${foundFiles.length} files`); + // console.log(`Found ${foundFiles.length} files`); return foundFiles; }; diff --git a/scripts/generateChangelog.ts b/scripts/generateChangelog.ts index e473b7a..d303d49 100644 --- a/scripts/generateChangelog.ts +++ b/scripts/generateChangelog.ts @@ -3,38 +3,42 @@ import showdown from 'showdown'; import findInDir from './findInDir'; -console.log('/// Beginning changelog generation'); +const generateChangelog = (): void => { + // console.log('/// Beginning changelog generation'); -const CHANGELOG_HTML_LOCATION = './public/changelog.html'; + const CHANGELOG_HTML_LOCATION = './public/changelog.html'; -const changelogMdContent = fs.readFileSync('./CHANGELOG.md', 'utf8'); -let changelogHtmlContent = fs.readFileSync(CHANGELOG_HTML_LOCATION, 'utf8'); + const changelogMdContent = fs.readFileSync('./CHANGELOG.md', 'utf8'); + let changelogHtmlContent = fs.readFileSync(CHANGELOG_HTML_LOCATION, 'utf8'); -const mdConverter = new showdown.Converter(); + const mdConverter = new showdown.Converter(); -const changelogContent = mdConverter.makeHtml(changelogMdContent); -changelogHtmlContent = changelogHtmlContent.replace( - '{changelog}', - changelogContent -); + const changelogContent = mdConverter.makeHtml(changelogMdContent); + changelogHtmlContent = changelogHtmlContent.replace( + '{changelog}', + changelogContent + ); -fs.writeFileSync(CHANGELOG_HTML_LOCATION, changelogHtmlContent, 'utf8'); + fs.writeFileSync(CHANGELOG_HTML_LOCATION, changelogHtmlContent, 'utf8'); -const versionMatch = changelogMdContent.match( - /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?/ -); + const versionMatch = changelogMdContent.match( + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?/ + ); -const version = versionMatch ? versionMatch[0] : 'ER.RO.R'; + const version = versionMatch ? versionMatch[0] : 'ER.RO.R'; -console.log(`Found version v${version}`); + // console.log(`Found version v${version}`); -const pages = findInDir('./public', '.html'); + const pages = findInDir('./public', '.html'); -pages.forEach((page) => { - const pageContent = fs.readFileSync(page, 'utf8'); - fs.writeFileSync(page, pageContent.replace('{version}', version), 'utf8'); -}); + pages.forEach((page) => { + const pageContent = fs.readFileSync(page, 'utf8'); + fs.writeFileSync(page, pageContent.replace('{version}', version), 'utf8'); + }); -console.log(`Updated ${pages.length} with correct version changelog link`); + // console.log(`Updated ${pages.length} with correct version changelog link`); -console.log('/// Finished changelog generation'); + // console.log('/// Finished changelog generation'); +}; + +export default generateChangelog; diff --git a/scripts/generatePages.ts b/scripts/generatePages.ts index 5af7c02..cf6ae38 100644 --- a/scripts/generatePages.ts +++ b/scripts/generatePages.ts @@ -2,67 +2,71 @@ import * as fs from 'fs'; import findInDir from './findInDir'; -console.log('/// Beginning generation of pages'); +const generatePages = (): void => { + // console.log('/// Beginning generation of pages'); -const templates = findInDir('./templates', '.html'); -const pages = findInDir('./pages', '.html'); + const partials = findInDir('./partials', '.html'); + const pages = findInDir('./pages', '.html'); -pages.forEach((page) => { - console.log(`Processing ${page}`); - let pageContents = fs.readFileSync(page, 'utf8'); - let pageName = page.replace('pages/', '').replace('.html', ''); - if (pageName === 'index') { - pageName = 'home'; - } + pages.forEach((page) => { + // console.log(`Processing ${page}`); + let pageContents = fs.readFileSync(page, 'utf8'); + let pageName = page.replace('pages/', '').replace('.html', ''); + if (pageName === 'index') { + pageName = 'home'; + } - let description = "I'm James King, and I make things for the web"; - switch (pageName) { - case 'thoughts': - description = 'A peak inside my brain you ask? Reader, beware...'; - break; - case 'profile': - description = - "So who am I? I'm James King, a 27 year old Software Engineer from Lincolnshire. You want some more info?"; - break; - case 'coding': - description = "Shall we take a look at some projects I've done?"; - break; - case 'changelog': - description = 'What changes have happened to this site?'; - break; - default: - // do nothing - already set description for home/index - } + let description = "I'm James King, and I make things for the web"; + switch (pageName) { + case 'thoughts': + description = 'A peak inside my brain you ask? Reader, beware...'; + break; + case 'profile': + description = + "So who am I? I'm James King, a 27 year old Software Engineer from Lincolnshire. You want some more info?"; + break; + case 'coding': + description = "Shall we take a look at some projects I've done?"; + break; + case 'changelog': + description = 'What changes have happened to this site?'; + break; + default: + // do nothing - already set description for home/index + } - templates.forEach((template) => { - const templateContents = fs - .readFileSync(template, 'utf8') - .replace(new RegExp(`{page}`, 'g'), pageName); + partials.forEach((template) => { + const templateContents = fs + .readFileSync(template, 'utf8') + .replace(new RegExp(`{page}`, 'g'), pageName); - pageContents = pageContents - .replace( - new RegExp(`{${template.replace('templates/', '')}}`, 'g'), - templateContents - ) - .replace(/{subpage}/g, '') - .replace(/{description}/g, description) - .replace( - /{age}/g, - new Number( - (new Date().getTime() - new Date('1992-05-21').getTime()) / - 31536000000 - ).toFixed(0) - ) - .replace(/{year}/g, new Date().getFullYear().toString()) - .replace( - /{noindex}/g, - process.env.NODE_ENV === 'development' - ? '<meta name="robots" content="noindex" />' - : '' - ); + pageContents = pageContents + .replace( + new RegExp(`{${template.replace('partials/', '')}}`, 'g'), + templateContents + ) + .replace(/{subpage}/g, '') + .replace(/{description}/g, description) + .replace( + /{age}/g, + new Number( + (new Date().getTime() - new Date('1992-05-21').getTime()) / + 31536000000 + ).toFixed(0) + ) + .replace(/{year}/g, new Date().getFullYear().toString()) + .replace( + /{noindex}/g, + process.env.NODE_ENV === 'development' + ? '<meta name="robots" content="noindex" />' + : '' + ); + }); + + fs.writeFileSync(page.replace('pages/', 'public/'), pageContents, 'utf8'); }); - fs.writeFileSync(page.replace('pages/', 'public/'), pageContents, 'utf8'); -}); + // console.log('/// Finished generation of pages'); +}; -console.log('/// Finished generation of pages'); +export default generatePages; diff --git a/scripts/generateSitemap.ts b/scripts/generateSitemap.ts index 95c0221..ea7f49e 100644 --- a/scripts/generateSitemap.ts +++ b/scripts/generateSitemap.ts @@ -5,131 +5,137 @@ import findInDir from './findInDir'; const SITE_ROOT = 'https://www.ripixel.co.uk/'; -console.log('/// Beginning sitemap generation'); - -const generatedPagesLocations = findInDir('./public', '.html'); -const generatedPages = generatedPagesLocations - .filter((page) => page !== 'public/404.html' && page !== 'public/index.html') - .map((page) => page.replace('public/', '').replace('.html', '')); - -const pagesModifiedDates: { - [key: string]: Date; -} = {}; - -const templatePagesLocations = findInDir('./pages', '.html'); -const thoughtsPagesLocations = findInDir('./thoughts/articles', '.md'); - -templatePagesLocations.forEach((pageLocation) => { - pagesModifiedDates[ - SITE_ROOT + - pageLocation - .replace('pages/', '') - .replace('.html', '') - .replace('index', '') - ] = fs.statSync(pageLocation).mtime; -}); - -thoughtsPagesLocations.forEach((pageLocation) => { - pagesModifiedDates[ - SITE_ROOT + pageLocation.replace('articles/', '').replace('.md', '') - ] = fs.statSync(pageLocation).mtime; -}); - -console.log( - `Found ${generatedPages.length} public pages (not including index or 404)` -); - -const generateUrlElement = (loc: string) => { - let changefreq = loc === SITE_ROOT ? 'monthly' : 'weekly'; - let prio = loc === SITE_ROOT ? '1.0' : '0.8'; - - if (loc.indexOf('thoughts/') > -1) { - // is an article/subpage - prio = '1'; - changefreq = 'yearly'; - } - - if (loc.indexOf('changelog') > 1) { - // it's the changelog - prio = '0.1'; - changefreq = 'weekly'; - } - - console.log(loc, prio, changefreq); - - return { - type: 'element', - name: 'url', - elements: [ - { - type: 'element', - name: 'loc', - elements: [ - { - type: 'text', - text: loc, - }, - ], - }, - { - type: 'element', - name: 'lastmod', - elements: [ - { - type: 'text', - text: pagesModifiedDates[loc].toISOString().split('T')[0], - }, - ], - }, - { - type: 'element', - name: 'changefreq', - elements: [ - { - type: 'text', - text: changefreq, - }, - ], +const generateSitemap = (): void => { + // console.log('/// Beginning sitemap generation'); + + const generatedPagesLocations = findInDir('./public', '.html'); + const generatedPages = generatedPagesLocations + .filter( + (page) => page !== 'public/404.html' && page !== 'public/index.html' + ) + .map((page) => page.replace('public/', '').replace('.html', '')); + + const pagesModifiedDates: { + [key: string]: Date; + } = {}; + + const templatePagesLocations = findInDir('./pages', '.html'); + const thoughtsPagesLocations = findInDir('./thoughts/articles', '.md'); + + templatePagesLocations.forEach((pageLocation) => { + pagesModifiedDates[ + SITE_ROOT + + pageLocation + .replace('pages/', '') + .replace('.html', '') + .replace('index', '') + ] = fs.statSync(pageLocation).mtime; + }); + + thoughtsPagesLocations.forEach((pageLocation) => { + pagesModifiedDates[ + SITE_ROOT + pageLocation.replace('articles/', '').replace('.md', '') + ] = fs.statSync(pageLocation).mtime; + }); + + // console.log( + // `Found ${generatedPages.length} public pages (not including index or 404)` + // ); + + const generateUrlElement = (loc: string) => { + let changefreq = loc === SITE_ROOT ? 'monthly' : 'weekly'; + let prio = loc === SITE_ROOT ? '1.0' : '0.8'; + + if (loc.indexOf('thoughts/') > -1) { + // is an article/subpage + prio = '1'; + changefreq = 'yearly'; + } + + if (loc.indexOf('changelog') > 1) { + // it's the changelog + prio = '0.1'; + changefreq = 'weekly'; + } + + // console.log(loc, prio, changefreq); + + return { + type: 'element', + name: 'url', + elements: [ + { + type: 'element', + name: 'loc', + elements: [ + { + type: 'text', + text: loc, + }, + ], + }, + { + type: 'element', + name: 'lastmod', + elements: [ + { + type: 'text', + text: pagesModifiedDates[loc].toISOString().split('T')[0], + }, + ], + }, + { + type: 'element', + name: 'changefreq', + elements: [ + { + type: 'text', + text: changefreq, + }, + ], + }, + { + type: 'element', + name: 'priority', + elements: [ + { + type: 'text', + text: prio, + }, + ], + }, + ], + }; + }; + + const sitemapJs = { + declaration: { + attributes: { + version: '1.0', + encoding: 'utf-8', }, + }, + elements: [ { type: 'element', - name: 'priority', - elements: [ - { - type: 'text', - text: prio, - }, - ], + name: 'urlset', + attributes: { + xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9', + }, + elements: [generateUrlElement(SITE_ROOT)], }, ], }; -}; -const sitemapJs = { - declaration: { - attributes: { - version: '1.0', - encoding: 'utf-8', - }, - }, - elements: [ - { - type: 'element', - name: 'urlset', - attributes: { - xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9', - }, - elements: [generateUrlElement(SITE_ROOT)], - }, - ], -}; + generatedPages.forEach((page) => { + sitemapJs.elements[0].elements.push(generateUrlElement(SITE_ROOT + page)); + }); -generatedPages.forEach((page) => { - sitemapJs.elements[0].elements.push(generateUrlElement(SITE_ROOT + page)); -}); + const sitemapXml = js2xml(sitemapJs, { spaces: 4 }); -const sitemapXml = js2xml(sitemapJs, { spaces: 4 }); + fs.writeFileSync('./public/sitemap.xml', sitemapXml, 'utf8'); -fs.writeFileSync('./public/sitemap.xml', sitemapXml, 'utf8'); + // console.log('/// Finished sitemap generation'); +}; -console.log('/// Finished sitemap generation'); +export default generateSitemap; diff --git a/scripts/generateThoughts.ts b/scripts/generateThoughts.ts index 94289a2..96805c4 100644 --- a/scripts/generateThoughts.ts +++ b/scripts/generateThoughts.ts @@ -7,128 +7,136 @@ import findInDir from './findInDir'; const ARTICLES_TO_SHOW = 5; -console.log('/// Beginning generation of thoughts'); +const generateThoughts = (): void => { + // console.log('/// Beginning generation of thoughts'); -const templates = findInDir('./templates', '.html'); + const partials = findInDir('./partials', '.html'); -console.log(`Processing initial thoughts page template`); -let thoughtsPageTemplateContents = fs.readFileSync( - './thoughts/template.html', - 'utf8' -); + // console.log(`Processing initial thoughts page template`); + let thoughtsPageTemplateContents = fs.readFileSync( + './thoughts/template.html', + 'utf8' + ); -templates.forEach((template) => { - const templateContents = fs - .readFileSync(template, 'utf8') - .replace(/{page}/g, 'thoughts'); + partials.forEach((template) => { + const templateContents = fs + .readFileSync(template, 'utf8') + .replace(/{page}/g, 'thoughts'); - thoughtsPageTemplateContents = thoughtsPageTemplateContents.replace( - new RegExp(`{${template.replace('templates/', '')}}`, 'g'), - templateContents - ); -}); - -console.log(`Processing articles`); -const articles = findInDir('./thoughts/articles', '.md'); - -const mdConverter = new showdown.Converter({ - extensions: [showdownHighlight], -}); - -const articlesGenerated: Array<{ - title: string; - link: string; - body: string; - date: string; - dateNum: number; -}> = []; - -articles.forEach((article) => { - const articleWithoutFolder = article - .replace('thoughts/articles/', '') - .replace('.md', '.html'); - const [datestring, titleWithDash] = articleWithoutFolder - .replace('.html', '') - .split('_'); - const dateObj = new Date(datestring); - const date = dateFormat(dateObj, 'do LLL, u'); - const title = titleWithDash.replace(/-/g, ' '); - const body = mdConverter.makeHtml(fs.readFileSync(article, 'utf8')); - - const splitBody = body.split('</p>'); - - const articleContents = thoughtsPageTemplateContents - .replace('{title}', title) - .replace('{date}', date) - .replace('{body}', body) - .replace(/thoughts {subpage}/g, `${title}`) - .replace( - /{description}/g, - `${splitBody[0]} ${splitBody[1]}` - .replace(/<(.*?)>/g, '') - .replace('\n', '') - ) - .replace(/{year}/g, new Date().getFullYear().toString()) - .replace( - /{noindex}/g, - process.env.NODE_ENV === 'development' - ? '<meta name="robots" content="noindex" />' - : '' + thoughtsPageTemplateContents = thoughtsPageTemplateContents.replace( + new RegExp(`{${template.replace('partials/', '')}}`, 'g'), + templateContents ); + }); - console.log(`Found article ${title} published ${date}`); - fs.writeFileSync( - `public/thoughts/${articleWithoutFolder}`, - articleContents, - 'utf8' - ); + // console.log(`Processing articles`); + const articles = findInDir('./thoughts/articles', '.md'); - articlesGenerated.push({ - link: `${datestring}_${titleWithDash}`, - title, - date, - dateNum: dateObj.valueOf(), - body: `${splitBody[0]}</p>${splitBody[1]}</p>`, + const mdConverter = new showdown.Converter({ + extensions: [showdownHighlight], }); -}); -console.log(`Generated ${articlesGenerated.length} articles`); + const articlesGenerated: Array<{ + title: string; + link: string; + body: string; + date: string; + dateNum: number; + }> = []; + + articles.forEach((article) => { + const articleWithoutFolder = article + .replace('thoughts/articles/', '') + .replace('.md', '.html'); + const [datestring, titleWithDash] = articleWithoutFolder + .replace('.html', '') + .split('_'); + const dateObj = new Date(datestring); + const date = dateFormat(dateObj, 'do LLL, u'); + const title = titleWithDash.replace(/-/g, ' '); + const body = mdConverter.makeHtml(fs.readFileSync(article, 'utf8')); + + const splitBody = body.split('</p>'); + + const articleContents = thoughtsPageTemplateContents + .replace('{title}', title) + .replace('{date}', date) + .replace('{body}', body) + .replace(/thoughts {subpage}/g, `${title}`) + .replace( + /{description}/g, + `${splitBody[0]} ${splitBody[1]}` + .replace(/<(.*?)>/g, '') + .replace('\n', '') + ) + .replace(/{year}/g, new Date().getFullYear().toString()) + .replace( + /{noindex}/g, + process.env.NODE_ENV === 'development' + ? '<meta name="robots" content="noindex" />' + : '' + ); + + // console.log(`Found article ${title} published ${date}`); + fs.writeFileSync( + `public/thoughts/${articleWithoutFolder}`, + articleContents, + 'utf8' + ); -console.log('Updating thoughts page proper'); -let thoughtsPageContents = fs.readFileSync('./public/thoughts.html', 'utf8'); + articlesGenerated.push({ + link: `${datestring}_${titleWithDash}`, + title, + date, + dateNum: dateObj.valueOf(), + body: `${splitBody[0]}</p>${splitBody[1]}</p>`, + }); + }); -const startRepPos = thoughtsPageContents.indexOf('<!--START_REP-->') + 16; // +16 for length of comment tag -const endRepPos = thoughtsPageContents.indexOf('<!--END_REP-->'); + // console.log(`Generated ${articlesGenerated.length} articles`); -const repeatableBlock = thoughtsPageContents.substr( - startRepPos, - endRepPos - startRepPos -); + // console.log('Updating thoughts page proper'); + let thoughtsPageContents = fs.readFileSync('./public/thoughts.html', 'utf8'); -let blockToPaste = ''; + const startRepPos = thoughtsPageContents.indexOf('<!--START_REP-->') + 16; // +16 for length of comment tag + const endRepPos = thoughtsPageContents.indexOf('<!--END_REP-->'); -articlesGenerated.sort((a, b) => b.dateNum - a.dateNum); // most-recent first + const repeatableBlock = thoughtsPageContents.substr( + startRepPos, + endRepPos - startRepPos + ); -for (let i = 0; i < Math.min(ARTICLES_TO_SHOW, articlesGenerated.length); i++) { - blockToPaste = + let blockToPaste = ''; + + articlesGenerated.sort((a, b) => b.dateNum - a.dateNum); // most-recent first + + for ( + let i = 0; + i < Math.min(ARTICLES_TO_SHOW, articlesGenerated.length); + i++ + ) { + blockToPaste = + blockToPaste + + `${repeatableBlock}` + .replace(`{title}`, articlesGenerated[i].title) + .replace(`{date}`, articlesGenerated[i].date) + .replace(`{body}`, articlesGenerated[i].body) + .replace(`{link}`, articlesGenerated[i].link); + } + + thoughtsPageContents = + `${thoughtsPageContents}`.substr(0, startRepPos) + blockToPaste + - `${repeatableBlock}` - .replace(`{title}`, articlesGenerated[i].title) - .replace(`{date}`, articlesGenerated[i].date) - .replace(`{body}`, articlesGenerated[i].body) - .replace(`{link}`, articlesGenerated[i].link); -} - -thoughtsPageContents = - `${thoughtsPageContents}`.substr(0, startRepPos) + - blockToPaste + - `${thoughtsPageContents}`.substr( - endRepPos, - thoughtsPageContents.length - endRepPos - ); + `${thoughtsPageContents}`.substr( + endRepPos, + thoughtsPageContents.length - endRepPos + ); + + // console.log('Updated thoughts page'); -console.log('Updated thoughts page'); + fs.writeFileSync('./public/thoughts.html', thoughtsPageContents, 'utf8'); -fs.writeFileSync('./public/thoughts.html', thoughtsPageContents, 'utf8'); + // console.log('/// Finished generation of thoughts'); +}; -console.log('/// Finished generation of thoughts'); +export default generateThoughts; diff --git a/scripts/humble.ts b/scripts/humble.ts new file mode 100755 index 0000000..37385d3 --- /dev/null +++ b/scripts/humble.ts @@ -0,0 +1,78 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import * as path from 'path'; +import { Listr } from 'listr2'; +import execa from 'execa'; + +import generatePages from './generatePages'; +import generateThoughts from './generateThoughts'; +import generateSitemap from './generateSitemap'; +import generateChangelog from './generateChangelog'; + +import { config } from '../humble.config'; + +const rootDir = path.resolve(config.rootDir); +const outDir = path.resolve(rootDir, config.outDir); +const cssDir = path.resolve(rootDir, config.cssDir); +const nodeModulesDir = path.resolve(rootDir, config.nodeModulesDir); +const imagesDir = path.resolve(rootDir, config.imagesDir); +// const pagesDir = path.resolve(rootDir, config.pagesDir); +// const partialsDir = path.resolve(rootDir, config.partialsDir); + +const allTaskList = [ + { + title: 'Create output directory', + task: () => execa(`mkdir`, ['-p', `${outDir}`]), + }, + { + title: 'Clean output directory', + task: () => execa(`rm`, [`-rf`, `${outDir}/*`]), + }, + { + title: 'Build CSS', + task: () => + execa(`${nodeModulesDir}/clean-css-cli/bin/cleancss`, [ + `-o`, + `${outDir}/styles.min.css`, + `${cssDir}/*.css`, + ]), + }, + { + title: 'Copy Images', + task: () => execa(`cp`, [`-R`, `${imagesDir}/.`, `${outDir}/`]), + }, + { + title: 'Build Pages', + task: () => generatePages(), + }, + { + title: 'Build Repeatable Pages', + task: () => + execa(`mkdir`, [`-p`, `${outDir}/thoughts`]).then(() => + generateThoughts() + ), + }, +]; + +const prodTaskList = [ + { + title: 'Build Favicons', + task: () => + execa(`node`, [`${nodeModulesDir}/favicons-generate/bin/cli.js`]), + skip: () => !config.generateFavicons, + }, + { + title: 'Build Sitemap', + task: () => generateSitemap(), + }, + { + title: 'Build Changelog', + task: () => generateChangelog(), + }, +]; + +const toExecute = + process.env.NODE_ENV !== 'development' + ? [...allTaskList, ...prodTaskList] + : allTaskList; + +new Listr(toExecute).run();