This is way too much time to spend on linters
This commit is contained in:
parent
69ebed5c7e
commit
0c880a7b4e
23
.eslintrc.js
23
.eslintrc.js
@ -5,7 +5,10 @@ module.exports = {
|
||||
},
|
||||
extends: [
|
||||
"plugin:react/recommended",
|
||||
"standard"
|
||||
"standard",
|
||||
"prettier",
|
||||
"prettier/@typescript-eslint",
|
||||
"prettier/react"
|
||||
],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
@ -25,25 +28,21 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
"space-before-function-paren": ["error", {
|
||||
anonymous: "always",
|
||||
named: "never",
|
||||
asyncArrow: "always"
|
||||
"no-unused-vars": ["error", {
|
||||
"vars": "all",
|
||||
"args": "after-used"
|
||||
}],
|
||||
"quote-props": ["error", "consistent"],
|
||||
"quotes": ["error", "double"],
|
||||
"sort-imports": ["error", {
|
||||
"ignoreCase": true,
|
||||
"allowSeparatedGroups": true
|
||||
}]
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["*.ts", "*.tsx"],
|
||||
rules: {
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars-experimental": "error"
|
||||
"@typescript-eslint/no-unused-vars-experimental": ["error", {
|
||||
"ignoreArgsIfArgsAfterAreUsed": true
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
2
.prettierignore
Normal file
2
.prettierignore
Normal file
@ -0,0 +1,2 @@
|
||||
dist
|
||||
node_packages
|
3
.prettierrc.json
Normal file
3
.prettierrc.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"quoteProps": "consistent"
|
||||
}
|
1640
package-lock.json
generated
1640
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
@ -56,10 +56,23 @@
|
||||
"@types/react-router-dom": "^5.1.3",
|
||||
"@types/webpack-dev-middleware": "^2.0.4",
|
||||
"@types/yargs": "^13.0.8",
|
||||
"@typescript-eslint/eslint-plugin": "^3.9.1",
|
||||
"@typescript-eslint/parser": "^3.9.1",
|
||||
"css-loader": "^3.4.2",
|
||||
"eslint": "^7.7.0",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.20.6",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"object-hash": "^2.0.3",
|
||||
"pg-monitor": "^1.3.1",
|
||||
"pino-pretty": "^3.6.1",
|
||||
"prettier": "2.0.5",
|
||||
"prettier-plugin-organize-imports": "^1.1.1",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-redux": "^7.2.0",
|
||||
@ -72,8 +85,6 @@
|
||||
"ts-node": "^8.8.1",
|
||||
"ts-node-dev": "^1.0.0-pre.44",
|
||||
"tsconfig-paths": "^3.9.0",
|
||||
"tslint": "^5.20.1",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"typescript": "^4.0.2",
|
||||
"webpack": "^4.44.1",
|
||||
"webpack-cli": "^3.3.12",
|
||||
|
@ -18,7 +18,7 @@ export const getTasks = async (
|
||||
throw new APIError("Invalid response from server.");
|
||||
}
|
||||
const count: number = json.count;
|
||||
const items: Task[] = (json.tasks as any[]).map(t => {
|
||||
const items: Task[] = (json.tasks as any[]).map((t) => {
|
||||
if (
|
||||
typeof t !== "object" ||
|
||||
!Number.isSafeInteger(t.id) ||
|
||||
@ -30,7 +30,7 @@ export const getTasks = async (
|
||||
return {
|
||||
id: t.id,
|
||||
name: t.name,
|
||||
schedule: { type: "Plain" }
|
||||
schedule: { type: "Plain" },
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -2,24 +2,33 @@ import * as React from "react";
|
||||
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
|
||||
import TaskList from "./TaskList";
|
||||
|
||||
export default () => <Router>
|
||||
function App() {
|
||||
return (
|
||||
<Router>
|
||||
<div>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="/auth">Login</a></li>
|
||||
<li><Link to="/about">About</Link></li>
|
||||
<li><Link to="/">Tasks</Link></li>
|
||||
<li>
|
||||
<a href="/auth">Login</a>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/about">About</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/">Tasks</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<Switch>
|
||||
<Route path="/about">
|
||||
About things, yay!
|
||||
</Route>
|
||||
<Route path="/about">About things, yay!</Route>
|
||||
<Route path="/">
|
||||
<TaskList />
|
||||
</Route>
|
||||
</Switch>
|
||||
</div>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
export default App
|
||||
|
@ -4,7 +4,7 @@ import { Task, TaskScheduleType } from "@kredens/frontend/store/tasks/types";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
export default () => {
|
||||
function TaskList() {
|
||||
const [taskName, setTaskName] = useState("");
|
||||
const tasks = useSelector<AppState, { [key: string]: Task }>(state => state.tasks.items);
|
||||
const dispatch = useDispatch();
|
||||
@ -37,3 +37,5 @@ export default () => {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default TaskList
|
@ -1,15 +0,0 @@
|
||||
{
|
||||
"extends": "../../tslint.json",
|
||||
"rules": {
|
||||
"no-implicit-dependencies": [
|
||||
true,
|
||||
"dev",
|
||||
["@kredens/frontend"]
|
||||
],
|
||||
"no-submodule-imports": [
|
||||
true,
|
||||
"@kredens/frontend",
|
||||
"redux-saga/effects"
|
||||
]
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ export const getUser = async (req: express.Request) =>
|
||||
|
||||
export const authMiddleware: () => express.Handler = () => async (
|
||||
req,
|
||||
res,
|
||||
_res,
|
||||
next
|
||||
) => {
|
||||
if (req.session.userID) {
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
decodeBase64,
|
||||
decodeUTF8,
|
||||
encodeBase64,
|
||||
encodeUTF8
|
||||
encodeUTF8,
|
||||
} from "tweetnacl-util";
|
||||
|
||||
const secret = decodeBase64(process.env.SECRET);
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
MigrationRepository,
|
||||
SessionRepository,
|
||||
TaskRepository,
|
||||
UserRepository
|
||||
UserRepository,
|
||||
} from "@kredens/server/db/repos";
|
||||
import { DateTime } from "luxon";
|
||||
import pg from "pg";
|
||||
@ -31,19 +31,19 @@ types.setTypeParser(types.builtins.TIMESTAMP, DateTime.fromSQL);
|
||||
type ExtendedProtocol = IDatabase<Extensions> & Extensions;
|
||||
|
||||
const initOptions: IInitOptions<Extensions> = {
|
||||
extend(obj: ExtendedProtocol, dc: any) {
|
||||
extend(obj: ExtendedProtocol) {
|
||||
obj.migrations = new MigrationRepository(obj, pgp);
|
||||
obj.tasks = new TaskRepository(obj, pgp);
|
||||
obj.users = new UserRepository(obj, pgp);
|
||||
obj.sessions = new SessionRepository(obj, pgp);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const pgp: pgPromise.IMain = pgPromise(initOptions);
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
// tslint:disable-next-line:no-implicit-dependencies
|
||||
import("pg-monitor").then(monitor => monitor.attach(initOptions));
|
||||
import("pg-monitor").then((monitor) => monitor.attach(initOptions));
|
||||
}
|
||||
|
||||
const db: ExtendedProtocol = pgp(process.env.DATABASE_URL);
|
||||
|
@ -24,7 +24,7 @@ export class LockError extends Error {}
|
||||
export class MigrationRepository {
|
||||
private db: IDatabase<any>;
|
||||
|
||||
constructor(db: IDatabase<any>, pgp: IMain) {
|
||||
constructor(db: IDatabase<any>, _pgp: IMain) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@ -45,15 +45,15 @@ export class MigrationRepository {
|
||||
|
||||
public async apply() {
|
||||
await this.lock();
|
||||
const applied = (await this.applied()).map(m => m.name);
|
||||
const applied = (await this.applied()).map((m) => m.name);
|
||||
const toApply = sql.patches.filter(
|
||||
p => p.up.isSome() && !applied.find(o => o === p.name)
|
||||
(p) => p.up.isSome() && !applied.find((o) => o === p.name)
|
||||
);
|
||||
|
||||
for (const patch of toApply) {
|
||||
logger.info("Applying migration", { name: patch.name });
|
||||
await patch.up
|
||||
.map(async qf => {
|
||||
.map(async (qf) => {
|
||||
await this.db.none(qf);
|
||||
await this.db.none(sql.apply, [patch.name]);
|
||||
})
|
||||
@ -63,10 +63,10 @@ export class MigrationRepository {
|
||||
}
|
||||
|
||||
public async applied(): Promise<Migration[]> {
|
||||
return this.db.map(sql.applied, [], row => ({
|
||||
return this.db.map(sql.applied, [], (row) => ({
|
||||
appliedAt: row.applied_at as DateTime,
|
||||
id: +row.id,
|
||||
name: row.name
|
||||
name: row.name,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -22,14 +22,14 @@ import { IDatabase, IMain } from "pg-promise";
|
||||
export class SessionRepository {
|
||||
private db: IDatabase<any>;
|
||||
|
||||
constructor(db: IDatabase<any>, pgp: IMain) {
|
||||
constructor(db: IDatabase<any>, _pgp: IMain) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
public async all(): Promise<Session[]> {
|
||||
return this.db.map(sql.all, [], row => ({
|
||||
return this.db.map(sql.all, [], (row) => ({
|
||||
session: row.session,
|
||||
sid: row.sid
|
||||
sid: row.sid,
|
||||
}));
|
||||
}
|
||||
|
||||
@ -42,25 +42,25 @@ export class SessionRepository {
|
||||
}
|
||||
|
||||
public async get(sid: string): Promise<Maybe<Session>> {
|
||||
return this.db.oneOrNone(sql.get, [sid]).then(row =>
|
||||
return this.db.oneOrNone(sql.get, [sid]).then((row) =>
|
||||
row
|
||||
? Maybe.Some({
|
||||
session: row.session,
|
||||
sid: row.sid
|
||||
sid: row.sid,
|
||||
})
|
||||
: Maybe.None()
|
||||
);
|
||||
}
|
||||
|
||||
public async length(): Promise<number> {
|
||||
return this.db.one(sql.length).then(row => +row.length);
|
||||
return this.db.one(sql.length).then((row) => +row.length);
|
||||
}
|
||||
|
||||
public async set(sid: string, session: SessionData, expiresAt: DateTime) {
|
||||
return this.db.none(sql.set, [
|
||||
sid,
|
||||
JSON.stringify(session),
|
||||
expiresAt.toSQL()
|
||||
expiresAt.toSQL(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { ScheduleType, Task } from "@kredens/server/db/models";
|
||||
import { Task } from "@kredens/server/db/models";
|
||||
import { tasks as sql } from "@kredens/server/db/sql";
|
||||
import { IDatabase, IMain } from "pg-promise";
|
||||
|
||||
@ -24,14 +24,14 @@ function rowToTask(row: any): Task {
|
||||
name: row.name,
|
||||
notes: row.notes,
|
||||
schedule: row.schedule,
|
||||
createdAt: row.created_at
|
||||
createdAt: row.created_at,
|
||||
};
|
||||
}
|
||||
|
||||
export class TaskRepository {
|
||||
private db: IDatabase<any>;
|
||||
|
||||
constructor(db: IDatabase<any>, pgp: IMain) {
|
||||
constructor(db: IDatabase<any>, _pgp: IMain) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@ -40,12 +40,12 @@ export class TaskRepository {
|
||||
limit?: number,
|
||||
offset?: number
|
||||
): Promise<Task[]> {
|
||||
return this.db.map(sql.list, [owner, limit || 10, offset || 0], row =>
|
||||
return this.db.map(sql.list, [owner, limit || 10, offset || 0], (row) =>
|
||||
rowToTask(row)
|
||||
);
|
||||
}
|
||||
|
||||
public async count(owner: number): Promise<number> {
|
||||
return this.db.one(sql.count, [owner], row => +row.c);
|
||||
return this.db.one(sql.count, [owner], (row) => +row.c);
|
||||
}
|
||||
}
|
||||
|
@ -22,16 +22,16 @@ import { IDatabase, IMain } from "pg-promise";
|
||||
export class UserRepository {
|
||||
private db: IDatabase<any>;
|
||||
|
||||
constructor(db: IDatabase<any>, pgp: IMain) {
|
||||
constructor(db: IDatabase<any>, _pgp: IMain) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
public async login(email: string, password: string): Promise<Maybe<number>> {
|
||||
const { id, encryptedPassword } = await this.db
|
||||
.oneOrNone(sql.login, [email])
|
||||
.then(user => ({
|
||||
.then((user) => ({
|
||||
encryptedPassword: user.encrypted_password,
|
||||
id: +user.id
|
||||
id: +user.id,
|
||||
}));
|
||||
if (id === null) {
|
||||
return None();
|
||||
|
@ -13,34 +13,34 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { requireAuthMiddleware } from "@kredens/server/auth";
|
||||
import { db } from "@kredens/server/db";
|
||||
import express from "express";
|
||||
import { db } from "@kredens/server/db"
|
||||
import express from "express"
|
||||
import { requireAuthMiddleware } from "@kredens/server/auth"
|
||||
|
||||
const router = express.Router();
|
||||
const router = express.Router()
|
||||
|
||||
function tryInt(v: string, def?: number): number | undefined {
|
||||
if (v) {
|
||||
const value = parseInt(v, 10);
|
||||
return isNaN(value) ? def : value;
|
||||
const value = parseInt(v, 10)
|
||||
return isNaN(value) ? def : value
|
||||
}
|
||||
|
||||
return def;
|
||||
return def
|
||||
}
|
||||
|
||||
router.use(requireAuthMiddleware());
|
||||
router.get("/tasks", async (req, res, next) => {
|
||||
const limit = tryInt(req.query.limit, 10);
|
||||
const offset = tryInt(req.query.offset, 0);
|
||||
router.use(requireAuthMiddleware())
|
||||
router.get("/tasks", async (req, res) => {
|
||||
const limit = tryInt(req.query.limit, 10)
|
||||
const offset = tryInt(req.query.offset, 0)
|
||||
|
||||
const result = await db.tx(async tx => {
|
||||
const tasks = await tx.tasks.list(req.user.id, limit, offset);
|
||||
const count = await tx.tasks.count(req.user.id);
|
||||
const tasks = await tx.tasks.list(req.user.id, limit, offset)
|
||||
const count = await tx.tasks.count(req.user.id)
|
||||
return {
|
||||
tasks,
|
||||
count
|
||||
};
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
res.json({
|
||||
tasks: result.tasks.map(t => ({
|
||||
@ -51,7 +51,7 @@ router.get("/tasks", async (req, res, next) => {
|
||||
createdAt: t.createdAt.toISO
|
||||
})),
|
||||
count: result.count
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
export default router;
|
||||
export default router
|
||||
|
@ -18,11 +18,11 @@ import express from "express";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get("/", async (req, res, next) => {
|
||||
router.get("/", async (req, res) => {
|
||||
res.render("login");
|
||||
});
|
||||
|
||||
router.post("/", async (req, res, next) => {
|
||||
router.post("/", async (req, res) => {
|
||||
const userID = await db.users.login(req.body.email, req.body.password);
|
||||
if (userID.isSome()) {
|
||||
req.session.userID = userID.some();
|
||||
|
@ -13,43 +13,43 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { box, unbox } from "@kredens/server/crypto";
|
||||
import { db } from "@kredens/server/db";
|
||||
import express from "express";
|
||||
import createHttpError from "http-errors";
|
||||
import { DateTime } from "luxon";
|
||||
import { box, unbox } from "@kredens/server/crypto"
|
||||
import createHttpError from "http-errors"
|
||||
import { DateTime } from "luxon"
|
||||
import { db } from "@kredens/server/db"
|
||||
import express from "express"
|
||||
|
||||
interface Token {
|
||||
expires: string;
|
||||
}
|
||||
|
||||
const router = express.Router();
|
||||
const router = express.Router()
|
||||
|
||||
router.get("/", async (req, res, next) => {
|
||||
router.get("/", async (req) => {
|
||||
const token: Token = {
|
||||
expires: DateTime.local()
|
||||
.plus({ hours: 2 })
|
||||
.toISO()
|
||||
};
|
||||
req.log.info("Token issued", { token: box(token) });
|
||||
});
|
||||
}
|
||||
req.log.info("Token issued", { token: box(token) })
|
||||
})
|
||||
|
||||
router.post("/", async (req, res, next) => {
|
||||
const token: Token = unbox(req.body.token);
|
||||
const expired = DateTime.fromISO(token.expires).diffNow();
|
||||
const token: Token = unbox(req.body.token)
|
||||
const expired = DateTime.fromISO(token.expires).diffNow()
|
||||
if (expired.as("milliseconds") < 0) {
|
||||
next(createHttpError(401));
|
||||
return;
|
||||
next(createHttpError(401))
|
||||
return
|
||||
}
|
||||
|
||||
const email: string = req.body.email;
|
||||
const password: string = req.body.password;
|
||||
const email: string = req.body.email
|
||||
const password: string = req.body.password
|
||||
|
||||
if (!email || !password || password.length < 8) {
|
||||
res.send("Please provide an email and a password longer than 8 characters");
|
||||
return;
|
||||
res.send("Please provide an email and a password longer than 8 characters")
|
||||
return
|
||||
}
|
||||
await db.users.create(email, password);
|
||||
});
|
||||
await db.users.create(email, password)
|
||||
})
|
||||
|
||||
export default router;
|
||||
export default router
|
||||
|
@ -17,7 +17,7 @@ import express from "express";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get("/", (req, res, next) => {
|
||||
router.get("/", (req, res) => {
|
||||
res.render("index", { title: "Hey", message: "Hi!" });
|
||||
});
|
||||
|
||||
|
@ -13,9 +13,9 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { Store } from "@holdyourwaffle/express-session";
|
||||
import { db } from "@kredens/server/db";
|
||||
import { DateTime, Duration } from "luxon";
|
||||
import { db } from "@kredens/server/db";
|
||||
import { Store } from "@holdyourwaffle/express-session";
|
||||
|
||||
export class PgStore extends Store {
|
||||
private ttl: Duration;
|
||||
@ -30,8 +30,8 @@ export class PgStore extends Store {
|
||||
) {
|
||||
db.sessions
|
||||
.get(sid)
|
||||
.then(s => cb(null, s.map(ss => ss.session).orNull()))
|
||||
.catch(r => cb(r, null));
|
||||
.then((s) => cb(null, s.map((ss) => ss.session).orNull()))
|
||||
.catch((r) => cb(r, null));
|
||||
}
|
||||
|
||||
public set(sid: string, session: SessionData, cb?: (err?: any) => void) {
|
||||
@ -39,7 +39,7 @@ export class PgStore extends Store {
|
||||
const p = db.sessions.set(sid, session, expiresAt);
|
||||
|
||||
if (cb) {
|
||||
p.then(s => cb(null)).catch(r => cb(r));
|
||||
p.then(() => cb(null)).catch((r) => cb(r));
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ export class PgStore extends Store {
|
||||
const p = db.sessions.destroy(sid);
|
||||
|
||||
if (cb) {
|
||||
p.then(s => cb()).catch(r => cb(r));
|
||||
p.then(() => cb()).catch((r) => cb(r));
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ export class PgStore extends Store {
|
||||
) {
|
||||
db.sessions
|
||||
.all()
|
||||
.then(ss => {
|
||||
.then((ss) => {
|
||||
const sessions: { [sid: string]: SessionData } = {};
|
||||
|
||||
for (const s of ss) {
|
||||
@ -65,27 +65,27 @@ export class PgStore extends Store {
|
||||
|
||||
cb(null, sessions);
|
||||
})
|
||||
.catch(r => cb(r, null));
|
||||
.catch((r) => cb(r, null));
|
||||
}
|
||||
|
||||
public length(cb: (err: any, length: number) => void) {
|
||||
db.sessions
|
||||
.length()
|
||||
.then(l => cb(null, l))
|
||||
.catch(r => cb(r, 0));
|
||||
.then((l) => cb(null, l))
|
||||
.catch((r) => cb(r, 0));
|
||||
}
|
||||
|
||||
public clear(cb?: (err?: any) => void) {
|
||||
const p = db.sessions.clear();
|
||||
if (cb) {
|
||||
p.then(() => cb()).catch(r => cb(r));
|
||||
p.then(() => cb()).catch((r) => cb(r));
|
||||
}
|
||||
}
|
||||
|
||||
public touch(sid: string, session: SessionData, cb?: (err?: any) => void) {
|
||||
const p = db.sessions.touch(sid, this.getExpiresAt(session));
|
||||
if (cb) {
|
||||
p.then(() => cb()).catch(r => cb(r));
|
||||
p.then(() => cb()).catch((r) => cb(r));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
{
|
||||
"extends": "../../tslint.json",
|
||||
"rules": {
|
||||
"no-implicit-dependencies": [
|
||||
true,
|
||||
["@kredens/server"]
|
||||
],
|
||||
"no-submodule-imports": [
|
||||
true,
|
||||
"@kredens/server"
|
||||
]
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import path from "path";
|
||||
import webpack from "webpack"; // tslint:disable-line:no-implicit-dependencies
|
||||
import webpack from "webpack";
|
||||
|
||||
const config: webpack.Configuration = {
|
||||
mode: "development",
|
||||
@ -8,28 +8,28 @@ const config: webpack.Configuration = {
|
||||
output: {
|
||||
filename: "[name].bundle.js",
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
publicPath: "/assets/"
|
||||
publicPath: "/assets/",
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
exclude: /node_modules/,
|
||||
loader: "ts-loader",
|
||||
test: /\.tsx?$/
|
||||
}
|
||||
]
|
||||
test: /\.tsx?$/,
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".ts", ".tsx", ".js"],
|
||||
alias: {
|
||||
"@kredens": path.resolve(__dirname, "src/")
|
||||
}
|
||||
"@kredens": path.resolve(__dirname, "src/"),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
API_URL: JSON.stringify("http://localhost:3000/api/")
|
||||
})
|
||||
]
|
||||
API_URL: JSON.stringify("http://localhost:3000/api/"),
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
Loading…
x
Reference in New Issue
Block a user