1
0
Fork 0

feat: Migrate to Deno

Signed-off-by: Sam Therapy <sam@samtherapy.net>
This commit is contained in:
Sam Therapy 2023-08-13 18:20:48 +02:00
parent 890b6efe00
commit 5df5818d74
Signed by: sam
GPG Key ID: 4D8B07C18F31ACBD
17 changed files with 134 additions and 2128 deletions

View File

@ -1,33 +0,0 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "prettier"],
"rules": {
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
"prettier/prettier": ["error", { "singleQuote": false }],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
]
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
]
}

View File

@ -1,27 +0,0 @@
name: Build
on:
- push
- pull_request
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [current]
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Lint
run: pnpm lint:ci
- name: Build
run: pnpm build

View File

View File

@ -1,33 +0,0 @@
# waifurudor.de
It's like foxrudor.de for anime girls, but worse
## How to use
Open the web site up and see the predefined anime girls, or define your own tags like:
https://waifurudor.de/?tags=tohsaka_rin,-feet,-underwear,rating:safe
## Server Install
Clone the repo to where ever you will be hosting this and run the following command to install the dependencies.
```sh
npm i
```
Now that the dependencies are taken care of you can verify it runs with `npm start` in the root directory of the project. If it tells you it is listening on a port you're probably good to go.
## Running as a service
I don't know anything so I spent some time (10 minutes) creating the provided sample systemd service file.
The user in the file needs accesss to the assets directory under `./waifurudor.de/src/public/` so the """app""" can pull images from Danbooru.
## Nginx
Yeah I set up a .conf file for this for my test instance but it sucks and you could probably do better so I won't share it just know it is possible to actually run this as a website.
### What's next
I have some small improvements in mind before I give up and call this "done".

10
deno.jsonc Normal file
View File

@ -0,0 +1,10 @@
{
"fmt": {
"semiColons": false
},
"imports": {
"booru/": "https://deno.land/x/booru@v3.0.0/",
"hono/": "https://deno.land/x/hono@v3.4.1/"
}
}

66
deno.lock Normal file
View File

@ -0,0 +1,66 @@
{
"version": "2",
"remote": {
"https://deno.land/x/booru@v3.0.0/src/Constants.ts": "582282889c2ae634765f969b334c9ca535161fbd153ddf61b8edd3d6e685cb89",
"https://deno.land/x/booru@v3.0.0/src/Utils.ts": "f84b4d692ba25f190051f4f16e85d306b95542741a2a49b1381917510b52b581",
"https://deno.land/x/booru@v3.0.0/src/boorus/Booru.ts": "aec290e2ab66dd2c7c7fddea0fe428eea0a12766fa857d7ead6998a905516494",
"https://deno.land/x/booru@v3.0.0/src/boorus/Derpibooru.ts": "45c9fba6204c7a4febf00cbcb21c9ebde27f5c3c6201fd9ef08318c6d4fa7ddb",
"https://deno.land/x/booru@v3.0.0/src/boorus/XmlBooru.ts": "a8f731bbe9074ab45aa0d5767d093cfaa7a24f8334e50d43f1df09a1beeca016",
"https://deno.land/x/booru@v3.0.0/src/index.ts": "6054f6e8ab0ac95db23eb9505b8c3c749553b4d1238f273a9a2763a7c002edfc",
"https://deno.land/x/booru@v3.0.0/src/sites.json": "c142a5fcef102f49202b8874ecfb3da6deab2e8b0342be7b3fc681cc7b20f872",
"https://deno.land/x/booru@v3.0.0/src/structures/InternalSearchParameters.ts": "a854c9dd1a7bf83251905fda2f3f9f41fecab7698b5383d650580191121aa0d7",
"https://deno.land/x/booru@v3.0.0/src/structures/Post.ts": "2dc2b94ebbc3f33c5429b9ac6a257346744d885cf548a85a06a05dce7bf5036c",
"https://deno.land/x/booru@v3.0.0/src/structures/SearchParameters.ts": "b465c8a50b24471b5dcf2b48815426d1eb78e82395d6551d587b21f64879fbff",
"https://deno.land/x/booru@v3.0.0/src/structures/SearchResults.ts": "832fc6c97d796a7ede7e25ccca846d8377e298a57f7ab7f7ff4fa5873f99e2a4",
"https://deno.land/x/booru@v3.0.0/src/structures/Site.ts": "b896cff9805db0edabf8648cdaefef6cdd7eb952271ce2f287ae4859d0b581ae",
"https://deno.land/x/booru@v3.0.0/src/structures/SiteApi.ts": "2dfeae2bfc9c484a513db9c9b00d851713ef9fdffed2bde0ce028cd96ba283e0",
"https://deno.land/x/booru@v3.0.0/src/structures/SiteInfo.ts": "e1e928d77ce50bbe54a15d0d71bec69502c86f8a582c28c46fc784bc5e1559c4",
"https://deno.land/x/hono@v3.4.1/client/client.ts": "7a819af2aa9aabc746add4d01715fa37f83676fdf1b63fba1bbcd655b2d066a5",
"https://deno.land/x/hono@v3.4.1/client/index.ts": "3ff4cf246f3543f827a85a2c84d66a025ac350ee927613629bda47e854bfb7ba",
"https://deno.land/x/hono@v3.4.1/client/utils.ts": "053273c002963b549d38268a1b423ac8ca211a8028bdab1ed0b781a62aa5e661",
"https://deno.land/x/hono@v3.4.1/compose.ts": "e55ed7be2134f363ff3c8e8e2f520ff682c6a11a47d7189100ed69704ce10b9e",
"https://deno.land/x/hono@v3.4.1/context.ts": "6e30e4964339ec08d18943a756a0cce5e2943b64eb63f17b45ce89f4106c64d7",
"https://deno.land/x/hono@v3.4.1/hono-base.ts": "ff1d58c55101a98892f59686db59a693d2bc1ad7e35f03df91ce1b8f0fe1216d",
"https://deno.land/x/hono@v3.4.1/hono.ts": "c185fae30dc3aa9966b0f3e8599f81314ba5e8621b907d27cffb77414a1c0908",
"https://deno.land/x/hono@v3.4.1/http-exception.ts": "6071df078b5f76d279684d52fe82a590f447a64ffe1b75eb5064d0c8a8d2d676",
"https://deno.land/x/hono@v3.4.1/mod.ts": "be5c09896830494225a12488e3e086b331b9c8829f66cc529cb8636a0c15f6fe",
"https://deno.land/x/hono@v3.4.1/request.ts": "661ea39a5c698c8b2b6aef75c0f3acfeb94dc6fefdb3a86b9bf99c12c4d641fb",
"https://deno.land/x/hono@v3.4.1/router.ts": "d03e2a9e862c898e8555b451ba80c65b1f39d487230815229e1f046dbd8546cb",
"https://deno.land/x/hono@v3.4.1/router/linear-router/index.ts": "8a2a7144c50b1f4a92d9ee99c2c396716af144c868e10608255f969695efccd0",
"https://deno.land/x/hono@v3.4.1/router/linear-router/router.ts": "90d4afc052b72f53dafbcf97fd32f24299b985f8a35dbdc70b28048201b3dcbc",
"https://deno.land/x/hono@v3.4.1/router/pattern-router/index.ts": "304a66c50e243872037ed41c7dd79ed0c89d815e17e172e7ad7cdc4bc07d3383",
"https://deno.land/x/hono@v3.4.1/router/pattern-router/router.ts": "8107b92cb713ba3727639c76fab44fd26883d5f2fa7dd39242150a0f269d4835",
"https://deno.land/x/hono@v3.4.1/router/reg-exp-router/index.ts": "52755829213941756159b7a963097bafde5cc4fc22b13b1c7c9184dc0512d1db",
"https://deno.land/x/hono@v3.4.1/router/reg-exp-router/node.ts": "8006b5bccb83d9fc98e0562a5545f6dd0be639ce445b089a6171c9c617aa8693",
"https://deno.land/x/hono@v3.4.1/router/reg-exp-router/router.ts": "aeddd88e16a7ec3cf088a13ee952cfcb3319f97559767253e1a600f72fc70f27",
"https://deno.land/x/hono@v3.4.1/router/reg-exp-router/trie.ts": "567493b301c44174f0895aedb8d055bbecf88f8a25626fa8ca61333bbd0c882c",
"https://deno.land/x/hono@v3.4.1/router/smart-router/index.ts": "74f9b4fe15ea535900f2b9b048581915f12fe94e531dd2b0032f5610e61c3bef",
"https://deno.land/x/hono@v3.4.1/router/smart-router/router.ts": "38209165dadea4182b42807a0a6c84a9258532a07ebf87262dc2b5b09d25a2a2",
"https://deno.land/x/hono@v3.4.1/router/trie-router/index.ts": "3eb75e7f71ba81801631b30de6b1f5cefb2c7239c03797e2b2cbab5085911b41",
"https://deno.land/x/hono@v3.4.1/router/trie-router/node.ts": "a52111dea7436d6817ffca04018eb65e552e9d7b15fba11b367016334dcb1b0f",
"https://deno.land/x/hono@v3.4.1/router/trie-router/router.ts": "ad0b3fdabc33abd11a9f5819734aec743602a743cfc9f90ddad73787cd5e7727",
"https://deno.land/x/hono@v3.4.1/types.ts": "6b72cc84ba6ed0c1ad2e7f5044b29d2e85f9ec3dd77800ff9803c92a7c3dd641",
"https://deno.land/x/hono@v3.4.1/utils/body.ts": "9eee0dcab3a2d44ef62fd4cda3de576f343a2ec73651e43503afce1caa615000",
"https://deno.land/x/hono@v3.4.1/utils/cookie.ts": "88d71e253882d0d1cf29abc61033c8b4ab6bebdcb883c1f7d6ab64f53098baf2",
"https://deno.land/x/hono@v3.4.1/utils/url.ts": "5fc3307ef3cb2e6f34ec2a03e3d7f2126c6a9f5f0eab677222df3f0e40bd7567",
"https://deno.land/x/hono@v3.4.1/validator/index.ts": "6c986e8b91dcf857ecc8164a506ae8eea8665792a4ff7215471df669c632ae7c",
"https://deno.land/x/hono@v3.4.1/validator/validator.ts": "7822737bf1d5d5b35709bc3c70862f3e7bd6a2746a51cc022b577816d2611242"
},
"npm": {
"specifiers": {
"fast-xml-parser": "fast-xml-parser@4.2.7"
},
"packages": {
"fast-xml-parser@4.2.7": {
"integrity": "sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig==",
"dependencies": {
"strnum": "strnum@1.0.5"
}
},
"strnum@1.0.5": {
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
"dependencies": {}
}
}
}
}

View File

@ -1,44 +0,0 @@
{
"dependencies": {
"booru": "2.6.4",
"express": ">=5.0.0-beta.1",
"helmet": "7.0.0",
"morgan": "1.10.0"
},
"name": "waifurudor.de",
"version": "1.0.0",
"type": "module",
"scripts": {
"build": "tsc -b",
"clean": "tsc -b --clean",
"lint": "eslint --ext .ts ./src --fix && prettier --write ./src",
"lint:ci": "eslint --ext .ts ./src && prettier --check ./src",
"dev": "nodemon --exec node --loader ts-node/esm src/index.ts",
"start": "node ./dist/index.js"
},
"repository": {
"type": "git",
"url": "https://git.froth.zone/sam/waifurudor.de.git"
},
"keywords": [],
"author": "",
"license": "GPL-3.0-or-later",
"private": true,
"devDependencies": {
"@types/express": "4.17.17",
"@types/morgan": "1.9.4",
"@types/node": "18.17.5",
"@typescript-eslint/eslint-plugin": "6.3.0",
"@typescript-eslint/parser": "6.3.0",
"eslint": "8.47.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-prettier": "4.2.1",
"nodemon": "3.0.1",
"prettier": "2.8.8",
"ts-node": "10.9.1",
"typescript": "5.1.6"
},
"volta": {
"node": "18.17.1"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
":npm",
":gomod",
":pinSkipCi",
":docker",
":enableVulnerabilityAlerts",
":semanticCommits"
]
}

View File

@ -1,50 +0,0 @@
import express, { NextFunction, Request, Response } from "express";
import helmet from "helmet";
import morgan from "morgan";
import { ParseGet, ParsePost } from "./helpers/parse.js";
import Search from "./helpers/search.js";
const app = express();
app.use(helmet());
app.use(morgan("combined"));
app.set("trust proxy", "loopback");
// app.use(morgan(process.env.NODE_ENV === "production" ? "tiny" : "dev"));
app.use(express.json());
// Errors
app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => {
console.error(err.stack);
res.status(500).json({ msg: "Wife machine broke", error: err });
});
app
.route("/")
.get(ParseGet, Search)
.post(ParsePost, Search)
// Also have a fallback for anyone who tries to be silly :)
.all((_req, res) => {
res.set("ALLOW", "GET, POST");
res.status(405).json({ msg: "Method not allowed." });
});
// Politely tell all crawlers to go away since there's nothing here.
app.get("/robots.txt", (_req, res) => {
res.setHeader("content-type", "text/plain");
res.status(200).send(`User-agent: *
Disallow: /`);
});
app.get("/source", (_req, res) => {
res.redirect(301, "https://git.froth.zone/sam/waifurudor.de");
});
// For 404s
app.use((_req, res) => {
res.setHeader("content-type", "text/plain");
res.status(404).send("Nothing beside remains.");
});
export default app;

View File

@ -50,7 +50,7 @@ export default function ContentType(extension: string): string {
case "tiff":
case "tiff-fx":
case "wmf":
return `image/${extension}`;
return `image/${extension}`
case "1d-interleaved-parityfec":
case "3gpp":
@ -101,8 +101,8 @@ export default function ContentType(extension: string): string {
case "vc2":
case "vp8":
case "vp9":
return `video/${extension}`;
return `video/${extension}`
default:
return "";
throw new Error(`Unknown extension: ${extension}`)
}
}

View File

@ -1,34 +0,0 @@
import { Request, Response, NextFunction } from "express";
/**
* Middleware for extracting the options from a GET.
*
* Why not just support JSON for both GET and POST requests?
* Don't wanna.
*/
export function ParseGet(
req: Request,
res: Response,
next: NextFunction
): void {
if (req.query.tags && typeof req.query.tags === "string") {
res.locals.tags = req.query.tags.split(",");
}
res.locals.booru = (req.query.booru as string) ?? "sb";
next();
}
/**
* Middleware for extracting the options from a POST.
*
* Accepts from the body only because.
*/
export function ParsePost(
req: Request,
res: Response,
next: NextFunction
): void {
res.locals.tags = req.body.tags;
res.locals.booru = (req.body.booru as string) ?? "sb";
next();
}

View File

@ -1,38 +1,43 @@
import { Request, Response } from "express";
import * as booru from "booru";
import ContentType from "./contentType.js";
import * as booru from "booru/src/index.ts"
import { Context } from "hono/mod.ts"
import ContentType from "./contentType.ts"
import { SearchQuery } from "./types.ts"
/**
* Searches the booru for an image to return.
* @param _req Express request (not used)
* @param res Node Response
* @param c: Context object from hono
* @param query: The SearchQuery
*/
export default async function Search(_req: Request, res: Response) {
export default async function Search(
c: Context,
query: SearchQuery,
): Promise<Response> {
const posts = await booru
.search(res.locals.booru, res.locals.tags, { random: true, limit: 1 })
.search(query.site, query.tags, { random: true, limit: 1 })
.catch((err: Error) => {
res.status(400).json({ msg: "WaaS Error", error: err });
console.error(err);
});
console.error(err)
return c.json({ error: err.message }, 400)
})
const imageURL = (posts as booru.SearchResults)[0]?.fileUrl as string;
const imageURL = (posts as booru.SearchResults)[0]?.fileUrl as string
const type = imageURL?.split(".")?.pop() as string;
const type = imageURL?.split(".")?.pop() as string
if (type == null) {
res.status(404).json({ msg: "No results found" });
return c.json({ error: "No results found" }, 404)
}
res.setHeader("content-type", ContentType(type));
c.header("content-type", ContentType(type))
const img = await fetch(imageURL)
// Turn the image into an ArrayBuffer (which is also a Promise)
.then(async (fetchRes) => {
return fetchRes?.arrayBuffer();
// Turn the image into an ArrayBuffer
.then((fetchRes) => {
return fetchRes?.arrayBuffer()
})
.catch((err: Error) => {
console.error(err);
res.status(500).json({ msg: "Wife machine broke", error: err });
});
console.error(err)
return c.json({ error: err.message }, 500)
})
// deepcode ignore XSS: nmp
res.status(200).end(Buffer.from(img as ArrayBuffer), "binary");
return c.body(img as ArrayBuffer)
}

4
src/helpers/types.ts Normal file
View File

@ -0,0 +1,4 @@
export type SearchQuery = {
site: string
tags: string[] | string
}

View File

@ -1,7 +1,27 @@
import app from "./app.js";
import { Hono } from "hono/mod.ts"
import { SearchQuery } from "./helpers/types.ts"
import Search from "./helpers/search.ts"
const port = process.env.PORT || 3000;
const app = new Hono()
app.onError((err, c) => {
console.error(err)
return c.json({ error: err.message }, 500)
})
app.get("/favicon.ico", (c) => c.body(null, 200))
// Politely tell robots to go away
app.get("/robots.txt", (c) => c.text("User-agent: *\nDisallow: /"))
app.all("*", (c) => {
const query: SearchQuery = {
site: c.req.query("booru") ?? "safebooru",
tags: c.req.query("tags") ?? "tohsaka_rin",
}
return Search(c, query)
})
Deno.serve(app.fetch)
app.listen(port, () => {
console.log(`listening on port ${port}`);
});

View File

@ -1,105 +0,0 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "ESNext" /* Specify what module code is generated. */,
"moduleResolution": "node",
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
"sourceMap": true /* Create source map files for emitted JavaScript files. */,
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": ["./src/**/*"]
}

View File

@ -1,14 +0,0 @@
[Unit]
Description=waifurudor.de - Anime as a Service (AaaS)
[Service]
ExecStart=yarn start
Restart=always
User=none
Group=nogroup
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/whatever/user/waifurudor.de/
[Install]
WantedBy=multi-user.target