Add linting and pre-commit

See: https://codeberg.org/kytta/toot/pulls/17
This commit is contained in:
Nikita Karamov 2023-03-01 12:46:12 +01:00
commit 725f9353cf
No known key found for this signature in database
GPG key ID: 41D6F71EE78E77CD
14 changed files with 986 additions and 71 deletions

2
.eslintignore Normal file
View file

@ -0,0 +1,2 @@
/dist/
/public/

23
.eslintrc.json Normal file
View file

@ -0,0 +1,23 @@
{
"env": {
"browser": true
},
"extends": ["eslint:recommended", "plugin:unicorn/recommended", "prettier"],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"overrides": [
{
"files": ["gulpfile.js", "api/*.js"],
"env": {
"node": true,
"browser": false
},
"rules": {
"unicorn/prefer-module": 0,
"unicorn/prefer-node-protocol": 0
}
}
]
}

View file

@ -1 +0,0 @@
14

27
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,27 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: end-of-file-fixer
- id: fix-byte-order-marker
- id: mixed-line-ending
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: check-json
- id: check-toml
- id: check-yaml
- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v2.7.1"
hooks:
- id: prettier
additional_dependencies:
- prettier@2
- repo: https://github.com/pre-commit/mirrors-eslint
rev: "v8.35.0"
hooks:
- id: eslint
additional_dependencies:
- eslint
- eslint-config-prettier
- eslint-plugin-unicorn
- prettier

View file

@ -1,3 +1,5 @@
*.md *.md
/public /dist/
/.vercel /public/
/.vercel/
pnpm-lock.yaml

View file

@ -1 +1,4 @@
{} {
"quoteProps": "consistent",
"trailingComma": "es5"
}

View file

@ -19,20 +19,21 @@
const http = require("http"); const http = require("http");
http http
.createServer(async (req, res) => { .createServer(async (request, response) => {
const buffers = []; const buffers = [];
for await (const chunk of req) { for await (const chunk of request) {
buffers.push(chunk); buffers.push(chunk);
} }
const data = Buffer.concat(buffers).toString(); const data = Buffer.concat(buffers).toString();
const params = new URLSearchParams(data); const searchParameters = new URLSearchParams(data);
const text = params.get("text") || ""; const text = searchParameters.get("text") || "";
const instanceURL = params.get("instance") || "https://mastodon.social/"; const instanceURL =
searchParameters.get("instance") || "https://mastodon.social/";
const finalURL = new URL("share", instanceURL); const finalURL = new URL("share", instanceURL);
finalURL.search = new URLSearchParams({ text }).toString(); finalURL.search = new URLSearchParams({ text }).toString();
res.writeHead(303, { Location: finalURL.toString() }).end(); response.writeHead(303, { Location: finalURL.toString() }).end();
}) })
.listen(8000); .listen(8000);

View file

@ -1,20 +1,22 @@
const { join, resolve } = require("path"); const path = require("path");
const gulp = require("gulp"); const gulp = require("gulp");
const postcss = require("gulp-postcss"); const postcss = require("gulp-postcss");
const sass = require("gulp-sass")(require("sass")); const sass = require("gulp-sass")(require("sass"));
const sourcemaps = require("gulp-sourcemaps"); const sourcemaps = require("gulp-sourcemaps");
const terser = require("gulp-terser"); const terser = require("gulp-terser");
const SOURCE_DIR = resolve(__dirname, "src"); const SOURCE_DIR = path.resolve(__dirname, "src");
const OUTPUT_DIR = resolve(__dirname, "public"); const OUTPUT_DIR = path.resolve(__dirname, "public");
function html() { function html() {
return gulp.src(join(SOURCE_DIR, "index.html")).pipe(gulp.dest(OUTPUT_DIR)); return gulp
.src(path.join(SOURCE_DIR, "index.html"))
.pipe(gulp.dest(OUTPUT_DIR));
} }
function css() { function css() {
return gulp return gulp
.src(join(SOURCE_DIR, "scss", "*.scss")) .src(path.join(SOURCE_DIR, "scss", "*.scss"))
.pipe(sourcemaps.init()) .pipe(sourcemaps.init())
.pipe(sass.sync().on("error", sass.logError)) .pipe(sass.sync().on("error", sass.logError))
.pipe(postcss([require("autoprefixer"), require("postcss-csso")])) .pipe(postcss([require("autoprefixer"), require("postcss-csso")]))
@ -24,24 +26,24 @@ function css() {
function js() { function js() {
return gulp return gulp
.src([join(SOURCE_DIR, "main.js"), join(SOURCE_DIR, "count.js")]) .src([path.join(SOURCE_DIR, "main.js"), path.join(SOURCE_DIR, "count.js")])
.pipe(sourcemaps.init()) .pipe(sourcemaps.init())
.pipe(terser({ ecma: 5 })) .pipe(terser({ ecma: 5 }))
.pipe(sourcemaps.write(".")) .pipe(sourcemaps.write("."))
.pipe(gulp.dest(OUTPUT_DIR)); .pipe(gulp.dest(OUTPUT_DIR));
} }
function static() { function staticFiles() {
return gulp return gulp
.src(join(SOURCE_DIR, "static", "**", "*")) .src(path.join(SOURCE_DIR, "static", "**", "*"))
.pipe(gulp.dest(OUTPUT_DIR)); .pipe(gulp.dest(OUTPUT_DIR));
} }
exports.default = gulp.parallel(html, css, js, static); exports.default = gulp.parallel(html, css, js, staticFiles);
exports.watch = () => { exports.watch = () => {
gulp.watch(join(SOURCE_DIR, "index.html"), html); gulp.watch(path.join(SOURCE_DIR, "index.html"), html);
gulp.watch(join(SOURCE_DIR, "scss", "*.scss"), css); gulp.watch(path.join(SOURCE_DIR, "scss", "*.scss"), css);
gulp.watch(join(SOURCE_DIR, "*.js"), js); gulp.watch(path.join(SOURCE_DIR, "*.js"), js);
gulp.watch(join(SOURCE_DIR, "static", "**", "*"), static); gulp.watch(path.join(SOURCE_DIR, "static", "**", "*"), staticFiles);
}; };

View file

@ -13,11 +13,17 @@
"scripts": { "scripts": {
"build": "gulp", "build": "gulp",
"dev": "gulp watch", "dev": "gulp watch",
"fmt": "prettier --write .",
"lint": "prettier --check . && eslint .",
"test": "pnpm run lint",
"serve": "sirv ./public --dev" "serve": "sirv ./public --dev"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^10.4.2", "autoprefixer": "^10.4.2",
"browserslist": "^4.19.1", "browserslist": "^4.19.1",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-unicorn": "^45.0.2",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-postcss": "^9.0.1", "gulp-postcss": "^9.0.1",
"gulp-sass": "^5.1.0", "gulp-sass": "^5.1.0",
@ -25,7 +31,7 @@
"gulp-terser": "^2.1.0", "gulp-terser": "^2.1.0",
"postcss": "^8.4.6", "postcss": "^8.4.6",
"postcss-csso": "^6.0.0", "postcss-csso": "^6.0.0",
"prettier": "2.5.1", "prettier": "^2.8.4",
"sass": "^1.49.7", "sass": "^1.49.7",
"sirv-cli": "^2.0.2" "sirv-cli": "^2.0.2"
} }

File diff suppressed because it is too large Load diff

View file

@ -38,8 +38,8 @@ if (
window.location.host === "s2f.kytta.dev" || window.location.host === "s2f.kytta.dev" ||
window.location.host === "share2fedi.kytta.dev" window.location.host === "share2fedi.kytta.dev"
) { ) {
fetch("//gc.zgo.at/", { method: "HEAD" }) // eslint-disable-next-line unicorn/prefer-top-level-await
.then((result) => { fetch("//gc.zgo.at/", { method: "HEAD" }).then((result) => {
if (!result.ok) { if (!result.ok) {
return; return;
} }
@ -57,6 +57,5 @@ if (
navigator.sendBeacon( navigator.sendBeacon(
`https://share2fedi.goatcounter.com/count?p=%2F&s=${screen}&b=0&rnd=${random}` `https://share2fedi.goatcounter.com/count?p=%2F&s=${screen}&b=0&rnd=${random}`
); );
}) });
.catch((_) => {});
} }

View file

@ -30,8 +30,8 @@ const INSTANCE_LIST_URL = "https://api.joinmastodon.org/servers";
const LOCAL_STORAGE_KEY = "recentInstances"; const LOCAL_STORAGE_KEY = "recentInstances";
const RECENT_INSTANCES_SIZE = 5; const RECENT_INSTANCES_SIZE = 5;
const $instance = document.getElementById("instance"); const $instance = document.querySelector("#instance");
const $instanceDatalist = document.getElementById("instanceDatalist"); const $instanceDatalist = document.querySelector("#instanceDatalist");
/** /**
* Adds missing "https://" and ending slash to the URL * Adds missing "https://" and ending slash to the URL
@ -40,7 +40,7 @@ const $instanceDatalist = document.getElementById("instanceDatalist");
* @return {string} normalized URL * @return {string} normalized URL
*/ */
function normalizeUrl(url) { function normalizeUrl(url) {
if (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) { if (!url.includes("http://") && !url.includes("https://")) {
url = "https://" + url; url = "https://" + url;
} }
if (url.charAt(url.length - 1) !== "/") { if (url.charAt(url.length - 1) !== "/") {
@ -59,16 +59,18 @@ function onLoadInstancesSuccess() {
} }
const currentInstance = $instance.value; const currentInstance = $instance.value;
const instanceDomains = JSON.parse(this.responseText).map((i) => i.domain); const instanceDomains = JSON.parse(this.responseText).map(
if (currentInstance && instanceDomains.indexOf(currentInstance) < 0) { (index) => index.domain
);
if (currentInstance && !instanceDomains.includes(currentInstance)) {
instanceDomains.push(currentInstance); instanceDomains.push(currentInstance);
} }
instanceDomains.sort(); instanceDomains.sort();
for (let i = 0; i < instanceDomains.length; i++) { for (const instanceDomain of instanceDomains) {
const $option = document.createElement("option"); const $option = document.createElement("option");
$option.value = normalizeUrl(instanceDomains[i]); $option.value = normalizeUrl(instanceDomain);
$instanceDatalist.appendChild($option); $instanceDatalist.append($option);
} }
} }
@ -106,6 +108,8 @@ function rememberInstance(instance) {
); );
} }
// Used in HTML
// eslint-disable-next-line no-unused-vars
function onFormSubmit(form) { function onFormSubmit(form) {
const formData = new FormData(form); const formData = new FormData(form);
@ -117,17 +121,19 @@ function onFormSubmit(form) {
let prefillInstance = getRecentInstances()[0]; let prefillInstance = getRecentInstances()[0];
const URLParams = window.location.search.substr(1).split("&"); const URLParameters = window.location.search.slice(1).split("&");
for (let i = 0; i < URLParams.length; i++) { for (const URLParameter of URLParameters) {
const URLParamPair = URLParams[i].split("="); const URLParameterPair = URLParameter.split("=");
if (URLParamPair[0] === "text") { if (URLParameterPair[0] === "text") {
document.getElementById("text").value = decodeURIComponent(URLParamPair[1]); document.querySelector("#text").value = decodeURIComponent(
} else if (URLParamPair[0] === "instance") { URLParameterPair[1]
prefillInstance = decodeURIComponent(URLParamPair[1]); );
} else if (URLParameterPair[0] === "instance") {
prefillInstance = decodeURIComponent(URLParameterPair[1]);
} }
} }
if (prefillInstance != null) { if (prefillInstance != undefined) {
$instance.value = normalizeUrl(prefillInstance); $instance.value = normalizeUrl(prefillInstance);
} }