Migrated to using typeorm+postgres for database
This commit is contained in:
parent
7f7051658b
commit
411b2ff045
@ -3,9 +3,9 @@
|
|||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"target": "es6",
|
"target": "es2017",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es6",
|
"es2017",
|
||||||
"dom",
|
"dom",
|
||||||
"scripthost"
|
"scripthost"
|
||||||
],
|
],
|
||||||
|
@ -8,6 +8,7 @@ export enum ErrorCode {
|
|||||||
Unauthorized = 106,
|
Unauthorized = 106,
|
||||||
NoPermission = 107,
|
NoPermission = 107,
|
||||||
NotImplemented = 108,
|
NotImplemented = 108,
|
||||||
|
NotFound = 109,
|
||||||
Internal = 200,
|
Internal = 200,
|
||||||
Timeout = 300,
|
Timeout = 300,
|
||||||
ServerDisconnected = 301,
|
ServerDisconnected = 301,
|
||||||
@ -27,6 +28,8 @@ export function toHttpStatus(errorCode: ErrorCode): number {
|
|||||||
return 401; // Unauthorized
|
return 401; // Unauthorized
|
||||||
case ErrorCode.NoPermission:
|
case ErrorCode.NoPermission:
|
||||||
return 403; // Forbidden
|
return 403; // Forbidden
|
||||||
|
case ErrorCode.NotFound:
|
||||||
|
return 404;
|
||||||
case ErrorCode.NotImplemented:
|
case ErrorCode.NotImplemented:
|
||||||
return 501;
|
return 501;
|
||||||
case ErrorCode.Internal:
|
case ErrorCode.Internal:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export default interface TokenClaims {
|
export default interface TokenClaims {
|
||||||
iss: string;
|
iss: string;
|
||||||
type: "access" | "refresh";
|
type: "access" | "refresh";
|
||||||
aud: string;
|
aud: number;
|
||||||
name: string;
|
name: string;
|
||||||
exp: number;
|
exp: number;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"target": "es6",
|
"target": "es2017",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es6"
|
"es2017"
|
||||||
],
|
],
|
||||||
"types": [
|
"types": [
|
||||||
"node"
|
"node"
|
||||||
|
@ -43,14 +43,17 @@
|
|||||||
"express-promise-router": "^3.0.2",
|
"express-promise-router": "^3.0.2",
|
||||||
"fork-ts-checker-webpack-plugin": "^0.4.2",
|
"fork-ts-checker-webpack-plugin": "^0.4.2",
|
||||||
"jsonwebtoken": "^8.3.0",
|
"jsonwebtoken": "^8.3.0",
|
||||||
|
"lodash": "^4.17.10",
|
||||||
"mobx": "^5.0.3",
|
"mobx": "^5.0.3",
|
||||||
"mobx-utils": "^5.0.0",
|
"mobx-utils": "^5.0.0",
|
||||||
"module-alias": "^2.1.0",
|
"module-alias": "^2.1.0",
|
||||||
"moment": "^2.22.2",
|
"moment": "^2.22.2",
|
||||||
"mqtt": "^2.18.1",
|
"mqtt": "^2.18.1",
|
||||||
|
"pg": "^7.4.3",
|
||||||
"pino": "^4.17.3",
|
"pino": "^4.17.3",
|
||||||
"rethinkdb": "^2.3.3",
|
"reflect-metadata": "^0.1.12",
|
||||||
"serializr": "^1.2.0",
|
"serializr": "^1.2.0",
|
||||||
|
"typeorm": "^0.2.7",
|
||||||
"uglify-es": "3.3.9",
|
"uglify-es": "3.3.9",
|
||||||
"ws": "^5.2.1"
|
"ws": "^5.2.1"
|
||||||
},
|
},
|
||||||
@ -61,7 +64,7 @@
|
|||||||
"@types/core-js": "^2.5.0",
|
"@types/core-js": "^2.5.0",
|
||||||
"@types/express": "^4.16.0",
|
"@types/express": "^4.16.0",
|
||||||
"@types/jsonwebtoken": "^7.2.7",
|
"@types/jsonwebtoken": "^7.2.7",
|
||||||
"@types/lodash-es": "^4.17.0",
|
"@types/lodash": "^4.14.112",
|
||||||
"@types/node": "^10.3.5",
|
"@types/node": "^10.3.5",
|
||||||
"@types/object-assign": "^4.0.30",
|
"@types/object-assign": "^4.0.30",
|
||||||
"@types/pino": "^4.16.0",
|
"@types/pino": "^4.16.0",
|
||||||
@ -70,7 +73,6 @@
|
|||||||
"@types/react-dom": "16.0.6",
|
"@types/react-dom": "16.0.6",
|
||||||
"@types/react-hot-loader": "^4.1.0",
|
"@types/react-hot-loader": "^4.1.0",
|
||||||
"@types/react-router-dom": "^4.2.7",
|
"@types/react-router-dom": "^4.2.7",
|
||||||
"@types/rethinkdb": "^2.3.11",
|
|
||||||
"@types/webpack-env": "^1.13.6",
|
"@types/webpack-env": "^1.13.6",
|
||||||
"@types/ws": "^5.1.2",
|
"@types/ws": "^5.1.2",
|
||||||
"async": "^2.6.1",
|
"async": "^2.6.1",
|
||||||
@ -83,7 +85,6 @@
|
|||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
"happypack": "^5.0.0",
|
"happypack": "^5.0.0",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"lodash-es": "^4.17.10",
|
|
||||||
"mini-css-extract-plugin": "^0.4.0",
|
"mini-css-extract-plugin": "^0.4.0",
|
||||||
"mobx-react": "^5.2.3",
|
"mobx-react": "^5.2.3",
|
||||||
"mobx-react-devtools": "^5.0.1",
|
"mobx-react-devtools": "^5.0.1",
|
||||||
|
85
server/Database.ts
Normal file
85
server/Database.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import * as path from "path";
|
||||||
|
import { Connection, createConnection, EntityManager, getConnectionOptions, Repository } from "typeorm";
|
||||||
|
|
||||||
|
import logger from "../common/logger";
|
||||||
|
|
||||||
|
import { SprinklersDevice, User } from "./entities";
|
||||||
|
import { SprinklersDeviceRepository, UserRepository } from "./repositories/";
|
||||||
|
|
||||||
|
export class Database {
|
||||||
|
users!: UserRepository;
|
||||||
|
sprinklersDevices!: SprinklersDeviceRepository;
|
||||||
|
|
||||||
|
private _conn: Connection | null = null;
|
||||||
|
|
||||||
|
get conn(): Connection {
|
||||||
|
if (this._conn == null) {
|
||||||
|
throw new Error("Not connected to rethinkDB");
|
||||||
|
}
|
||||||
|
return this._conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
async connect() {
|
||||||
|
const options = await getConnectionOptions();
|
||||||
|
Object.assign(options, {
|
||||||
|
entities: [
|
||||||
|
path.resolve(__dirname, "entities", "*.js"),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
this._conn = await createConnection(options);
|
||||||
|
this.users = this._conn.getCustomRepository(UserRepository);
|
||||||
|
this.sprinklersDevices = this._conn.getCustomRepository(SprinklersDeviceRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
async disconnect() {
|
||||||
|
if (this._conn) {
|
||||||
|
return this._conn.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createAll() {
|
||||||
|
await this.conn.synchronize();
|
||||||
|
await this.insertData();
|
||||||
|
}
|
||||||
|
|
||||||
|
async insertData() {
|
||||||
|
const NUM = 100;
|
||||||
|
const users: User[] = [];
|
||||||
|
for (let i = 0; i < NUM; i++) {
|
||||||
|
const username = "alex" + i;
|
||||||
|
let user = await this.users.findByUsername(username);
|
||||||
|
if (!user) {
|
||||||
|
user = await this.users.create({
|
||||||
|
name: "Alex Mikhalev" + i,
|
||||||
|
username,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await user.setPassword("kakashka" + i);
|
||||||
|
users.push(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < NUM; i++) {
|
||||||
|
const name = "test" + i;
|
||||||
|
let device = await this.sprinklersDevices.findByName(name);
|
||||||
|
if (!device) {
|
||||||
|
device = await this.sprinklersDevices.create({
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await this.sprinklersDevices.save(device);
|
||||||
|
for (let j = 0; j < 5; j++) {
|
||||||
|
const userIdx = (i + j * 10) % NUM;
|
||||||
|
const user = users[userIdx];
|
||||||
|
user.devices = (user.devices || []).concat([device]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("inserted/updated devices");
|
||||||
|
|
||||||
|
await this.users.save(users);
|
||||||
|
logger.info("inserted/updated users");
|
||||||
|
|
||||||
|
const alex2 = await this.users.findOne({ username: "alex0" });
|
||||||
|
logger.info("password valid: " + await alex2!.comparePassword("kakashka0"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
38
server/entities/SprinklersDevice.ts
Normal file
38
server/entities/SprinklersDevice.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from "typeorm";
|
||||||
|
|
||||||
|
import { User } from "./User";
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class SprinklersDevice {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id!: number;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
name: string = "";
|
||||||
|
|
||||||
|
@ManyToMany((type) => User)
|
||||||
|
users: User[] | undefined;
|
||||||
|
|
||||||
|
constructor(data?: Partial<SprinklersDevice>) {
|
||||||
|
if (data) {
|
||||||
|
Object.assign(this, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Entity()
|
||||||
|
export class UserSprinklersDevice {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id!: number;
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
userId: string = "";
|
||||||
|
@Column()
|
||||||
|
sprinklersDeviceId: string = "";
|
||||||
|
|
||||||
|
constructor(data?: UserSprinklersDevice) {
|
||||||
|
if (data) {
|
||||||
|
Object.assign(this, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
server/entities/User.ts
Normal file
44
server/entities/User.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import * as bcrypt from "bcrypt";
|
||||||
|
import { omit } from "lodash";
|
||||||
|
import { Column, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from "typeorm";
|
||||||
|
|
||||||
|
import { SprinklersDevice} from "./SprinklersDevice";
|
||||||
|
|
||||||
|
const HASH_ROUNDS = 1;
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class User {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id!: number;
|
||||||
|
|
||||||
|
@Column({ unique: true })
|
||||||
|
username: string = "";
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
name: string = "";
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
passwordHash: string = "";
|
||||||
|
|
||||||
|
@ManyToMany((type) => SprinklersDevice)
|
||||||
|
@JoinTable({ name: "user_sprinklers_device" })
|
||||||
|
devices: SprinklersDevice[] | undefined;
|
||||||
|
|
||||||
|
constructor(data?: Partial<User>) {
|
||||||
|
if (data) {
|
||||||
|
Object.assign(this, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async setPassword(newPassword: string): Promise<void> {
|
||||||
|
this.passwordHash = await bcrypt.hash(newPassword, HASH_ROUNDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
async comparePassword(password: string): Promise<boolean> {
|
||||||
|
return bcrypt.compare(password, this.passwordHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON() {
|
||||||
|
return omit(this, "passwordHash");
|
||||||
|
}
|
||||||
|
}
|
2
server/entities/index.ts
Normal file
2
server/entities/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export { User } from "./User";
|
||||||
|
export { SprinklersDevice, UserSprinklersDevice } from "./SprinklersDevice";
|
@ -2,17 +2,17 @@ import * as Express from "express";
|
|||||||
import Router from "express-promise-router";
|
import Router from "express-promise-router";
|
||||||
import * as jwt from "jsonwebtoken";
|
import * as jwt from "jsonwebtoken";
|
||||||
|
|
||||||
import TokenClaims from "@common/TokenClaims";
|
import ApiError from "@common/ApiError";
|
||||||
|
import { ErrorCode } from "@common/ErrorCode";
|
||||||
import {
|
import {
|
||||||
TokenGrantPasswordRequest,
|
TokenGrantPasswordRequest,
|
||||||
TokenGrantRefreshRequest,
|
TokenGrantRefreshRequest,
|
||||||
TokenGrantRequest,
|
TokenGrantRequest,
|
||||||
TokenGrantResponse,
|
TokenGrantResponse,
|
||||||
} from "@common/httpApi";
|
} from "@common/httpApi";
|
||||||
import { ErrorCode } from "@common/ErrorCode";
|
import TokenClaims from "@common/TokenClaims";
|
||||||
import { User } from "../models/User";
|
import { User } from "../entities";
|
||||||
import { ServerState } from "../state";
|
import { ServerState } from "../state";
|
||||||
import ApiError from "@common/ApiError";
|
|
||||||
|
|
||||||
export { TokenClaims };
|
export { TokenClaims };
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ export function verifyToken(token: string): Promise<TokenClaims> {
|
|||||||
function generateAccessToken(user: User, secret: string): Promise<string> {
|
function generateAccessToken(user: User, secret: string): Promise<string> {
|
||||||
const access_token_claims: TokenClaims = {
|
const access_token_claims: TokenClaims = {
|
||||||
iss: "sprinklers3",
|
iss: "sprinklers3",
|
||||||
aud: user.id || "",
|
aud: user.id,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
type: "access",
|
type: "access",
|
||||||
exp: getExpTime(ACCESS_TOKEN_LIFETIME),
|
exp: getExpTime(ACCESS_TOKEN_LIFETIME),
|
||||||
@ -84,7 +84,7 @@ function generateAccessToken(user: User, secret: string): Promise<string> {
|
|||||||
function generateRefreshToken(user: User, secret: string): Promise<string> {
|
function generateRefreshToken(user: User, secret: string): Promise<string> {
|
||||||
const refresh_token_claims: TokenClaims = {
|
const refresh_token_claims: TokenClaims = {
|
||||||
iss: "sprinklers3",
|
iss: "sprinklers3",
|
||||||
aud: user.id || "",
|
aud: user.id,
|
||||||
name: user.name,
|
name: user.name,
|
||||||
type: "refresh",
|
type: "refresh",
|
||||||
exp: getExpTime(REFRESH_TOKEN_LIFETIME),
|
exp: getExpTime(REFRESH_TOKEN_LIFETIME),
|
||||||
@ -102,7 +102,7 @@ export function authentication(state: ServerState) {
|
|||||||
if (!body || !username || !password) {
|
if (!body || !username || !password) {
|
||||||
throw new ApiError("Must specify username and password");
|
throw new ApiError("Must specify username and password");
|
||||||
}
|
}
|
||||||
const user = await User.loadByUsername(state.database, username);
|
const user = await state.database.users.findByUsername(username);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new ApiError("User does not exist");
|
throw new ApiError("User does not exist");
|
||||||
}
|
}
|
||||||
@ -123,7 +123,7 @@ export function authentication(state: ServerState) {
|
|||||||
if (claims.type !== "refresh") {
|
if (claims.type !== "refresh") {
|
||||||
throw new ApiError("Not a refresh token");
|
throw new ApiError("Not a refresh token");
|
||||||
}
|
}
|
||||||
const user = await User.load(state.database, claims.aud);
|
const user = await state.database.users.findOne(claims.aud);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new ApiError("User no longer exists");
|
throw new ApiError("User no longer exists");
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@ import { ServerState } from "../state";
|
|||||||
import requestLogger from "./requestLogger";
|
import requestLogger from "./requestLogger";
|
||||||
import serveApp from "./serveApp";
|
import serveApp from "./serveApp";
|
||||||
|
|
||||||
import { User } from "../models/User";
|
import ApiError from "@common/ApiError";
|
||||||
|
import { ErrorCode } from "@common/ErrorCode";
|
||||||
import { authentication } from "./authentication";
|
import { authentication } from "./authentication";
|
||||||
import errorHandler from "./errorHandler";
|
import errorHandler from "./errorHandler";
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ export function createApp(state: ServerState) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.get("/api/users", (req, res) => {
|
app.get("/api/users", (req, res) => {
|
||||||
User.loadAll(state.database)
|
state.database.users.find()
|
||||||
.then((users) => {
|
.then((users) => {
|
||||||
res.json({
|
res.json({
|
||||||
data: users,
|
data: users,
|
||||||
@ -34,8 +35,12 @@ export function createApp(state: ServerState) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.get("/api/users/:username", (req, res, next) => {
|
app.get("/api/users/:username", (req, res, next) => {
|
||||||
User.loadByUsername(state.database, req.params.username)
|
const { username } = req.params;
|
||||||
|
state.database.users.findByUsername(username)
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
|
if (!user) {
|
||||||
|
throw new ApiError(`user ${username} does not exist`, ErrorCode.NotFound);
|
||||||
|
}
|
||||||
res.json({
|
res.json({
|
||||||
data: user,
|
data: user,
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* tslint:disable:ordered-imports */
|
/* tslint:disable:ordered-imports */
|
||||||
|
import "reflect-metadata";
|
||||||
import "./configureAlias";
|
import "./configureAlias";
|
||||||
import "env";
|
import "env";
|
||||||
import "./configureLogger";
|
import "./configureLogger";
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
import * as r from "rethinkdb";
|
|
||||||
|
|
||||||
import logger from "@common/logger";
|
|
||||||
import { SprinklersDevice, UserSprinklersDevice } from "./SprinklersDevice";
|
|
||||||
import { User } from "./User";
|
|
||||||
|
|
||||||
export class Database {
|
|
||||||
static readonly databaseName = "sprinklers3";
|
|
||||||
|
|
||||||
db: r.Db;
|
|
||||||
private _conn: r.Connection | null = null;
|
|
||||||
|
|
||||||
get conn(): r.Connection {
|
|
||||||
if (this._conn == null) {
|
|
||||||
throw new Error("Not connected to rethinkDB");
|
|
||||||
}
|
|
||||||
return this._conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.db = r.db(Database.databaseName);
|
|
||||||
}
|
|
||||||
|
|
||||||
async connect() {
|
|
||||||
this._conn = await r.connect("localhost");
|
|
||||||
}
|
|
||||||
|
|
||||||
async disconnect() {
|
|
||||||
if (this._conn) {
|
|
||||||
return this._conn.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async createAll() {
|
|
||||||
const dbs = await r.dbList().run(this.conn);
|
|
||||||
if (dbs.indexOf(Database.databaseName) === -1) {
|
|
||||||
await r.dbCreate(Database.databaseName).run(this.conn);
|
|
||||||
}
|
|
||||||
await this.createTables();
|
|
||||||
}
|
|
||||||
|
|
||||||
async createTables() {
|
|
||||||
const tables = await this.db.tableList().run(this.conn);
|
|
||||||
if (tables.indexOf(User.tableName) === -1) {
|
|
||||||
await User.createTable(this);
|
|
||||||
}
|
|
||||||
if (tables.indexOf(SprinklersDevice.tableName) === -1) {
|
|
||||||
await SprinklersDevice.createTable(this);
|
|
||||||
}
|
|
||||||
if (tables.indexOf(UserSprinklersDevice.tableName) === -1) {
|
|
||||||
await UserSprinklersDevice.createTable(this);
|
|
||||||
}
|
|
||||||
const alex = new User(this, {
|
|
||||||
name: "Alex Mikhalev",
|
|
||||||
username: "alex",
|
|
||||||
});
|
|
||||||
await alex.setPassword("kakashka");
|
|
||||||
const created = await alex.createOrUpdate();
|
|
||||||
logger.info((created ? "created" : "updated") + " user alex");
|
|
||||||
|
|
||||||
const alex2 = await User.loadByUsername(this, "alex");
|
|
||||||
logger.info("password valid: " + await alex2!.comparePassword("kakashka"));
|
|
||||||
|
|
||||||
const device = new SprinklersDevice(this, {
|
|
||||||
name: "test",
|
|
||||||
});
|
|
||||||
await device.createOrUpdate();
|
|
||||||
|
|
||||||
device.addToUser
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
import * as r from "rethinkdb";
|
|
||||||
import { createModelSchema, primitive, serialize, update } from "serializr";
|
|
||||||
|
|
||||||
import { Database } from "./Database";
|
|
||||||
import { User } from "./User";
|
|
||||||
|
|
||||||
export interface ISprinklersDevice {
|
|
||||||
id: string | undefined;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SprinklersDevice implements ISprinklersDevice {
|
|
||||||
static readonly tableName = "SprinklersDevices";
|
|
||||||
|
|
||||||
id: string | undefined;
|
|
||||||
name: string = "";
|
|
||||||
|
|
||||||
private db: Database;
|
|
||||||
private _table: r.Table | null = null;
|
|
||||||
|
|
||||||
constructor(db: Database, data?: Partial<ISprinklersDevice>) {
|
|
||||||
this.db = db;
|
|
||||||
if (data) {
|
|
||||||
update(this, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static async createTable(db: Database) {
|
|
||||||
await db.db.tableCreate(SprinklersDevice.tableName).run(db.conn);
|
|
||||||
await db.db.table(SprinklersDevice.tableName).indexCreate("name").run(db.conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static async loadAll(db: Database): Promise<SprinklersDevice[]> {
|
|
||||||
const cursor = await db.db.table(SprinklersDevice.tableName)
|
|
||||||
.run(db.conn);
|
|
||||||
const users = await cursor.toArray();
|
|
||||||
return users.map((data) => {
|
|
||||||
return new SprinklersDevice(db, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static async load(db: Database, id: string): Promise<SprinklersDevice | null> {
|
|
||||||
const data = await db.db.table(SprinklersDevice.tableName)
|
|
||||||
.get(id)
|
|
||||||
.run(db.conn);
|
|
||||||
if (data == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new SprinklersDevice(db, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static getTable(db: Database): r.Table {
|
|
||||||
return db.db.table(this.tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private get table() {
|
|
||||||
if (!this._table) {
|
|
||||||
this._table = SprinklersDevice.getTable(this.db);
|
|
||||||
}
|
|
||||||
return this._table;
|
|
||||||
}
|
|
||||||
|
|
||||||
async create() {
|
|
||||||
const data = serialize(this);
|
|
||||||
delete data.id;
|
|
||||||
const result = await this.table
|
|
||||||
.insert(data)
|
|
||||||
.run(this.db.conn);
|
|
||||||
this.id = result.generated_keys[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
async createOrUpdate() {
|
|
||||||
const data = serialize(this);
|
|
||||||
delete data.id;
|
|
||||||
const device = this.table.filter(r.row("name").eq(this.name));
|
|
||||||
const nameDoesNotExist = device.isEmpty();
|
|
||||||
const a: r.WriteResult = await r.branch(nameDoesNotExist,
|
|
||||||
this.table.insert(data) as r.Expression<any>,
|
|
||||||
device.nth(0).update(data) as r.Expression<any>)
|
|
||||||
.run(this.db.conn);
|
|
||||||
if (a.inserted > 0) {
|
|
||||||
this.id = a.generated_keys[0];
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async addToUser(user: User | number) {
|
|
||||||
const userId = (typeof user === "number") ? user : user.id;
|
|
||||||
const userDevice = new UserSprinklersDevice(this.db, {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toJSON(): any {
|
|
||||||
return serialize(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createModelSchema(SprinklersDevice, {
|
|
||||||
id: primitive(),
|
|
||||||
name: primitive(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export interface IUserSprinklersDevice {
|
|
||||||
id: string | undefined;
|
|
||||||
userId: string;
|
|
||||||
sprinklersDeviceId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class UserSprinklersDevice implements IUserSprinklersDevice {
|
|
||||||
static readonly tableName = "UserSprinklersDevices";
|
|
||||||
|
|
||||||
id: string | undefined;
|
|
||||||
|
|
||||||
userId: string = "";
|
|
||||||
sprinklersDeviceId: string = "";
|
|
||||||
|
|
||||||
private db: Database;
|
|
||||||
private _table: r.Table | null = null;
|
|
||||||
|
|
||||||
constructor(db: Database) {
|
|
||||||
this.db = db;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async createTable(db: Database) {
|
|
||||||
await db.db.tableCreate(UserSprinklersDevice.tableName).run(db.conn);
|
|
||||||
await db.db.table(UserSprinklersDevice.tableName).indexCreate("userId").run(db.conn);
|
|
||||||
await db.db.table(UserSprinklersDevice.tableName).indexCreate("sprinklersDeviceId").run(db.conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static getTable(db: Database): r.Table {
|
|
||||||
return db.db.table(this.tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
async create() {
|
|
||||||
const data = serialize(this);
|
|
||||||
delete data.id;
|
|
||||||
const result = await this.table
|
|
||||||
.insert(data)
|
|
||||||
.run(this.db.conn);
|
|
||||||
this.id = result.generated_keys[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private get table() {
|
|
||||||
if (!this._table) {
|
|
||||||
this._table = UserSprinklersDevice.getTable(this.db);
|
|
||||||
}
|
|
||||||
return this._table;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
import * as bcrypt from "bcrypt";
|
|
||||||
import * as r from "rethinkdb";
|
|
||||||
import { createModelSchema, primitive, serialize, update } from "serializr";
|
|
||||||
|
|
||||||
import { Database } from "./Database";
|
|
||||||
|
|
||||||
export interface IUser {
|
|
||||||
id: string | undefined;
|
|
||||||
username: string;
|
|
||||||
name: string;
|
|
||||||
passwordHash: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const HASH_ROUNDS = 10;
|
|
||||||
|
|
||||||
export class User implements IUser {
|
|
||||||
static readonly tableName = "Users";
|
|
||||||
|
|
||||||
id: string | undefined;
|
|
||||||
username: string = "";
|
|
||||||
name: string = "";
|
|
||||||
passwordHash: string = "";
|
|
||||||
|
|
||||||
private db: Database;
|
|
||||||
|
|
||||||
private get table() {
|
|
||||||
return this.db.db.table(User.tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(db: Database, data?: Partial<IUser>) {
|
|
||||||
this.db = db;
|
|
||||||
if (data) {
|
|
||||||
update(this, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static async createTable(db: Database) {
|
|
||||||
await db.db.tableCreate(User.tableName).run(db.conn);
|
|
||||||
await db.db.table(User.tableName).indexCreate("username").run(db.conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static async loadAll(db: Database): Promise<User[]> {
|
|
||||||
const cursor = await db.db.table(User.tableName)
|
|
||||||
.run(db.conn);
|
|
||||||
const users = await cursor.toArray();
|
|
||||||
return users.map((data) => {
|
|
||||||
return new User(db, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static async load(db: Database, id: string): Promise<User | null> {
|
|
||||||
const data = await db.db.table(User.tableName)
|
|
||||||
.get(id)
|
|
||||||
.run(db.conn);
|
|
||||||
if (data == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new User(db, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static async loadByUsername(db: Database, username: string): Promise<User | null> {
|
|
||||||
const seq = await db.db.table(User.tableName)
|
|
||||||
.filter(r.row("username").eq(username))
|
|
||||||
.run(db.conn);
|
|
||||||
const data = await seq.toArray();
|
|
||||||
if (data.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new User(db, data[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
async create() {
|
|
||||||
const data = serialize(this);
|
|
||||||
delete data.id;
|
|
||||||
const result = await this.table
|
|
||||||
.insert(data)
|
|
||||||
.run(this.db.conn);
|
|
||||||
this.id = result.generated_keys[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
async createOrUpdate() {
|
|
||||||
const data = serialize(this);
|
|
||||||
delete data.id;
|
|
||||||
const user = this.table.filter(r.row("username").eq(this.username));
|
|
||||||
const usernameDoesNotExist = user.isEmpty();
|
|
||||||
const a: r.WriteResult = await r.branch(usernameDoesNotExist,
|
|
||||||
this.table.insert(data) as r.Expression<any>,
|
|
||||||
user.nth(0).update(data) as r.Expression<any>)
|
|
||||||
.run(this.db.conn);
|
|
||||||
if (a.inserted > 0) {
|
|
||||||
this.id = a.generated_keys[0];
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async setPassword(newPassword: string): Promise<void> {
|
|
||||||
this.passwordHash = await bcrypt.hash(newPassword, HASH_ROUNDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
async comparePassword(password: string): Promise<boolean> {
|
|
||||||
return bcrypt.compare(password, this.passwordHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
toJSON(): any {
|
|
||||||
const data = serialize(this);
|
|
||||||
delete data.passwordHash;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createModelSchema(User, {
|
|
||||||
id: primitive(),
|
|
||||||
username: primitive(),
|
|
||||||
name: primitive(),
|
|
||||||
passwordHash: primitive(),
|
|
||||||
});
|
|
@ -1,3 +0,0 @@
|
|||||||
export { User, IUser } from "./User";
|
|
||||||
export { SprinklersDevice, ISprinklersDevice, UserSprinklersDevice } from "./SprinklersDevice";
|
|
||||||
export { Database } from "./Database";
|
|
10
server/repositories/SprinklersDeviceRepository.ts
Normal file
10
server/repositories/SprinklersDeviceRepository.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { EntityRepository, Repository } from "typeorm";
|
||||||
|
|
||||||
|
import { SprinklersDevice } from "../entities";
|
||||||
|
|
||||||
|
@EntityRepository(SprinklersDevice)
|
||||||
|
export class SprinklersDeviceRepository extends Repository<SprinklersDevice> {
|
||||||
|
findByName(name: string) {
|
||||||
|
return this.findOne({ name });
|
||||||
|
}
|
||||||
|
}
|
10
server/repositories/UserRepository.ts
Normal file
10
server/repositories/UserRepository.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { EntityRepository, Repository } from "typeorm";
|
||||||
|
|
||||||
|
import { User } from "../entities";
|
||||||
|
|
||||||
|
@EntityRepository(User)
|
||||||
|
export class UserRepository extends Repository<User> {
|
||||||
|
findByUsername(username: string) {
|
||||||
|
return this.findOne({ username }, { relations: ["devices"] });
|
||||||
|
}
|
||||||
|
}
|
2
server/repositories/index.ts
Normal file
2
server/repositories/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export { UserRepository } from "./UserRepository";
|
||||||
|
export { SprinklersDeviceRepository } from "./SprinklersDeviceRepository";
|
@ -2,10 +2,10 @@ import { autorun } from "mobx";
|
|||||||
import { serialize } from "serializr";
|
import { serialize } from "serializr";
|
||||||
import * as WebSocket from "ws";
|
import * as WebSocket from "ws";
|
||||||
|
|
||||||
|
import { ErrorCode } from "@common/ErrorCode";
|
||||||
import * as rpc from "@common/jsonRpc";
|
import * as rpc from "@common/jsonRpc";
|
||||||
import log from "@common/logger";
|
import log from "@common/logger";
|
||||||
import * as deviceRequests from "@common/sprinklersRpc/deviceRequests";
|
import * as deviceRequests from "@common/sprinklersRpc/deviceRequests";
|
||||||
import { ErrorCode } from "@common/ErrorCode";
|
|
||||||
import * as schema from "@common/sprinklersRpc/schema";
|
import * as schema from "@common/sprinklersRpc/schema";
|
||||||
import * as ws from "@common/sprinklersRpc/websocketData";
|
import * as ws from "@common/sprinklersRpc/websocketData";
|
||||||
import { TokenClaims, verifyToken } from "../express/authentication";
|
import { TokenClaims, verifyToken } from "../express/authentication";
|
||||||
@ -21,7 +21,7 @@ export class WebSocketClient {
|
|||||||
deviceSubscriptions: string[] = [];
|
deviceSubscriptions: string[] = [];
|
||||||
|
|
||||||
/// This shall be the user id if the client has been authenticated, null otherwise
|
/// This shall be the user id if the client has been authenticated, null otherwise
|
||||||
userId: string | null = null;
|
userId: number | null = null;
|
||||||
|
|
||||||
get state() {
|
get state() {
|
||||||
return this.api.state;
|
return this.api.state;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import logger from "@common/logger";
|
import logger from "@common/logger";
|
||||||
import * as mqtt from "@common/sprinklersRpc/mqtt";
|
import * as mqtt from "@common/sprinklersRpc/mqtt";
|
||||||
import { Database } from "./models/Database";
|
import { Database } from "./Database";
|
||||||
|
|
||||||
export class ServerState {
|
export class ServerState {
|
||||||
mqttClient: mqtt.MqttRpcClient;
|
mqttClient: mqtt.MqttRpcClient;
|
||||||
|
@ -1,31 +1,32 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../dist",
|
"outDir": "../dist",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"target": "es2017",
|
"emitDecoratorMetadata": true,
|
||||||
"module": "commonjs",
|
"target": "es2017",
|
||||||
"lib": [
|
"module": "commonjs",
|
||||||
"es6",
|
"lib": [
|
||||||
"dom"
|
"es6",
|
||||||
],
|
"dom"
|
||||||
"types": [
|
],
|
||||||
"webpack-env",
|
"types": [
|
||||||
"node"
|
"webpack-env",
|
||||||
],
|
"node"
|
||||||
"strict": true,
|
],
|
||||||
"allowJs": true,
|
"strict": true,
|
||||||
"baseUrl": "..",
|
"allowJs": true,
|
||||||
"paths": {
|
"baseUrl": "..",
|
||||||
"@common/*": [
|
"paths": {
|
||||||
"./common/*"
|
"@common/*": [
|
||||||
],
|
"./common/*"
|
||||||
"@app/*": [
|
],
|
||||||
"./app/*"
|
"@app/*": [
|
||||||
]
|
"./app/*"
|
||||||
}
|
]
|
||||||
},
|
}
|
||||||
"include": [
|
},
|
||||||
"./**/*.ts"
|
"include": [
|
||||||
]
|
"./**/*.ts"
|
||||||
|
]
|
||||||
}
|
}
|
234
yarn.lock
234
yarn.lock
@ -82,15 +82,9 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/lodash-es@^4.17.0":
|
"@types/lodash@^4.14.112":
|
||||||
version "4.17.0"
|
version "4.14.112"
|
||||||
resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.0.tgz#ed9044d62ee36a93e0650b112701986b1c74c766"
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.112.tgz#4a8d8e5716b97a1ac01fe1931ad1e4cba719de5a"
|
||||||
dependencies:
|
|
||||||
"@types/lodash" "*"
|
|
||||||
|
|
||||||
"@types/lodash@*":
|
|
||||||
version "4.14.110"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.110.tgz#fb07498f84152947f30ea09d89207ca07123461e"
|
|
||||||
|
|
||||||
"@types/mime@*":
|
"@types/mime@*":
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
@ -154,12 +148,6 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
csstype "^2.2.0"
|
csstype "^2.2.0"
|
||||||
|
|
||||||
"@types/rethinkdb@^2.3.11":
|
|
||||||
version "2.3.11"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/rethinkdb/-/rethinkdb-2.3.11.tgz#13b7148c0fd1f4e65ea1e5a242fbae01ccc3259b"
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@types/serve-static@*":
|
"@types/serve-static@*":
|
||||||
version "1.13.2"
|
version "1.13.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48"
|
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48"
|
||||||
@ -411,6 +399,10 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
color-convert "^1.9.0"
|
color-convert "^1.9.0"
|
||||||
|
|
||||||
|
any-promise@^1.0.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
|
||||||
|
|
||||||
anymatch@^1.3.0:
|
anymatch@^1.3.0:
|
||||||
version "1.3.2"
|
version "1.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
|
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
|
||||||
@ -425,6 +417,10 @@ anymatch@^2.0.0:
|
|||||||
micromatch "^3.1.4"
|
micromatch "^3.1.4"
|
||||||
normalize-path "^2.1.1"
|
normalize-path "^2.1.1"
|
||||||
|
|
||||||
|
app-root-path@^2.0.1:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.1.0.tgz#98bf6599327ecea199309866e8140368fd2e646a"
|
||||||
|
|
||||||
aproba@^1.0.3, aproba@^1.1.1:
|
aproba@^1.0.3, aproba@^1.1.1:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
||||||
@ -715,10 +711,6 @@ block-stream@*:
|
|||||||
dependencies:
|
dependencies:
|
||||||
inherits "~2.0.0"
|
inherits "~2.0.0"
|
||||||
|
|
||||||
"bluebird@>= 2.3.2 < 3":
|
|
||||||
version "2.11.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
|
|
||||||
|
|
||||||
bluebird@^3.5.1:
|
bluebird@^3.5.1:
|
||||||
version "3.5.1"
|
version "3.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
|
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
|
||||||
@ -902,6 +894,10 @@ buffer-indexof@^1.0.0:
|
|||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
|
resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
|
||||||
|
|
||||||
|
buffer-writer@1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-1.0.1.tgz#22a936901e3029afcd7547eb4487ceb697a3bf08"
|
||||||
|
|
||||||
buffer-xor@^1.0.3:
|
buffer-xor@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
|
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
|
||||||
@ -914,6 +910,13 @@ buffer@^4.3.0:
|
|||||||
ieee754 "^1.1.4"
|
ieee754 "^1.1.4"
|
||||||
isarray "^1.0.0"
|
isarray "^1.0.0"
|
||||||
|
|
||||||
|
buffer@^5.1.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.1.0.tgz#c913e43678c7cb7c8bd16afbcddb6c5505e8f9fe"
|
||||||
|
dependencies:
|
||||||
|
base64-js "^1.0.2"
|
||||||
|
ieee754 "^1.1.4"
|
||||||
|
|
||||||
builtin-modules@^1.0.0, builtin-modules@^1.1.1:
|
builtin-modules@^1.0.0, builtin-modules@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
|
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
|
||||||
@ -1049,7 +1052,7 @@ chalk@1.1.3, chalk@^1.1.1, chalk@^1.1.3:
|
|||||||
strip-ansi "^3.0.0"
|
strip-ansi "^3.0.0"
|
||||||
supports-color "^2.0.0"
|
supports-color "^2.0.0"
|
||||||
|
|
||||||
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.0, chalk@^2.4.1:
|
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.0, chalk@^2.4.1:
|
||||||
version "2.4.1"
|
version "2.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1159,6 +1162,16 @@ cli-cursor@^2.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
restore-cursor "^2.0.0"
|
restore-cursor "^2.0.0"
|
||||||
|
|
||||||
|
cli-highlight@^1.2.3:
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-1.2.3.tgz#b200f97ed0e43d24633e89de0f489a48bb87d2bf"
|
||||||
|
dependencies:
|
||||||
|
chalk "^2.3.0"
|
||||||
|
highlight.js "^9.6.0"
|
||||||
|
mz "^2.4.0"
|
||||||
|
parse5 "^3.0.3"
|
||||||
|
yargs "^10.0.3"
|
||||||
|
|
||||||
cli-width@^2.0.0:
|
cli-width@^2.0.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
|
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
|
||||||
@ -1836,6 +1849,10 @@ dot-prop@^4.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-obj "^1.0.0"
|
is-obj "^1.0.0"
|
||||||
|
|
||||||
|
dotenv@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef"
|
||||||
|
|
||||||
dotenv@^6.0.0:
|
dotenv@^6.0.0:
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.0.0.tgz#24e37c041741c5f4b25324958ebbc34bca965935"
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.0.0.tgz#24e37c041741c5f4b25324958ebbc34bca965935"
|
||||||
@ -2288,6 +2305,10 @@ fbjs@^0.8.16:
|
|||||||
setimmediate "^1.0.5"
|
setimmediate "^1.0.5"
|
||||||
ua-parser-js "^0.7.18"
|
ua-parser-js "^0.7.18"
|
||||||
|
|
||||||
|
figlet@^1.1.1:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.2.0.tgz#6c46537378fab649146b5a6143dda019b430b410"
|
||||||
|
|
||||||
figures@^2.0.0:
|
figures@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
|
resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
|
||||||
@ -2847,6 +2868,10 @@ help-me@^1.0.1:
|
|||||||
through2 "^2.0.1"
|
through2 "^2.0.1"
|
||||||
xtend "^4.0.0"
|
xtend "^4.0.0"
|
||||||
|
|
||||||
|
highlight.js@^9.6.0:
|
||||||
|
version "9.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
|
||||||
|
|
||||||
history@^4.7.2:
|
history@^4.7.2:
|
||||||
version "4.7.2"
|
version "4.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b"
|
resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b"
|
||||||
@ -3527,7 +3552,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
|
|||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
||||||
|
|
||||||
js-yaml@^3.4.3, js-yaml@^3.7.0:
|
js-yaml@^3.11.0, js-yaml@^3.4.3, js-yaml@^3.7.0:
|
||||||
version "3.12.0"
|
version "3.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
|
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -3724,10 +3749,6 @@ locate-path@^2.0.0:
|
|||||||
p-locate "^2.0.0"
|
p-locate "^2.0.0"
|
||||||
path-exists "^3.0.0"
|
path-exists "^3.0.0"
|
||||||
|
|
||||||
lodash-es@^4.17.10:
|
|
||||||
version "4.17.10"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.10.tgz#62cd7104cdf5dd87f235a837f0ede0e8e5117e05"
|
|
||||||
|
|
||||||
lodash._reinterpolate@~3.0.0:
|
lodash._reinterpolate@~3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
||||||
@ -4227,6 +4248,14 @@ mute-stream@0.0.7:
|
|||||||
version "0.0.7"
|
version "0.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||||
|
|
||||||
|
mz@^2.4.0:
|
||||||
|
version "2.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
|
||||||
|
dependencies:
|
||||||
|
any-promise "^1.0.0"
|
||||||
|
object-assign "^4.0.1"
|
||||||
|
thenify-all "^1.0.0"
|
||||||
|
|
||||||
nan@2.10.0, nan@^2.10.0, nan@^2.9.2:
|
nan@2.10.0, nan@^2.10.0, nan@^2.9.2:
|
||||||
version "2.10.0"
|
version "2.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
|
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
|
||||||
@ -4690,6 +4719,10 @@ package-json@^4.0.0:
|
|||||||
registry-url "^3.0.3"
|
registry-url "^3.0.3"
|
||||||
semver "^5.1.0"
|
semver "^5.1.0"
|
||||||
|
|
||||||
|
packet-reader@0.3.1:
|
||||||
|
version "0.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-0.3.1.tgz#cd62e60af8d7fea8a705ec4ff990871c46871f27"
|
||||||
|
|
||||||
pako@~1.0.5:
|
pako@~1.0.5:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
|
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
|
||||||
@ -4708,6 +4741,10 @@ param-case@2.1.x:
|
|||||||
dependencies:
|
dependencies:
|
||||||
no-case "^2.2.0"
|
no-case "^2.2.0"
|
||||||
|
|
||||||
|
parent-require@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/parent-require/-/parent-require-1.0.0.tgz#746a167638083a860b0eef6732cb27ed46c32977"
|
||||||
|
|
||||||
parse-asn1@^5.0.0:
|
parse-asn1@^5.0.0:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8"
|
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8"
|
||||||
@ -4848,6 +4885,41 @@ performance-now@^0.2.0:
|
|||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
|
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
|
||||||
|
|
||||||
|
pg-connection-string@0.1.3:
|
||||||
|
version "0.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7"
|
||||||
|
|
||||||
|
pg-pool@~2.0.3:
|
||||||
|
version "2.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.3.tgz#c022032c8949f312a4f91fb6409ce04076be3257"
|
||||||
|
|
||||||
|
pg-types@~1.12.1:
|
||||||
|
version "1.12.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.12.1.tgz#d64087e3903b58ffaad279e7595c52208a14c3d2"
|
||||||
|
dependencies:
|
||||||
|
postgres-array "~1.0.0"
|
||||||
|
postgres-bytea "~1.0.0"
|
||||||
|
postgres-date "~1.0.0"
|
||||||
|
postgres-interval "^1.1.0"
|
||||||
|
|
||||||
|
pg@^7.4.3:
|
||||||
|
version "7.4.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/pg/-/pg-7.4.3.tgz#f7b6f93f5340ecc2596afbb94a13e3d6b609834b"
|
||||||
|
dependencies:
|
||||||
|
buffer-writer "1.0.1"
|
||||||
|
packet-reader "0.3.1"
|
||||||
|
pg-connection-string "0.1.3"
|
||||||
|
pg-pool "~2.0.3"
|
||||||
|
pg-types "~1.12.1"
|
||||||
|
pgpass "1.x"
|
||||||
|
semver "4.3.2"
|
||||||
|
|
||||||
|
pgpass@1.x:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306"
|
||||||
|
dependencies:
|
||||||
|
split "^1.0.0"
|
||||||
|
|
||||||
pify@^2.0.0:
|
pify@^2.0.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||||
@ -5436,6 +5508,24 @@ postcss@^6.0, postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.16, postcss@^6.0.18,
|
|||||||
source-map "^0.6.1"
|
source-map "^0.6.1"
|
||||||
supports-color "^5.4.0"
|
supports-color "^5.4.0"
|
||||||
|
|
||||||
|
postgres-array@~1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-1.0.2.tgz#8e0b32eb03bf77a5c0a7851e0441c169a256a238"
|
||||||
|
|
||||||
|
postgres-bytea@~1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
|
||||||
|
|
||||||
|
postgres-date@~1.0.0:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.3.tgz#e2d89702efdb258ff9d9cee0fe91bd06975257a8"
|
||||||
|
|
||||||
|
postgres-interval@^1.1.0:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.1.2.tgz#bf71ff902635f21cb241a013fc421d81d1db15a9"
|
||||||
|
dependencies:
|
||||||
|
xtend "^4.0.0"
|
||||||
|
|
||||||
prepend-http@^1.0.0, prepend-http@^1.0.1:
|
prepend-http@^1.0.0, prepend-http@^1.0.1:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
||||||
@ -5817,6 +5907,10 @@ reduce-function-call@^1.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
balanced-match "^0.4.2"
|
balanced-match "^0.4.2"
|
||||||
|
|
||||||
|
reflect-metadata@^0.1.12:
|
||||||
|
version "0.1.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2"
|
||||||
|
|
||||||
regenerate@^1.2.1:
|
regenerate@^1.2.1:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
|
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
|
||||||
@ -6015,12 +6109,6 @@ ret@~0.1.10:
|
|||||||
version "0.1.15"
|
version "0.1.15"
|
||||||
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
||||||
|
|
||||||
rethinkdb@^2.3.3:
|
|
||||||
version "2.3.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/rethinkdb/-/rethinkdb-2.3.3.tgz#3dc6586e22fa1dabee0d254e64bd0e379fad2f72"
|
|
||||||
dependencies:
|
|
||||||
bluebird ">= 2.3.2 < 3"
|
|
||||||
|
|
||||||
right-align@^0.1.1:
|
right-align@^0.1.1:
|
||||||
version "0.1.3"
|
version "0.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
|
resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
|
||||||
@ -6105,7 +6193,7 @@ sass-loader@^7.0.3:
|
|||||||
neo-async "^2.5.0"
|
neo-async "^2.5.0"
|
||||||
pify "^3.0.0"
|
pify "^3.0.0"
|
||||||
|
|
||||||
sax@^1.2.4, sax@~1.2.1:
|
sax@>=0.6.0, sax@^1.2.4, sax@~1.2.1:
|
||||||
version "1.2.4"
|
version "1.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||||
|
|
||||||
@ -6160,6 +6248,10 @@ semver-diff@^2.0.0:
|
|||||||
version "5.5.0"
|
version "5.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||||
|
|
||||||
|
semver@4.3.2:
|
||||||
|
version "4.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7"
|
||||||
|
|
||||||
semver@~5.3.0:
|
semver@~5.3.0:
|
||||||
version "5.3.0"
|
version "5.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
|
||||||
@ -6503,6 +6595,12 @@ split@0.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
through "2"
|
through "2"
|
||||||
|
|
||||||
|
split@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
|
||||||
|
dependencies:
|
||||||
|
through "2"
|
||||||
|
|
||||||
sprintf-js@~1.0.2:
|
sprintf-js@~1.0.2:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||||
@ -6733,6 +6831,18 @@ text-table@0.2.0:
|
|||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||||
|
|
||||||
|
thenify-all@^1.0.0:
|
||||||
|
version "1.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
|
||||||
|
dependencies:
|
||||||
|
thenify ">= 3.1.0 < 4"
|
||||||
|
|
||||||
|
"thenify@>= 3.1.0 < 4":
|
||||||
|
version "3.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
|
||||||
|
dependencies:
|
||||||
|
any-promise "^1.0.0"
|
||||||
|
|
||||||
through2-filter@^2.0.0:
|
through2-filter@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec"
|
resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec"
|
||||||
@ -6910,6 +7020,24 @@ typedarray@^0.0.6:
|
|||||||
version "0.0.6"
|
version "0.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
|
|
||||||
|
typeorm@^0.2.7:
|
||||||
|
version "0.2.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.7.tgz#4bbbace80dc91b1303be13f42d44ebf01d1b2558"
|
||||||
|
dependencies:
|
||||||
|
app-root-path "^2.0.1"
|
||||||
|
buffer "^5.1.0"
|
||||||
|
chalk "^2.3.2"
|
||||||
|
cli-highlight "^1.2.3"
|
||||||
|
debug "^3.1.0"
|
||||||
|
dotenv "^5.0.1"
|
||||||
|
glob "^7.1.2"
|
||||||
|
js-yaml "^3.11.0"
|
||||||
|
mkdirp "^0.5.1"
|
||||||
|
reflect-metadata "^0.1.12"
|
||||||
|
xml2js "^0.4.17"
|
||||||
|
yargonaut "^1.1.2"
|
||||||
|
yargs "^11.1.0"
|
||||||
|
|
||||||
typescript@^2.9.2:
|
typescript@^2.9.2:
|
||||||
version "2.9.2"
|
version "2.9.2"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
|
||||||
@ -7464,6 +7592,17 @@ xdg-basedir@^3.0.0:
|
|||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
|
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
|
||||||
|
|
||||||
|
xml2js@^0.4.17:
|
||||||
|
version "0.4.19"
|
||||||
|
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
|
||||||
|
dependencies:
|
||||||
|
sax ">=0.6.0"
|
||||||
|
xmlbuilder "~9.0.1"
|
||||||
|
|
||||||
|
xmlbuilder@~9.0.1:
|
||||||
|
version "9.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
|
||||||
|
|
||||||
xmlhttprequest-ssl@~1.5.4:
|
xmlhttprequest-ssl@~1.5.4:
|
||||||
version "1.5.5"
|
version "1.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
|
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
|
||||||
@ -7488,12 +7627,26 @@ yallist@^3.0.0, yallist@^3.0.2:
|
|||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9"
|
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9"
|
||||||
|
|
||||||
|
yargonaut@^1.1.2:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargonaut/-/yargonaut-1.1.3.tgz#1cf6bbe511ecc865d6014203385628bcc39b0493"
|
||||||
|
dependencies:
|
||||||
|
chalk "^1.1.1"
|
||||||
|
figlet "^1.1.1"
|
||||||
|
parent-require "^1.0.0"
|
||||||
|
|
||||||
yargs-parser@^5.0.0:
|
yargs-parser@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
|
||||||
dependencies:
|
dependencies:
|
||||||
camelcase "^3.0.0"
|
camelcase "^3.0.0"
|
||||||
|
|
||||||
|
yargs-parser@^8.1.0:
|
||||||
|
version "8.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950"
|
||||||
|
dependencies:
|
||||||
|
camelcase "^4.1.0"
|
||||||
|
|
||||||
yargs-parser@^9.0.2:
|
yargs-parser@^9.0.2:
|
||||||
version "9.0.2"
|
version "9.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
|
||||||
@ -7517,6 +7670,23 @@ yargs@11.0.0, yargs@^11.0.0:
|
|||||||
y18n "^3.2.1"
|
y18n "^3.2.1"
|
||||||
yargs-parser "^9.0.2"
|
yargs-parser "^9.0.2"
|
||||||
|
|
||||||
|
yargs@^10.0.3:
|
||||||
|
version "10.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.1.2.tgz#454d074c2b16a51a43e2fb7807e4f9de69ccb5c5"
|
||||||
|
dependencies:
|
||||||
|
cliui "^4.0.0"
|
||||||
|
decamelize "^1.1.1"
|
||||||
|
find-up "^2.1.0"
|
||||||
|
get-caller-file "^1.0.1"
|
||||||
|
os-locale "^2.0.0"
|
||||||
|
require-directory "^2.1.1"
|
||||||
|
require-main-filename "^1.0.1"
|
||||||
|
set-blocking "^2.0.0"
|
||||||
|
string-width "^2.0.0"
|
||||||
|
which-module "^2.0.0"
|
||||||
|
y18n "^3.2.1"
|
||||||
|
yargs-parser "^8.1.0"
|
||||||
|
|
||||||
yargs@^11.1.0:
|
yargs@^11.1.0:
|
||||||
version "11.1.0"
|
version "11.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
|
resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user