Commit 91c68eaa authored by Nguyễn Hải Sơn's avatar Nguyễn Hải Sơn

Update

parent 22d732ce
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#using-environment-variables
# Prisma supports the native connection string format for PostgreSQL, MySQL and SQLite.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
DATABASE_URL="mysql://qldh:qldh@2021!wGqvF9DV4W@localhost:3308/qldh"
\ No newline at end of file
node_modules
dist
node_modules/
dist/
*.log
.env
\ No newline at end of file
# REST API Example
This example shows how to implement a **REST API with TypeScript** using [Express](https://expressjs.com/) and [Prisma Client](https://www.prisma.io/docs/concepts/components/prisma-client). It is based on a SQLite database, you can find the database file with some dummy data at [`./prisma/dev.db`](./prisma/dev.db).
## Getting started
### 1. Download example and install dependencies
Download this example:
```
curl https://codeload.github.com/prisma/prisma-examples/tar.gz/latest | tar -xz --strip=2 prisma-examples-latest/typescript/rest-express
```
Install npm dependencies:
```
cd rest-express
npm install
```
<details><summary><strong>Alternative:</strong> Clone the entire repo</summary>
Clone this repository:
```
git clone git@github.com:prisma/prisma-examples.git --depth=1
```
Install npm dependencies:
```
cd prisma-examples/typescript/rest-express
npm install
```
</details>
### 2. Create and seed the database
Run the following command to create your SQLite database file. This also creates the `User` and `Post` tables that are defined in [`prisma/schema.prisma`](./prisma/schema.prisma):
```
npx prisma migrate dev --name init
```
Now, seed the database with the sample data in [`prisma/seed.ts`](./prisma/seed.ts) by running the following command:
```
npx prisma db seed --preview-feature
```
### 3. Start the REST API server
```
npm run dev
```
The server is now running on `http://localhost:3000`. You can now the API requests, e.g. [`http://localhost:3000/feed`](http://localhost:3000/feed).
## Using the REST API
You can access the REST API of the server using the following endpoints:
### `GET`
- `/post/:id`: Fetch a single post by its `id`
- `/feed?searchString={searchString}&take={take}&skip={skip}&orderBy={orderBy}`: Fetch all _published_ posts
- Query Parameters
- `searchString` (optional): This filters posts by `title` or `content`
- `take` (optional): This specifies how many objects should be returned in the list
- `skip` (optional): This specifies how many of the returned objects in the list should be skipped
- `orderBy` (optional): The sort order for posts in either ascending or descending order. The value can either `asc` or `desc`
- `/user/:id/drafts`: Fetch user's drafts by their `id`
- `/users`: Fetch all users
### `POST`
- `/post`: Create a new post
- Body:
- `title: String` (required): The title of the post
- `content: String` (optional): The content of the post
- `authorEmail: String` (required): The email of the user that creates the post
- `/signup`: Create a new user
- Body:
- `email: String` (required): The email address of the user
- `name: String` (optional): The name of the user
- `postData: PostCreateInput[]` (optional): The posts of the user
### `PUT`
- `/publish/:id`: Toggle the publish value of a post by its `id`
- `/post/:id/views`: Increases the `viewCount` of a `Post` by one `id`
### `DELETE`
- `/post/:id`: Delete a post by its `id`
## Evolving the app
Evolving the application typically requires two steps:
1. Migrate your database using Prisma Migrate
1. Update your application code
For the following example scenario, assume you want to add a "profile" feature to the app where users can create a profile and write a short bio about themselves.
### 1. Migrate your database using Prisma Migrate
The first step is to add a new table, e.g. called `Profile`, to the database. You can do this by adding a new model to your [Prisma schema file](./prisma/schema.prisma) file and then running a migration afterwards:
```diff
// ./prisma/schema.prisma
model User {
id Int @default(autoincrement()) @id
name String?
email String @unique
posts Post[]
+ profile Profile?
}
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String
content String?
published Boolean @default(false)
viewCount Int @default(0)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
+model Profile {
+ id Int @default(autoincrement()) @id
+ bio String?
+ user User @relation(fields: [userId], references: [id])
+ userId Int @unique
+}
```
Once you've updated your data model, you can execute the changes against your database with the following command:
```
npx prisma migrate dev --name add-profile
```
This adds another migration to the `prisma/migrations` directory and creates the new `Profile` table in the database.
### 2. Update your application code
You can now use your `PrismaClient` instance to perform operations against the new `Profile` table. Those operations can be used to implement API endpoints in the REST API.
#### 2.1 Add the API endpoint to your app
Update your `index.ts` file by adding a new endpoint to your API:
```ts
app.post('/user/:id/profile', async (req, res) => {
const { id } = req.params
const { bio } = req.body
const profile = await prisma.profile.create({
data: {
bio,
user: {
connect: {
id: Number(id)
}
}
}
})
res.json(profile)
})
```
#### 2.2 Testing out your new endpoint
Restart your application server and test out your new endpoint.
##### `POST`
- `/user/:id/profile`: Create a new profile based on the user id
- Body:
- `bio: String` : The bio of the user
<details><summary>Expand to view more sample Prisma Client queries on <code>Profile</code></summary>
Here are some more sample Prisma Client queries on the new <code>Profile</code> model:
##### Create a new profile for an existing user
```ts
const profile = await prisma.profile.create({
data: {
bio: 'Hello World',
user: {
connect: { email: 'alice@prisma.io' },
},
},
})
```
##### Create a new user with a new profile
```ts
const user = await prisma.user.create({
data: {
email: 'john@prisma.io',
name: 'John',
profile: {
create: {
bio: 'Hello World',
},
},
},
})
```
##### Update the profile of an existing user
```ts
const userWithUpdatedProfile = await prisma.user.update({
where: { email: 'alice@prisma.io' },
data: {
profile: {
update: {
bio: 'Hello Friends',
},
},
},
})
```
</details>
## Switch to another database (e.g. PostgreSQL, MySQL, SQL Server)
If you want to try this example with another database than SQLite, you can adjust the the database connection in [`prisma/schema.prisma`](./prisma/schema.prisma) by reconfiguring the `datasource` block.
Learn more about the different connection configurations in the [docs](https://www.prisma.io/docs/reference/database-reference/connection-urls).
<details><summary>Expand for an overview of example configurations with different databases</summary>
### PostgreSQL
For PostgreSQL, the connection URL has the following structure:
```prisma
datasource db {
provider = "postgresql"
url = "postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA"
}
```
Here is an example connection string with a local PostgreSQL database:
```prisma
datasource db {
provider = "postgresql"
url = "postgresql://janedoe:mypassword@localhost:5432/notesapi?schema=public"
}
```
### MySQL
For MySQL, the connection URL has the following structure:
```prisma
datasource db {
provider = "mysql"
url = "mysql://USER:PASSWORD@HOST:PORT/DATABASE"
}
```
Here is an example connection string with a local MySQL database:
```prisma
datasource db {
provider = "mysql"
url = "mysql://janedoe:mypassword@localhost:3306/notesapi"
}
```
### Microsoft SQL Server (Preview)
Here is an example connection string with a local Microsoft SQL Server database:
```prisma
datasource db {
provider = "sqlserver"
url = "sqlserver://localhost:1433;initial catalog=sample;user=sa;password=mypassword;"
}
```
Because SQL Server is currently in [Preview](https://www.prisma.io/docs/about/releases#preview), you need to specify the `previewFeatures` on your `generator` block:
```prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["microsoftSqlServer"]
}
```
</details>
## Next steps
- Check out the [Prisma docs](https://www.prisma.io/docs)
- Share your feedback in the [`prisma2`](https://prisma.slack.com/messages/CKQTGR6T0/) channel on the [Prisma Slack](https://slack.prisma.io/)
- Create issues and ask questions on [GitHub](https://github.com/prisma/prisma/)
- Watch our biweekly "What's new in Prisma" livestreams on [Youtube](https://www.youtube.com/channel/UCptAHlN1gdwD89tFM3ENb6w)
\ No newline at end of file
{
"name": "api",
"name": "rest-express",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
......@@ -30,15 +30,6 @@
"js-tokens": "^4.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
......@@ -49,21 +40,6 @@
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
}
}
},
......@@ -113,12 +89,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
}
}
},
......@@ -148,6 +118,25 @@
"fastq": "^1.6.0"
}
},
"@prisma/client": {
"version": "2.20.1",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-2.20.1.tgz",
"integrity": "sha512-/IYPubBi55rNMHfE0wwglA6eTWEZD77oz+x+3Mm9ji2lDKdS1lnYKZ0wZX0E3AB8gTNL/zsGtfzmfjgn3ePyIw==",
"requires": {
"@prisma/engines-version": "2.20.0-26.60ba6551f29b17d7d6ce479e5733c70d9c00860e"
}
},
"@prisma/engines": {
"version": "2.20.0-26.60ba6551f29b17d7d6ce479e5733c70d9c00860e",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-2.20.0-26.60ba6551f29b17d7d6ce479e5733c70d9c00860e.tgz",
"integrity": "sha512-zOWETm7DTRvlwf/CekPNSeJe6EC5bn2IFexd74wM9zgBXCZo+1sMDuNGtCqIt4Rzv8CcimEgyzrEFVq0LPV8qg==",
"dev": true
},
"@prisma/engines-version": {
"version": "2.20.0-26.60ba6551f29b17d7d6ce479e5733c70d9c00860e",
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-2.20.0-26.60ba6551f29b17d7d6ce479e5733c70d9c00860e.tgz",
"integrity": "sha512-fJhbGZXm2SPs/RsI79Ew4SFe+6QmChNdgU2I/SIjmU18bUgK8f1TBEWnVtFdBqEDHYPGxbpaianF7lp04KN7EA=="
},
"@sindresorhus/is": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
......@@ -182,6 +171,18 @@
"@types/node": "*"
}
},
"@types/cors": {
"version": "2.8.10",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz",
"integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==",
"dev": true
},
"@types/crypto-js": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.0.1.tgz",
"integrity": "sha512-6+OPzqhKX/cx5xh+yO8Cqg3u3alrkhoxhE5ZOdSEv0DOzJ13lwJ6laqGU0Kv6+XDMFmlnGId04LtY22PsFLQUw==",
"dev": true
},
"@types/express": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz",
......@@ -211,6 +212,15 @@
"integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==",
"dev": true
},
"@types/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
......@@ -221,6 +231,7 @@
"version": "2.15.18",
"resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.18.tgz",
"integrity": "sha512-JW74Nh3P/RDAnaP8uXe1qmRpoFBO84SiWvWoSju/F5+2S1kVBi1FbbDoqK/sTZrCCxySaOJnRATvWD+bLcJjAg==",
"dev": true,
"requires": {
"@types/node": "*"
}
......@@ -228,7 +239,8 @@
"@types/node": {
"version": "14.14.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz",
"integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw=="
"integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==",
"dev": true
},
"@types/qs": {
"version": "6.9.6",
......@@ -252,6 +264,12 @@
"@types/node": "*"
}
},
"@types/uuid": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz",
"integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==",
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.21.0.tgz",
......@@ -452,6 +470,24 @@
"string-width": "^3.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
......@@ -462,6 +498,15 @@
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
......@@ -472,18 +517,18 @@
"dev": true
},
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
"color-convert": "^1.9.0"
}
},
"anymatch": {
......@@ -560,21 +605,6 @@
"qs": "6.7.0",
"raw-body": "2.4.0",
"type-is": "~1.6.17"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"boxen": {
......@@ -591,6 +621,57 @@
"term-size": "^2.1.0",
"type-fest": "^0.8.1",
"widest-line": "^3.1.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"brace-expansion": {
......@@ -612,6 +693,11 @@
"fill-range": "^7.0.1"
}
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
......@@ -678,15 +764,39 @@
"dev": true
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
......@@ -742,18 +852,18 @@
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"concat-map": {
......@@ -804,6 +914,15 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"requires": {
"object-assign": "^4",
"vary": "^1"
}
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
......@@ -821,19 +940,28 @@
"which": "^2.0.1"
}
},
"crypto-js": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
},
"crypto-random-string": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"dev": true
},
"date-format": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz",
"integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w=="
},
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "^2.1.1"
"ms": "2.0.0"
}
},
"decompress-response": {
......@@ -912,15 +1040,23 @@
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
"dev": true
},
"ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"encodeurl": {
......@@ -1008,22 +1144,6 @@
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
......@@ -1033,12 +1153,6 @@
"ms": "2.1.2"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
......@@ -1058,32 +1172,8 @@
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
},
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
}
}
},
"eslint-config-prettier": {
......@@ -1245,21 +1335,6 @@
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"express-validator": {
......@@ -1348,21 +1423,6 @@
"parseurl": "~1.3.3",
"statuses": "~1.5.0",
"unpipe": "~1.0.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"flat-cache": {
......@@ -1373,13 +1433,20 @@
"requires": {
"flatted": "^3.1.0",
"rimraf": "^3.0.2"
}
},
"dependencies": {
"flatted": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
"integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
"dev": true
}
}
},
"flatted": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA=="
},
"forwarded": {
"version": "0.1.2",
......@@ -1391,6 +1458,16 @@
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
......@@ -1469,9 +1546,9 @@
}
},
"globals": {
"version": "13.7.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.7.0.tgz",
"integrity": "sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA==",
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz",
"integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
......@@ -1521,8 +1598,7 @@
"graceful-fs": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
"dev": true
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
},
"has": {
"version": "1.0.3",
......@@ -1676,9 +1752,9 @@
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"is-glob": {
......@@ -1793,6 +1869,57 @@
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"requires": {
"graceful-fs": "^4.1.6"
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"dependencies": {
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
}
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"keyv": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
......@@ -1838,12 +1965,74 @@
"integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
"dev": true
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
},
"lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
},
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
},
"lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
},
"lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"lodash.truncate": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
"integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
"dev": true
},
"log4js": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz",
"integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==",
"requires": {
"date-format": "^3.0.0",
"debug": "^4.1.1",
"flatted": "^2.0.1",
"rfdc": "^1.1.4",
"streamroller": "^2.2.4"
},
"dependencies": {
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"lowercase-keys": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
......@@ -1953,10 +2142,9 @@
"dev": true
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"mysql": {
"version": "2.18.1",
......@@ -1996,6 +2184,23 @@
"touch": "^3.1.0",
"undefsafe": "^2.0.3",
"update-notifier": "^4.1.0"
},
"dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
}
}
},
"nopt": {
......@@ -2019,6 +2224,11 @@
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
"dev": true
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
......@@ -2146,6 +2356,15 @@
"fast-diff": "^1.1.2"
}
},
"prisma": {
"version": "2.20.1",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-2.20.1.tgz",
"integrity": "sha512-zyPvJSUfJrmciP2D/4aUrsyIefiH8AIJUeuq1a0X1df1AFw9QQ+ata/7VQdoP+RIQHnCb6Kln9kqfUw/fieljw==",
"dev": true,
"requires": {
"@prisma/engines": "2.20.0-26.60ba6551f29b17d7d6ce479e5733c70d9c00860e"
}
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
......@@ -2234,6 +2453,14 @@
"ini": "~1.3.0",
"minimist": "^1.2.0",
"strip-json-comments": "~2.0.1"
},
"dependencies": {
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"dev": true
}
}
},
"readable-stream": {
......@@ -2310,6 +2537,11 @@
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true
},
"rfdc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
......@@ -2341,8 +2573,7 @@
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"semver-diff": {
"version": "3.1.1",
......@@ -2380,22 +2611,7 @@
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
},
"dependencies": {
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
......@@ -2457,10 +2673,28 @@
"is-fullwidth-code-point": "^3.0.0"
},
"dependencies": {
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
}
}
......@@ -2497,6 +2731,36 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"streamroller": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz",
"integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==",
"requires": {
"date-format": "^2.1.0",
"debug": "^4.1.1",
"fs-extra": "^8.1.0"
},
"dependencies": {
"date-format": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
"integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA=="
},
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"string-width": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
......@@ -2506,35 +2770,6 @@
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
}
}
},
"string_decoder": {
......@@ -2546,18 +2781,18 @@
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
"ansi-regex": "^5.0.0"
}
},
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"supports-color": {
......@@ -2710,9 +2945,9 @@
}
},
"typescript": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz",
"integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==",
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
"dev": true
},
"undefsafe": {
......@@ -2722,23 +2957,6 @@
"dev": true,
"requires": {
"debug": "^2.2.0"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
}
}
},
"unique-string": {
......@@ -2750,6 +2968,11 @@
"crypto-random-string": "^2.0.0"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
......@@ -2774,6 +2997,57 @@
"pupa": "^2.0.1",
"semver-diff": "^3.1.1",
"xdg-basedir": "^4.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"uri-js": {
......@@ -2804,6 +3078,11 @@
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"v8-compile-cache": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
......
{
"name": "api",
"name": "rest-express",
"version": "1.0.0",
"description": "",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "node dist/app.js",
"dev": "nodemon src/app.ts",
"start": "node dist/index.js",
"dev": "nodemon src/index.ts",
"build": "tsc -p ."
},
"author": "",
"license": "ISC",
"dependencies": {
"@prisma/client": "2.20.1",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"crypto-js": "^4.0.0",
"express": "4.17.1",
"express-validator": "^6.10.0",
"http-status-codes": "^2.1.4",
"jsonwebtoken": "^8.5.1",
"log4js": "^6.3.0",
"mysql": "^2.18.1",
"uuid": "^8.3.2"
},
"devDependencies": {
"@types/cors": "^2.8.10",
"@types/crypto-js": "^4.0.1",
"@types/express": "^4.17.11",
"@types/jsonwebtoken": "^8.5.1",
"@types/mysql": "^2.15.18",
"@types/node": "^14.14.37",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^4.21.0",
"@typescript-eslint/parser": "^4.21.0",
"eslint": "^7.23.0",
......@@ -20,14 +35,11 @@
"eslint-plugin-prettier": "^3.3.1",
"nodemon": "^2.0.7",
"prettier": "^2.2.1",
"prisma": "2.20.1",
"ts-node": "^9.1.1",
"typescript": "^4.2.3"
},
"dependencies": {
"@types/mysql": "^2.15.18",
"express": "^4.17.1",
"express-validator": "^6.10.0",
"http-status-codes": "^2.1.4",
"mysql": "^2.18.1"
"engines": {
"node": ">=10.0.0"
}
}
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model account_app {
id Int @id @default(autoincrement())
user_name String? @db.VarChar(30)
password String? @db.VarChar(50)
full_name String? @db.VarChar(50)
phone String? @db.VarChar(20)
email String? @db.VarChar(50)
address String? @db.VarChar(255)
status Int?
partner_id Int?
data_access_limit Int?
is_supper Int?
create_time DateTime? @db.DateTime(0)
create_by String? @db.VarChar(255)
update_time DateTime? @db.DateTime(0)
update_by String? @db.VarChar(255)
position_name String? @db.VarChar(500)
avatar String? @db.VarChar(2000)
department Int?
session_id String? @db.VarChar(50)
expire_time DateTime? @db.DateTime(0)
fcm_key String? @db.VarChar(2000)
}
model account_app_role {
account_id Int
view_id Int
role_id Int
@@id([account_id, view_id, role_id])
}
model account_cms {
id Int @id @default(autoincrement())
user_name String? @db.VarChar(30)
password String? @db.VarChar(50)
full_name String? @db.VarChar(50)
phone String? @db.VarChar(20)
email String? @db.VarChar(50)
address String? @db.VarChar(255)
status Int?
partner_id Int?
data_access_limit Int?
is_supper Int?
create_time DateTime? @db.DateTime(0)
create_by String? @db.VarChar(255)
update_time DateTime? @db.DateTime(0)
update_by String? @db.VarChar(255)
}
model app_role {
id Int @id
role_name String? @db.VarChar(255)
}
model building {
id Int @id @default(autoincrement())
code String? @db.VarChar(255)
name String @db.VarChar(2000)
adress String @db.VarChar(2000)
lng Float?
lat Float?
district Int?
province Int?
description String? @db.VarChar(500)
room_position room_position[]
}
model building_floor {
building_id Int
floor_id Int
@@id([building_id, floor_id])
}
model capacity {
id Int @id
type Int?
value String? @db.VarChar(255)
text String @db.VarChar(255)
}
model car {
id Int @id
code String? @db.VarChar(255)
name String @db.VarChar(500)
icon String? @db.VarChar(255)
status Int?
capacity String? @db.VarChar(255)
car_type Int?
license_plate String? @db.VarChar(50)
car_image car_image[]
}
model car_image {
id Int @id @default(autoincrement())
car_id Int
image_url String? @db.VarChar(2000)
car car @relation(fields: [car_id], references: [id])
@@index([car_id], name: "car_id")
}
model car_order {
id Int @id @default(autoincrement())
trans_id String @db.VarChar(50)
start_time DateTime? @db.DateTime(0)
end_time DateTime? @db.DateTime(0)
work_content String? @db.VarChar(2000)
car_id Int?
create_time DateTime? @db.DateTime(0)
create_by String? @db.VarChar(50)
update_time DateTime? @db.DateTime(0)
update_by String? @db.VarChar(50)
data_part Int?
time_type Int?
location_address String? @db.VarChar(2000)
lat Float?
lng Float?
}
model car_service {
order_id Int
service_id Int
quantity Int?
@@id([order_id, service_id])
}
model car_type {
id Int @id
name String? @db.VarChar(255)
}
/// The underlying table does not contain a valid unique identifier and can therefore currently not be handled by the Prisma Client.
model config_range_time {
id Int @default(autoincrement())
value String @db.VarChar(20)
text String @db.VarChar(50)
from String? @db.VarChar(20)
to String? @db.VarChar(20)
@@index([id], name: "id")
@@ignore
}
/// The underlying table does not contain a valid unique identifier and can therefore currently not be handled by the Prisma Client.
model config_range_time_his {
id Int
value Int
text String @db.VarChar(50)
@@ignore
}
model department {
id Int @id @default(autoincrement())
code String? @db.VarChar(50)
name String? @db.VarChar(500)
}
model device {
id Int @id
code String? @db.VarChar(255)
name String @db.VarChar(2000)
model String? @db.VarChar(500)
image String? @db.VarChar(2000)
status Int?
create_time DateTime? @db.DateTime(0)
create_by String? @db.VarChar(50)
update_time DateTime? @db.DateTime(0)
update_by String? @db.VarChar(50)
}
model err_code {
id Int @id
err_code Int
err_text String @db.VarChar(50)
err_text_vn String? @db.VarChar(500)
}
model floor {
id Int @id
code String? @db.VarChar(255)
name String @db.VarChar(2000)
room_position room_position[]
}
model groups {
id Int @id @default(autoincrement())
group_name String? @db.VarChar(100)
descrtiption String? @db.VarChar(255)
status Int?
create_time DateTime? @db.DateTime(0)
create_by String? @db.VarChar(30)
update_time DateTime? @db.DateTime(0)
update_by String? @db.VarChar(30)
}
model group_account_cms {
group_id Int
account_id Int
@@id([group_id, account_id])
}
model group_page_role {
group_id Int
page_id Int
role_id Int
@@id([group_id, page_id, role_id])
}
model pages {
id Int @id
page_name String? @db.VarChar(100)
page_url String? @db.VarChar(255)
page_icon String? @db.VarChar(50)
description String? @db.VarChar(255)
parent_id Int?
define_key String? @db.VarChar(100)
menu_index Int?
}
model page_role {
page_id Int
role_id Int
@@id([page_id, role_id])
}
model roles {
id Int @id
page_id Int?
role_name String? @db.VarChar(100)
description String? @db.VarChar(255)
status Int?
define_key String? @db.VarChar(100)
}
model room {
id Int @id @default(autoincrement())
code String? @db.VarChar(255)
name String @db.VarChar(2000)
description String? @db.VarChar(500)
capacity String @db.VarChar(255)
floor Int
buliding Int
status Int?
room_image room_image[]
room_position room_position[]
}
model room_device {
room_id Int
device_id Int
@@id([room_id, device_id])
}
model room_image {
id Int @id @default(autoincrement())
room_id Int
image_url String? @db.VarChar(2000)
room room @relation(fields: [room_id], references: [id])
@@index([room_id], name: "room_id")
}
model room_position {
id Int @id @default(autoincrement())
room_id Int
building Int
floor Int
position Int?
building_buildingToroom_position building @relation(fields: [building], references: [id])
floor_floorToroom_position floor @relation(fields: [floor], references: [id])
room room @relation(fields: [room_id], references: [id])
@@index([building], name: "building")
@@index([floor], name: "floor")
@@index([room_id], name: "room_id")
}
model schedule_meeting {
id Int @id @default(autoincrement())
trans_id String @db.VarChar(50)
start_time DateTime? @db.DateTime(0)
end_time DateTime? @db.DateTime(0)
work_content String? @db.VarChar(2000)
room_id Int?
create_time DateTime? @db.DateTime(0)
create_by String? @db.VarChar(50)
update_time DateTime? @db.DateTime(0)
update_by String? @db.VarChar(50)
data_part Int?
time_type Int?
}
model schedule_meeting_device {
schedule_id Int
device_id Int
@@id([schedule_id, device_id])
}
model schedule_meeting_service {
schedule_id Int
service_id Int
quantity Int?
@@id([schedule_id, service_id])
}
model service {
id Int @id
code String? @db.VarChar(255)
name String @db.VarChar(2000)
model String? @db.VarChar(500)
image String? @db.VarChar(2000)
status Int?
create_time DateTime? @db.DateTime(0)
create_by String? @db.VarChar(50)
update_time DateTime? @db.DateTime(0)
update_by String? @db.VarChar(50)
}
/// The underlying table does not contain a valid unique identifier and can therefore currently not be handled by the Prisma Client.
model system_config {
number_day_warning Int?
@@ignore
}
/// The underlying table does not contain a valid unique identifier and can therefore currently not be handled by the Prisma Client.
model tbl_sql {
v_sql String? @db.VarChar(4000)
@@ignore
}
model view_group {
id Int @id
code String? @db.VarChar(255)
name String? @db.VarChar(500)
parent_id Int?
}
model view_role {
view_id Int
role_id Int
@@id([view_id, role_id])
}
model work_schedule {
id Int @id @default(autoincrement())
trans_id String @db.VarChar(255)
expire_time DateTime @db.DateTime(0)
work_content String @db.VarChar(4000)
create_time DateTime @db.Date
create_by String @db.VarChar(255)
update_time DateTime? @db.Date
update_by String? @db.VarChar(255)
status Int?
data_part Int?
title String? @db.VarChar(1000)
}
model work_schedule_detail {
work_id Int
trans_id String @db.VarChar(50)
department_id Int
account_id Int
status Int?
@@id([work_id, department_id, account_id])
}
export const AppConfig = {
PORT: 3000,
DB_CONNECTION_AMOUNT: 3,
DB_HOST: 'localhost',
DB_USER: 'qldh',
DB_PASSWORD: 'qldh@2021!wGqvF9DV4W',
DB_DATABASE: 'qldh',
DB_PORT: 3308,
JWT_SECRET:
'1f6f8049cb10c1302d1c9ed34ba7e6be7da6fa57a050e2af8174dac29a386f4a811092fc2a491366efd8adfa47692c1997ef1b37840439d3a3c650ca679b200d',
};
import log4js from 'log4js';
const isProduction = process.env.NODE_ENV === 'production';
console.log(isProduction);
log4js.configure({
appenders: {
log: {
type: 'file',
filename: 'log.log',
maxLogSize: 10485760,
backups: 10,
compress: true,
},
},
categories: {
default: {
appenders: ['log'],
level: isProduction ? 'info' : 'debug',
},
},
});
export const logger = log4js.getLogger('log');
export enum queryErrorCode {
P2000 = '',
P2001 = '',
P2002 = '',
P2003 = '',
P2004 = '',
P2005 = '',
P2006 = '',
P2007 = '',
P2008 = '',
P2009 = '',
P2010 = '',
P2011 = '',
P2012 = '',
P2013 = '',
P2014 = '',
P2015 = '',
P2016 = '',
P2017 = '',
P2018 = '',
P2019 = '',
P2020 = '',
P2021 = '',
P2022 = '',
P2023 = '',
P2024 = '',
P2025 = '',
}
import { StatusCodes } from 'http-status-codes';
import { AppConfig } from './../../configurations/app-config';
import { sign, verify } from 'jsonwebtoken';
import { NextFunction, Request, Response } from 'express';
import { errorBody } from '../../response/error-body';
import { ResponseMessages } from '../../response/response-messages';
import { account_cms } from '@prisma/client';
export const generateAccessToken = (user: account_cms) => {
return sign({ ...user }, AppConfig.JWT_SECRET, { expiresIn: '1d' });
};
export const authenticateToken = (req: Request, res: Response, next: NextFunction) => {
const authHeader = req.headers.authorization;
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
return res
.status(StatusCodes.UNAUTHORIZED)
.send(errorBody(ResponseMessages.UNAUTHORIZED, StatusCodes.UNAUTHORIZED, ResponseMessages.UNAUTHORIZED));
}
verify(token, AppConfig.JWT_SECRET, (error: any, user: any) => {
if (error) {
return res
.status(StatusCodes.FORBIDDEN)
.send(errorBody(error, StatusCodes.FORBIDDEN, ResponseMessages.FORBIDDEN));
}
// @ts-ignore
req.user = user;
next();
});
};
import { account_cms, Prisma, PrismaClient } from '@prisma/client';
import express from 'express';
import { AppConfig } from './configurations/app-config';
import { v4 as uuidv4 } from 'uuid';
import { loginRouter } from './routes/login';
export const prisma = new PrismaClient();
declare global {
namespace Express {
interface Request {
user?: account_cms;
requestId: string;
}
}
}
const app = express();
app.use((req, res, next) => {
req.requestId = uuidv4();
next();
});
app.use(express.json());
app.use('/login', loginRouter);
const server = app.listen(AppConfig.PORT, () => console.log(`🚀 Server ready at: http://localhost:${AppConfig.PORT}`));
import { Prisma } from '@prisma/client';
import { Request, Response } from 'express';
import { Result, ValidationError } from 'express-validator';
import { ReasonPhrases, StatusCodes } from 'http-status-codes';
import { logger } from '../../configurations/log4js.config';
import { ValidatorMessage } from '../../validators/validator-config';
export const errorBody = (data: unknown, code: number, requestId: string, message?: string) => {
return {
requestId,
error: {
code,
message,
},
data,
};
};
export const queryErrorResponse = (req: Request, res: Response, error: Prisma.PrismaClientKnownRequestError) => {
logger.error(`[${req.requestId}][QUERY ERROR ${error.code}]: `, error.stack);
logger.info(`[${req.requestId}][QUERY ERROR ${error.code}]: `, error.message);
res.status(StatusCodes.INTERNAL_SERVER_ERROR).send(
errorBody(error.message, StatusCodes.INTERNAL_SERVER_ERROR, req.requestId, ReasonPhrases.INTERNAL_SERVER_ERROR),
);
};
export const validationErrorResponse = (req: Request, res: Response, errors: Result<ValidationError>) => {
const errorArray = errors.array();
res.status(StatusCodes.UNPROCESSABLE_ENTITY).send(
errorBody(errorArray, StatusCodes.UNPROCESSABLE_ENTITY, errorArray[0].msg),
);
};
export enum ResponseMessages {
UNAUTHORIZED = 'Vui lòng đăng nhập',
FORBIDDEN = 'Không được phép truy cập',
}
import { Request, Response } from 'express';
import { ReasonPhrases, StatusCodes } from 'http-status-codes';
export const successBody = (data: unknown, code: number, requestId: string, message?: string) => {
return {
requestId,
error: {
code,
message,
},
data,
};
};
export const successResponse = <T>(req: Request, res: Response, data: T) => {
res.status(StatusCodes.OK).send(successBody(data, StatusCodes.OK, req.requestId, ReasonPhrases.OK));
};
import { account_cms, Prisma } from '@prisma/client';
import { MD5 } from 'crypto-js';
import { Request, Response, Router } from 'express';
import { validationResult } from 'express-validator';
import { StatusCodes } from 'http-status-codes';
import { prisma } from '../..';
import { logger } from '../../configurations/log4js.config';
import { generateAccessToken } from '../../functions/jwt-authentication';
import { errorBody, queryErrorResponse, validationErrorResponse } from '../../response/error-body';
import { successResponse } from '../../response/success-body';
import { loginValidator } from '../../validators/login';
import { ValidatorMessage } from '../../validators/validator-config';
const loginRouter = Router();
loginRouter.post('/', loginValidator, async (req: Request, res: Response) => {
try {
const validationErrors = validationResult(req);
if (validationErrors.isEmpty()) {
const reqBody = req.body as account_cms;
const user = await prisma.account_cms.findFirst({
where: {
user_name: {
equals: reqBody.user_name,
},
password: {
equals: MD5(reqBody.password || '').toString(),
},
},
});
if (user) {
const jwtToken = generateAccessToken(user);
const data = {
id: user.id,
user_name: user.user_name,
email: user.email,
accessToken: jwtToken,
};
return successResponse(req, res, data);
} else {
logger.warn(`[${req.requestId}]: `, req.body);
return res
.status(StatusCodes.UNPROCESSABLE_ENTITY)
.send(
errorBody(
ValidatorMessage.WRONG_USERNAME_OR_PASSWORD,
StatusCodes.UNPROCESSABLE_ENTITY,
req.requestId,
ValidatorMessage.WRONG_USERNAME_OR_PASSWORD,
),
);
}
} else {
return validationErrorResponse(req, res, validationErrors);
}
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
return queryErrorResponse(req, res, error);
}
}
});
export { loginRouter };
import { check } from 'express-validator';
import { passwordMaxLength, usernameMaxLength, ValidatorMessage } from '../validator-config';
export const loginValidator = [
check('user_name', ValidatorMessage.REQUIRE_USERNAME).notEmpty(),
check('user_name', ValidatorMessage.INVALID_USERNAME).isString(),
check('user_name', ValidatorMessage.INVALID_USERNAME_LENGTH).isLength({
max: usernameMaxLength,
}),
check('password', ValidatorMessage.REQUIRE_PASSWORD).notEmpty(),
check('password', ValidatorMessage.INVALID_PASSWORD).isString(),
check('password', ValidatorMessage.INVALID_PASSWORD_LENGTH).isLength({
max: passwordMaxLength,
}),
];
import { account_cms } from '@prisma/client';
export const usernameMaxLength = 30;
export const passwordMaxLength = 50;
export const ValidatorMessage = {
REQUIRE_USERNAME: 'Vui lòng nhập tên đăng nhập',
INVALID_USERNAME: 'Tên đăng nhập không hợp lệ',
INVALID_USERNAME_LENGTH: `Độ dài tối đa của tên đăng nhập là ${usernameMaxLength} ký tự`,
REQUIRE_PASSWORD: 'Vui lòng nhập mật khẩu',
INVALID_PASSWORD: 'Mật khẩu không hợp lệ',
INVALID_PASSWORD_LENGTH: `Độ dài tối đa của mật khẩu là ${passwordMaxLength} ký tự`,
WRONG_USERNAME_OR_PASSWORD: 'Tài khoản hoặc mật khẩu sai',
};
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist" /* Redirect output structure to the directory. */,
"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
/* Module Resolution Options */
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"sourceMap": true,
"outDir": "dist",
"strict": true,
"lib": ["esnext"],
"esModuleInterop": true,
"moduleResolution": "node",
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment