From e0b0102603a09e4a5561278e027b01156200d7a0 Mon Sep 17 00:00:00 2001 From: Max Leiter Date: Mon, 28 Mar 2022 12:13:22 -0700 Subject: [PATCH] server: rework migrations/sequelize, add basic admin page/role, bug fixes --- README.md | 1 + client/components/admin/admin.module.css | 14 + client/components/admin/index.tsx | 79 +++ client/components/header/header.tsx | 20 +- client/components/settings/index.tsx | 24 - client/lib/hooks/use-user-data.ts | 41 ++ client/lib/types.d.ts | 3 + client/pages/admin.tsx | 58 ++ client/pages/mine.tsx | 1 + client/pages/settings.tsx | 32 - server/127.0.0.1 | Bin 12288 -> 0 bytes server/Dockerfile | 38 -- server/config/config.js | 5 - server/package.json | 100 ++-- server/src/app.ts | 3 +- server/src/database.ts | 36 ++ server/src/lib/middleware/is-admin.ts | 42 ++ server/src/lib/middleware/jwt.ts | 6 +- server/src/lib/models/File.ts | 16 +- server/src/lib/models/Post.ts | 6 +- server/src/lib/models/PostAuthor.ts | 7 +- server/src/lib/models/User.ts | 8 +- server/src/lib/sequelize.ts | 12 - server/src/migrations/00_user-table.ts | 31 + server/src/migrations/01_user-add-role.ts | 12 + server/src/migrations/02_post_table.ts | 34 ++ server/src/migrations/03_files_table.ts | 59 ++ .../src/migrations/04_post_authors_table.ts | 41 ++ server/src/routes/admin.ts | 63 ++ server/src/routes/auth.ts | 5 +- server/src/routes/index.ts | 1 + server/src/routes/users.ts | 37 +- server/src/server.ts | 14 +- server/tsconfig.json | 56 +- server/yarn.lock | 550 ++++++++++++------ 35 files changed, 1069 insertions(+), 386 deletions(-) create mode 100644 client/components/admin/admin.module.css create mode 100644 client/components/admin/index.tsx delete mode 100644 client/components/settings/index.tsx create mode 100644 client/lib/hooks/use-user-data.ts create mode 100644 client/pages/admin.tsx delete mode 100644 client/pages/settings.tsx delete mode 100644 server/127.0.0.1 delete mode 100644 server/Dockerfile create mode 100644 server/src/database.ts create mode 100644 server/src/lib/middleware/is-admin.ts delete mode 100644 server/src/lib/sequelize.ts create mode 100644 server/src/migrations/00_user-table.ts create mode 100644 server/src/migrations/01_user-add-role.ts create mode 100644 server/src/migrations/02_post_table.ts create mode 100644 server/src/migrations/03_files_table.ts create mode 100644 server/src/migrations/04_post_authors_table.ts create mode 100644 server/src/routes/admin.ts diff --git a/README.md b/README.md index 6b067875..50b5dccc 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ You can change these to your liking. - `SECRET_KEY`: the same secret key as the client - `WELCOME_CONTENT`: a markdown string that's rendered on the home page - `WELCOME_TITLE`: the file title for the post on the homepage. +- `ENABLE_ADMIN`: the first account created is an administrator account ## Current status diff --git a/client/components/admin/admin.module.css b/client/components/admin/admin.module.css new file mode 100644 index 00000000..57d378dc --- /dev/null +++ b/client/components/admin/admin.module.css @@ -0,0 +1,14 @@ +.adminWrapper table { + width: 100%; + border-spacing: 0; + border: 1px solid var(--gray); + border-radius: var(--radius); + padding: var(--gap-half); +} + +.adminWrapper table th { + text-align: left; + background: var(--gray-light); + color: var(--gray-dark); + font-weight: bold; +} diff --git a/client/components/admin/index.tsx b/client/components/admin/index.tsx new file mode 100644 index 00000000..ffff89e4 --- /dev/null +++ b/client/components/admin/index.tsx @@ -0,0 +1,79 @@ +import { Text, Fieldset, Spacer, Link } from '@geist-ui/core' +import getPostPath from '@lib/get-post-path' +import { Post, User } from '@lib/types' +import Cookies from 'js-cookie' +import useSWR from 'swr' +import styles from './admin.module.css' +const fetcher = (url: string) => fetch(url, { + method: "GET", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${Cookies.get('drift-token')}`, + } +}).then(res => res.json()) + +const Admin = () => { + const { data: posts, error } = useSWR('/server-api/admin/posts', fetcher) + const { data: users, error: errorUsers } = useSWR('/server-api/admin/users', fetcher) + console.log(posts, error) + return ( +
+ Administration +
+ Users + {users && {users.length} users} + {!users && Loading...} + {users && + + + + + + + + + + {users?.map(user => ( + + + + + + + ))} + +
UsernamePostsCreatedRole
{user.username}{user.posts?.length}{new Date(user.createdAt).toLocaleDateString()} {new Date(user.createdAt).toLocaleTimeString()}{user.role}
} + +
+ +
+ Posts + {posts && {posts.length} posts} + {!posts && Loading...} + {posts && + + + + + + + + + + {posts?.map(post => ( + + + + + + + ))} + +
TitleVisibilityCreatedAuthor
{post.title}{post.visibility}{new Date(post.createdAt).toLocaleDateString()} {new Date(post.createdAt).toLocaleTimeString()}{post.users ? post.users[0].username : ''}
} +
+ +
+ ) +} + +export default Admin \ No newline at end of file diff --git a/client/components/header/header.tsx b/client/components/header/header.tsx index fb66531d..a0d35949 100644 --- a/client/components/header/header.tsx +++ b/client/components/header/header.tsx @@ -15,15 +15,15 @@ import SignUpIcon from '@geist-ui/icons/userPlus'; import NewIcon from '@geist-ui/icons/plusCircle'; import YourIcon from '@geist-ui/icons/list' import MoonIcon from '@geist-ui/icons/moon'; -// import SettingsIcon from '@geist-ui/icons/settings'; +import SettingsIcon from '@geist-ui/icons/settings'; import SunIcon from '@geist-ui/icons/sun'; import { useTheme } from "next-themes" import { Button } from "@geist-ui/core"; +import useUserData from "@lib/hooks/use-user-data"; type Tab = { name: string icon: JSX.Element - condition?: boolean value: string onClick?: () => void href?: string @@ -37,6 +37,7 @@ const Header = () => { const [, setBodyHidden] = useBodyScroll(null, { scrollLayer: true }) const isMobile = useMediaQuery('xs', { match: 'down' }) const { signedIn: isSignedIn, signout } = useSignedIn() + const userData = useUserData(); const [pages, setPages] = useState([]) const { setTheme, theme } = useTheme() useEffect(() => { @@ -55,7 +56,6 @@ const Header = () => { name: isMobile ? "GitHub" : "", href: "https://github.com/maxleiter/drift", icon: , - condition: true, value: "github" }, { @@ -65,7 +65,6 @@ const Header = () => { setTheme(theme === 'light' ? 'dark' : 'light'); }, icon: theme === 'light' ? : , - condition: true, value: "theme", } ] @@ -120,9 +119,20 @@ const Header = () => { }, ...defaultPages ]) + if (userData?.role === "admin") { + setPages((pages) => [ + ...pages, + { + name: 'admin', + icon: , + value: 'admin', + href: '/admin' + } + ]) + } // TODO: investigate deps causing infinite loop // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isMobile, isSignedIn, theme]) + }, [isMobile, isSignedIn, theme, userData]) const onTabChange = useCallback((tab: string) => { if (typeof window === 'undefined') return diff --git a/client/components/settings/index.tsx b/client/components/settings/index.tsx deleted file mode 100644 index 1fcb2eda..00000000 --- a/client/components/settings/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Button, Text, Fieldset } from '@geist-ui/core' - -const Settings = () => { - - return ( -
- Settings - -
- Custom Theme - - Drift currently supports theming by overriding CSS variables. - - - {/* */} - -
- - -
- ) -} - -export default Settings \ No newline at end of file diff --git a/client/lib/hooks/use-user-data.ts b/client/lib/hooks/use-user-data.ts new file mode 100644 index 00000000..d823085c --- /dev/null +++ b/client/lib/hooks/use-user-data.ts @@ -0,0 +1,41 @@ +import { User } from "@lib/types"; +import Cookies from "js-cookie"; +import { useRouter } from "next/router"; +import { useEffect, useMemo, useState } from "react"; + +const useUserData = () => { + const [authToken, setAuthToken] = useState(Cookies.get("drift-token") || ''); + const [user, setUser] = useState(); + const router = useRouter() + useEffect(() => { + const token = Cookies.get("drift-token") + if (token) { + setAuthToken(token) + } + }, [setAuthToken]) + + useEffect(() => { + if (authToken) { + const fetchUser = async () => { + const response = await fetch(`/server-api/users/self`, { + headers: { + "Authorization": `Bearer ${authToken}` + } + }) + if (response.ok) { + const user = await response.json() + setUser(user) + } else { + Cookies.remove("drift-token") + setAuthToken("") + router.push("/") + } + } + fetchUser() + } + }, [authToken, router]) + + return user; +} + +export default useUserData \ No newline at end of file diff --git a/client/lib/types.d.ts b/client/lib/types.d.ts index d29bf200..cf35bb38 100644 --- a/client/lib/types.d.ts +++ b/client/lib/types.d.ts @@ -29,4 +29,7 @@ export type Post = { type User = { id: string username: string + posts?: Post[] + role: "admin" | "user" | "" + createdAt: string } diff --git a/client/pages/admin.tsx b/client/pages/admin.tsx new file mode 100644 index 00000000..80184ea2 --- /dev/null +++ b/client/pages/admin.tsx @@ -0,0 +1,58 @@ +import styles from '@styles/Home.module.css' + +import Header from '@components/header' +import { Page } from '@geist-ui/core'; +import { useEffect } from 'react'; +import Admin from '@components/admin'; +import useSignedIn from '@lib/hooks/use-signed-in'; +import { useRouter } from 'next/router'; +import { GetServerSideProps } from 'next'; +import cookie from "cookie"; + +const AdminPage = () => { + const { signedIn } = useSignedIn() + const router = useRouter() + useEffect(() => { + if (typeof window === 'undefined') return + if (!signedIn) { + router.push('/') + } + }, [router, signedIn]) + return ( + + +
+ + + + + + ) +} + +export const getServerSideProps: GetServerSideProps = async ({ req }) => { + const driftToken = cookie.parse(req.headers.cookie || '')[`drift-token`] + const res = await fetch(`${process.env.API_URL}/admin/is-admin`, { + headers: { + 'Authorization': `Bearer ${driftToken}`, + 'x-secret-key': process.env.SECRET_KEY || '' + } + }) + + if (res.ok) { + return { + props: { + signedIn: true + } + } + } else { + return { + redirect: { + destination: '/', + permanent: false + } + } + } +} + +export default AdminPage diff --git a/client/pages/mine.tsx b/client/pages/mine.tsx index ec78c9f8..4c795fc0 100644 --- a/client/pages/mine.tsx +++ b/client/pages/mine.tsx @@ -41,6 +41,7 @@ export const getServerSideProps: GetServerSideProps = async ({ req }) => { }) if (!posts.ok) { + console.error(await posts.json()) return { redirect: { destination: '/', diff --git a/client/pages/settings.tsx b/client/pages/settings.tsx deleted file mode 100644 index 66ac5dcd..00000000 --- a/client/pages/settings.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import styles from '@styles/Home.module.css' - -import Header from '@components/header' -import { Page } from '@geist-ui/core'; -import { useEffect } from 'react'; -import Settings from '@components/settings'; -import useSignedIn from '@lib/hooks/use-signed-in'; -import { useRouter } from 'next/router'; - -const SettingsPage = () => { - const { signedIn } = useSignedIn() - const router = useRouter() - useEffect(() => { - console.log("here", signedIn) - if (typeof window === 'undefined') return - if (!signedIn) { - console.log("here") - router.push('/') - } - }, [router, signedIn]) - return ( - - -
- - - - - - ) -} -export default SettingsPage diff --git a/server/127.0.0.1 b/server/127.0.0.1 deleted file mode 100644 index e5f2b6ec6e6489290ed59bc8f032b6ae4c849958..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI#%}T>S5C`y0Dk?%rZ@rGEHU~?ZSizfXNwGAEHcf?|nn+fNqz!Eo5O2PLFXXfM z8XnD-BIIJP7XAbKF)X|6{`NGJv6JM2p0o8L%E@94rYP)&h%r{%wQ|^oQuar?xg2D^ zFKVna`lxH)Ow|TV8)%>VHeekB5P$##AOHafKmY;|fB*y_@P7pg<)qnaDern7J*8qI zR)t8DH{psrsw8UPw|QVwz;7L!!pd4m?Qj__L`aX^@85C1ZT5OPdG`T%Q^%pHHylrG zdhmxX_h&S+XZp2z+;m$COO~;C-K^5GlAlLKo^A7a<@9;ClFHitRC?BB*I-Qhk`n|3 zAOHafKmY;|fB*y_009U<00M_8aBdo=X;|i!VRbF*@}k&?HIHLIOGW2pb0!~!`u{M$ e7Pp1~1Rwwb2tWV=5P$##AOHaf{0jVC|Nj6}U{-tp diff --git a/server/Dockerfile b/server/Dockerfile deleted file mode 100644 index a61abac1..00000000 --- a/server/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -# Install dependencies only when needed -FROM node:16-alpine AS deps -# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. -RUN apk add --no-cache libc6-compat git -WORKDIR /app -COPY package.json yarn.lock tsconfig.json tslint.json ./ -RUN yarn install --frozen-lockfile - -# If using npm with a `package-lock.json` comment out above and use below instead -# COPY package.json package-lock.json ./ -# RUN npm ci - -# Rebuild the source code only when needed -FROM node:16-alpine AS builder -WORKDIR /app -COPY --from=deps /app/node_modules ./node_modules -COPY . . - -RUN yarn build - -FROM node:16-alpine AS runner -WORKDIR /app - -ENV NODE_ENV production - -RUN addgroup --system --gid 1001 nodejs -RUN adduser --system --uid 1001 drift - -COPY --from=builder /app/dist ./dist -COPY --from=builder /app/node_modules ./node_modules - -USER drift - -EXPOSE 3000 - -ENV PORT 3000 - -CMD ["node", "dist/index.js"] diff --git a/server/config/config.js b/server/config/config.js index 6af874e8..fcff1476 100644 --- a/server/config/config.js +++ b/server/config/config.js @@ -1,12 +1,7 @@ const path = require("path") -console.log(path.join(__dirname, "..", "drift.sqlite")) module.exports = { production: { database: path.join(__dirname, "..", "drift.sqlite"), - host: "127.0.0.1", - port: "3306", - user: "root", - password: "root", dialect: "sqlite" }, development: { diff --git a/server/package.json b/server/package.json index ba4476cd..b371e7e4 100644 --- a/server/package.json +++ b/server/package.json @@ -1,51 +1,53 @@ { - "name": "sequelize-typescript-starter", - "version": "1.0.0", - "description": "", - "main": "index.ts", - "scripts": { - "start": "ts-node index.ts", - "dev": "nodemon index.ts", - "build": "tsc -p .", - "migrate": "sequelize db:migrate", - "lint": "prettier --config .prettierrc 'src/**/*.ts' 'index.ts' --write" - }, - "author": "", - "license": "ISC", - "dependencies": { - "bcrypt": "^5.0.1", - "body-parser": "^1.18.2", - "celebrate": "^15.0.1", - "cors": "^2.8.5", - "dotenv": "^16.0.0", - "express": "^4.16.2", - "express-jwt": "^6.1.1", - "jsonwebtoken": "^8.5.1", - "marked": "^4.0.12", - "nodemon": "^2.0.15", - "prism-react-renderer": "^1.3.1", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "reflect-metadata": "^0.1.10", - "sequelize": "^6.17.0", - "sequelize-auto-migrations-v2": "^1.2.1", - "sequelize-typescript": "^2.1.3", - "sqlite3": "https://github.com/mapbox/node-sqlite3#918052b538b0effe6c4a44c74a16b2749c08a0d2", - "strong-error-handler": "^4.0.0" - }, - "devDependencies": { - "@types/bcrypt": "^5.0.0", - "@types/cors": "^2.8.12", - "@types/express": "^4.0.39", - "@types/express-jwt": "^6.0.4", - "@types/jsonwebtoken": "^8.5.8", - "@types/marked": "^4.0.3", - "@types/node": "^17.0.21", - "@types/react-dom": "^17.0.14", - "prettier": "^2.6.0", - "ts-node": "^10.6.0", - "tsconfig-paths": "^3.14.1", - "tslint": "^6.1.3", - "typescript": "^4.6.2" - } + "name": "sequelize-typescript-starter", + "version": "1.0.0", + "description": "", + "main": "index.ts", + "scripts": { + "start": "ts-node index.ts", + "dev": "nodemon index.ts", + "build": "tsc -p .", + "migrate": "sequelize-cli-ts db:migrate", + "migrate:undo": "sequelize-cli-ts db:migrate:undo", + "lint": "prettier --config .prettierrc 'src/**/*.ts' 'index.ts' --write" + }, + "author": "", + "license": "ISC", + "dependencies": { + "bcrypt": "^5.0.1", + "body-parser": "^1.18.2", + "celebrate": "^15.0.1", + "cors": "^2.8.5", + "dotenv": "^16.0.0", + "express": "^4.16.2", + "express-jwt": "^6.1.1", + "jsonwebtoken": "^8.5.1", + "marked": "^4.0.12", + "nodemon": "^2.0.15", + "prism-react-renderer": "^1.3.1", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "reflect-metadata": "^0.1.10", + "sequelize": "^6.17.0", + "sequelize-cli-ts": "^5.5.2", + "sequelize-typescript": "^2.1.3", + "sqlite3": "https://github.com/mapbox/node-sqlite3#918052b538b0effe6c4a44c74a16b2749c08a0d2", + "strong-error-handler": "^4.0.0", + "umzug": "^3.1.0" + }, + "devDependencies": { + "@types/bcrypt": "^5.0.0", + "@types/cors": "^2.8.12", + "@types/express": "^4.0.39", + "@types/express-jwt": "^6.0.4", + "@types/jsonwebtoken": "^8.5.8", + "@types/marked": "^4.0.3", + "@types/node": "^17.0.21", + "@types/react-dom": "^17.0.14", + "prettier": "^2.6.0", + "ts-node": "^10.6.0", + "tsconfig-paths": "^3.14.1", + "tslint": "^6.1.3", + "typescript": "^4.6.2" + } } diff --git a/server/src/app.ts b/server/src/app.ts index 879ee99a..ce811085 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -1,7 +1,7 @@ import * as express from "express" import * as bodyParser from "body-parser" import * as errorhandler from "strong-error-handler" -import { posts, users, auth, files } from "@routes/index" +import { posts, users, auth, files, admin } from "@routes/index" import { errors } from "celebrate" import secretKey from "@lib/middleware/secret-key" import markdown from "@lib/render-markdown" @@ -15,6 +15,7 @@ app.use("/auth", auth) app.use("/posts", posts) app.use("/users", users) app.use("/files", files) +app.use("/admin", admin) app.get("/welcome", secretKey, (req, res) => { const introContent = process.env.WELCOME_CONTENT diff --git a/server/src/database.ts b/server/src/database.ts new file mode 100644 index 00000000..ad42db2e --- /dev/null +++ b/server/src/database.ts @@ -0,0 +1,36 @@ +import { Sequelize } from "sequelize-typescript" +import { SequelizeStorage, Umzug } from "umzug" + +export const sequelize = new Sequelize({ + dialect: "sqlite", + database: "drift", + storage: + process.env.MEMORY_DB === "true" + ? ":memory:" + : __dirname + "/../drift.sqlite", + models: [__dirname + "/lib/models"], + logging: true +}) + +const umzug = new Umzug({ + migrations: { glob: __dirname + "/migrations/*.ts" }, + context: sequelize.getQueryInterface(), + storage: new SequelizeStorage({ sequelize }), + logger: console +}) + +export type Migration = typeof umzug._types.migration + + ; (async () => { + // Checks migrations and run them if they are not already applied. To keep + // track of the executed migrations, a table (and sequelize model) called SequelizeMeta + // will be automatically created (if it doesn't exist already) and parsed. + console.log("Checking migrations...") + const migrations = await umzug.up() + if (migrations.length > 0) { + console.log("Migrations applied:") + console.log(migrations) + } else { + console.log("No migrations applied.") + } + })() diff --git a/server/src/lib/middleware/is-admin.ts b/server/src/lib/middleware/is-admin.ts new file mode 100644 index 00000000..f3c198a8 --- /dev/null +++ b/server/src/lib/middleware/is-admin.ts @@ -0,0 +1,42 @@ +import { NextFunction, Request, Response } from "express" +import * as jwt from "jsonwebtoken" +import config from "../config" +import { User as UserModel } from "../models/User" + +export interface User { + id: string +} + +export interface UserJwtRequest extends Request { + user?: User +} + +export default function authenticateToken( + req: UserJwtRequest, + res: Response, + next: NextFunction +) { + const authHeader = req.headers["authorization"] + const token = authHeader && authHeader.split(" ")[1] + console.log(token, process.env.ENABLE_ADMIN) + if (token == null) return res.sendStatus(401) + if (!process.env.ENABLE_ADMIN) return res.sendStatus(404) + + jwt.verify(token, config.jwt_secret, async (err: any, user: any) => { + if (err) return res.sendStatus(403) + const userObj = await UserModel.findByPk(user.id, { + attributes: { + exclude: ["password"], + } + }) + + console.log(userObj) + if (!userObj || userObj.role !== 'admin') { + return res.sendStatus(403) + } + + req.user = userObj + + next() + }) +} diff --git a/server/src/lib/middleware/jwt.ts b/server/src/lib/middleware/jwt.ts index 1de91fef..ca7d1582 100644 --- a/server/src/lib/middleware/jwt.ts +++ b/server/src/lib/middleware/jwt.ts @@ -23,7 +23,11 @@ export default function authenticateToken( jwt.verify(token, config.jwt_secret, async (err: any, user: any) => { if (err) return res.sendStatus(403) - const userObj = await UserModel.findByPk(user.id) + const userObj = await UserModel.findByPk(user.id, { + attributes: { + exclude: ["password"] + } + }) if (!userObj) { return res.sendStatus(403) } diff --git a/server/src/lib/models/File.ts b/server/src/lib/models/File.ts index f8c7e756..db7f0f11 100644 --- a/server/src/lib/models/File.ts +++ b/server/src/lib/models/File.ts @@ -28,7 +28,11 @@ import { User } from "./User" ] } })) -@Table + +@Table({ + tableName: "files", +}) + export class File extends Model { @IsUUID(4) @PrimaryKey @@ -51,14 +55,20 @@ export class File extends Model { @Column html!: string - @ForeignKey(() => User) @BelongsTo(() => User, "userId") user!: User - @ForeignKey(() => Post) @BelongsTo(() => Post, "postId") post!: Post + @ForeignKey(() => User) + @Column + userId!: number + + @ForeignKey(() => Post) + @Column + postId!: number + @CreatedAt @Column createdAt!: Date diff --git a/server/src/lib/models/Post.ts b/server/src/lib/models/Post.ts index ed5a8bc6..93dd39ff 100644 --- a/server/src/lib/models/Post.ts +++ b/server/src/lib/models/Post.ts @@ -38,7 +38,11 @@ import { File } from "./File" ] } })) -@Table +@Table( + { + tableName: "posts", + } +) export class Post extends Model { @IsUUID(4) @PrimaryKey diff --git a/server/src/lib/models/PostAuthor.ts b/server/src/lib/models/PostAuthor.ts index 0d4eeec5..eae891ac 100644 --- a/server/src/lib/models/PostAuthor.ts +++ b/server/src/lib/models/PostAuthor.ts @@ -11,7 +11,10 @@ import { import { Post } from "./Post" import { User } from "./User" -@Table +@Table({ + tableName: "post_authors", +}) + export class PostAuthor extends Model { @IsUUID(4) @PrimaryKey @@ -28,5 +31,5 @@ export class PostAuthor extends Model { @ForeignKey(() => User) @Column - authorId!: number + userId!: number } diff --git a/server/src/lib/models/User.ts b/server/src/lib/models/User.ts index 17c8a750..63d90bab 100644 --- a/server/src/lib/models/User.ts +++ b/server/src/lib/models/User.ts @@ -29,7 +29,10 @@ import { PostAuthor } from "./PostAuthor" } } })) -@Table +@Table({ + tableName: "users", +}) + export class User extends Model { @IsUUID(4) @PrimaryKey @@ -56,4 +59,7 @@ export class User extends Model { @UpdatedAt @Column updatedAt!: Date + + @Column + role!: string } diff --git a/server/src/lib/sequelize.ts b/server/src/lib/sequelize.ts deleted file mode 100644 index 261724af..00000000 --- a/server/src/lib/sequelize.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Sequelize } from "sequelize-typescript" - -export const sequelize = new Sequelize({ - dialect: "sqlite", - database: "drift", - storage: - process.env.MEMORY_DB === "true" - ? ":memory:" - : __dirname + "/../../drift.sqlite", - models: [__dirname + "/models"], - host: "localhost" -}) diff --git a/server/src/migrations/00_user-table.ts b/server/src/migrations/00_user-table.ts new file mode 100644 index 00000000..f0f01ab0 --- /dev/null +++ b/server/src/migrations/00_user-table.ts @@ -0,0 +1,31 @@ +"use strict" +import { DataTypes } from "sequelize" +import type { Migration } from "../database" + +export const up: Migration = async ({ context: queryInterface }) => + queryInterface.createTable("users", { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + unique: true + }, + username: { + type: DataTypes.STRING, + }, + password: { + type: DataTypes.STRING, + }, + createdAt: { + type: DataTypes.DATE, + }, + updatedAt: { + type: DataTypes.DATE, + }, + deletedAt: { + type: DataTypes.DATE, + } + }) + +export const down: Migration = async ({ context: queryInterface }) => + queryInterface.dropTable("users") diff --git a/server/src/migrations/01_user-add-role.ts b/server/src/migrations/01_user-add-role.ts new file mode 100644 index 00000000..186aa629 --- /dev/null +++ b/server/src/migrations/01_user-add-role.ts @@ -0,0 +1,12 @@ +"use strict" +import { DataTypes } from "sequelize" +import type { Migration } from "../database" + +export const up: Migration = async ({ context: queryInterface }) => + queryInterface.addColumn("users", "role", { + type: DataTypes.STRING, + defaultValue: "user" + }) + +export const down: Migration = async ({ context: queryInterface }) => + queryInterface.removeColumn("users", "role") diff --git a/server/src/migrations/02_post_table.ts b/server/src/migrations/02_post_table.ts new file mode 100644 index 00000000..d751ea5b --- /dev/null +++ b/server/src/migrations/02_post_table.ts @@ -0,0 +1,34 @@ +"use strict" +import { DataTypes } from "sequelize" +import type { Migration } from "../database" + +export const up: Migration = async ({ context: queryInterface }) => + queryInterface.createTable("posts", { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + unique: true + }, + title: { + type: DataTypes.STRING, + }, + visibility: { + type: DataTypes.STRING, + }, + password: { + type: DataTypes.STRING, + }, + createdAt: { + type: DataTypes.DATE, + }, + updatedAt: { + type: DataTypes.DATE, + }, + deletedAt: { + type: DataTypes.DATE, + } + }) + +export const down: Migration = async ({ context: queryInterface }) => + await queryInterface.dropTable("posts") diff --git a/server/src/migrations/03_files_table.ts b/server/src/migrations/03_files_table.ts new file mode 100644 index 00000000..294bd627 --- /dev/null +++ b/server/src/migrations/03_files_table.ts @@ -0,0 +1,59 @@ +"use strict" +import { DataTypes } from "sequelize" +import type { Migration } from "../database" + +export const up: Migration = async ({ context: queryInterface }) => + queryInterface.createTable("files", { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + allowNull: false, + unique: true + }, + title: { + type: DataTypes.STRING, + }, + content: { + type: DataTypes.STRING, + }, + sha: { + type: DataTypes.STRING, + + }, + html: { + type: DataTypes.STRING, + }, + createdAt: { + type: DataTypes.DATE, + }, + updatedAt: { + type: DataTypes.DATE, + }, + deletedAt: { + type: DataTypes.DATE, + }, + userId: { + type: DataTypes.UUID, + allowNull: false, + references: { + model: "users", + key: "id" + }, + onDelete: "SET NULL", + onUpdate: "CASCADE" + }, + postId: { + type: DataTypes.UUID, + allowNull: false, + references: { + model: "posts", + key: "id" + }, + onDelete: "SET NULL", + onUpdate: "CASCADE" + } + }) + +export const down: Migration = async ({ context: queryInterface }) => + await queryInterface.dropTable("files") diff --git a/server/src/migrations/04_post_authors_table.ts b/server/src/migrations/04_post_authors_table.ts new file mode 100644 index 00000000..6b4d4ccd --- /dev/null +++ b/server/src/migrations/04_post_authors_table.ts @@ -0,0 +1,41 @@ +"use strict" +import { DataTypes } from "sequelize" +import type { Migration } from "../database" + +export const up: Migration = async ({ context: queryInterface }) => + queryInterface.createTable("post_authors", { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + }, + createdAt: { + type: DataTypes.DATE, + }, + updatedAt: { + type: DataTypes.DATE, + }, + postId: { + type: DataTypes.UUID, + primaryKey: true, + references: { + model: "posts", + key: "id" + }, + onDelete: "CASCADE", + onUpdate: "CASCADE" + }, + userId: { + type: DataTypes.UUID, + primaryKey: true, + references: { + model: "users", + key: "id" + }, + onDelete: "CASCADE", + onUpdate: "CASCADE" + } + }) + +export const down: Migration = async ({ context: queryInterface }) => + await queryInterface.dropTable("post_authors") diff --git a/server/src/routes/admin.ts b/server/src/routes/admin.ts new file mode 100644 index 00000000..cf7831e3 --- /dev/null +++ b/server/src/routes/admin.ts @@ -0,0 +1,63 @@ +import isAdmin from "@lib/middleware/is-admin"; +import { Post } from "@lib/models/Post"; +import { User } from "@lib/models/User"; +import { File } from "@lib/models/File"; +import { Router } from "express"; + +export const admin = Router() + +admin.use(isAdmin) + +admin.get("/is-admin", async (req, res) => { + return res.json({ + isAdmin: true + }) +}) + +admin.get("/users", async (req, res, next) => { + try { + const users = await User.findAll({ + attributes: { + exclude: ["password"], + include: ["id", "username", "createdAt", "updatedAt"] + }, + include: [ + { + model: Post, + as: "posts", + attributes: ["id"] + } + ], + }) + res.json(users) + } catch (e) { + next(e) + } +}) + +admin.get("/posts", async (req, res, next) => { + try { + const posts = await Post.findAll({ + attributes: { + exclude: ["content"], + include: ["id", "title", "visibility", "createdAt"] + }, + include: [ + { + model: File, + as: "files", + attributes: ["id", "title", "content", "sha", "createdAt", "updatedAt"] + }, + { + model: User, + as: "users", + attributes: ["id", "username"] + } + ] + }) + res.json(posts) + } catch (e) { + next(e) + } +}) + diff --git a/server/src/routes/auth.ts b/server/src/routes/auth.ts index 16045930..6197191d 100644 --- a/server/src/routes/auth.ts +++ b/server/src/routes/auth.ts @@ -63,9 +63,12 @@ auth.post( } const salt = await genSalt(10) + const { count } = await User.findAndCountAll() + const user = { username: username as string, - password: await hash(req.body.password, salt) + password: await hash(req.body.password, salt), + role: (!process.env.MEMORY_DB && process.env.ENABLE_ADMIN && count === 0) ? "admin" : "user" } const created_user = await User.create(user) diff --git a/server/src/routes/index.ts b/server/src/routes/index.ts index 415b51fa..c2c4628e 100644 --- a/server/src/routes/index.ts +++ b/server/src/routes/index.ts @@ -2,3 +2,4 @@ export { auth } from "./auth" export { posts } from "./posts" export { users } from "./users" export { files } from "./files" +export { admin } from "./admin" diff --git a/server/src/routes/users.ts b/server/src/routes/users.ts index 0ccc0b10..a74a443b 100644 --- a/server/src/routes/users.ts +++ b/server/src/routes/users.ts @@ -1,14 +1,31 @@ import { Router } from "express" -// import jwt from "@lib/middleware/jwt"; -// import { User } from "@lib/models/User"; +import jwt, { UserJwtRequest } from "@lib/middleware/jwt" +import { User } from "@lib/models/User" export const users = Router() -// users.get("/", jwt, async (req, res, next) => { -// try { -// const allUsers = await User.findAll(); -// res.json(allUsers); -// } catch (error) { -// next(error); -// } -// }); +users.get("/self", jwt, async (req: UserJwtRequest, res, next) => { + const error = () => + res.status(401).json({ + message: "Unauthorized" + }) + + try { + if (!req.user) { + return error() + } + + const user = await User.findByPk(req.user?.id, { + attributes: { + exclude: ["password"] + } + }) + if (!user) { + return error() + } + + res.json(user) + } catch (error) { + next(error) + } +}) diff --git a/server/src/server.ts b/server/src/server.ts index 4d729ec8..2296b12b 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -1,10 +1,10 @@ import { createServer } from "http" import { app } from "./app" import config from "./lib/config" -import { sequelize } from "./lib/sequelize" -;(async () => { - await sequelize.sync({}) - createServer(app).listen(config.port, () => - console.info(`Server running on port ${config.port}`) - ) -})() +import "./database" + ; (async () => { + // await sequelize.sync() + createServer(app).listen(config.port, () => + console.info(`Server running on port ${config.port}`) + ) + })() diff --git a/server/tsconfig.json b/server/tsconfig.json index 6cf7b311..771446d0 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -1,30 +1,30 @@ { - "compileOnSave": false, - "compilerOptions": { - "target": "es6", - "module": "commonjs", - "moduleResolution": "node", - "jsx": "react-jsxdev", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "noUnusedLocals": true, - "sourceMap": true, - "declaration": false, - "pretty": true, - "strictNullChecks": true, - "skipLibCheck": true, - "strictPropertyInitialization": true, - "outDir": "dist", - "baseUrl": ".", - "paths": { - "@routes/*": ["./src/routes/*"], - "@lib/*": ["./src/lib/*"] - } - }, - "ts-node": { - // Do not forget to `npm i -D tsconfig-paths` - "require": ["tsconfig-paths/register"] - }, - "include": ["index.ts", "src/**/*.ts"], - "exclude": ["node_modules"] + "compileOnSave": false, + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "moduleResolution": "node", + "jsx": "react-jsxdev", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "noUnusedLocals": true, + "sourceMap": true, + "declaration": false, + "pretty": true, + "strictNullChecks": true, + "skipLibCheck": true, + "strictPropertyInitialization": true, + "outDir": "dist", + "baseUrl": ".", + "paths": { + "@routes/*": ["./src/routes/*"], + "@lib/*": ["./src/lib/*"] + } + }, + "ts-node": { + // Do not forget to `npm i -D tsconfig-paths` + "require": ["tsconfig-paths/register"] + }, + "include": ["index.ts", "src/**/*.ts"], + "exclude": ["node_modules"] } diff --git a/server/yarn.lock b/server/yarn.lock index 0fa9fd72..b1d7d568 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -62,6 +62,16 @@ semver "^7.3.5" tar "^6.1.11" +"@rushstack/ts-command-line@^4.7.7": + version "4.10.7" + resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.10.7.tgz#21e3757a756cbd4f7eeab8f89ec028a64d980efc" + integrity sha512-CjS+DfNXUSO5Ab2wD1GBGtUTnB02OglRWGqfaTcac9Jn45V5MeUOsq/wA8wEeS5Y/3TZ2P1k+IWdVDiuOFP9Og== + dependencies: + "@types/argparse" "1.0.38" + argparse "~1.0.9" + colors "~1.2.1" + string-argv "~0.3.1" + "@sideway/address@^4.1.3": version "4.1.3" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.3.tgz#d93cce5d45c5daec92ad76db492cc2ee3c64ab27" @@ -111,6 +121,11 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== +"@types/argparse@1.0.38": + version "1.0.38" + resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" + integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== + "@types/bcrypt@^5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-5.0.0.tgz#a835afa2882d165aff5690893db314eaa98b9f20" @@ -179,16 +194,6 @@ "@types/qs" "*" "@types/serve-static" "*" -"@types/geojson@^1.0.0": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-1.0.6.tgz#3e02972728c69248c2af08d60a48cbb8680fffdf" - integrity sha512-Xqg/lIZMrUd0VRmSRbCAewtwGZiAk3mEUDvV4op1tGl+LvyPcb/MIOSxTl9z+9+J+R4/vpjiCAT4xeKzH9ji1w== - -"@types/geojson@^7946.0.0 || ^1.0.0": - version "7946.0.8" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" - integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== - "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" @@ -325,17 +330,22 @@ ansi-align@^3.0.0: dependencies: string-width "^4.1.0" -ansi-regex@^2.0.0: +ansi-regex@^2.0.0, ansi-regex@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= +ansi-regex@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -388,18 +398,13 @@ arg@^4.1.0: resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== -argparse@^1.0.7: +argparse@^1.0.7, argparse@~1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" -array-back@^3.0.1, array-back@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" - integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== - array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -427,13 +432,6 @@ async@^1.5.0: resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= -async@^2.5.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -479,7 +477,7 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bluebird@^3.4.6, bluebird@^3.5.0: +bluebird@^3.5.3, bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -557,6 +555,11 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" @@ -633,6 +636,27 @@ cli-boxes@^2.2.1: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +cli-color@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-1.4.0.tgz#7d10738f48526824f8fe7da51857cb0f572fe01f" + integrity sha512-xu6RvQqqrWEo6MPR1eixqGPywhYBHRs653F9jfXB2Hx4jdM/3WxiNE1vppRmxtMIfl16SFYTpYlrnqH/HsK/2w== + dependencies: + ansi-regex "^2.1.1" + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + memoizee "^0.4.14" + timers-ext "^0.1.5" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" @@ -640,14 +664,6 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" -cls-bluebird@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cls-bluebird/-/cls-bluebird-2.1.0.tgz#37ef1e080a8ffb55c2f4164f536f1919e7968aee" - integrity sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4= - dependencies: - is-bluebird "^1.0.2" - shimmer "^1.1.0" - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -682,6 +698,11 @@ color-support@^1.1.2: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== +colors@~1.2.1: + version "1.2.5" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.5.tgz#89c7ad9a374bc030df8013241f68136ed8835afc" + integrity sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -689,16 +710,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -command-line-args@^5.0.2: - version "5.2.1" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" - integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== - dependencies: - array-back "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - commander@^2.12.1, commander@^2.19.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -803,6 +814,14 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -810,7 +829,7 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -debug@2.6.9, debug@^2.6.9: +debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -824,13 +843,18 @@ debug@4, debug@^4.1.1, debug@^4.2.0, debug@^4.3.3: dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.2.7: +debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" @@ -838,11 +862,6 @@ decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" -deep-diff@^0.3.8: - version "0.3.8" - resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84" - integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ= - deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -863,7 +882,7 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -depd@^1.1.0, depd@~1.1.2: +depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= @@ -895,7 +914,7 @@ dotenv@^16.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.0.tgz#c619001253be89ebb638d027b609c75c26e47411" integrity sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q== -dottie@^2.0.0, dottie@^2.0.2: +dottie@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.2.tgz#cc91c0726ce3a054ebf11c55fbc92a7f266dd154" integrity sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg== @@ -942,6 +961,16 @@ ejs@^3.1.3: dependencies: jake "^10.6.1" +emittery@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.1.tgz#3d01ab87e2b6542681f8fd6cbd6597a66daa1869" + integrity sha512-OBSS9uVXbpgqEGq2V5VnpfCu9vSnfiR9eYVJmxFYToNIcWRHkM4BAFbJe/PWjf/pQdEL7OPxd2jOW/bJiyX7gg== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -964,6 +993,42 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.59" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.59.tgz#71038939730eb6f4f165f1421308fb60be363bc6" + integrity sha512-cOgyhW0tIJyQY1Kfw6Kr0viu9ZlUctVchRMZ7R0HiH3dxTSp5zJDLecwxUqPUrGKMsgBI1wd1FL+d9Jxfi4cLw== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + escape-goat@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" @@ -989,6 +1054,14 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + execa@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" @@ -1055,6 +1128,13 @@ express@^4.16.2: utils-merge "1.0.1" vary "~1.1.2" +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -1112,12 +1192,12 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-replace@^3.0.0: +find-up@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" - integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: - array-back "^3.0.1" + locate-path "^3.0.0" forever-agent@~0.6.1: version "0.6.1" @@ -1143,6 +1223,23 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-jetpack@^4.1.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/fs-jetpack/-/fs-jetpack-4.3.1.tgz#cdfd4b64e6bfdec7c7dc55c76b39efaa7853bb20" + integrity sha512-dbeOK84F6BiQzk2yqqCVwCPWTxAvVGJ3fMQc6E2wuEohS28mR6yHngbrKuVCK1KHRx/ccByDylqu4H5PCP2urQ== + dependencies: + minimatch "^3.0.2" + rimraf "^2.6.3" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -1194,10 +1291,10 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -generic-pool@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.5.0.tgz#acac4fd743a175ff20574f380910036464cb61f7" - integrity sha512-dEkxmX+egB2o4NR80c/q+xzLLzLX+k68/K8xv81XprD+Sk7ZtP14VugeCz+fUwv5FzpWq40pPtAkzPRqT8ka9w== +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-stream@^4.1.0: version "4.1.0" @@ -1227,7 +1324,7 @@ glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob@7.2.0, glob@^7.0.5, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4: +glob@7.2.0, glob@^7.0.5, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -1270,7 +1367,7 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.2.3: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.3: version "4.2.9" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== @@ -1380,11 +1477,6 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -inflection@1.12.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" - integrity sha1-ogCTVlbW9fa8TcdQLhrstwMihBY= - inflection@^1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.2.tgz#15e8c797c6c3dadf31aa658f8df8a4ea024798b0" @@ -1430,11 +1522,6 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-bluebird@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-bluebird/-/is-bluebird-1.0.2.tgz#096439060f4aa411abee19143a84d6a55346d6e2" - integrity sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI= - is-buffer@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -1466,6 +1553,11 @@ is-fullwidth-code-point@^1.0.0: dependencies: number-is-nan "^1.0.0" +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -1506,6 +1598,11 @@ is-path-inside@^3.0.2: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-promise@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" @@ -1557,7 +1654,7 @@ joi@17.x.x: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" -js-beautify@^1.8.9: +js-beautify@^1.8.8: version "1.14.0" resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.14.0.tgz#2ce790c555d53ce1e3d7363227acf5dc69024c2d" integrity sha512-yuck9KirNSCAwyNJbqW+BxJqJ0NLJ4PwBUzQQACl5O3qHMBXVkXb/rD0ilh/Lat/tn88zSZ+CAHOlk0DsY7GuQ== @@ -1619,6 +1716,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + jsonwebtoken@^8.1.0, jsonwebtoken@^8.5.1: version "8.5.1" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" @@ -1683,10 +1787,13 @@ lcid@^3.0.0: dependencies: invert-kv "^3.0.0" -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" lodash.includes@^4.3.0: version "4.3.0" @@ -1723,7 +1830,7 @@ lodash.once@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash@4.17.x, lodash@^4.17.1, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.20, lodash@^4.17.21: +lodash@4.17.x, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -1760,6 +1867,13 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= + dependencies: + es5-ext "~0.10.2" + make-dir@^3.0.0, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -1807,6 +1921,20 @@ mem@^5.0.0: mimic-fn "^2.1.0" p-is-promise "^2.1.0" +memoizee@^0.4.14: + version "0.4.15" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" + integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ== + dependencies: + d "^1.0.1" + es5-ext "^0.10.53" + es6-weak-map "^2.0.3" + event-emitter "^0.3.5" + is-promise "^2.2.2" + lru-queue "^0.1.0" + next-tick "^1.1.0" + timers-ext "^0.1.7" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -1849,7 +1977,7 @@ mimic-response@^1.0.0, mimic-response@^1.0.1: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== -minimatch@^3.0.4: +minimatch@^3.0.2, minimatch@^3.0.4: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -1893,14 +2021,14 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -moment-timezone@^0.5.14, moment-timezone@^0.5.34: +moment-timezone@^0.5.34: version "0.5.34" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.34.tgz#a75938f7476b88f155d3504a9343f7519d9a405c" integrity sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg== dependencies: moment ">= 2.9.0" -"moment@>= 2.9.0", moment@^2.20.0, moment@^2.29.1: +"moment@>= 2.9.0", moment@^2.29.1: version "2.29.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== @@ -1925,6 +2053,11 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +next-tick@1, next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + node-addon-api@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" @@ -2040,11 +2173,6 @@ object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -object-hash@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" - integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== - on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -2090,6 +2218,25 @@ p-is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + package-json@^6.3.0: version "6.5.0" resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" @@ -2105,6 +2252,11 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -2140,6 +2292,11 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pony-cause@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pony-cause/-/pony-cause-1.1.1.tgz#f795524f83bebbf1878bd3587b45f69143cbf3f9" + integrity sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g== + prepend-http@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" @@ -2334,7 +2491,17 @@ request@^2.88.2: tunnel-agent "^0.6.0" uuid "^3.3.2" -resolve@^1.3.2: +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve@^1.3.2, resolve@^1.5.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== @@ -2350,19 +2517,18 @@ responselike@^1.0.2: dependencies: lowercase-keys "^1.0.0" -retry-as-promised@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-2.3.2.tgz#cd974ee4fd9b5fe03cbf31871ee48221c07737b7" - integrity sha1-zZdO5P2bX+A8vzGHHuSCIcB3N7c= - dependencies: - bluebird "^3.4.6" - debug "^2.6.9" - retry-as-promised@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-5.0.0.tgz#f4ecc25133603a2d2a7aff4a128691d7bc506d54" integrity sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA== +rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -2400,7 +2566,7 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -semver@^5.3.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: +semver@^5.3.0, semver@^5.6.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -2436,18 +2602,19 @@ send@0.17.2: range-parser "~1.2.1" statuses "~1.5.0" -sequelize-auto-migrations-v2@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/sequelize-auto-migrations-v2/-/sequelize-auto-migrations-v2-1.2.1.tgz#0f5c68af9a1ad5697ac574eea06a4c7c65165de6" - integrity sha512-5ZeXZgW9Ea+reAnDRSikIoB0It78TjYYPAE2sIUjgUPTBNQgW4ftvK2btsXLfjEK3sP0U7nbHIrz4n01qqJfmg== +sequelize-cli-ts@^5.5.2: + version "5.5.2" + resolved "https://registry.yarnpkg.com/sequelize-cli-ts/-/sequelize-cli-ts-5.5.2.tgz#923bc92c348f6f01355ea56677318a1892cc6a26" + integrity sha512-NBK8WmC7igLCPJG+kEaRJFHleBtV3hZpH+gN+4vOZpTsDfq1wldPbvQoAILyovU13JWna3NtCGyyuBKp1gvmBA== dependencies: - async "^2.5.1" - command-line-args "^5.0.2" - deep-diff "^0.3.8" - js-beautify "^1.8.9" - lodash "^4.17.11" - object-hash "^1.3.1" - sequelize "^4.42.0" + bluebird "^3.5.3" + cli-color "^1.4.0" + fs-extra "^7.0.1" + js-beautify "^1.8.8" + lodash "^4.17.5" + resolve "^1.5.0" + umzug "^2.1.0" + yargs "^13.1.0" sequelize-pool@^7.1.0: version "7.1.0" @@ -2461,29 +2628,6 @@ sequelize-typescript@^2.1.3: dependencies: glob "7.2.0" -sequelize@^4.42.0: - version "4.44.4" - resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-4.44.4.tgz#9607eaa3e59080d27d8b17481d2e449e87e58f18" - integrity sha512-nkHmYkbwQK7uwpgW9VBalCBnQqQ8mslTdgcBthtJLORuPvAYRPlfkXZMVUU9TLLJt9CX+/y0MYg0DpcP6ywsEQ== - dependencies: - bluebird "^3.5.0" - cls-bluebird "^2.1.0" - debug "^3.1.0" - depd "^1.1.0" - dottie "^2.0.0" - generic-pool "3.5.0" - inflection "1.12.0" - lodash "^4.17.1" - moment "^2.20.0" - moment-timezone "^0.5.14" - retry-as-promised "^2.3.2" - semver "^5.5.0" - terraformer-wkt-parser "^1.1.2" - toposort-class "^1.0.1" - uuid "^3.2.1" - validator "^10.4.0" - wkx "^0.4.1" - sequelize@^6.17.0: version "6.17.0" resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.17.0.tgz#78a21f39b8a7548c65c0cc2055e8231137c679a3" @@ -2538,11 +2682,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shimmer@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" - integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== - sigmund@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" @@ -2592,6 +2731,11 @@ stable@^0.1.6: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +string-argv@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -2610,6 +2754,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -2631,6 +2784,13 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -2712,20 +2872,13 @@ tar@^6.0.2, tar@^6.1.11: mkdirp "^1.0.3" yallist "^4.0.0" -terraformer-wkt-parser@^1.1.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/terraformer-wkt-parser/-/terraformer-wkt-parser-1.2.1.tgz#8041e2aeb0c9f2b4cbbec8ec2c5c00c45ddfee02" - integrity sha512-+CJyNLWb3lJ9RsZMTM66BY0MT3yIo4l4l22Jd9CrZuwzk54fsu4Sc7zejuS9fCITTuTQy3p06d4MZMVI7v5wSg== +timers-ext@^0.1.5, timers-ext@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== dependencies: - "@types/geojson" "^1.0.0" - terraformer "~1.0.5" - -terraformer@~1.0.5: - version "1.0.12" - resolved "https://registry.yarnpkg.com/terraformer/-/terraformer-1.0.12.tgz#39e08f9c753606421acce02e122440c72dfa12d3" - integrity sha512-MokUp0+MFal4CmJDVL6VAO1bKegeXcBM2RnPVfqcFIp2IIv8EbPAjG0j/vEy/vuKB8NVMMSF2vfpVS/QLe4DBg== - optionalDependencies: - "@types/geojson" "^7946.0.0 || ^1.0.0" + es5-ext "~0.10.46" + next-tick "1" to-readable-stream@^1.0.0: version "1.0.0" @@ -2846,6 +2999,11 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-fest@^2.0.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.12.1.tgz#d2be8f50bf5f8f0a5fd916d29bf3e98c17e960be" + integrity sha512-AiknQSEqKVGDDjtZqeKrUoTlcj7FKhupmnVUgz6KoOKtvMwRGE6hUNJ/nVear+h7fnUPO1q/htSkYKb1pyntkQ== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -2854,6 +3012,16 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -2866,10 +3034,24 @@ typescript@^4.6.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4" integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg== -typical@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== +umzug@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/umzug/-/umzug-2.3.0.tgz#0ef42b62df54e216b05dcaf627830a6a8b84a184" + integrity sha512-Z274K+e8goZK8QJxmbRPhl89HPO1K+ORFtm6rySPhFKfKc5GHhqdzD0SGhSWHkzoXasqJuItdhorSvY7/Cgflw== + dependencies: + bluebird "^3.7.2" + +umzug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/umzug/-/umzug-3.1.0.tgz#81149cad74f0e10ad0c9908244a164561a969ce9" + integrity sha512-Ox/D/N4VuWBrLbRPWrF/x0pIETmpNakKP+Jna1ZrfJDiLQyYwbTTayPd5NEtfjSSz9JG2DOOKie251Vu6teKWw== + dependencies: + "@rushstack/ts-command-line" "^4.7.7" + emittery "^0.10.0" + fs-jetpack "^4.1.0" + glob "^7.1.6" + pony-cause "^1.1.1" + type-fest "^2.0.0" undefsafe@^2.0.5: version "2.0.5" @@ -2883,6 +3065,11 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -2932,7 +3119,7 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.2.1, uuid@^3.3.2: +uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== @@ -2947,11 +3134,6 @@ v8-compile-cache-lib@^3.0.0: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== -validator@^10.4.0: - version "10.11.0" - resolved "https://registry.yarnpkg.com/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228" - integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw== - validator@^13.7.0: version "13.7.0" resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" @@ -2984,6 +3166,11 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -3005,13 +3192,6 @@ widest-line@^3.1.0: dependencies: string-width "^4.0.0" -wkx@^0.4.1: - version "0.4.8" - resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.8.tgz#a092cf088d112683fdc7182fd31493b2c5820003" - integrity sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ== - dependencies: - "@types/node" "*" - wkx@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c" @@ -3019,6 +3199,15 @@ wkx@^0.5.0: dependencies: "@types/node" "*" +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -3053,6 +3242,11 @@ xmlcreate@^2.0.4: resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.4.tgz#0c5ab0f99cdd02a81065fa9cd8f8ae87624889be" integrity sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg== +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -3071,6 +3265,30 @@ yamljs@^0.3.0: argparse "^1.0.7" glob "^7.0.5" +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^13.1.0: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"