typescripting2
This commit is contained in:
parent
850a3bf4d2
commit
aacc685da1
12 changed files with 381 additions and 128 deletions
|
@ -12,12 +12,11 @@ Upcoming Features:
|
|||
|
||||
Source:
|
||||
```Bash
|
||||
EBPASS=changeme
|
||||
EBPORT=3000
|
||||
EBAPI_KEY=changeme #ShareX support
|
||||
$ export EBPASS=changeme
|
||||
$ export EBPORT=3000
|
||||
$ export EBAPI_KEY=changeme #ShareX support
|
||||
|
||||
$ npm install
|
||||
$ node app/db.js
|
||||
$ npm start
|
||||
```
|
||||
Default username is admin with the password being whatever EBPASS is
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
import type {MediaRow, UserRow} from './types';
|
||||
|
||||
require("dotenv").config();
|
||||
|
||||
const express = require("express");
|
||||
const passport = require("passport");
|
||||
const session = require("express-session");
|
||||
const cookieParser = require("cookie-parser");
|
||||
const SQLiteStore = require("connect-sqlite3")(session);
|
||||
import express from "express";
|
||||
import passport from "passport";
|
||||
import session from "express-session";
|
||||
import cookieParser from "cookie-parser";
|
||||
import sqlite3 from "connect-sqlite3";
|
||||
const SQLiteStore = sqlite3(session);
|
||||
|
||||
const fs = require("fs");
|
||||
const http = require("http");
|
||||
const path = require("path");
|
||||
import fs from "fs";
|
||||
import http from "http";
|
||||
import path from "path";
|
||||
|
||||
const authRouter = require("./routes/auth");
|
||||
const indexRouter = require("./routes/index");
|
||||
import authRouter from "./routes/auth";
|
||||
import indexRouter from "./routes/index";
|
||||
|
||||
const db = require("./db").db;
|
||||
import {createUser} from "./db";
|
||||
import db from "./db"
|
||||
|
||||
let app = express();
|
||||
let server = http.createServer(app);
|
||||
let port = normalizePort(process.env.EBPORT || "3000");
|
||||
app.set("port", port);
|
||||
|
||||
server.listen(port);
|
||||
server.on("error", onError);
|
||||
server.on("listening", onListening);
|
||||
|
||||
function normalizePort(val) {
|
||||
function normalizePort(val: string) {
|
||||
var port = parseInt(val, 10);
|
||||
|
||||
if (isNaN(port)) {
|
||||
|
@ -40,7 +39,12 @@ function normalizePort(val) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function onError(error) {
|
||||
app.set("port", port);
|
||||
server.listen(port);
|
||||
server.on("error", onError);
|
||||
server.on("listening", onListening);
|
||||
|
||||
function onError(error: any) {
|
||||
if (error.syscall !== "listen") {
|
||||
throw error;
|
||||
}
|
||||
|
@ -64,6 +68,24 @@ function onError(error) {
|
|||
}
|
||||
}
|
||||
|
||||
db.serialize(function() {
|
||||
// create the database schema for the todos app
|
||||
db.run("CREATE TABLE IF NOT EXISTS users ( \
|
||||
id INTEGER PRIMARY KEY, \
|
||||
username TEXT UNIQUE, \
|
||||
hashed_password BLOB, \
|
||||
salt BLOB \
|
||||
)");
|
||||
|
||||
db.run("CREATE TABLE IF NOT EXISTS media ( \
|
||||
id INTEGER PRIMARY KEY, \
|
||||
path TEXT NOT NULL, \
|
||||
expire INTEGER \
|
||||
)");
|
||||
|
||||
createUser("admin", process.env.EBPASS || "changeme");
|
||||
});
|
||||
|
||||
function onListening() {
|
||||
var addr = server.address();
|
||||
var bind = typeof addr === "string"
|
||||
|
@ -90,6 +112,7 @@ app.use(session({
|
|||
secret: process.env.EBSECRET || "pleasechangeme",
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
// @ts-ignore
|
||||
store: new SQLiteStore({
|
||||
db: "sessions.db",
|
||||
dir: "./var/db"
|
||||
|
@ -103,7 +126,7 @@ app.use("/", authRouter);
|
|||
app.use("/uploads", express.static("uploads"));
|
||||
|
||||
function prune () {
|
||||
db.all("SELECT * FROM media", (err, rows) => {
|
||||
db.all("SELECT * FROM media", (err: Error, rows: []) => {
|
||||
console.log("Uploaded files: " + rows.length);
|
||||
console.log(rows);
|
||||
});
|
||||
|
@ -111,23 +134,23 @@ function prune () {
|
|||
console.log("Vacuuming database...");
|
||||
db.run("VACUUM");
|
||||
|
||||
db.all("SELECT * FROM media WHERE expire < ?", [Date.now()], (err, rows) => {
|
||||
db.all("SELECT * FROM media WHERE expire < ?", [Date.now()], (err: Error, rows: []) => {
|
||||
console.log("Expired rows: " + rows);
|
||||
if (err) return console.error(err);
|
||||
rows.forEach((row) => {
|
||||
rows.forEach((row: MediaRow) => {
|
||||
console.log(`Deleting ${row.path}`);
|
||||
fs.unlink(`uploads/${row.path}`, (err) => {
|
||||
if (err) {
|
||||
if(err.errno == -4058) {
|
||||
console.log("File already deleted");
|
||||
db.all("DELETE FROM media WHERE path = ?", [row.path], (err) => {
|
||||
db.all("DELETE FROM media WHERE path = ?", [row.path], (err: Error) => {
|
||||
if (err) return console.error(err);
|
||||
});
|
||||
} else {
|
||||
console.error(err);
|
||||
}
|
||||
} else {
|
||||
db.all("DELETE FROM media WHERE path = ?", [row.path], (err) => {
|
||||
db.all("DELETE FROM media WHERE path = ?", [row.path], (err: Error) => {
|
||||
if (err) return console.error(err);
|
||||
});
|
||||
}
|
||||
|
@ -138,5 +161,3 @@ function prune () {
|
|||
}
|
||||
|
||||
setInterval(prune, 1000 * 60); //prune every minute
|
||||
|
||||
module.exports = app;
|
37
app/db.js
37
app/db.js
|
@ -1,37 +0,0 @@
|
|||
const sqlite3 = require("sqlite3");
|
||||
const mkdirp = require("mkdirp");
|
||||
const crypto = require("crypto");
|
||||
|
||||
mkdirp.sync("./uploads");
|
||||
mkdirp.sync("./var/db");
|
||||
|
||||
let db = new sqlite3.Database("./var/db/media.db");
|
||||
|
||||
db.serialize(function() {
|
||||
// create the database schema for the todos app
|
||||
db.run("CREATE TABLE IF NOT EXISTS users ( \
|
||||
id INTEGER PRIMARY KEY, \
|
||||
username TEXT UNIQUE, \
|
||||
hashed_password BLOB, \
|
||||
salt BLOB \
|
||||
)");
|
||||
|
||||
db.run("CREATE TABLE IF NOT EXISTS media ( \
|
||||
id INTEGER PRIMARY KEY, \
|
||||
path TEXT NOT NULL, \
|
||||
expire INTEGER \
|
||||
)");
|
||||
|
||||
createUser("admin", process.env.EBPASS || "changeme");
|
||||
});
|
||||
|
||||
function createUser(username, password) {
|
||||
var salt = crypto.randomBytes(16);
|
||||
db.run("INSERT OR IGNORE INTO users (username, hashed_password, salt) VALUES (?, ?, ?)", [
|
||||
username,
|
||||
crypto.pbkdf2Sync(password, salt, 310000, 32, "sha256"),
|
||||
salt
|
||||
]);
|
||||
}
|
||||
|
||||
module.exports = {db: db, createUser: createUser};
|
21
app/db.ts
Normal file
21
app/db.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import type {RequestHandler as Middleware} from 'express';
|
||||
|
||||
const sqlite3 = require("sqlite3");
|
||||
const mkdirp = require("mkdirp");
|
||||
const crypto = require("crypto");
|
||||
|
||||
mkdirp.sync("./uploads");
|
||||
mkdirp.sync("./var/db");
|
||||
|
||||
let db = new sqlite3.Database("./var/db/media.db");
|
||||
|
||||
export function createUser(username: string, password: string) {
|
||||
var salt = crypto.randomBytes(16);
|
||||
db.run("INSERT OR IGNORE INTO users (username, hashed_password, salt) VALUES (?, ?, ?)", [
|
||||
username,
|
||||
crypto.pbkdf2Sync(password, salt, 310000, 32, "sha256"),
|
||||
salt
|
||||
]);
|
||||
}
|
||||
|
||||
export default db;
|
|
@ -1,14 +1,18 @@
|
|||
const crypto = require("crypto");
|
||||
const express = require("express");
|
||||
const passport = require("passport");
|
||||
const LocalStrategy = require("passport-local");
|
||||
import type {MediaRow, UserRow} from '../types';
|
||||
import type {RequestHandler as Middleware} from 'express';
|
||||
|
||||
let db = require("../db").db;
|
||||
import crypto from "crypto";
|
||||
import express from "express";
|
||||
import passport from "passport";
|
||||
|
||||
import { Strategy as LocalStrategy } from "passport-local";
|
||||
|
||||
import db from "../db";
|
||||
|
||||
let router = express.Router();
|
||||
|
||||
passport.use(new LocalStrategy(function verify(username, password, cb) {
|
||||
db.get("SELECT * FROM users WHERE username = ?", [username], function(err, row) {
|
||||
db.get("SELECT * FROM users WHERE username = ?", [username], function(err: Error, row: UserRow) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
@ -35,7 +39,9 @@ passport.use(new LocalStrategy(function verify(username, password, cb) {
|
|||
passport.serializeUser(function(user, cb) {
|
||||
process.nextTick(function() {
|
||||
cb(null, {
|
||||
// @ts-ignore
|
||||
id: user.id,
|
||||
// @ts-ignore
|
||||
username: user.username
|
||||
});
|
||||
});
|
||||
|
@ -47,6 +53,7 @@ passport.deserializeUser(function(user, cb) {
|
|||
});
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
router.get("/login", function(req, res) {
|
||||
res.render("login");
|
||||
});
|
||||
|
@ -66,4 +73,4 @@ router.post("/logout", function(req, res, next) {
|
|||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
export default router;
|
|
@ -1,19 +1,24 @@
|
|||
const multer = require("multer");
|
||||
const express = require("express");
|
||||
const ffmpeg = require("fluent-ffmpeg");
|
||||
const imageProbe = require("probe-image-size");
|
||||
const ffmpegpath = require("@ffmpeg-installer/ffmpeg").path;
|
||||
const ffprobepath = require("@ffprobe-installer/ffprobe").path;
|
||||
import type {RequestHandler as Middleware, Router, Request, Response} from 'express';
|
||||
import types from 'multer';
|
||||
|
||||
ffmpeg.setFfmpegPath(ffmpegpath);
|
||||
ffmpeg.setFfprobePath(ffprobepath);
|
||||
import multer from "multer";
|
||||
import express from "express";
|
||||
import ffmpeg from "fluent-ffmpeg";
|
||||
import imageProbe from "probe-image-size";
|
||||
import ffmpegpath from "@ffmpeg-installer/ffmpeg";
|
||||
// @ts-ignore
|
||||
import ffprobepath from "@ffprobe-installer/ffprobe";
|
||||
|
||||
const fs = require("fs");
|
||||
ffmpeg.setFfmpegPath(ffmpegpath.path);
|
||||
ffmpeg.setFfprobePath(ffprobepath.path);
|
||||
|
||||
let db = require("../db").db;
|
||||
let {checkAuth, convert, handleUpload} = require("./middleware");
|
||||
import fs from "fs";
|
||||
|
||||
function extension(str){
|
||||
import db from "../db";
|
||||
import {checkAuth, convert, handleUpload} from "./middleware";
|
||||
import { MediaRow } from '../types';
|
||||
|
||||
function extension(str: String){
|
||||
let file = str.split("/").pop();
|
||||
return [file.substr(0,file.lastIndexOf(".")),file.substr(file.lastIndexOf("."),file.length).toLowerCase()];
|
||||
}
|
||||
|
@ -24,7 +29,7 @@ const storage = multer.diskStorage({
|
|||
},
|
||||
filename : function(req, file, cb) {
|
||||
let nameAndExtension = extension(file.originalname);
|
||||
db.all("SELECT * FROM media WHERE path = ?", [nameAndExtension[0] + nameAndExtension[1]], function (err, exists) {
|
||||
db.all("SELECT * FROM media WHERE path = ?", [nameAndExtension[0] + nameAndExtension[1]], function (err: Error, exists: []) {
|
||||
if (exists.length != 0) {
|
||||
let suffix = new Date().getTime() / 1000;
|
||||
|
||||
|
@ -65,10 +70,10 @@ const fileFilter = function(req, file, cb) {
|
|||
|
||||
let upload = multer({ storage: storage /**, fileFilter: fileFilter**/ }); //maybe make this a env variable?
|
||||
|
||||
function fetchMedia(req, res, next) {
|
||||
db.all("SELECT * FROM media", (err, rows) => {
|
||||
const fetchMedia: Middleware = (req, res, next) => {
|
||||
db.all("SELECT * FROM media", (err: Error, rows: []) => {
|
||||
if (err) return next(err);
|
||||
let files = rows.map((row)=> {
|
||||
let files = rows.map((row: MediaRow)=> {
|
||||
return {
|
||||
id: row.id,
|
||||
path: row.path,
|
||||
|
@ -84,11 +89,11 @@ function fetchMedia(req, res, next) {
|
|||
|
||||
let router = express.Router();
|
||||
|
||||
router.get("/", function (req, res, next) {
|
||||
router.get("/", (req, res, next) => {
|
||||
// @ts-ignore, user is part of req header
|
||||
if (!req.user) { return res.render("home"); }
|
||||
next();
|
||||
}, fetchMedia, function(req, res) {
|
||||
}, fetchMedia, (req, res) => {
|
||||
res.locals.filter = null;
|
||||
// @ts-ignore, user is part of req header
|
||||
res.render("index", { user: req.user });
|
||||
|
@ -125,16 +130,17 @@ router.get("/gifv/:file", async function (req, res, next) {
|
|||
}
|
||||
});
|
||||
|
||||
router.post("/", [upload.array("fileupload"), convert, handleUpload], function(req, res) {
|
||||
router.post("/", [upload.array("fileupload"), convert, handleUpload], (req: Request, res: Response) => {
|
||||
return res.redirect("/");
|
||||
});
|
||||
|
||||
router.post("/sharex", [checkAuth, upload.array("fileupload"), convert, handleUpload], function(req, res) {
|
||||
router.post("/sharex", [checkAuth, upload.array("fileupload"), convert, handleUpload], (req: Request, res: Response) => {
|
||||
// @ts-ignore
|
||||
return res.send(`${req.protocol}://${req.get("host")}/uploads/${req.files[0].filename}`);
|
||||
});
|
||||
|
||||
router.post("/:id(\\d+)/delete", function(req, res, next) {
|
||||
db.all("SELECT path FROM media WHERE id = ?", [ req.params.id ], function(err, path) {
|
||||
db.all("SELECT path FROM media WHERE id = ?", [ req.params.id ], function(err: Error, path: Array<any>) {
|
||||
if (err) { return next(err); }
|
||||
fs.unlink(`uploads/${path[0].path}`, (err => {
|
||||
if (err) {
|
||||
|
@ -142,7 +148,7 @@ router.post("/:id(\\d+)/delete", function(req, res, next) {
|
|||
if (err.errno == -4058) { //File just doesnt exist anymore
|
||||
db.run("DELETE FROM media WHERE id = ?", [
|
||||
req.params.id
|
||||
], function(err) {
|
||||
], (err: Error) => {
|
||||
if (err) { return next(err); }
|
||||
return res.redirect("/");
|
||||
});
|
||||
|
@ -155,7 +161,7 @@ router.post("/:id(\\d+)/delete", function(req, res, next) {
|
|||
//Callback Hell :D
|
||||
db.run("DELETE FROM media WHERE id = ?", [
|
||||
req.params.id
|
||||
], function(err) {
|
||||
], (err: Error) => {
|
||||
if (err) { return next(err); }
|
||||
return res.redirect("/");
|
||||
});
|
||||
|
@ -164,4 +170,4 @@ router.post("/:id(\\d+)/delete", function(req, res, next) {
|
|||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
export default router;
|
|
@ -1,21 +1,25 @@
|
|||
const ffmpeg = require("fluent-ffmpeg");
|
||||
const ffmpegpath = require("@ffmpeg-installer/ffmpeg").path;
|
||||
const ffprobepath = require("@ffprobe-installer/ffprobe").path;
|
||||
ffmpeg.setFfmpegPath(ffmpegpath);
|
||||
ffmpeg.setFfprobePath(ffprobepath);
|
||||
import type {MediaRow, UserRow} from '../types';
|
||||
import type {RequestHandler as Middleware, Router, Request, Response} from 'express';
|
||||
|
||||
const fs = require("fs");
|
||||
const process = require("process");
|
||||
import ffmpeg from "fluent-ffmpeg";
|
||||
import ffmpegpath from "@ffmpeg-installer/ffmpeg";
|
||||
// @ts-ignore
|
||||
import ffprobepath from "@ffprobe-installer/ffprobe";
|
||||
ffmpeg.setFfmpegPath(ffmpegpath.path);
|
||||
ffmpeg.setFfprobePath(ffprobepath.path);
|
||||
|
||||
let db = require("../db.js").db;
|
||||
import fs from "fs";
|
||||
import process from "process";
|
||||
|
||||
function extension(str){
|
||||
import db from "../db";
|
||||
|
||||
function extension(str: String){
|
||||
let file = str.split("/").pop();
|
||||
return [file.substr(0,file.lastIndexOf(".")),file.substr(file.lastIndexOf("."),file.length).toLowerCase()];
|
||||
}
|
||||
|
||||
//Checks ShareX key
|
||||
function checkAuth(req, res, next) {
|
||||
export const checkAuth: Middleware = (req: Request, res: Response, next: Function) => {
|
||||
let auth = process.env.EBAPI_KEY || process.env.EBPASS || "pleaseSetAPI_KEY";
|
||||
let key = null;
|
||||
|
||||
|
@ -36,8 +40,9 @@ function checkAuth(req, res, next) {
|
|||
}
|
||||
|
||||
//Converts mp4 to gif and vice versa with ffmpeg
|
||||
function convert(req, res, next) {
|
||||
export const convert: Middleware = (req: Request, res: Response, next: Function) => {
|
||||
for (let file in req.files) {
|
||||
// @ts-ignore
|
||||
let nameAndExtension = extension(req.files[file].originalname);
|
||||
let oembed = {
|
||||
type: "video",
|
||||
|
@ -92,7 +97,7 @@ function convert(req, res, next) {
|
|||
next();
|
||||
}
|
||||
|
||||
function handleUpload(req, res, next) {
|
||||
export const handleUpload: Middleware = (req: Request, res: Response, next: Function) => {
|
||||
if (!req.files || Object.keys(req.files).length === 0) {
|
||||
console.log("No files were uploaded");
|
||||
return res.status(400).send("No files were uploaded.");
|
||||
|
@ -100,31 +105,27 @@ function handleUpload(req, res, next) {
|
|||
|
||||
for (let file in req.files) {
|
||||
let currentdate = Date.now();
|
||||
let expireDate;
|
||||
let expireDate: Date;
|
||||
if (req.body.expire) {
|
||||
expireDate = new Date(currentdate + (req.body.expire * 24 * 60 * 60 * 1000));
|
||||
console.log(req.body.expire);
|
||||
console.log(expireDate);
|
||||
} else
|
||||
expireDate = null;
|
||||
// @ts-ignore
|
||||
db.run("INSERT INTO media (path, expire) VALUES (?, ?)", [req.files[file].filename, expireDate], function (err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
return next(err);
|
||||
}
|
||||
// @ts-ignore
|
||||
console.log(`Uploaded ${req.files[file].filename} to database`);
|
||||
if (expireDate == null)
|
||||
console.log("It will not expire");
|
||||
else if (expireDate != null || expireDate != undefined || expireDate != "")
|
||||
else if (expireDate != null || expireDate != undefined)
|
||||
console.log(`It will expire on ${expireDate}`);
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
checkAuth: checkAuth,
|
||||
convert: convert,
|
||||
handleUpload: handleUpload
|
||||
};
|
12
app/types.ts
Normal file
12
app/types.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
export interface MediaRow {
|
||||
id? : Number,
|
||||
path: String,
|
||||
expire: Number
|
||||
}
|
||||
|
||||
export interface UserRow {
|
||||
id? : Number,
|
||||
username: String,
|
||||
hashed_password: any,
|
||||
salt: any
|
||||
}
|
|
@ -1,22 +1,21 @@
|
|||
FROM node:16-alpine AS BUILD_IMAGE
|
||||
|
||||
RUN apk add curl
|
||||
RUN curl -sf https://gobinaries.com/tj/node-prune | sh
|
||||
|
||||
COPY package*.json ./
|
||||
COPY tsconfig.json ./
|
||||
COPY /app ./app
|
||||
RUN npm install
|
||||
|
||||
RUN npm prune --production
|
||||
RUN /usr/local/bin/node-prune
|
||||
|
||||
FROM node:16-alpine
|
||||
|
||||
COPY --from=BUILD_IMAGE /node_modules ./node_modules
|
||||
COPY /app ./app
|
||||
COPY /dist ./dist
|
||||
COPY package*.json ./
|
||||
COPY tsconfig.json ./
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
RUN node /app/db.js
|
||||
|
||||
CMD ["npm", "start"]
|
215
package-lock.json
generated
215
package-lock.json
generated
|
@ -28,9 +28,18 @@
|
|||
"sqlite3": "^5.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/connect-sqlite3": "^0.9.1",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/express-session": "^1.17.5",
|
||||
"@types/fluent-ffmpeg": "^2.1.20",
|
||||
"@types/mkdirp": "^1.0.2",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^18.11.10",
|
||||
"@types/passport": "^1.0.11",
|
||||
"@types/passport-local": "^1.0.34",
|
||||
"@types/probe-image-size": "^7.2.0",
|
||||
"@typescript-eslint/parser": "^5.45.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"cypress": "^11.1.0",
|
||||
|
@ -616,6 +625,24 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/connect-sqlite3": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect-sqlite3/-/connect-sqlite3-0.9.1.tgz",
|
||||
"integrity": "sha512-KVwSEPhE76YhQemOp+gTlJ/nq6fswEopmx68J9AuB9ofbR/MA9k8i5J8pE6OvQEtPiOzXHDUIz4wye9o8Fsd7g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cookie-parser": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.3.tgz",
|
||||
"integrity": "sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/dotenv": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-8.2.0.tgz",
|
||||
|
@ -649,18 +676,103 @@
|
|||
"@types/range-parser": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express-session": {
|
||||
"version": "1.17.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.5.tgz",
|
||||
"integrity": "sha512-l0DhkvNVfyUPEEis8fcwbd46VptfA/jmMwHfob2TfDMf3HyPLiB9mKD71LXhz5TMUobODXPD27zXSwtFQLHm+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/fluent-ffmpeg": {
|
||||
"version": "2.1.20",
|
||||
"resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.20.tgz",
|
||||
"integrity": "sha512-B+OvhCdJ3LgEq2PhvWNOiB/EfwnXLElfMCgc4Z1K5zXgSfo9I6uGKwR/lqmNPFQuebNnes7re3gqkV77SyypLg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
||||
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/mkdirp": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz",
|
||||
"integrity": "sha512-o0K1tSO0Dx5X6xlU5F1D6625FawhC3dU3iqr25lluNv/+/QIVH8RLNEiVokgIZo+mz+87w/3Mkg/VvQS+J51fQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/multer": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz",
|
||||
"integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/needle": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/needle/-/needle-2.5.3.tgz",
|
||||
"integrity": "sha512-RwgTwMRaedfyCBe5SSWMpm1Yqzc5UPZEMw0eAd09OSyV93nLRj9/evMGZmgFeHKzUOd4xxtHvgtc+rjcBjI1Qg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
|
||||
"integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/passport": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.11.tgz",
|
||||
"integrity": "sha512-pz1cx9ptZvozyGKKKIPLcVDVHwae4hrH5d6g5J+DkMRRjR3cVETb4jMabhXAUbg3Ov7T22nFHEgaK2jj+5CBpw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/passport-local": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.34.tgz",
|
||||
"integrity": "sha512-PSc07UdYx+jhadySxxIYWuv6sAnY5e+gesn/5lkPKfBeGuIYn9OPR+AAEDq73VRUh6NBTpvE/iPE62rzZUslog==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/express": "*",
|
||||
"@types/passport": "*",
|
||||
"@types/passport-strategy": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/passport-strategy": {
|
||||
"version": "0.2.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz",
|
||||
"integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/express": "*",
|
||||
"@types/passport": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/probe-image-size": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/probe-image-size/-/probe-image-size-7.2.0.tgz",
|
||||
"integrity": "sha512-R5H3vw62gHNHrn+JGZbKejb+Z2D/6E5UNVlhCzIaBBLroMQMOFqy5Pap2gM+ZZHdqBtVU0/cx/M6to+mOJcoew==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/needle": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||
|
@ -6139,6 +6251,24 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/connect-sqlite3": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect-sqlite3/-/connect-sqlite3-0.9.1.tgz",
|
||||
"integrity": "sha512-KVwSEPhE76YhQemOp+gTlJ/nq6fswEopmx68J9AuB9ofbR/MA9k8i5J8pE6OvQEtPiOzXHDUIz4wye9o8Fsd7g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"@types/cookie-parser": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.3.tgz",
|
||||
"integrity": "sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"@types/dotenv": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-8.2.0.tgz",
|
||||
|
@ -6171,18 +6301,103 @@
|
|||
"@types/range-parser": "*"
|
||||
}
|
||||
},
|
||||
"@types/express-session": {
|
||||
"version": "1.17.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.5.tgz",
|
||||
"integrity": "sha512-l0DhkvNVfyUPEEis8fcwbd46VptfA/jmMwHfob2TfDMf3HyPLiB9mKD71LXhz5TMUobODXPD27zXSwtFQLHm+w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"@types/fluent-ffmpeg": {
|
||||
"version": "2.1.20",
|
||||
"resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.20.tgz",
|
||||
"integrity": "sha512-B+OvhCdJ3LgEq2PhvWNOiB/EfwnXLElfMCgc4Z1K5zXgSfo9I6uGKwR/lqmNPFQuebNnes7re3gqkV77SyypLg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
||||
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mkdirp": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz",
|
||||
"integrity": "sha512-o0K1tSO0Dx5X6xlU5F1D6625FawhC3dU3iqr25lluNv/+/QIVH8RLNEiVokgIZo+mz+87w/3Mkg/VvQS+J51fQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/multer": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz",
|
||||
"integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"@types/needle": {
|
||||
"version": "2.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/needle/-/needle-2.5.3.tgz",
|
||||
"integrity": "sha512-RwgTwMRaedfyCBe5SSWMpm1Yqzc5UPZEMw0eAd09OSyV93nLRj9/evMGZmgFeHKzUOd4xxtHvgtc+rjcBjI1Qg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "18.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.10.tgz",
|
||||
"integrity": "sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/passport": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.11.tgz",
|
||||
"integrity": "sha512-pz1cx9ptZvozyGKKKIPLcVDVHwae4hrH5d6g5J+DkMRRjR3cVETb4jMabhXAUbg3Ov7T22nFHEgaK2jj+5CBpw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
},
|
||||
"@types/passport-local": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.34.tgz",
|
||||
"integrity": "sha512-PSc07UdYx+jhadySxxIYWuv6sAnY5e+gesn/5lkPKfBeGuIYn9OPR+AAEDq73VRUh6NBTpvE/iPE62rzZUslog==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express": "*",
|
||||
"@types/passport": "*",
|
||||
"@types/passport-strategy": "*"
|
||||
}
|
||||
},
|
||||
"@types/passport-strategy": {
|
||||
"version": "0.2.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz",
|
||||
"integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express": "*",
|
||||
"@types/passport": "*"
|
||||
}
|
||||
},
|
||||
"@types/probe-image-size": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/probe-image-size/-/probe-image-size-7.2.0.tgz",
|
||||
"integrity": "sha512-R5H3vw62gHNHrn+JGZbKejb+Z2D/6E5UNVlhCzIaBBLroMQMOFqy5Pap2gM+ZZHdqBtVU0/cx/M6to+mOJcoew==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/needle": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/qs": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||
|
|
13
package.json
13
package.json
|
@ -23,9 +23,9 @@
|
|||
"scripts": {
|
||||
"start": "node ./dist/app.js",
|
||||
"clean": "rimraf dist/",
|
||||
"copy-files": "copyfiles -a -V -u 1 app/public/* app/views/* app/public/**/* app/views/**/* dist/",
|
||||
"copy-files": "copyfiles -a -u 1 app/public/* app/views/* app/public/**/* app/views/**/* dist/",
|
||||
"tsc": "tsc",
|
||||
"postinstall": "npm run tsc",
|
||||
"postinstall": "npm run tsc && npm run copy-files",
|
||||
"dev": "tsc-node-dev --respawn --pretty --transpile-only index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -47,9 +47,18 @@
|
|||
"sqlite3": "^5.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/connect-sqlite3": "^0.9.1",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/express-session": "^1.17.5",
|
||||
"@types/fluent-ffmpeg": "^2.1.20",
|
||||
"@types/mkdirp": "^1.0.2",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^18.11.10",
|
||||
"@types/passport": "^1.0.11",
|
||||
"@types/passport-local": "^1.0.34",
|
||||
"@types/probe-image-size": "^7.2.0",
|
||||
"@typescript-eslint/parser": "^5.45.0",
|
||||
"copyfiles": "^2.4.1",
|
||||
"cypress": "^11.1.0",
|
||||
|
|
|
@ -76,9 +76,9 @@
|
|||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
|
||||
/* Type Checking */
|
||||
"strict": false, /* Enable all strict type-checking options. */
|
||||
"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'. */
|
||||
"strictNullChecks": false, /* 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. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue