dev docker setup, auth service start

This commit is contained in:
Evert Prants 2023-06-29 20:41:36 +03:00
parent 4f64a72de7
commit efdbad4ed7
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
34 changed files with 768 additions and 57 deletions

4
.dockerignore Normal file
View File

@ -0,0 +1,4 @@
/database
/dist
/node_modules
/.env

4
.gitignore vendored
View File

@ -2,6 +2,7 @@
/dist
/node_modules
/database
/private
# Logs
logs
@ -18,6 +19,7 @@ lerna-debug.log*
# Tests
/coverage
/.nyc_output
.env*
# IDEs and editors
/.idea
@ -34,5 +36,3 @@ lerna-debug.log*
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.env*

18
Dockerfile.dev Normal file
View File

@ -0,0 +1,18 @@
FROM node:18-alpine
WORKDIR /usr/src/app
ARG SERVICE
RUN npm i -g pnpm
COPY package.json ./
COPY pnpm-lock.yaml ./
RUN pnpm install
COPY . ./
ENV APP_NAME=${SERVICE}
CMD [ "/bin/sh", "-c", "pnpm start:dev $APP_NAME" ]

View File

@ -1,6 +1,6 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { AuthService } from './services/auth.service';
describe('AuthController', () => {
let authController: AuthController;

View File

@ -1,5 +1,5 @@
import { Controller } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthService } from './services/auth.service';
import { MessagePattern } from '@nestjs/microservices';
import { LoginRequest } from './interfaces/auth.interface';

View File

@ -1,12 +1,37 @@
import { Module } from '@nestjs/common';
import { Module, OnModuleInit } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { AuthService } from './services/auth.service';
import { ClientsModule } from '@nestjs/microservices';
import { natsClient } from '@freeblox/shared';
import { makeKnex, makeTypeOrm, natsClient } from '@freeblox/shared';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import knex from 'knex';
import { security } from './config/security.config';
import { keysProviders } from './providers/keys.providers';
import { JWTService } from './services/jwt.service';
@Module({
imports: [ClientsModule.register([natsClient('auth')])],
imports: [
ConfigModule.forRoot({
ignoreEnvFile: process.env.NODE_ENV === 'development',
load: [makeKnex('auth', __dirname), makeTypeOrm('auth'), security],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => config.get('typeorm'),
}),
ClientsModule.register([natsClient('auth')]),
],
controllers: [AuthController],
providers: [AuthService],
providers: [AuthService, ...keysProviders, JWTService],
})
export class AuthModule {}
export class AuthModule implements OnModuleInit {
constructor(private readonly config: ConfigService) {}
async onModuleInit() {
const knexInstance = knex(this.config.get('knex'));
await knexInstance.migrate.latest();
await knexInstance.seed.run();
}
}

View File

@ -0,0 +1,8 @@
import { registerAs } from '@nestjs/config';
import { resolve } from 'path';
export const security = registerAs('security', () => ({
algorithm: String(process.env.JWT_ALGORITHM || 'RS512'),
privateKeyPath: resolve(String(process.env.PRIVATE_KEY_FILE)),
publicKeyPath: resolve(String(process.env.PUBLIC_KEY_FILE)),
}));

View File

@ -0,0 +1,26 @@
import { Knex } from 'knex';
export async function up(knex: Knex): Promise<void> {
return knex.schema.createTable('users', (table) => {
table.uuid('id').primary().defaultTo(knex.raw('uuid_generate_v4()'));
table.string('username', 255).notNullable();
table.string('email', 255).notNullable();
table.string('phone', 255).nullable();
table.string('country', 2).nullable();
table.string('language', 2).notNullable().defaultTo('en');
table.text('password').notNullable();
table.text('display_name').nullable();
table.boolean('verified').defaultTo(false);
table.boolean('activated').defaultTo(true);
table.timestamps(true, true);
table.timestamp('login_at');
});
}
export async function down(knex: Knex): Promise<void> {
return knex.schema.dropTable('users');
}

View File

@ -0,0 +1,21 @@
import { hash } from 'bcrypt';
import { Knex } from 'knex';
export async function seed(knex: Knex): Promise<void> {
const userExists = await knex('users').where({ username: 'freeblox' });
if (userExists?.length) return;
await knex('users').insert([
{
username: 'freeblox',
email: 'freeblox@icynet.eu',
phone: null,
country: 'ee',
language: 'en',
password: await hash('FBLXAdmin123', 12),
display_name: 'Freeblox',
verified: true,
activated: true,
},
]);
}

View File

@ -0,0 +1,5 @@
import { getKnex } from '../../../libs/shared/src/';
module.exports = {
development: getKnex('auth', __dirname, ['.ts', '.js']),
};

View File

@ -8,7 +8,7 @@ async function bootstrap() {
{
transport: Transport.NATS,
options: {
servers: ['nats://localhost:4222'],
servers: [String(process.env.NATS_ENTRYPOINT)],
},
},
);

View File

@ -0,0 +1,32 @@
import { FactoryProvider } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { promises as fs } from 'fs';
import * as jose from 'jose';
/**
* ssh-keygen -t rsa -b 4096 -m PKCS8 -f jwt.private.pem
* openssl rsa -in jwt.private.pem -pubout -outform PEM -out jwt.public.pem
*/
export const keysProviders = [
<FactoryProvider>{
provide: 'APP_PRIVATE_KEY',
inject: [ConfigService],
useFactory: async (config: ConfigService) =>
fs
.readFile(config.get('security.privateKeyPath'), 'utf-8')
.then((key) => jose.importPKCS8(key, 'RS512')),
},
<FactoryProvider>{
provide: 'APP_PUBLIC_KEY',
inject: [ConfigService],
useFactory: async (config: ConfigService) =>
fs
.readFile(config.get('security.publicKeyPath'), 'utf-8')
.then((key) => jose.importSPKI(key, 'RS512')),
},
<FactoryProvider>{
provide: 'APP_PUBLIC_KEY_JWK',
inject: ['APP_PUBLIC_KEY'],
useFactory: async (key: jose.KeyLike) => jose.exportJWK(key),
},
];

View File

@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common';
import { LoginRequest } from './interfaces/auth.interface';
import { LoginRequest } from '../interfaces/auth.interface';
@Injectable()
export class AuthService {

View File

@ -0,0 +1,36 @@
import { ForbiddenException, Inject, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JWK, KeyLike, SignJWT, jwtVerify } from 'jose';
@Injectable()
export class JWTService {
constructor(
@Inject('APP_PRIVATE_KEY') private readonly privateKey: KeyLike,
@Inject('APP_PUBLIC_KEY') private readonly publicKey: KeyLike,
@Inject('APP_PUBLIC_KEY_JWK') private readonly publicKeyJWK: JWK,
private readonly config: ConfigService,
) {}
async sign(data: Record<string, unknown>, audience = 'urn:freeblox:service') {
const alg = this.config.get('security.algorithm');
const jwt = await new SignJWT(data)
.setProtectedHeader({ alg })
.setIssuedAt()
.setIssuer('urn:freeblox:auth')
.setAudience(audience)
.setExpirationTime('8d')
.sign(this.privateKey);
return jwt;
}
async verify(jwt: string, audience = 'urn:freeblox:service') {
const alg = this.config.get('security.algorithm');
const { payload, protectedHeader } = await jwtVerify(jwt, this.publicKey, {
issuer: 'urn:freeblox:auth',
audience,
});
if (protectedHeader.alg !== alg)
throw new ForbiddenException('Provided JWT contains invalid headers.');
return payload;
}
}

View File

@ -4,6 +4,13 @@
"declaration": false,
"outDir": "../../dist/apps/auth"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist",
"test",
"**/*spec.ts"
]
}

View File

@ -2,10 +2,21 @@ import { Module } from '@nestjs/common';
import { CatalogController } from './catalog.controller';
import { CatalogService } from './catalog.service';
import { ClientsModule } from '@nestjs/microservices';
import { natsClient } from '@freeblox/shared';
import { makeKnex, makeTypeOrm, natsClient } from '@freeblox/shared';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
ConfigModule.forRoot({
ignoreEnvFile: process.env.NODE_ENV === 'development',
load: [makeKnex('catalog', __dirname), makeTypeOrm('catalog')],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => config.get('typeorm'),
}),
ClientsModule.register([
natsClient('catalog'),
natsClient('auth'),

View File

@ -8,7 +8,7 @@ async function bootstrap() {
{
transport: Transport.NATS,
options: {
servers: ['nats://localhost:4222'],
servers: [String(process.env.NATS_ENTRYPOINT)],
},
},
);

View File

@ -2,10 +2,21 @@ import { Module } from '@nestjs/common';
import { GameController } from './game.controller';
import { GameService } from './game.service';
import { ClientsModule } from '@nestjs/microservices';
import { natsClient } from '@freeblox/shared';
import { makeKnex, makeTypeOrm, natsClient } from '@freeblox/shared';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
ConfigModule.forRoot({
ignoreEnvFile: process.env.NODE_ENV === 'development',
load: [makeKnex('game', __dirname), makeTypeOrm('game')],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => config.get('typeorm'),
}),
ClientsModule.register([
natsClient('game'),
natsClient('auth'),

View File

@ -8,7 +8,7 @@ async function bootstrap() {
{
transport: Transport.NATS,
options: {
servers: ['nats://localhost:4222'],
servers: [String(process.env.NATS_ENTRYPOINT)],
},
},
);

View File

@ -8,7 +8,7 @@ async function bootstrap() {
{
transport: Transport.NATS,
options: {
servers: ['nats://localhost:4222'],
servers: [String(process.env.NATS_ENTRYPOINT)],
},
},
);

View File

@ -2,10 +2,23 @@ import { Module } from '@nestjs/common';
import { PlayerController } from './player.controller';
import { PlayerService } from './player.service';
import { ClientsModule } from '@nestjs/microservices';
import { natsClient } from '@freeblox/shared';
import { makeKnex, makeTypeOrm, natsClient } from '@freeblox/shared';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [ClientsModule.register([natsClient('player'), natsClient('auth')])],
imports: [
ConfigModule.forRoot({
ignoreEnvFile: process.env.NODE_ENV === 'development',
load: [makeKnex('player', __dirname), makeTypeOrm('player')],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => config.get('typeorm'),
}),
ClientsModule.register([natsClient('player'), natsClient('auth')]),
],
controllers: [PlayerController],
providers: [PlayerService],
})

View File

@ -8,7 +8,7 @@ async function bootstrap() {
{
transport: Transport.NATS,
options: {
servers: ['nats://localhost:4222'],
servers: [String(process.env.NATS_ENTRYPOINT)],
},
},
);

View File

@ -1,11 +1,22 @@
import { Module } from '@nestjs/common';
import { ServerController } from './server.controller';
import { ServerService } from './server.service';
import { natsClient } from '@freeblox/shared';
import { makeKnex, makeTypeOrm, natsClient } from '@freeblox/shared';
import { ClientsModule } from '@nestjs/microservices';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
ConfigModule.forRoot({
ignoreEnvFile: process.env.NODE_ENV === 'development',
load: [makeKnex('server', __dirname), makeTypeOrm('server')],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => config.get('typeorm'),
}),
ClientsModule.register([
natsClient('server'),
natsClient('auth'),

View File

@ -8,7 +8,7 @@ async function bootstrap() {
{
transport: Transport.NATS,
options: {
servers: ['nats://localhost:4222'],
servers: [String(process.env.NATS_ENTRYPOINT)],
},
},
);

View File

@ -2,10 +2,21 @@ import { Module } from '@nestjs/common';
import { SessionController } from './session.controller';
import { SessionService } from './session.service';
import { ClientsModule } from '@nestjs/microservices';
import { natsClient } from '@freeblox/shared';
import { makeKnex, makeTypeOrm, natsClient } from '@freeblox/shared';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
ConfigModule.forRoot({
ignoreEnvFile: process.env.NODE_ENV === 'development',
load: [makeKnex('session', __dirname), makeTypeOrm('server')],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => config.get('typeorm'),
}),
ClientsModule.register([
natsClient('session'),
natsClient('server'),

View File

@ -7,13 +7,154 @@ services:
- 4222:4222
- 6222:6222
- 8222:8222
networks:
- fblx
postgres:
container_name: fblx-pg
container_name: fblx-postgres
image: postgres:15-alpine
ports:
- 5432:5432
environment:
- POSTGRES_MULTIPLE_DATABASES=auth,catalog,game,player,server,session
- POSTGRES_USER=freeblox
- POSTGRES_PASSWORD=FREEBLOXDataBaseDEV@123
volumes:
- ./database:/var/lib/postgresql/data
- ./docker/postgres:/docker-entrypoint-initdb.d
networks:
- fblx
auth:
container_name: fblx-auth
build:
context: .
dockerfile: Dockerfile.dev
args:
- SERVICE=auth
networks:
- fblx
environment:
- NATS_ENTRYPOINT=nats://nats:4222
- POSTGRES_HOST=postgres
- POSTGRES_USER=freeblox
- POSTGRES_PASSWORD=FREEBLOXDataBaseDEV@123
- PRIVATE_KEY_FILE=private/jwt.private.pem
- PUBLIC_KEY_FILE=private/jwt.public.pem
volumes:
- ./apps:/usr/src/app/apps
- ./libs:/usr/src/app/libs
- ./private:/usr/src/app/private
catalog:
container_name: fblx-catalog
build:
context: .
dockerfile: Dockerfile.dev
args:
- SERVICE=catalog
networks:
- fblx
environment:
- NATS_ENTRYPOINT=nats://nats:4222
- POSTGRES_HOST=postgres
- POSTGRES_USER=freeblox
- POSTGRES_PASSWORD=FREEBLOXDataBaseDEV@123
volumes:
- ./apps:/usr/src/app/apps
- ./libs:/usr/src/app/libs
game:
container_name: fblx-game
build:
context: .
dockerfile: Dockerfile.dev
args:
- SERVICE=game
networks:
- fblx
environment:
- NATS_ENTRYPOINT=nats://nats:4222
- POSTGRES_HOST=postgres
- POSTGRES_USER=freeblox
- POSTGRES_PASSWORD=FREEBLOXDataBaseDEV@123
volumes:
- ./apps:/usr/src/app/apps
- ./libs:/usr/src/app/libs
player:
container_name: fblx-player
build:
context: .
dockerfile: Dockerfile.dev
args:
- SERVICE=player
networks:
- fblx
environment:
- NATS_ENTRYPOINT=nats://nats:4222
- POSTGRES_HOST=postgres
- POSTGRES_USER=freeblox
- POSTGRES_PASSWORD=FREEBLOXDataBaseDEV@123
volumes:
- ./apps:/usr/src/app/apps
- ./libs:/usr/src/app/libs
server:
container_name: fblx-server
build:
context: .
dockerfile: Dockerfile.dev
args:
- SERVICE=server
networks:
- fblx
environment:
- NATS_ENTRYPOINT=nats://nats:4222
- POSTGRES_HOST=postgres
- POSTGRES_USER=freeblox
- POSTGRES_PASSWORD=FREEBLOXDataBaseDEV@123
volumes:
- ./apps:/usr/src/app/apps
- ./libs:/usr/src/app/libs
session:
container_name: fblx-session
build:
context: .
dockerfile: Dockerfile.dev
args:
- SERVICE=session
networks:
- fblx
environment:
- NATS_ENTRYPOINT=nats://nats:4222
- POSTGRES_HOST=postgres
- POSTGRES_USER=freeblox
- POSTGRES_PASSWORD=FREEBLOXDataBaseDEV@123
volumes:
- ./apps:/usr/src/app/apps
- ./libs:/usr/src/app/libs
web-service:
container_name: fblx-web-service
build:
context: .
dockerfile: Dockerfile.dev
args:
- SERVICE=freeblox-web-service
networks:
- fblx
ports:
- 4555:3000
environment:
- NATS_ENTRYPOINT=nats://nats:4222
volumes:
- ./apps:/usr/src/app/apps
- ./libs:/usr/src/app/libs
pgadmin:
container_name: fblx-pgadmin
image: dpage/pgadmin4
ports:
- 4556:80
networks:
- fblx
volumes:
- fblx-pgadmin:/var/lib/pgadmin
environment:
- PGADMIN_DEFAULT_EMAIL=freeblox@freeblox.gg
- PGADMIN_DEFAULT_PASSWORD=password
networks:
fblx:
volumes:
fblx-pgadmin:

23
docker/postgres/databases.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
# https://stackoverflow.com/a/59466352
set -e
set -u
function create_user_and_database() {
local database=$(echo $1)
echo " Creating user and database '$database'"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
CREATE DATABASE $database;
EOSQL
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" -d "$database" <<-EOSQL
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
EOSQL
}
if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then
echo "Creating databases: $POSTGRES_MULTIPLE_DATABASES"
for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do
create_user_and_database $db
done
echo "Databases created"
fi

View File

@ -0,0 +1,35 @@
import { registerAs } from '@nestjs/config';
import { Knex } from 'knex';
import { join } from 'path';
export const getKnex = (
database: string,
directory: string,
loadExtensions = ['.js'],
) =>
({
client: 'pg',
connection: {
port: 5432,
host: String(process.env.POSTGRES_HOST),
user: String(process.env.POSTGRES_USER),
password: String(process.env.POSTGRES_PASSWORD),
database,
},
migrations: {
directory: join(directory, 'database', 'migrations'),
extension: 'ts',
loadExtensions,
},
seeds: {
directory: join(directory, 'database', 'seeds'),
extension: 'ts',
loadExtensions,
},
} as Knex.Config);
export const makeKnex = (
database: string,
directory: string,
loadExtensions?: string[],
) => registerAs('knex', () => getKnex(database, directory, loadExtensions));

View File

@ -0,0 +1,17 @@
import { registerAs } from '@nestjs/config';
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
export const makeTypeOrm = (database: string) =>
registerAs(
'typeorm',
() =>
({
type: 'postgres',
port: 5432,
host: String(process.env.POSTGRES_HOST),
username: String(process.env.POSTGRES_USER),
password: String(process.env.POSTGRES_PASSWORD),
database,
autoLoadEntities: true,
} as TypeOrmModuleOptions),
);

View File

@ -1,3 +1,5 @@
export * from './shared.module';
export * from './shared.service';
export * from './utils/nats-client';
export * from './database/make-typeorm';
export * from './database/make-knex';

View File

@ -5,6 +5,6 @@ export const natsClient = (name: string) =>
name,
transport: Transport.NATS,
options: {
servers: ['nats://localhost:4222'],
servers: [String(process.env.NATS_ENTRYPOINT)],
},
};

View File

@ -30,8 +30,11 @@
"@nestjs/swagger": "^7.0.11",
"@nestjs/typeorm": "^10.0.0",
"axios": "^1.4.0",
"bcrypt": "^5.1.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"jose": "^4.14.4",
"jsonwebtoken": "^9.0.0",
"knex": "^2.4.2",
"nats": "^2.15.1",
"pg": "^8.11.1",
@ -44,6 +47,7 @@
"@nestjs/cli": "^10.0.5",
"@nestjs/schematics": "^10.0.1",
"@nestjs/testing": "^10.0.3",
"@types/bcrypt": "^5.0.0",
"@types/express": "^4.17.17",
"@types/jest": "29.5.2",
"@types/node": "^20.3.2",
@ -53,6 +57,7 @@
"eslint": "^8.43.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"glob": "^10.3.1",
"jest": "29.5.0",
"prettier": "^2.8.8",
"source-map-support": "^0.5.21",
@ -87,4 +92,4 @@
"^@freeblox/shared(|/.*)$": "<rootDir>/libs/shared/src/$1"
}
}
}
}

View File

@ -32,12 +32,21 @@ dependencies:
axios:
specifier: ^1.4.0
version: 1.4.0
bcrypt:
specifier: ^5.1.0
version: 5.1.0
class-transformer:
specifier: ^0.5.1
version: 0.5.1
class-validator:
specifier: ^0.14.0
version: 0.14.0
jose:
specifier: ^4.14.4
version: 4.14.4
jsonwebtoken:
specifier: ^9.0.0
version: 9.0.0
knex:
specifier: ^2.4.2
version: 2.4.2(pg@8.11.1)
@ -70,6 +79,9 @@ devDependencies:
'@nestjs/testing':
specifier: ^10.0.3
version: 10.0.3(@nestjs/common@10.0.3)(@nestjs/core@10.0.3)(@nestjs/microservices@10.0.3)(@nestjs/platform-express@10.0.3)
'@types/bcrypt':
specifier: ^5.0.0
version: 5.0.0
'@types/express':
specifier: ^4.17.17
version: 4.17.17
@ -97,6 +109,9 @@ devDependencies:
eslint-plugin-prettier:
specifier: ^4.2.1
version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.43.0)(prettier@2.8.8)
glob:
specifier: ^10.3.1
version: 10.3.1
jest:
specifier: 29.5.0
version: 29.5.0(@types/node@20.3.2)(ts-node@10.9.1)
@ -605,7 +620,6 @@ packages:
strip-ansi-cjs: /strip-ansi@6.0.1
wrap-ansi: 8.1.0
wrap-ansi-cjs: /wrap-ansi@7.0.0
dev: false
/@istanbuljs/load-nyc-config@1.1.0:
resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
@ -890,6 +904,24 @@ packages:
resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==}
engines: {node: '>=8'}
/@mapbox/node-pre-gyp@1.0.10:
resolution: {integrity: sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==}
hasBin: true
dependencies:
detect-libc: 2.0.1
https-proxy-agent: 5.0.1
make-dir: 3.1.0
node-fetch: 2.6.11
nopt: 5.0.0
npmlog: 5.0.1
rimraf: 3.0.2
semver: 7.5.3
tar: 6.1.15
transitivePeerDependencies:
- encoding
- supports-color
dev: false
/@nestjs/axios@3.0.0(@nestjs/common@10.0.3)(axios@1.4.0)(reflect-metadata@0.1.13)(rxjs@7.8.1):
resolution: {integrity: sha512-ULdH03jDWkS5dy9X69XbUVbhC+0pVnrRcj7bIK/ytTZ76w7CgvTZDJqsIyisg3kNOiljRW/4NIjSf3j6YGvl+g==}
peerDependencies:
@ -1208,7 +1240,6 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
requiresBuild: true
dev: false
optional: true
/@sinclair/typebox@0.25.24:
@ -1272,6 +1303,12 @@ packages:
'@babel/types': 7.22.5
dev: true
/@types/bcrypt@5.0.0:
resolution: {integrity: sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==}
dependencies:
'@types/node': 20.3.2
dev: true
/@types/body-parser@1.19.2:
resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
dependencies:
@ -1682,6 +1719,10 @@ packages:
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
dev: true
/abbrev@1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
dev: false
/accepts@1.3.8:
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
engines: {node: '>= 0.6'}
@ -1714,6 +1755,15 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
/agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
dependencies:
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/ajv-formats@2.1.1(ajv@8.12.0):
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
peerDependencies:
@ -1770,7 +1820,6 @@ packages:
/ansi-regex@6.0.1:
resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
engines: {node: '>=12'}
dev: false
/ansi-styles@3.2.1:
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
@ -1793,7 +1842,6 @@ packages:
/ansi-styles@6.2.1:
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
engines: {node: '>=12'}
dev: false
/any-promise@1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
@ -1815,6 +1863,18 @@ packages:
/append-field@1.0.0:
resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
/aproba@2.0.0:
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
dev: false
/are-we-there-yet@2.0.0:
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
engines: {node: '>=10'}
dependencies:
delegates: 1.0.0
readable-stream: 3.6.2
dev: false
/arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@ -1934,6 +1994,18 @@ packages:
/base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
/bcrypt@5.1.0:
resolution: {integrity: sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==}
engines: {node: '>= 10.0.0'}
requiresBuild: true
dependencies:
'@mapbox/node-pre-gyp': 1.0.10
node-addon-api: 5.1.0
transitivePeerDependencies:
- encoding
- supports-color
dev: false
/binary-extensions@2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'}
@ -1990,7 +2062,6 @@ packages:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
dev: true
/brace-expansion@2.0.1:
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
@ -2028,6 +2099,10 @@ packages:
node-int64: 0.4.0
dev: true
/buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
dev: false
/buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
@ -2125,6 +2200,11 @@ packages:
fsevents: 2.3.2
dev: true
/chownr@2.0.0:
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
engines: {node: '>=10'}
dev: false
/chrome-trace-event@1.0.3:
resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==}
engines: {node: '>=6.0'}
@ -2237,6 +2317,11 @@ packages:
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
/color-support@1.1.3:
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
hasBin: true
dev: false
/colorette@2.0.19:
resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==}
dev: false
@ -2278,7 +2363,6 @@ packages:
/concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
/concat-stream@1.6.2:
resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
@ -2292,6 +2376,10 @@ packages:
/consola@2.15.3:
resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
/console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
dev: false
/content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
@ -2404,6 +2492,10 @@ packages:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
/delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
dev: false
/depd@2.0.0:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
@ -2412,6 +2504,11 @@ packages:
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
/detect-libc@2.0.1:
resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==}
engines: {node: '>=8'}
dev: false
/detect-newline@3.1.0:
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
engines: {node: '>=8'}
@ -2464,6 +2561,11 @@ packages:
/eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
/ecdsa-sig-formatter@1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
dependencies:
safe-buffer: 5.2.1
dev: false
/ee-first@1.1.1:
@ -2483,7 +2585,6 @@ packages:
/emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
dev: false
/encodeurl@1.0.2:
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
@ -2902,7 +3003,6 @@ packages:
dependencies:
cross-spawn: 7.0.3
signal-exit: 4.0.2
dev: false
/fork-ts-checker-webpack-plugin@8.0.0(typescript@5.1.3)(webpack@5.87.0):
resolution: {integrity: sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==}
@ -2961,6 +3061,13 @@ packages:
universalify: 2.0.0
dev: true
/fs-minipass@2.1.0:
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
engines: {node: '>= 8'}
dependencies:
minipass: 3.3.6
dev: false
/fs-monkey@1.0.4:
resolution: {integrity: sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==}
dev: true
@ -2979,6 +3086,21 @@ packages:
/function-bind@1.1.1:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
/gauge@3.0.2:
resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
engines: {node: '>=10'}
dependencies:
aproba: 2.0.0
color-support: 1.1.3
console-control-strings: 1.1.0
has-unicode: 2.0.1
object-assign: 4.1.1
signal-exit: 3.0.7
string-width: 4.2.3
strip-ansi: 6.0.1
wide-align: 1.1.5
dev: false
/gensync@1.0.0-beta.2:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
@ -3044,7 +3166,6 @@ packages:
minimatch: 9.0.2
minipass: 6.0.2
path-scurry: 1.10.0
dev: false
/glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
@ -3055,7 +3176,6 @@ packages:
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
dev: true
/glob@8.1.0:
resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
@ -3136,6 +3256,10 @@ packages:
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
engines: {node: '>= 0.4'}
/has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
dev: false
/has@1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
@ -3165,6 +3289,16 @@ packages:
statuses: 2.0.1
toidentifier: 1.0.1
/https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
dependencies:
agent-base: 6.0.2
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/human-signals@1.1.1:
resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==}
engines: {node: '>=8.12.0'}
@ -3401,7 +3535,6 @@ packages:
'@isaacs/cliui': 8.0.2
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
dev: false
/jest-changed-files@29.5.0:
resolution: {integrity: sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==}
@ -3822,6 +3955,10 @@ packages:
- ts-node
dev: true
/jose@4.14.4:
resolution: {integrity: sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==}
dev: false
/js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
dev: true
@ -3880,6 +4017,31 @@ packages:
graceful-fs: 4.2.11
dev: true
/jsonwebtoken@9.0.0:
resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==}
engines: {node: '>=12', npm: '>=6'}
dependencies:
jws: 3.2.2
lodash: 4.17.21
ms: 2.1.3
semver: 7.5.3
dev: false
/jwa@1.4.1:
resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==}
dependencies:
buffer-equal-constant-time: 1.0.1
ecdsa-sig-formatter: 1.0.11
safe-buffer: 5.2.1
dev: false
/jws@3.2.2:
resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==}
dependencies:
jwa: 1.4.1
safe-buffer: 5.2.1
dev: false
/kleur@3.0.3:
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
engines: {node: '>=6'}
@ -4005,7 +4167,6 @@ packages:
engines: {node: '>=10'}
dependencies:
yallist: 4.0.0
dev: true
/macos-release@2.5.1:
resolution: {integrity: sha512-DXqXhEM7gW59OjZO8NIjBCz9AQ1BEMrfiOAl4AYByHCtVHRF4KoGNO8mqQeM8lRCtQe/UnJ4imO/d2HdkKsd+A==}
@ -4024,7 +4185,6 @@ packages:
engines: {node: '>=8'}
dependencies:
semver: 6.3.0
dev: true
/make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
@ -4100,7 +4260,6 @@ packages:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
dependencies:
brace-expansion: 1.1.11
dev: true
/minimatch@5.1.6:
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
@ -4121,26 +4280,51 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
dependencies:
brace-expansion: 2.0.1
dev: false
/minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
/minipass@3.3.6:
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
engines: {node: '>=8'}
dependencies:
yallist: 4.0.0
dev: false
/minipass@4.2.8:
resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==}
engines: {node: '>=8'}
dev: true
/minipass@5.0.0:
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
engines: {node: '>=8'}
dev: false
/minipass@6.0.2:
resolution: {integrity: sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==}
engines: {node: '>=16 || 14 >=14.17'}
/minizlib@2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'}
dependencies:
minipass: 3.3.6
yallist: 4.0.0
dev: false
/mkdirp@0.5.6:
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
hasBin: true
dependencies:
minimist: 1.2.8
/mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
engines: {node: '>=10'}
hasBin: true
dev: false
/mkdirp@2.1.6:
resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==}
engines: {node: '>=10'}
@ -4212,6 +4396,10 @@ packages:
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
dev: true
/node-addon-api@5.1.0:
resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==}
dev: false
/node-emoji@1.11.0:
resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==}
dependencies:
@ -4237,6 +4425,14 @@ packages:
resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==}
dev: true
/nopt@5.0.0:
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
engines: {node: '>=6'}
hasBin: true
dependencies:
abbrev: 1.1.1
dev: false
/normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
@ -4249,6 +4445,15 @@ packages:
path-key: 3.1.1
dev: true
/npmlog@5.0.1:
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
dependencies:
are-we-there-yet: 2.0.0
console-control-strings: 1.1.0
gauge: 3.0.2
set-blocking: 2.0.0
dev: false
/object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
@ -4394,7 +4599,6 @@ packages:
/path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
dev: true
/path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
@ -4669,7 +4873,6 @@ packages:
inherits: 2.0.4
string_decoder: 1.3.0
util-deprecate: 1.0.2
dev: true
/readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
@ -4760,7 +4963,6 @@ packages:
hasBin: true
dependencies:
glob: 7.2.3
dev: true
/rimraf@4.4.1:
resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==}
@ -4815,7 +5017,6 @@ packages:
/semver@6.3.0:
resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
hasBin: true
dev: true
/semver@7.5.3:
resolution: {integrity: sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==}
@ -4823,7 +5024,6 @@ packages:
hasBin: true
dependencies:
lru-cache: 6.0.0
dev: true
/send@0.18.0:
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
@ -4862,6 +5062,10 @@ packages:
transitivePeerDependencies:
- supports-color
/set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
dev: false
/setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
@ -4902,12 +5106,10 @@ packages:
/signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true
/signal-exit@4.0.2:
resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==}
engines: {node: '>=14'}
dev: false
/sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
@ -4989,7 +5191,6 @@ packages:
eastasianwidth: 0.2.0
emoji-regex: 9.2.2
strip-ansi: 7.1.0
dev: false
/string_decoder@1.1.1:
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
@ -5000,7 +5201,6 @@ packages:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
dependencies:
safe-buffer: 5.2.1
dev: true
/strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
@ -5013,7 +5213,6 @@ packages:
engines: {node: '>=12'}
dependencies:
ansi-regex: 6.0.1
dev: false
/strip-bom@3.0.0:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
@ -5101,6 +5300,18 @@ packages:
engines: {node: '>=6'}
dev: true
/tar@6.1.15:
resolution: {integrity: sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==}
engines: {node: '>=10'}
dependencies:
chownr: 2.0.0
fs-minipass: 2.1.0
minipass: 5.0.0
minizlib: 2.1.2
mkdirp: 1.0.4
yallist: 4.0.0
dev: false
/tarn@3.0.2:
resolution: {integrity: sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==}
engines: {node: '>=8.0.0'}
@ -5667,6 +5878,12 @@ packages:
dependencies:
isexe: 2.0.0
/wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
dependencies:
string-width: 4.2.3
dev: false
/windows-release@4.0.0:
resolution: {integrity: sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==}
engines: {node: '>=10'}
@ -5689,7 +5906,6 @@ packages:
ansi-styles: 6.2.1
string-width: 5.1.2
strip-ansi: 7.1.0
dev: false
/wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
@ -5716,7 +5932,6 @@ packages:
/yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true
/yaml@1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}

34
webpack.config.js Normal file
View File

@ -0,0 +1,34 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const glob = require('glob');
const path = require('path');
const writeGlobEntry = (pattern, to) => {
return glob.sync(pattern).reduce(
(collection, file) => ({
...collection,
[`${to}/${path.basename(file, '.ts')}`]: file,
}),
{},
);
};
module.exports = function (config) {
const appName = process.argv[process.argv.length - 1];
config.entry = {
main: path.join(__dirname, 'apps', appName, 'src', 'main.ts'),
...writeGlobEntry(
path.resolve('apps', appName, 'src', 'database', 'migrations', '*.ts'),
'database/migrations',
),
...writeGlobEntry(
path.resolve('apps', appName, 'src', 'database', 'seeds', '*.ts'),
'database/seeds',
),
};
config.output = {
path: `${__dirname}/dist/apps/${appName}`,
filename: '[name].js',
libraryTarget: 'commonjs',
};
return config;
};