eleventy-generate-posts 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 John M. Wargo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/changelog.md ADDED
@@ -0,0 +1 @@
1
+ # Changelog
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+ import boxen from 'boxen';
5
+ import chalk from 'chalk';
6
+ import { Command } from 'commander';
7
+ import YAML from 'yaml';
8
+ import logger from 'cli-logger';
9
+ var log = logger();
10
+ var HighlightType;
11
+ (function (HighlightType) {
12
+ HighlightType[HighlightType["Red"] = 0] = "Red";
13
+ HighlightType[HighlightType["Yellow"] = 1] = "Yellow";
14
+ HighlightType[HighlightType["Green"] = 2] = "Green";
15
+ })(HighlightType || (HighlightType = {}));
16
+ const APP_NAME = '11ty Generate Posts';
17
+ const APP_AUTHOR = 'by John M. Wargo (https://johnwargo.com)';
18
+ const ELEVENTY_FILES = ['.eleventy.js', 'eleventy.config.js'];
19
+ const NEW_LINE = "\n";
20
+ const red = HighlightType.Red;
21
+ const yellow = HighlightType.Yellow;
22
+ const green = HighlightType.Green;
23
+ function zeroPad(tmpVal, numChars = 2) {
24
+ return tmpVal.toString().padStart(numChars, '0');
25
+ }
26
+ function directoryExists(filePath) {
27
+ if (fs.existsSync(filePath)) {
28
+ try {
29
+ return fs.lstatSync(filePath).isDirectory();
30
+ }
31
+ catch (err) {
32
+ log.error(`checkDirectory error: ${err}`);
33
+ return false;
34
+ }
35
+ }
36
+ return false;
37
+ }
38
+ function writeConsole(color, highlightText, msg) {
39
+ if (color == HighlightType.Red)
40
+ console.log(NEW_LINE + chalk.red(`${highlightText}: `) + msg + NEW_LINE);
41
+ if (color == HighlightType.Yellow)
42
+ console.log(chalk.yellow(`${highlightText}: `) + msg);
43
+ if (color == HighlightType.Green)
44
+ console.log(chalk.green(`${highlightText}: `) + msg);
45
+ }
46
+ function getRandomInt(max) {
47
+ return Math.floor(Math.random() * max) + 1;
48
+ }
49
+ function checkEleventyProject() {
50
+ log.debug('Validating project folder');
51
+ let result = false;
52
+ ELEVENTY_FILES.forEach((file) => {
53
+ let tmpFile = path.join(process.cwd(), file);
54
+ if (fs.existsSync(tmpFile)) {
55
+ result = true;
56
+ }
57
+ });
58
+ return result;
59
+ }
60
+ if (!checkEleventyProject()) {
61
+ log.error('Current folder is not an Eleventy project folder.');
62
+ process.exit(1);
63
+ }
64
+ const program = new Command();
65
+ program
66
+ .name('11ty-gp')
67
+ .description('Generate a set of posts for an Eleventy project')
68
+ .argument('<numPosts>', 'Number of posts to generate')
69
+ .argument('<targetFolder>', 'Target folder for generated posts files')
70
+ .argument('<tag>', 'Tag to apply to all generated posts')
71
+ .argument('[startYear]', 'Start year for generated posts')
72
+ .option('-d, --debug', 'Debug mode')
73
+ .action(async (numPosts, targetFolder, tag, startYear) => {
74
+ console.log(boxen(APP_NAME, { padding: 1 }));
75
+ console.log(APP_AUTHOR);
76
+ const options = program.opts();
77
+ const debugMode = options.debug;
78
+ if (debugMode) {
79
+ console.log('Debug mode enabled.');
80
+ }
81
+ log.level(debugMode ? log.DEBUG : log.INFO);
82
+ writeConsole(yellow, 'Number of posts', numPosts);
83
+ writeConsole(yellow, 'Target Folder', targetFolder);
84
+ if (startYear)
85
+ writeConsole(yellow, 'Start Year', startYear);
86
+ writeConsole(yellow, 'Tag', tag);
87
+ if (!Number.isInteger(parseInt(numPosts))) {
88
+ writeConsole(red, 'Error', 'Number of posts must be an integer');
89
+ process.exit(1);
90
+ }
91
+ if (!(numPosts > 0 && numPosts < 101)) {
92
+ writeConsole(red, 'Error', 'Number of posts must be between 1 and 100');
93
+ process.exit(1);
94
+ }
95
+ var outputFilePath = path.join(process.cwd(), targetFolder);
96
+ writeConsole(yellow, 'Output folder', outputFilePath);
97
+ if (!directoryExists(outputFilePath)) {
98
+ writeConsole(red, 'Error', 'Target folder does not exist');
99
+ process.exit(1);
100
+ }
101
+ var currentDate = new Date();
102
+ if (startYear)
103
+ currentDate.setFullYear(startYear);
104
+ numPosts++;
105
+ for (let i = 1; i < numPosts; i++) {
106
+ log.debug('\nGetting random words (this may take a few seconds)');
107
+ let wordCount = getRandomInt(4) + 3;
108
+ let letTitleRes = await fetch(`https://random-word-api.vercel.app/api?words=${wordCount}`);
109
+ let titleWords = await letTitleRes.json();
110
+ titleWords = titleWords.map((a) => a.charAt(0).toUpperCase() + a.substr(1));
111
+ let postTitle = titleWords.join(' ');
112
+ log.debug(`Post title: ${postTitle}`);
113
+ currentDate.setDate(currentDate.getDate() - getRandomInt(20));
114
+ let postDate = `${currentDate.getFullYear()}-${zeroPad(currentDate.getMonth() + 1)}-${zeroPad(currentDate.getDate())}`;
115
+ log.debug(`Post date: ${postDate}`);
116
+ var postFm = {
117
+ title: postTitle,
118
+ date: postDate,
119
+ tags: tag
120
+ };
121
+ log.debug('Getting bacon ipsum text (this may take a few seconds)...');
122
+ let response = await fetch(`https://baconipsum.com/api/?type=all-meat&paras=${getRandomInt(10)}&start-with-lorem=1`);
123
+ let postContent = await response.json();
124
+ log.debug(`Post content: ${postContent}`);
125
+ var thePost = '---\n';
126
+ thePost += YAML.stringify(postFm, { logLevel: 'silent' });
127
+ thePost += '---\n\n';
128
+ thePost += postContent.join('\n\n');
129
+ var outputFilePath = path.join(targetFolder, postTitle.toLowerCase().replaceAll(' ', '-') + '.md');
130
+ writeConsole(green, 'Writing', outputFilePath);
131
+ fs.writeFileSync(outputFilePath, thePost, 'utf8');
132
+ }
133
+ });
134
+ console.log();
135
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "eleventy-generate-posts",
3
+ "version": "0.0.1",
4
+ "description": "Generates batches of Eleventy posts",
5
+ "author": "John M. Wargo",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/johnwargo/eleventy-generate-posts"
10
+ },
11
+ "type": "module",
12
+ "main": "eleventy-generate-posts.js",
13
+ "bin": {
14
+ "11ty-gp": "eleventy-generate-posts.js"
15
+ },
16
+ "keywords": [
17
+ "node",
18
+ "eleventy"
19
+ ],
20
+ "scripts": {
21
+ "test": "echo \"Error: no test specified\" && exit 1",
22
+ "start": "tsc && node eleventy-generate-posts.js 5 posts post"
23
+ },
24
+ "dependencies": {
25
+ "boxen": "^7.0.2",
26
+ "chalk": "^5.2.0",
27
+ "cli-logger": "^0.5.40",
28
+ "commander": "^10.0.1",
29
+ "fs-extra": "^11.1.1",
30
+ "yaml": "^2.2.2"
31
+ },
32
+ "devDependencies": {
33
+ "@types/fs-extra": "^11.0.1",
34
+ "@types/node": "^18.15.5",
35
+ "@types/prompts": "^2.4.4",
36
+ "eleventy": "^1.0.6"
37
+ }
38
+ }
package/readme.md ADDED
@@ -0,0 +1,86 @@
1
+ # Eleventy Generate Posts
2
+
3
+ A simple command-line utility that creates a batch of new posts for an [Eleventy](https://www.11ty.dev/) site.
4
+
5
+ When you're testing out some aspect of an Eleventy site or doing a demo, you often need to populate the site with a set of posts to flesh out the site. Copying a single post or set of posts repeatedly into the site works, but an automated solution is better. This is that solution.
6
+
7
+ The utility generates batches of Eleventy site posts, populating the post title with a random quantity of random words and populating the post body with a random number of paragraphs of [Bacon Ipsum](https://baconipsum.com/) text.
8
+
9
+ ## Installation
10
+
11
+ To install the command globally on the system, open a terminal window or command prompt, then execute the following command:
12
+
13
+ ```shell
14
+ npm install -g eleventy-generate-posts
15
+ ```
16
+
17
+ This adds a `11ty-gp` command to the system.
18
+
19
+ You don't have to install the package to use it; simply open a terminal window or command prompt to your Eleventy project folder and execute the command using `npx eleventy-generate-posts` and the command-line options described in the following section.
20
+ ## Usage
21
+
22
+ Execute the command using the following command-line parameters:
23
+
24
+ ```shell
25
+ 11ty-gp [options] <numPosts> <targetFolder> <tag> [startYear]
26
+ ```
27
+
28
+ Supported command-line options are:
29
+
30
+ * `numPosts` (required) An integer value representing the number of posts generated.
31
+ * `targetFolder` (required) Relative path pointing to the Eleventy project's posts folder; use `.` for the current folder.
32
+ * `tag` (required) The post tag applied to the generated posts
33
+ * `startYear` (optional) The starting year used for post date in the generated posts. The command uses the current date or the current date with the specified year (when provided) to for the post date for the first generated post. For subsequent post dates, the command randomly decrements the day.
34
+
35
+ As an example, to generate 10 posts in the project's `posts` folder using a `tags` value of `post`, use:
36
+
37
+ ```shell
38
+ 11ty-gp 10 posts post
39
+ ```
40
+
41
+ This command sets the post date for the current post to the current date, then works backwards (random days) for each subsequent generated post.
42
+
43
+ To generate 20 posts starting in 2021, use the following:
44
+
45
+ ```shell
46
+ 11ty-gp 20 posts post 2021
47
+ ```
48
+
49
+ This command sets the post date for the current post to the current month/day plus the provided year, then works backwards (random days) for each subsequent generated post. So, if you execute the command on May 10, 2023, the command sets the post date for the first post to May 10, 2021 and works (randomly) backwards from there.
50
+
51
+ Supported command-line options (flags) are:
52
+
53
+ * `-d` or `--debug`: Enables debug mode which generates additional content to the terminal during execution
54
+ * `h` or `--help`: Displays usage information in the terminal
55
+
56
+ A sample generated post looks like the following:
57
+
58
+ ```markdown
59
+ ---
60
+ title: Boaster Halogen Jokingly Evident Decode Steadfast
61
+ date: 2023-03-19
62
+ tags: post
63
+ ---
64
+
65
+ Bacon ipsum dolor amet brisket picanha swine beef ribs pork. Pig short ribs andouille ham ribeye hamburger
66
+ tail rump turducken kevin alcatra bacon beef meatloaf. Bresaola pancetta pig, cupim frankfurter brisket
67
+ pork belly turkey. Pork belly frankfurter cupim, salami picanha short ribs beef ribs chuck fatback pastrami
68
+ doner chicken ham. Tail fatback landjaeger chicken jowl, pancetta bresaola picanha. Pork belly ball tip
69
+ picanha bresaola capicola prosciutto drumstick swine flank cupim corned beef.
70
+
71
+ Sausage frankfurter ground round tail, tri-tip burgdoggen flank pork loin. Bresaola landjaeger shoulder
72
+ pastrami burgdoggen meatball. Frankfurter kevin pig, hamburger andouille tail meatloaf cupim meatball beef
73
+ ribs prosciutto. Meatloaf chislic flank tri-tip swine filet mignon brisket sirloin turkey porchetta.
74
+ ```
75
+
76
+ ### Getting Help Or Making Changes
77
+
78
+ Use [GitHub Issues](https://github.com/johnwargo/eleventy-generate-posts/issues) to get help with this module.
79
+
80
+ Pull Requests gladly accepted, but only with complete documentation of what the change is, why you made it, and why you think its important to have in the module.
81
+
82
+ ***
83
+
84
+ If this code helps you, please consider buying me a coffee.
85
+
86
+ <a href="https://www.buymeacoffee.com/johnwargo" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>