Compare commits
	
		
			12 Commits
		
	
	
		
			df172e94ea
			...
			3c9d62b840
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3c9d62b840 | |||
| 4dae70a45f | |||
| 25ae3a2b65 | |||
| ef3a394657 | |||
| d713786685 | |||
| 4311a4c841 | |||
| 48fde2c0b6 | |||
| 3ed57b75f4 | |||
| f8708909b6 | |||
| 2d42605c59 | |||
| 35760c2da2 | |||
| c8f87ade58 | 
							
								
								
									
										77
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					kind: pipeline
 | 
				
			||||||
 | 
					type: docker
 | 
				
			||||||
 | 
					name: figlet-http build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					platform:
 | 
				
			||||||
 | 
					  os: linux
 | 
				
			||||||
 | 
					  arch: amd64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					volumes:
 | 
				
			||||||
 | 
					  - name: cache
 | 
				
			||||||
 | 
					    host:
 | 
				
			||||||
 | 
					      path: /tmp/cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					steps:
 | 
				
			||||||
 | 
					  - name: Load cached node_modules packages
 | 
				
			||||||
 | 
					    image: sinlead/drone-cache:1.0.0
 | 
				
			||||||
 | 
					    settings:
 | 
				
			||||||
 | 
					      action: load
 | 
				
			||||||
 | 
					      key: yarn.lock
 | 
				
			||||||
 | 
					      mount: node_modules
 | 
				
			||||||
 | 
					      prefix: yarn-modules-figlet-http
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - name: cache
 | 
				
			||||||
 | 
					        path: /cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - name: Install
 | 
				
			||||||
 | 
					    image: node:18.2.0
 | 
				
			||||||
 | 
					    commands:
 | 
				
			||||||
 | 
					      - node -v
 | 
				
			||||||
 | 
					      - yarn --version
 | 
				
			||||||
 | 
					      - yarn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - name: Cache node_modules packages
 | 
				
			||||||
 | 
					    image: sinlead/drone-cache:1.0.0
 | 
				
			||||||
 | 
					    settings:
 | 
				
			||||||
 | 
					      action: save
 | 
				
			||||||
 | 
					      key: yarn.lock
 | 
				
			||||||
 | 
					      mount: node_modules
 | 
				
			||||||
 | 
					      prefix: yarn-modules-figlet-http
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - name: cache
 | 
				
			||||||
 | 
					        path: /cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - name: Build ts
 | 
				
			||||||
 | 
					    image: node:18.2.0
 | 
				
			||||||
 | 
					    commands:
 | 
				
			||||||
 | 
					      - yarn build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - name: Lint project using eslint
 | 
				
			||||||
 | 
					    image: node:18.2.0
 | 
				
			||||||
 | 
					    commands:
 | 
				
			||||||
 | 
					      - yarn lint
 | 
				
			||||||
 | 
					    failure: ignore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - name: Build and publish docker image
 | 
				
			||||||
 | 
					    image: plugins/docker
 | 
				
			||||||
 | 
					    settings:
 | 
				
			||||||
 | 
					      registry: ghcr.io
 | 
				
			||||||
 | 
					      repo: ghcr.io/kevinmidboe/figlet-http
 | 
				
			||||||
 | 
					      dockerfile: Dockerfile
 | 
				
			||||||
 | 
					      username:
 | 
				
			||||||
 | 
					        from_secret: GITHUB_USERNAME
 | 
				
			||||||
 | 
					      password:
 | 
				
			||||||
 | 
					        from_secret: GITHUB_PASSWORD
 | 
				
			||||||
 | 
					      tags: latest
 | 
				
			||||||
 | 
					    when:
 | 
				
			||||||
 | 
					      event:
 | 
				
			||||||
 | 
					        - push
 | 
				
			||||||
 | 
					      branch:
 | 
				
			||||||
 | 
					        - master
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					trigger:
 | 
				
			||||||
 | 
					  event:
 | 
				
			||||||
 | 
					    include:
 | 
				
			||||||
 | 
					      - push
 | 
				
			||||||
 | 
					      - pull_request
 | 
				
			||||||
							
								
								
									
										41
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "root": true,
 | 
				
			||||||
 | 
					  "parserOptions": {
 | 
				
			||||||
 | 
					    "parser": "@typescript-eslint/parser",
 | 
				
			||||||
 | 
					    "ecmaVersion": 2020,
 | 
				
			||||||
 | 
					    "sourceType": "module"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "extends": [
 | 
				
			||||||
 | 
					    "eslint-config-airbnb-base",
 | 
				
			||||||
 | 
					    "plugin:@typescript-eslint/recommended"
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  "plugins": ["@typescript-eslint"],
 | 
				
			||||||
 | 
					  "rules": {
 | 
				
			||||||
 | 
					    "lines-between-class-members": [
 | 
				
			||||||
 | 
					      "error",
 | 
				
			||||||
 | 
					      "always",
 | 
				
			||||||
 | 
					      { "exceptAfterSingleLine": true }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "max-classes-per-file": 1,
 | 
				
			||||||
 | 
					    "no-empty": [
 | 
				
			||||||
 | 
					      2,
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "allowEmptyCatch": true
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "no-promise-executor-return": 1,
 | 
				
			||||||
 | 
					    "import/extensions": "off",
 | 
				
			||||||
 | 
					    "max-classes-per-file": "off",
 | 
				
			||||||
 | 
					    "no-shadow": "off",
 | 
				
			||||||
 | 
					    "no-underscore-dangle": "off",
 | 
				
			||||||
 | 
					    "@typescript-eslint/no-var-requires": "off"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "settings": {
 | 
				
			||||||
 | 
					    "import/resolver": {
 | 
				
			||||||
 | 
					      "node": {
 | 
				
			||||||
 | 
					        "extensions": [".js", ".ts"]
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,4 @@
 | 
				
			|||||||
node_modules/
 | 
					node_modules/
 | 
				
			||||||
 | 
					lib/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.DS_Store
 | 
					.DS_Store
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,16 +1,14 @@
 | 
				
			|||||||
FROM node:18
 | 
					FROM node:18
 | 
				
			||||||
LABEL org.opencontainers.image.source https://github.com/KevinMidboe/figlet-http
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN mkdir -p /opt/figlet-http/src
 | 
					RUN mkdir -p /opt/figlet-http/lib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /opt/figlet-http
 | 
					WORKDIR /opt/figlet-http
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY src/ src
 | 
					 | 
				
			||||||
COPY package.json .
 | 
					COPY package.json .
 | 
				
			||||||
COPY yarn.lock .
 | 
					COPY lib/ lib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN yarn
 | 
					RUN yarn install --production
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPOSE 3000
 | 
					EXPOSE 3000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CMD ["yarn", "start"]
 | 
					CMD ["node", "lib/app.js"]
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										54
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								README.md
									
									
									
									
									
								
							@@ -20,10 +20,23 @@ yarn start
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Examples
 | 
					## Examples
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Generate Larry 3D ascii response from text:
 | 
					Generate Larry 3D figlet response from text:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
curl localhost:3000/ascii\?text\=ragnhild
 | 
					curl localhost:3000/figlet\?text\=ragnhild
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Outputs:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					                             __           ___       __     
 | 
				
			||||||
 | 
					                            /\ \      __ /\_ \     /\ \    
 | 
				
			||||||
 | 
					 _ __    __       __     ___\ \ \___ /\_\\//\ \    \_\ \   
 | 
				
			||||||
 | 
					/\`'__\/'__`\   /'_ `\ /' _ `\ \  _ `\/\ \ \ \ \   /'_` \  
 | 
				
			||||||
 | 
					\ \ \//\ \L\.\_/\ \L\ \/\ \/\ \ \ \ \ \ \ \ \_\ \_/\ \L\ \ 
 | 
				
			||||||
 | 
					 \ \_\\ \__/.\_\ \____ \ \_\ \_\ \_\ \_\ \_\/\____\ \___,_\
 | 
				
			||||||
 | 
					  \/_/ \/__/\/_/\/___L\ \/_/\/_/\/_/\/_/\/_/\/____/\/__,_ /
 | 
				
			||||||
 | 
					                  /\____/                                  
 | 
				
			||||||
 | 
					                  \_/__/
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Generate motd executable with text and save to file:
 | 
					Generate motd executable with text and save to file:
 | 
				
			||||||
@@ -32,35 +45,60 @@ Generate motd executable with text and save to file:
 | 
				
			|||||||
curl localhost:3000/motd\?text\=ragnhild > 20-hostname
 | 
					curl localhost:3000/motd\?text\=ragnhild > 20-hostname
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Options
 | 
				
			||||||
 | 
					Api endpoints `/text` & `/motd` have the following query options:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| query param | type   | description                          | required |
 | 
				
			||||||
 | 
					|-------------|--------|--------------------------------------|----------|
 | 
				
			||||||
 | 
					| text        | string | text to generate                     | yes      |
 | 
				
			||||||
 | 
					| font        | string | select font, get list from /fonts    | no       |
 | 
				
			||||||
 | 
					| width       | number | max character width before linebreak | no       |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Docker install
 | 
					## Docker install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Run as a docker container using:
 | 
					Run as a docker container from github container registry:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
docker run -d \
 | 
					sudo docker run -d \
 | 
				
			||||||
  --name figlet-http \
 | 
					  --name figlet-http \
 | 
				
			||||||
  -p 3000:3000 \
 | 
					  -p 3000:3000 \
 | 
				
			||||||
  ghcr.io/kevinmidboe/figlet-http
 | 
					  ghcr.io/kevinmidboe/figlet-http
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Run as docker locally:
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn build; \
 | 
				
			||||||
 | 
					sudo docker build -t figlet-http .; \
 | 
				
			||||||
 | 
					sudo docker run -d \
 | 
				
			||||||
 | 
					  --name figlet-http \
 | 
				
			||||||
 | 
					  -p 3000:3000 \
 | 
				
			||||||
 | 
					  figlet-http
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Systemd service
 | 
					## Systemd service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example systemd config for running http server.
 | 
					Example systemd config for running http server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Clone repo to: `/opt/figlet-http`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`/etc/systemd/system/figlet-http.service`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
[Unit]
 | 
					[Unit]
 | 
				
			||||||
Description=Http server for running homename-larry
 | 
					Description=Http server for running figlet-http
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Service]
 | 
					[Service]
 | 
				
			||||||
WorkingDirectory=/opt/hostname-larry
 | 
					WorkingDirectory=/opt/figlet-http
 | 
				
			||||||
ExecStart=/usr/bin/node index.js
 | 
					ExecStart=/usr/bin/yarn start
 | 
				
			||||||
Restart=always
 | 
					Restart=always
 | 
				
			||||||
# Restart service after 10 seconds if node service crashes
 | 
					# Restart service after 10 seconds if node service crashes
 | 
				
			||||||
RestartSec=10
 | 
					RestartSec=10
 | 
				
			||||||
# Output to syslog
 | 
					# Output to syslog
 | 
				
			||||||
StandardOutput=syslog
 | 
					StandardOutput=syslog
 | 
				
			||||||
StandardError=syslog
 | 
					StandardError=syslog
 | 
				
			||||||
SyslogIdentifier=hostname-larry
 | 
					SyslogIdentifier=figlet-http
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Install]
 | 
					[Install]
 | 
				
			||||||
WantedBy=multi-user.target
 | 
					WantedBy=multi-user.target
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								package.json
									
									
									
									
									
								
							@@ -1,9 +1,21 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  "version": "1.0.0",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "start": "node src/app.js"
 | 
					    "build": "tsc",
 | 
				
			||||||
 | 
					    "start": "node lib/app.js",
 | 
				
			||||||
 | 
					    "lint": "eslint src"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "express": "^4.18.2",
 | 
					    "express": "^4.18.2",
 | 
				
			||||||
    "figlet": "^1.5.2"
 | 
					    "figlet": "^1.5.2"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "devDependencies": {
 | 
				
			||||||
 | 
					    "@types/node": "^18.11.2",
 | 
				
			||||||
 | 
					    "@typescript-eslint/eslint-plugin": "^5.40.1",
 | 
				
			||||||
 | 
					    "@typescript-eslint/parser": "^5.40.1",
 | 
				
			||||||
 | 
					    "eslint": "^8.25.0",
 | 
				
			||||||
 | 
					    "eslint-config-airbnb-base": "^15.0.0",
 | 
				
			||||||
 | 
					    "eslint-plugin-import": "^2.26.0",
 | 
				
			||||||
 | 
					    "typescript": "^4.8.4"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								src/app.js
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/app.js
									
									
									
									
									
								
							@@ -1,15 +0,0 @@
 | 
				
			|||||||
const express = require("express");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const asciiFontController = require("./controllers/asciiController.js");
 | 
					 | 
				
			||||||
const modtFontController = require("./controllers/motdController.js");
 | 
					 | 
				
			||||||
const requiredQueryMiddleware = require("./requiredQueryMiddleware");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const app = express();
 | 
					 | 
				
			||||||
const port = 3000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.get("/ascii", requiredQueryMiddleware, asciiFontController);
 | 
					 | 
				
			||||||
app.get("/motd", requiredQueryMiddleware, modtFontController);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.listen(port, () => {
 | 
					 | 
				
			||||||
  console.log(`Font generation application listening on port ${port}.`);
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
							
								
								
									
										17
									
								
								src/app.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/app.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					import express from 'express';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import figletontController from './controllers/figletController';
 | 
				
			||||||
 | 
					import modtFontController from './controllers/motdController';
 | 
				
			||||||
 | 
					import fontsController from './controllers/fontsController';
 | 
				
			||||||
 | 
					import requiredQueryMiddleware from './requiredQueryMiddleware';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const app = express();
 | 
				
			||||||
 | 
					const port = 3000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.get('/figlet', requiredQueryMiddleware, figletontController);
 | 
				
			||||||
 | 
					app.get('/motd', requiredQueryMiddleware, modtFontController);
 | 
				
			||||||
 | 
					app.get('/fonts', fontsController);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.listen(port, () => {
 | 
				
			||||||
 | 
					  console.log(`Figlet generation application listening on port ${port}.`); // eslint-disable-line no-console
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										33
									
								
								src/ascii.js
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								src/ascii.js
									
									
									
									
									
								
							@@ -1,33 +0,0 @@
 | 
				
			|||||||
const figlet = require("figlet");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const defaultFontOptions = {
 | 
					 | 
				
			||||||
  font: "Larry 3D",
 | 
					 | 
				
			||||||
  horizontalLayout: "default",
 | 
					 | 
				
			||||||
  verticalLayout: "default",
 | 
					 | 
				
			||||||
  width: 80,
 | 
					 | 
				
			||||||
  whitespaceBreak: true,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function generateAscii(message, options) {
 | 
					 | 
				
			||||||
  const _options = {
 | 
					 | 
				
			||||||
    ...defaultFontOptions,
 | 
					 | 
				
			||||||
    ...options,
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return new Promise((resolve, reject) => {
 | 
					 | 
				
			||||||
    figlet.text(message, _options, (err, data) => {
 | 
					 | 
				
			||||||
      if (err) {
 | 
					 | 
				
			||||||
        console.error("error from figlet:", error);
 | 
					 | 
				
			||||||
        return reject(err);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (_options.font === "Larry 3D") {
 | 
					 | 
				
			||||||
        data = data.replaceAll("L", "_");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      resolve(data);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = generateAscii;
 | 
					 | 
				
			||||||
@@ -1,16 +0,0 @@
 | 
				
			|||||||
const generateAscii = require("../ascii.js");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const asciiFontController = (req, res) => {
 | 
					 | 
				
			||||||
  const { text } = req.query;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return generateAscii(text)
 | 
					 | 
				
			||||||
    .then((ascii) => res.send(ascii))
 | 
					 | 
				
			||||||
    .catch((error) =>
 | 
					 | 
				
			||||||
      res.status(error?.statusCode || 500).send({
 | 
					 | 
				
			||||||
        success: false,
 | 
					 | 
				
			||||||
        message: error?.message || "Unexpected error from font generation",
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = asciiFontController;
 | 
					 | 
				
			||||||
							
								
								
									
										20
									
								
								src/controllers/figletController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/controllers/figletController.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					import FigletFonts from '../figletFonts';
 | 
				
			||||||
 | 
					import IFigletOptions from '../interfaces/IFigletOptions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const figletFonts = new FigletFonts();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const figletTextController = async (req, res) => {
 | 
				
			||||||
 | 
					  const { text, font, width } = req.query;
 | 
				
			||||||
 | 
					  let options: IFigletOptions;
 | 
				
			||||||
 | 
					  if (font) options = { ...options, font };
 | 
				
			||||||
 | 
					  if (width) options = { ...options, width };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  figletFonts.generateText(text, options)
 | 
				
			||||||
 | 
					    .then((data) => res.send(data))
 | 
				
			||||||
 | 
					    .catch((error) => {
 | 
				
			||||||
 | 
					      const msg = error?.message || 'Unexpected error from generating figlet';
 | 
				
			||||||
 | 
					      res.status(error?.statusCode || 500).send(msg);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default figletTextController;
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/controllers/fontsController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/controllers/fontsController.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					import FigletFonts from '../figletFonts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const figletFonts = new FigletFonts();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const fontsController = (req, res) => figletFonts.fonts
 | 
				
			||||||
 | 
					  .then((fonts) => res.send(fonts))
 | 
				
			||||||
 | 
					  .catch((error) => {
 | 
				
			||||||
 | 
					    const msg = error?.message || 'Unexpected error from fetching fonts';
 | 
				
			||||||
 | 
					    res.status(error?.statusCode || 500).send(msg);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default fontsController;
 | 
				
			||||||
@@ -1,17 +0,0 @@
 | 
				
			|||||||
const generateAscii = require("../ascii.js");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const modtFontController = (req, res) => {
 | 
					 | 
				
			||||||
  const { text } = req.query;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return generateAscii(message)
 | 
					 | 
				
			||||||
    .then((ascii) => generateCatOutput(ascii))
 | 
					 | 
				
			||||||
    .then((motd) => res.send(motd))
 | 
					 | 
				
			||||||
    .catch((error) => {
 | 
					 | 
				
			||||||
      return res.status(500).send({
 | 
					 | 
				
			||||||
        success: false,
 | 
					 | 
				
			||||||
        message: "Unexpected error from font generation",
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = modtFontController;
 | 
					 | 
				
			||||||
							
								
								
									
										29
									
								
								src/controllers/motdController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/controllers/motdController.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					import FigletFonts from '../figletFonts';
 | 
				
			||||||
 | 
					import IFigletOptions from '../interfaces/IFigletOptions';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const figletFonts = new FigletFonts();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function generateCatOutput(data: string) {
 | 
				
			||||||
 | 
					  return Promise.resolve(`#!/bin/sh
 | 
				
			||||||
 | 
					cat << 'EOF'
 | 
				
			||||||
 | 
					${data}
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					  `);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const modtFontController = (req, res) => {
 | 
				
			||||||
 | 
					  const { text, font, width } = req.query;
 | 
				
			||||||
 | 
					  let options: IFigletOptions;
 | 
				
			||||||
 | 
					  if (font) options = { ...options, font };
 | 
				
			||||||
 | 
					  if (width) options = { ...options, width };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  figletFonts.generateText(text, options)
 | 
				
			||||||
 | 
					    .then((data) => generateCatOutput(data))
 | 
				
			||||||
 | 
					    .then((motd) => res.send(motd))
 | 
				
			||||||
 | 
					    .catch((error) => {
 | 
				
			||||||
 | 
					      const msg = error?.message || 'Unexpected error from generating motd figlet';
 | 
				
			||||||
 | 
					      res.status(error?.statusCode || 500).send(msg);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default modtFontController;
 | 
				
			||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
class MissingTextError extends Error {
 | 
					 | 
				
			||||||
  constructor(error = null) {
 | 
					 | 
				
			||||||
    const message = `Missing query parameter 'text'`;
 | 
					 | 
				
			||||||
    super(message);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.error = error;
 | 
					 | 
				
			||||||
    this.statusCode = 400;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = {
 | 
					 | 
				
			||||||
  MissingTextError,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
							
								
								
									
										47
									
								
								src/errors.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/errors.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					class MissingTextError extends Error {
 | 
				
			||||||
 | 
					  error: string;
 | 
				
			||||||
 | 
					  statusCode: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(error = null) {
 | 
				
			||||||
 | 
					    const message = 'Missing query parameter \'text\'.';
 | 
				
			||||||
 | 
					    super(message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.error = error;
 | 
				
			||||||
 | 
					    this.statusCode = 400;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FontNotFoundError extends Error {
 | 
				
			||||||
 | 
					  error: string;
 | 
				
			||||||
 | 
					  statusCode: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(font, error = null) {
 | 
				
			||||||
 | 
					    const message = `Font '${font}' not found. Check /fonts.`;
 | 
				
			||||||
 | 
					    super(message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.error = error;
 | 
				
			||||||
 | 
					    this.statusCode = 404;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UnexpectedFigletError extends Error {
 | 
				
			||||||
 | 
					  error: string;
 | 
				
			||||||
 | 
					  statusCode: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(error) {
 | 
				
			||||||
 | 
					    const message = 'Unexpected error from figlet!';
 | 
				
			||||||
 | 
					    super(message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.error = error;
 | 
				
			||||||
 | 
					    this.statusCode = 500;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console.log(message); // eslint-disable-line no-console
 | 
				
			||||||
 | 
					    console.log(error); // eslint-disable-line no-console
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
					  MissingTextError,
 | 
				
			||||||
 | 
					  FontNotFoundError,
 | 
				
			||||||
 | 
					  UnexpectedFigletError,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										58
									
								
								src/figletFonts.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/figletFonts.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					import figlet from 'figlet';
 | 
				
			||||||
 | 
					import IFigletOptions from './interfaces/IFigletOptions';
 | 
				
			||||||
 | 
					import { UnexpectedFigletError } from './errors';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FigletFonts {
 | 
				
			||||||
 | 
					  cachedFonts: Array<string>;
 | 
				
			||||||
 | 
					  defaultFontOptions: IFigletOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    this.cachedFonts = [];
 | 
				
			||||||
 | 
					    this.defaultFontOptions = {
 | 
				
			||||||
 | 
					      font: 'Larry 3D',
 | 
				
			||||||
 | 
					      horizontalLayout: 'default',
 | 
				
			||||||
 | 
					      verticalLayout: 'default',
 | 
				
			||||||
 | 
					      width: 80,
 | 
				
			||||||
 | 
					      whitespaceBreak: true,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static sanitizeLarry(text: string) {
 | 
				
			||||||
 | 
					    return text.replaceAll('L', '_');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  generateText(text: string, options: IFigletOptions): Promise<string> {
 | 
				
			||||||
 | 
					    const _options: IFigletOptions = {
 | 
				
			||||||
 | 
					      ...this.defaultFontOptions,
 | 
				
			||||||
 | 
					      ...options,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					      figlet.text(text, _options, (err, data) => {
 | 
				
			||||||
 | 
					        if (err) {
 | 
				
			||||||
 | 
					          return reject(new UnexpectedFigletError(err));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return resolve(data);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get fonts(): Promise<Array<string>> {
 | 
				
			||||||
 | 
					    if (this.cachedFonts.length > 0) {
 | 
				
			||||||
 | 
					      return Promise.resolve(this.cachedFonts);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					      figlet.fonts((err, fonts) => {
 | 
				
			||||||
 | 
					        if (err) {
 | 
				
			||||||
 | 
					          return reject(new UnexpectedFigletError(err));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return resolve(fonts);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default FigletFonts;
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/interfaces/IFigletOptions.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/interfaces/IFigletOptions.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					interface IFigletOptions {
 | 
				
			||||||
 | 
					  font: string;
 | 
				
			||||||
 | 
					  width: number;
 | 
				
			||||||
 | 
					  horizontalLayout?: string;
 | 
				
			||||||
 | 
					  verticalLayout?: string;
 | 
				
			||||||
 | 
					  whitespaceBreak?: boolean;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default IFigletOptions;
 | 
				
			||||||
@@ -1,14 +0,0 @@
 | 
				
			|||||||
const { MissingTextError } = require("./errors.js");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const requiredQueryMiddleware = (req, res, next) => {
 | 
					 | 
				
			||||||
  const { text } = req.query;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!text || text?.length === 0) {
 | 
					 | 
				
			||||||
    const error = new MissingTextError();
 | 
					 | 
				
			||||||
    return res.status(error?.statusCode || 500).send(error?.message);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  next();
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = requiredQueryMiddleware;
 | 
					 | 
				
			||||||
							
								
								
									
										30
									
								
								src/requiredQueryMiddleware.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/requiredQueryMiddleware.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					import FigletFonts from './figletFonts';
 | 
				
			||||||
 | 
					import { MissingTextError, FontNotFoundError } from './errors';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const figletFonts = new FigletFonts();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function doesFontExist(font: string) {
 | 
				
			||||||
 | 
					  const fontLowercased = font.toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const fonts: Array<string> = await figletFonts.fonts;
 | 
				
			||||||
 | 
					  return fonts.findIndex((_font) => _font.toLowerCase() === fontLowercased) === -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const requiredQueryMiddleware = async (req, res, next) => {
 | 
				
			||||||
 | 
					  const { text, font = '' } = req.query;
 | 
				
			||||||
 | 
					  let error = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!text || text?.length === 0) {
 | 
				
			||||||
 | 
					    error = new MissingTextError();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (font && (await doesFontExist(font))) {
 | 
				
			||||||
 | 
					    error = new FontNotFoundError(font, error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (error) return res.status(error?.statusCode || 500).send(error?.message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return next();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default requiredQueryMiddleware;
 | 
				
			||||||
							
								
								
									
										15
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "compilerOptions": {
 | 
				
			||||||
 | 
					    "allowJs": true,
 | 
				
			||||||
 | 
					    "checkJs": false,
 | 
				
			||||||
 | 
					    "target": "esnext",
 | 
				
			||||||
 | 
					    "module": "commonjs",
 | 
				
			||||||
 | 
					    "moduleResolution": "node",
 | 
				
			||||||
 | 
					    "strict": false,
 | 
				
			||||||
 | 
					    "esModuleInterop": true,
 | 
				
			||||||
 | 
					    "lib": ["esnext", "dom"],
 | 
				
			||||||
 | 
					    "outDir": "lib"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "include": ["src/**/*.js", "src/**/*.ts", "src/**/*.d.ts"],
 | 
				
			||||||
 | 
					  "exclude": ["node_modules"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user