Skip to content
Snippets Groups Projects
Commit 9a8f552a authored by Bernard Roland (Student Com20)'s avatar Bernard Roland (Student Com20)
Browse files

Merge branch 'deployment' into devel

parents aa95c067 7a76cb29
No related branches found
No related tags found
No related merge requests found
node_modules/
# vim / vscode workspace config # vim / vscode workspace config
.vim .vim
.vscode .vscode
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",
"build": "react-scripts build", "build": "react-scripts build",
"test": "react-scripts test" "test": "react-scripts test --watchAll=false --passWithNoTests"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [
......
export const apiRoot = 'http://localhost:8000/v1'; export const apiRoot = `${window.location.origin}/v1`;
{
"name": "ryoko",
"version": "0.1.0",
"description": "Ryoko is a project planning tool build with developers in mind",
"repository": "https://gitlab.inf.unibz.it/Roland.Bernard/wie_202021_csbillero11.git/",
"author": "Roland Bernard <rolbernard@unibz.it>",
"license": "MIT",
"private": true,
"main": "server/build.js",
"scripts": {
"install": "cd server && yarn install --production=false && cd ../client && yarn install --production=false",
"build": "cd server && yarn build && cd ../client && yarn build",
"start": "cd server && node build/index.js"
},
"keywords": [ ],
"dependencies": { },
"engines": {
"node": "16.x"
}
}
...@@ -14,3 +14,6 @@ ...@@ -14,3 +14,6 @@
*.db *.db
*.sqlite3 *.sqlite3
# keys
/keys
...@@ -16,14 +16,14 @@ ...@@ -16,14 +16,14 @@
"express-fileupload": "^1.2.1", "express-fileupload": "^1.2.1",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"knex": "^0.95.4", "knex": "^0.95.4",
"pg": "^8.6.0",
"sharp": "^0.28.1", "sharp": "^0.28.1",
"sqlite3": "^5.0.2",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
"scripts": { "scripts": {
"start": "nodemon src/index.ts", "start": "nodemon src/index.ts",
"build": "tsc --project .", "build": "tsc --project .",
"test": "jest --watch --config ./jest.config.json" "test": "jest --passWithNoTests --config ./jest.config.json"
}, },
"devDependencies": { "devDependencies": {
"@types/bcrypt": "^3.0.1", "@types/bcrypt": "^3.0.1",
...@@ -37,8 +37,10 @@ ...@@ -37,8 +37,10 @@
"@types/uuid": "^8.3.0", "@types/uuid": "^8.3.0",
"jest": "^26.6.3", "jest": "^26.6.3",
"nodemon": "^2.0.7", "nodemon": "^2.0.7",
"sqlite3": "^5.0.2",
"ts-jest": "^26.5.4", "ts-jest": "^26.5.4",
"ts-node": "^9.1.1", "ts-node": "^9.1.1",
"tsc": "^2.0.3",
"typescript": "^4.2.4" "typescript": "^4.2.4"
} }
} }
import { env } from 'process'; import { env } from 'process';
export const port = 8000; export const port = env.PORT ?? 8000;
export const keys = { export const keys = {
private: '/etc/ssl/localcerts/cert.key', private: './keys/cert.key',
public: '/etc/ssl/localcerts/cert.pem', public: './keys/cert.pem',
}; };
export const allowedOrigins = [ "*" ]; export const allowedOrigins = [ "*" ];
export const environment = (env.NODE_ENV ?? 'development') as ('development' | 'staging' | 'production'); export const environment = (env.NODE_ENV ?? 'development') as ('development' | 'staging' | 'production');
export const web_serve = '../client/build/';
...@@ -3,7 +3,7 @@ import express, { Request, Response, NextFunction } from 'express'; ...@@ -3,7 +3,7 @@ import express, { Request, Response, NextFunction } from 'express';
import { json as bodyJson } from 'body-parser'; import { json as bodyJson } from 'body-parser';
import fileupload from 'express-fileupload'; import fileupload from 'express-fileupload';
import { port } from './config'; import { port, web_serve } from './config';
import { addDefaultHeaders } from './headers'; import { addDefaultHeaders } from './headers';
import v1 from './v1'; import v1 from './v1';
...@@ -15,6 +15,9 @@ app.use(fileupload()); ...@@ -15,6 +15,9 @@ app.use(fileupload());
app.use('/v1', v1); app.use('/v1', v1);
if (web_serve) {
app.use('/', express.static(web_serve));
}
app.use((_req, res) => { app.use((_req, res) => {
res.status(404).json({ res.status(404).json({
...@@ -30,7 +33,5 @@ app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => { ...@@ -30,7 +33,5 @@ app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => {
}); });
}); });
app.listen(port, () => { app.listen(port);
console.log(`[server] Server is running at http://localhost:${port}`);
});
import { readFileBuffer } from './util'; import { readFileBuffer } from './util';
import { env } from 'process';
import { keys } from './config'; import { keys } from './config';
let privateKey: Buffer; let privateKey: string;
export async function getPrivateKey(): Promise<Buffer> { export async function getPrivateKey(): Promise<string> {
if (!privateKey) { if (env.JWT_PRIVATE_KEY) {
privateKey = await readFileBuffer(keys.private); return env.JWT_PRIVATE_KEY;
} else {
if (!privateKey) {
privateKey = (await readFileBuffer(keys.private)).toString();
}
return privateKey;
} }
return privateKey;
} }
let publicKey: Buffer; let publicKey: string;
export async function getPublicKey(): Promise<Buffer> { export async function getPublicKey(): Promise<string> {
if (!publicKey) { if (env.JWT_PUBLIC_KEY) {
publicKey = await readFileBuffer(keys.public); return env.JWT_PUBLIC_KEY;
} else {
if (!publicKey) {
publicKey = (await readFileBuffer(keys.public)).toString();
}
return publicKey;
} }
return publicKey;
} }
import { env } from 'process';
import { join } from 'path';
import { parse } from 'pg-connection-string';
const pgconfig: any = parse(env.DATABASE_URL ?? '');
export default { export default {
development: { development: {
client: "sqlite3", client: "sqlite3",
connection: { connection: {
filename: "./dev.sqlite3" filename: "./dev.sqlite3",
} },
migrations: {
tableName: "knex_migrations",
directory: join(__dirname, 'migrations'),
},
}, },
staging: { staging: {
client: "postgresql", client: "postgresql",
connection: { connection: pgconfig,
database: "my_db",
user: "username",
password: "password"
},
pool: { pool: {
min: 2, min: 2,
max: 10 max: 10,
}, },
migrations: { migrations: {
tableName: "knex_migrations" tableName: "knex_migrations",
} directory: join(__dirname, 'migrations'),
},
}, },
production: { production: {
client: "postgresql", client: "postgresql",
connection: { connection: {
database: "my_db", ...pgconfig,
user: "username", ssl: {
password: "password" rejectUnauthorized: false,
}
}, },
pool: { pool: {
min: 2, min: 2,
max: 10 max: 10,
}, },
migrations: { migrations: {
tableName: "knex_migrations" tableName: "knex_migrations",
} directory: join(__dirname, 'migrations'),
},
} }
}; };
...@@ -15,17 +15,17 @@ export async function up(database: Knex): Promise<void> { ...@@ -15,17 +15,17 @@ export async function up(database: Knex): Promise<void> {
table.uuid('id').notNullable().primary(); table.uuid('id').notNullable().primary();
table.text('name').notNullable(); table.text('name').notNullable();
}) })
.createTable('roles', table => {
table.uuid('id').notNullable().primary();
table.uuid('team_id').notNullable().references('teams.id');
table.text('name').notNullable();
})
.createTable('team_members', table => { .createTable('team_members', table => {
table.uuid('user_id').notNullable().references('users.id'); table.uuid('user_id').notNullable().references('users.id');
table.uuid('team_id').notNullable().references('teams.id'); table.uuid('team_id').notNullable().references('teams.id');
table.primary(['user_id', 'team_id']); table.primary(['user_id', 'team_id']);
table.uuid('role_id').notNullable().references('roles.id'); table.uuid('role_id').notNullable().references('roles.id');
}) })
.createTable('roles', table => {
table.uuid('id').notNullable().primary();
table.uuid('team_id').notNullable().references('teams.id');
table.text('name').notNullable();
})
.createTable('projects', table => { .createTable('projects', table => {
table.uuid('id').notNullable().primary(); table.uuid('id').notNullable().primary();
table.text('name').notNullable(); table.text('name').notNullable();
......
...@@ -16,10 +16,10 @@ user.get('/name/:username', async (req, res) => { ...@@ -16,10 +16,10 @@ user.get('/name/:username', async (req, res) => {
const name = req.params.username.trim().toLowerCase(); const name = req.params.username.trim().toLowerCase();
const user = await database('users') const user = await database('users')
.select({ .select({
id: 'id', id: 'users.id',
username: 'user_name', username: 'users.user_name',
}) })
.where({ username: name }); .where({ 'users.user_name': name });
if (user.length >= 1) { if (user.length >= 1) {
res.status(200).json({ res.status(200).json({
status: 'success', status: 'success',
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
"moduleResolution": "node", "moduleResolution": "node",
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"noEmit": true,
"module": "commonjs", "module": "commonjs",
"rootDir": "src", "rootDir": "src",
"outDir": "build", "outDir": "build",
......
...@@ -1150,6 +1150,11 @@ buffer-from@1.x, buffer-from@^1.0.0: ...@@ -1150,6 +1150,11 @@ buffer-from@1.x, buffer-from@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
buffer-writer@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04"
integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==
buffer@^5.5.0: buffer@^5.5.0:
version "5.7.1" version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
...@@ -3970,6 +3975,11 @@ package-json@^6.3.0: ...@@ -3970,6 +3975,11 @@ package-json@^6.3.0:
registry-url "^5.0.0" registry-url "^5.0.0"
semver "^6.2.0" semver "^6.2.0"
packet-reader@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74"
integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==
parse-json@^5.0.0: parse-json@^5.0.0:
version "5.2.0" version "5.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
...@@ -4035,6 +4045,57 @@ pg-connection-string@2.4.0: ...@@ -4035,6 +4045,57 @@ pg-connection-string@2.4.0:
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.4.0.tgz#c979922eb47832999a204da5dbe1ebf2341b6a10" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.4.0.tgz#c979922eb47832999a204da5dbe1ebf2341b6a10"
integrity sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ== integrity sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==
pg-connection-string@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34"
integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==
pg-int8@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
pg-pool@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.3.0.tgz#12d5c7f65ea18a6e99ca9811bd18129071e562fc"
integrity sha512-0O5huCql8/D6PIRFAlmccjphLYWC+JIzvUhSzXSpGaf+tjTZc4nn+Lr7mLXBbFJfvwbP0ywDv73EiaBsxn7zdg==
pg-protocol@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0"
integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==
pg-types@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3"
integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==
dependencies:
pg-int8 "1.0.1"
postgres-array "~2.0.0"
postgres-bytea "~1.0.0"
postgres-date "~1.0.4"
postgres-interval "^1.1.0"
pg@^8.6.0:
version "8.6.0"
resolved "https://registry.yarnpkg.com/pg/-/pg-8.6.0.tgz#e222296b0b079b280cce106ea991703335487db2"
integrity sha512-qNS9u61lqljTDFvmk/N66EeGq3n6Ujzj0FFyNMGQr6XuEv4tgNTXvJQTfJdcvGit5p5/DWPu+wj920hAJFI+QQ==
dependencies:
buffer-writer "2.0.0"
packet-reader "1.0.0"
pg-connection-string "^2.5.0"
pg-pool "^3.3.0"
pg-protocol "^1.5.0"
pg-types "^2.1.0"
pgpass "1.x"
pgpass@1.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.4.tgz#85eb93a83800b20f8057a2b029bf05abaf94ea9c"
integrity sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==
dependencies:
split2 "^3.1.1"
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
version "2.2.3" version "2.2.3"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d"
...@@ -4059,6 +4120,28 @@ posix-character-classes@^0.1.0: ...@@ -4059,6 +4120,28 @@ posix-character-classes@^0.1.0:
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
postgres-array@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==
postgres-bytea@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=
postgres-date@~1.0.4:
version "1.0.7"
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8"
integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==
postgres-interval@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695"
integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==
dependencies:
xtend "^4.0.0"
prebuild-install@^6.1.1: prebuild-install@^6.1.1:
version "6.1.2" version "6.1.2"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.2.tgz#6ce5fc5978feba5d3cbffedca0682b136a0b5bff" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.2.tgz#6ce5fc5978feba5d3cbffedca0682b136a0b5bff"
...@@ -4222,7 +4305,7 @@ readable-stream@^2.0.6: ...@@ -4222,7 +4305,7 @@ readable-stream@^2.0.6:
string_decoder "~1.1.1" string_decoder "~1.1.1"
util-deprecate "~1.0.1" util-deprecate "~1.0.1"
readable-stream@^3.1.1, readable-stream@^3.4.0: readable-stream@^3.0.0, readable-stream@^3.1.1, readable-stream@^3.4.0:
version "3.6.0" version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
...@@ -4698,6 +4781,13 @@ split-string@^3.0.1, split-string@^3.0.2: ...@@ -4698,6 +4781,13 @@ split-string@^3.0.1, split-string@^3.0.2:
dependencies: dependencies:
extend-shallow "^3.0.0" extend-shallow "^3.0.0"
split2@^3.1.1:
version "3.2.2"
resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f"
integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==
dependencies:
readable-stream "^3.0.0"
sprintf-js@~1.0.2: sprintf-js@~1.0.2:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
...@@ -5093,6 +5183,11 @@ ts-node@^9.1.1: ...@@ -5093,6 +5183,11 @@ ts-node@^9.1.1:
source-map-support "^0.5.17" source-map-support "^0.5.17"
yn "3.1.1" yn "3.1.1"
tsc@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/tsc/-/tsc-2.0.3.tgz#037fe579e3bd67a5cbdaa604b43c6c1991b04bef"
integrity sha512-SN+9zBUtrpUcOpaUO7GjkEHgWtf22c7FKbKCA4e858eEM7Qz86rRDpgOU2lBIDf0fLCsEg65ms899UMUIB2+Ow==
tunnel-agent@^0.6.0: tunnel-agent@^0.6.0:
version "0.6.0" version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
...@@ -5422,6 +5517,11 @@ xmlchars@^2.2.0: ...@@ -5422,6 +5517,11 @@ xmlchars@^2.2.0:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
xtend@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^4.0.0: y18n@^4.0.0:
version "4.0.3" version "4.0.3"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
......
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment