mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 13:21:46 +00:00
feature: db agnostic + base tables
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/node_modules
|
||||||
|
/build
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
/coverage
|
||||||
|
/.nyc_output
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# temp directory
|
||||||
|
.temp
|
||||||
|
.tmp
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="120" alt="Nest Logo" /></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
|
||||||
|
[circleci-url]: https://circleci.com/gh/nestjs/nest
|
||||||
|
|
||||||
|
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
|
||||||
|
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
|
||||||
|
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
|
||||||
|
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
|
||||||
|
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
|
||||||
|
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
|
||||||
|
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
|
||||||
|
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg" alt="Donate us"/></a>
|
||||||
|
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
|
||||||
|
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow" alt="Follow us on Twitter"></a>
|
||||||
|
</p>
|
||||||
|
<!--[](https://opencollective.com/nest#backer)
|
||||||
|
[](https://opencollective.com/nest#sponsor)-->
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compile and run the project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# development
|
||||||
|
$ npm run start
|
||||||
|
|
||||||
|
# watch mode
|
||||||
|
$ npm run start:dev
|
||||||
|
|
||||||
|
# production mode
|
||||||
|
$ npm run start:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# unit tests
|
||||||
|
$ npm run test
|
||||||
|
|
||||||
|
# e2e tests
|
||||||
|
$ npm run test:e2e
|
||||||
|
|
||||||
|
# test coverage
|
||||||
|
$ npm run test:cov
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
When you're ready to deploy your NestJS application to production, there are some key steps you can take to ensure it runs as efficiently as possible. Check out the [deployment documentation](https://docs.nestjs.com/deployment) for more information.
|
||||||
|
|
||||||
|
If you are looking for a cloud-based platform to deploy your NestJS application, check out [Mau](https://mau.nestjs.com), our official platform for deploying NestJS applications on AWS. Mau makes deployment straightforward and fast, requiring just a few simple steps:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm install -g @nestjs/mau
|
||||||
|
$ mau deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
With Mau, you can deploy your application in just a few clicks, allowing you to focus on building features rather than managing infrastructure.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
Check out a few resources that may come in handy when working with NestJS:
|
||||||
|
|
||||||
|
- Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework.
|
||||||
|
- For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy).
|
||||||
|
- To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/).
|
||||||
|
- Deploy your application to AWS with the help of [NestJS Mau](https://mau.nestjs.com) in just a few clicks.
|
||||||
|
- Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com).
|
||||||
|
- Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com).
|
||||||
|
- To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs).
|
||||||
|
- Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com).
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
|
||||||
|
|
||||||
|
## Stay in touch
|
||||||
|
|
||||||
|
- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
|
||||||
|
- Website - [https://nestjs.com](https://nestjs.com/)
|
||||||
|
- Twitter - [@nestframework](https://twitter.com/nestframework)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE).
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
// @ts-check
|
||||||
|
import eslint from '@eslint/js';
|
||||||
|
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
||||||
|
import globals from 'globals';
|
||||||
|
import tseslint from 'typescript-eslint';
|
||||||
|
|
||||||
|
export default tseslint.config(
|
||||||
|
{
|
||||||
|
ignores: ['eslint.config.mjs'],
|
||||||
|
},
|
||||||
|
eslint.configs.recommended,
|
||||||
|
...tseslint.configs.recommendedTypeChecked,
|
||||||
|
eslintPluginPrettierRecommended,
|
||||||
|
{
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node,
|
||||||
|
...globals.jest,
|
||||||
|
},
|
||||||
|
sourceType: 'commonjs',
|
||||||
|
parserOptions: {
|
||||||
|
projectService: true,
|
||||||
|
tsconfigRootDir: import.meta.dirname,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-floating-promises': 'warn',
|
||||||
|
'@typescript-eslint/no-unsafe-argument': 'warn',
|
||||||
|
"prettier/prettier": ["error", { endOfLine: "auto" }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/nest-cli",
|
||||||
|
"collection": "@nestjs/schematics",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"compilerOptions": {
|
||||||
|
"deleteOutDir": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+11956
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"name": "server-nest-2",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "",
|
||||||
|
"author": "",
|
||||||
|
"private": true,
|
||||||
|
"license": "UNLICENSED",
|
||||||
|
"scripts": {
|
||||||
|
"build": "nest build",
|
||||||
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
||||||
|
"start": "nest start",
|
||||||
|
"start:dev": "nest start --watch",
|
||||||
|
"start:debug": "nest start --debug --watch",
|
||||||
|
"start:prod": "node dist/main",
|
||||||
|
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "jest --watch",
|
||||||
|
"test:cov": "jest --coverage",
|
||||||
|
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||||
|
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@better-auth/oauth-provider": "^1.6.9",
|
||||||
|
"@better-auth/passkey": "^1.6.9",
|
||||||
|
"@hedystia/better-auth-typeorm": "^0.8.2",
|
||||||
|
"@nestjs/common": "^11.1.19",
|
||||||
|
"@nestjs/config": "^4.0.4",
|
||||||
|
"@nestjs/core": "^11.1.19",
|
||||||
|
"@nestjs/platform-express": "^11.1.19",
|
||||||
|
"@nestjs/platform-socket.io": "^11.1.19",
|
||||||
|
"@nestjs/throttler": "^6.5.0",
|
||||||
|
"@nestjs/typeorm": "^11.0.1",
|
||||||
|
"@nestjs/websockets": "^11.1.19",
|
||||||
|
"@thallesp/nestjs-better-auth": "^2.6.0",
|
||||||
|
"better-auth": "^1.6.9",
|
||||||
|
"better-sqlite3": "^12.9.0",
|
||||||
|
"csrf-csrf": "^4.0.3",
|
||||||
|
"helmet": "^8.1.0",
|
||||||
|
"mysql2": "^3.22.2",
|
||||||
|
"pg": "^8.20.0",
|
||||||
|
"reflect-metadata": "^0.2.2",
|
||||||
|
"rxjs": "^7.8.2",
|
||||||
|
"typeorm": "^0.3.28"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "^3.2.0",
|
||||||
|
"@eslint/js": "^9.18.0",
|
||||||
|
"@nestjs/cli": "^11.0.0",
|
||||||
|
"@nestjs/schematics": "^11.0.0",
|
||||||
|
"@nestjs/testing": "^11.0.1",
|
||||||
|
"@types/express": "^5.0.0",
|
||||||
|
"@types/jest": "^30.0.0",
|
||||||
|
"@types/node": "^24.0.0",
|
||||||
|
"@types/supertest": "^7.0.0",
|
||||||
|
"eslint": "^9.18.0",
|
||||||
|
"eslint-config-prettier": "^10.0.1",
|
||||||
|
"eslint-plugin-prettier": "^5.2.2",
|
||||||
|
"globals": "^17.0.0",
|
||||||
|
"jest": "^30.0.0",
|
||||||
|
"prettier": "^3.4.2",
|
||||||
|
"source-map-support": "^0.5.21",
|
||||||
|
"supertest": "^7.0.0",
|
||||||
|
"ts-jest": "^29.2.5",
|
||||||
|
"ts-loader": "^9.5.2",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"tsconfig-paths": "^4.2.0",
|
||||||
|
"typescript": "^5.7.3",
|
||||||
|
"typescript-eslint": "^8.20.0"
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"moduleFileExtensions": [
|
||||||
|
"js",
|
||||||
|
"json",
|
||||||
|
"ts"
|
||||||
|
],
|
||||||
|
"rootDir": "src",
|
||||||
|
"testRegex": ".*\\.spec\\.ts$",
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.(t|j)s$": "ts-jest"
|
||||||
|
},
|
||||||
|
"collectCoverageFrom": [
|
||||||
|
"**/*.(t|j)s"
|
||||||
|
],
|
||||||
|
"coverageDirectory": "../coverage",
|
||||||
|
"testEnvironment": "node"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import authConfig from './config/auth.config.js';
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { AuthModule } from './auth/auth.module.js';
|
||||||
|
|
||||||
|
type SupportedDbType = 'mysql' | 'mariadb' | 'postgres' | 'sqlite';
|
||||||
|
|
||||||
|
function resolveDriver(type: SupportedDbType) {
|
||||||
|
switch (type) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'mariadb':
|
||||||
|
return require('mysql2');
|
||||||
|
case 'postgres':
|
||||||
|
return require('pg');
|
||||||
|
case 'sqlite':
|
||||||
|
return require('better-sqlite3');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
ConfigModule.forRoot({ isGlobal: true, load: [authConfig] }),
|
||||||
|
AuthModule,
|
||||||
|
TypeOrmModule.forRootAsync({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
useFactory: (config: ConfigService) => {
|
||||||
|
const type = config.get<SupportedDbType>('DB_TYPE', 'sqlite');
|
||||||
|
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
driver: resolveDriver(type),
|
||||||
|
host: config.get<string>('DB_HOST', 'localhost'),
|
||||||
|
port: config.get<number>('DB_PORT', 5432),
|
||||||
|
username: config.get<string>('DB_USER', 'usr'),
|
||||||
|
password: config.get<string>('DB_PASS', 'pwd'),
|
||||||
|
database: config.get<string>('DB_NAME', 'data/travel.db'),
|
||||||
|
autoLoadEntities: true,
|
||||||
|
synchronize: config.get<string>('NODE_ENV') !== 'production',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
inject: [ConfigService],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { betterAuth } from 'better-auth';
|
||||||
|
import { typeormAdapter } from '@hedystia/better-auth-typeorm';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
import { AuthConfig } from '../config/auth.config.js';
|
||||||
|
|
||||||
|
export function createAuth(dataSource: DataSource, cfg: AuthConfig) {
|
||||||
|
return betterAuth({
|
||||||
|
database: typeormAdapter(dataSource, { debugLogs: cfg.debugLogs }),
|
||||||
|
secret: cfg.secret,
|
||||||
|
baseURL: cfg.baseURL,
|
||||||
|
basePath: '/api/auth',
|
||||||
|
trustedOrigins: cfg.frontendUrl ? [cfg.frontendUrl] : [],
|
||||||
|
advanced: {
|
||||||
|
cookies: { session_token: { name: 'trek_session' } },
|
||||||
|
useSecureCookies: cfg.cookieSecure,
|
||||||
|
},
|
||||||
|
emailAndPassword: { enabled: true },
|
||||||
|
plugins: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { betterAuth } from 'better-auth';
|
||||||
|
import { typeormAdapter } from '@hedystia/better-auth-typeorm';
|
||||||
|
import { magicLink } from 'better-auth/plugins/magic-link';
|
||||||
|
import { genericOAuth } from 'better-auth/plugins/generic-oauth';
|
||||||
|
import { jwt } from 'better-auth/plugins/jwt';
|
||||||
|
import { oauthProvider } from '@better-auth/oauth-provider';
|
||||||
|
import { passkey } from '@better-auth/passkey';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
|
||||||
|
// Used only by `npx @better-auth/cli generate`.
|
||||||
|
// Not imported at runtime — auth.factory.ts uses the DI DataSource.
|
||||||
|
const dataSource = new DataSource({
|
||||||
|
type: 'better-sqlite3',
|
||||||
|
database: ':memory:',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const auth = betterAuth({
|
||||||
|
baseURL: 'http://localhost:3000',
|
||||||
|
database: typeormAdapter(dataSource, {
|
||||||
|
entitiesDir: './src/models/entities/auth',
|
||||||
|
migrationsDir: './src/database/migrations',
|
||||||
|
}),
|
||||||
|
emailAndPassword: {
|
||||||
|
enabled: true,
|
||||||
|
requireEmailVerification: true,
|
||||||
|
sendVerificationEmail: async () => {},
|
||||||
|
sendResetPassword: async () => {},
|
||||||
|
},
|
||||||
|
emailVerification: {
|
||||||
|
sendVerificationEmail: async () => {},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
jwt(),
|
||||||
|
magicLink({ sendMagicLink: async () => {} }),
|
||||||
|
genericOAuth({ config: [] }),
|
||||||
|
oauthProvider({ loginPage: '/login' }),
|
||||||
|
passkey(),
|
||||||
|
],
|
||||||
|
});
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { AuthModule as BetterAuthNestModule } from '@thallesp/nestjs-better-auth';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
import { createAuth } from './auth.factory.js';
|
||||||
|
import { AuthConfig } from '../config/auth.config.js';
|
||||||
|
import { User } from '../models/entities/auth/User.js';
|
||||||
|
import { Account } from '../models/entities/auth/Account.js';
|
||||||
|
import { Session } from '../models/entities/auth/Session.js';
|
||||||
|
import { Verification } from '../models/entities/auth/Verification.js';
|
||||||
|
import { Passkey } from '../models/entities/auth/Passkey.js';
|
||||||
|
import { Jwks } from '../models/entities/auth/Jwks.js';
|
||||||
|
import { OauthClient } from '../models/entities/auth/OauthClient.js';
|
||||||
|
import { OauthAccessToken } from '../models/entities/auth/OauthAccessToken.js';
|
||||||
|
import { OauthRefreshToken } from '../models/entities/auth/OauthRefreshToken.js';
|
||||||
|
import { OauthConsent } from '../models/entities/auth/OauthConsent.js';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
TypeOrmModule.forFeature([
|
||||||
|
User,
|
||||||
|
Account,
|
||||||
|
Session,
|
||||||
|
Verification,
|
||||||
|
Passkey,
|
||||||
|
Jwks,
|
||||||
|
OauthClient,
|
||||||
|
OauthAccessToken,
|
||||||
|
OauthRefreshToken,
|
||||||
|
OauthConsent,
|
||||||
|
]),
|
||||||
|
BetterAuthNestModule.forRootAsync({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
inject: [DataSource, ConfigService],
|
||||||
|
useFactory: (ds: DataSource, config: ConfigService) => ({
|
||||||
|
auth: createAuth(ds, config.get<AuthConfig>('auth')!),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
exports: [BetterAuthNestModule],
|
||||||
|
})
|
||||||
|
export class AuthModule {}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { registerAs } from '@nestjs/config';
|
||||||
|
import { boolean } from 'better-auth';
|
||||||
|
|
||||||
|
export interface AuthConfig {
|
||||||
|
secret: string;
|
||||||
|
baseURL: string;
|
||||||
|
frontendUrl: string | undefined;
|
||||||
|
cookieSecure: boolean;
|
||||||
|
debugLogs: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default registerAs(
|
||||||
|
'auth',
|
||||||
|
(): AuthConfig => ({
|
||||||
|
secret: process.env.BETTER_AUTH_SECRET ?? 'changeme',
|
||||||
|
baseURL: process.env.BETTER_AUTH_URL ?? 'http://localhost:3000',
|
||||||
|
frontendUrl: process.env.BASE_URL,
|
||||||
|
cookieSecure:
|
||||||
|
process.env.COOKIE_SECURE === 'true' &&
|
||||||
|
process.env.NODE_ENV === 'production' &&
|
||||||
|
process.env.BASE_URL?.startsWith('https') === true,
|
||||||
|
debugLogs:
|
||||||
|
process.env.BETTER_AUTH_DEBUG_LOGS === 'true' ||
|
||||||
|
process.env.NODE_ENV === 'development',
|
||||||
|
}),
|
||||||
|
);
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateAccount1777216318138 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'account',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accountId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'providerId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'idToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scope',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'password',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'account',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'account_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'account',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('account');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateSession1777216318138 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'session',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ipAddress',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userAgent',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'session',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'session_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'session',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('session');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateUser1777216318138 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'user',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'email',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'emailVerified',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('user');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateVerification1777216318138 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'verification',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'identifier',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'value',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'verification',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'verification_identifier_idx',
|
||||||
|
columnNames: ['identifier'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('verification');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateAccount1777217712285 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'account',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accountId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'providerId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'idToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scope',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'password',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'account',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'account_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'account',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('account');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthAccessToken1777217712285 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthAccessToken',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'oauthAccessToken_clientId_idx',
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthApplication',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'oauthAccessToken_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthAccessToken');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthApplication1777217712285 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthApplication',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'icon',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'metadata',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientSecret',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'redirectUrls',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'type',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'disabled',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'oauthApplication',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'oauthApplication_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthApplication',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthApplication');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthConsent1777217712285 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthConsent',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'consentGiven',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'oauthConsent_clientId_idx',
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthApplication',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'oauthConsent_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthConsent');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreatePasskey1777217712285 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'passkey',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publicKey',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'credentialID',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'counter',
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'deviceType',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'backedUp',
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'transports',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'aaguid',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'passkey',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'passkey_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'passkey',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'passkey',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'passkey_credentialID_idx',
|
||||||
|
columnNames: ['credentialID'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('passkey');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateSession1777217712285 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'session',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ipAddress',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userAgent',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'session',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'session_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'session',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('session');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateUser1777217712285 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'user',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'email',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'emailVerified',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('user');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateVerification1777217712285 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'verification',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'identifier',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'value',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'verification',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'verification_identifier_idx',
|
||||||
|
columnNames: ['identifier'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('verification');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateAccount1777217820713 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'account',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accountId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'providerId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'idToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scope',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'password',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'account',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'account_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'account',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('account');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthAccessToken1777217820713 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthAccessToken',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sessionId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthClient',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['sessionId'],
|
||||||
|
referencedTableName: 'session',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['refreshId'],
|
||||||
|
referencedTableName: 'oauthRefreshToken',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthAccessToken');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthClient1777217820713 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthClient',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientSecret',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'disabled',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'skipConsent',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'enableEndSession',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'subjectType',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'uri',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'icon',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'contacts',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tos',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'policy',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'softwareId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'softwareVersion',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'softwareStatement',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'redirectUris',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'postLogoutRedirectUris',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tokenEndpointAuthMethod',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'grantTypes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'responseTypes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'public',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'type',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'requirePKCE',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'metadata',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthClient',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthClient');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthConsent1777217820713 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthConsent',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthClient',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthConsent');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthRefreshToken1777217820713 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthRefreshToken',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sessionId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'revoked',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'authTime',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthRefreshToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthClient',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthRefreshToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['sessionId'],
|
||||||
|
referencedTableName: 'session',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthRefreshToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthRefreshToken');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreatePasskey1777217820713 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'passkey',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publicKey',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'credentialID',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'counter',
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'deviceType',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'backedUp',
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'transports',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'aaguid',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'passkey',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'passkey_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'passkey',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'passkey',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'passkey_credentialID_idx',
|
||||||
|
columnNames: ['credentialID'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('passkey');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateSession1777217820713 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'session',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ipAddress',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userAgent',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'session',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'session_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'session',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('session');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateUser1777217820713 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'user',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'email',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'emailVerified',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('user');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateVerification1777217820713 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'verification',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'identifier',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'value',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'verification',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'verification_identifier_idx',
|
||||||
|
columnNames: ['identifier'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('verification');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateAccount1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'account',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accountId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'providerId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'idToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scope',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'password',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'account',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'account_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'account',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('account');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateJwks1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'jwks',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publicKey',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'privateKey',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('jwks');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthAccessToken1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthAccessToken',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sessionId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthClient',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['sessionId'],
|
||||||
|
referencedTableName: 'session',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['refreshId'],
|
||||||
|
referencedTableName: 'oauthRefreshToken',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthAccessToken');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthClient1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthClient',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientSecret',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'disabled',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'skipConsent',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'enableEndSession',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'subjectType',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'uri',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'icon',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'contacts',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tos',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'policy',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'softwareId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'softwareVersion',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'softwareStatement',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'redirectUris',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'postLogoutRedirectUris',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tokenEndpointAuthMethod',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'grantTypes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'responseTypes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'public',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'type',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'requirePKCE',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'metadata',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthClient',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthClient');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthConsent1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthConsent',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthClient',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthConsent');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthRefreshToken1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthRefreshToken',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sessionId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'revoked',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'authTime',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthRefreshToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthClient',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthRefreshToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['sessionId'],
|
||||||
|
referencedTableName: 'session',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthRefreshToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthRefreshToken');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreatePasskey1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'passkey',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publicKey',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'credentialID',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'counter',
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'deviceType',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'backedUp',
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'transports',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'aaguid',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'passkey',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'passkey_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'passkey',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'passkey',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'passkey_credentialID_idx',
|
||||||
|
columnNames: ['credentialID'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('passkey');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateSession1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'session',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ipAddress',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userAgent',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'session',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'session_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'session',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('session');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateUser1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'user',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'email',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'emailVerified',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('user');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateVerification1777217882945 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'verification',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'identifier',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'value',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'verification',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'verification_identifier_idx',
|
||||||
|
columnNames: ['identifier'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('verification');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateAccount1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'account',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accountId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'providerId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'idToken',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accessTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshTokenExpiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scope',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'password',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'account',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'account_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'account',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('account');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateJwks1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'jwks',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publicKey',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'privateKey',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('jwks');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthAccessToken1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthAccessToken',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sessionId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refreshId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthClient',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['sessionId'],
|
||||||
|
referencedTableName: 'session',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthAccessToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['refreshId'],
|
||||||
|
referencedTableName: 'oauthRefreshToken',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthAccessToken');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthClient1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthClient',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientSecret',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'disabled',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'skipConsent',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'enableEndSession',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'subjectType',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'uri',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'icon',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'contacts',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tos',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'policy',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'softwareId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'softwareVersion',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'softwareStatement',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'redirectUris',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'postLogoutRedirectUris',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tokenEndpointAuthMethod',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'grantTypes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'responseTypes',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'public',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'type',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'requirePKCE',
|
||||||
|
type: 'boolean',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'metadata',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthClient',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthClient');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthConsent1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthConsent',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthClient',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthConsent',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthConsent');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateOauthRefreshToken1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'oauthRefreshToken',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'clientId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sessionId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'referenceId',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'revoked',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'authTime',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'scopes',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthRefreshToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['clientId'],
|
||||||
|
referencedTableName: 'oauthClient',
|
||||||
|
referencedColumnNames: ['clientId'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthRefreshToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['sessionId'],
|
||||||
|
referencedTableName: 'session',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'oauthRefreshToken',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('oauthRefreshToken');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreatePasskey1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'passkey',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publicKey',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'credentialID',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'counter',
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'deviceType',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'backedUp',
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'transports',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'aaguid',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'passkey',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'passkey_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'passkey',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'passkey',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'passkey_credentialID_idx',
|
||||||
|
columnNames: ['credentialID'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('passkey');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateSession1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'session',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'token',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ipAddress',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userAgent',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userId',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'session',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'session_userId_idx',
|
||||||
|
columnNames: ['userId'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createForeignKey(
|
||||||
|
'session',
|
||||||
|
new TableForeignKey({
|
||||||
|
columnNames: ['userId'],
|
||||||
|
referencedTableName: 'user',
|
||||||
|
referencedColumnNames: ['id'],
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('session');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateUser1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'user',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'email',
|
||||||
|
type: 'text',
|
||||||
|
isUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'emailVerified',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
type: 'text',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('user');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import {
|
||||||
|
type MigrationInterface,
|
||||||
|
type QueryRunner,
|
||||||
|
Table,
|
||||||
|
TableColumn,
|
||||||
|
TableForeignKey,
|
||||||
|
TableIndex,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
export class CreateVerification1777217895075 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: 'verification',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
type: 'text',
|
||||||
|
isPrimary: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'identifier',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'value',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expiresAt',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createdAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatedAt',
|
||||||
|
type: 'datetime',
|
||||||
|
default: 'CURRENT_TIMESTAMP',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await queryRunner.createIndex(
|
||||||
|
'verification',
|
||||||
|
new TableIndex({
|
||||||
|
name: 'verification_identifier_idx',
|
||||||
|
columnNames: ['identifier'],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropTable('verification');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { NestFactory } from '@nestjs/core';
|
||||||
|
import { AppModule } from './app.module';
|
||||||
|
|
||||||
|
async function bootstrap() {
|
||||||
|
const app = await NestFactory.create(AppModule, { bodyParser: false });
|
||||||
|
await app.listen(process.env.PORT ?? 3001);
|
||||||
|
}
|
||||||
|
bootstrap();
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Entity('bucket_list')
|
||||||
|
export class BucketList extends IntBaseEntity {
|
||||||
|
@Column({ name: 'name' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name: 'lat', nullable: true })
|
||||||
|
lat: number | null;
|
||||||
|
|
||||||
|
@Column({ name: 'lng', nullable: true })
|
||||||
|
lng: number | null;
|
||||||
|
|
||||||
|
@Column({ name: 'country_code', nullable: true })
|
||||||
|
countryCode: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'notes', nullable: true })
|
||||||
|
notes: string | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'target_date',
|
||||||
|
nullable: true,
|
||||||
|
default: null,
|
||||||
|
})
|
||||||
|
targetDate: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.bucketLists, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Entity('visited_countries')
|
||||||
|
export class VisitedCountries extends IntBaseEntity {
|
||||||
|
@Column('text', { name: 'country_code' })
|
||||||
|
countryCode: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.visitedCountries, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Index('idx_visited_regions_country', ['countryCode'], {})
|
||||||
|
@Entity('visited_regions')
|
||||||
|
export class VisitedRegions extends IntBaseEntity {
|
||||||
|
@Column({ name: 'region_code' })
|
||||||
|
regionCode: string;
|
||||||
|
|
||||||
|
@Column({ name: 'region_name' })
|
||||||
|
regionName: string;
|
||||||
|
|
||||||
|
@Column({ name: 'country_code' })
|
||||||
|
countryCode: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.visitedRegions, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
PrimaryColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { User } from './User';
|
||||||
|
|
||||||
|
@Entity('account')
|
||||||
|
export class Account {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'accountId' })
|
||||||
|
accountId: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'providerId' })
|
||||||
|
providerId: string;
|
||||||
|
|
||||||
|
@Index('account_userId_idx')
|
||||||
|
@Column('text', { name: 'userId' })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { onDelete: 'CASCADE', nullable: false })
|
||||||
|
@JoinColumn({ name: 'userId', referencedColumnName: 'id' })
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
@Column('text', { name: 'accessToken', nullable: true })
|
||||||
|
accessToken: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'refreshToken', nullable: true })
|
||||||
|
refreshToken: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'idToken', nullable: true })
|
||||||
|
idToken: string | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'accessTokenExpiresAt', nullable: true })
|
||||||
|
accessTokenExpiresAt: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'refreshTokenExpiresAt', nullable: true })
|
||||||
|
refreshTokenExpiresAt: Date | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'scope', nullable: true })
|
||||||
|
scope: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'password', nullable: true })
|
||||||
|
password: string | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt' })
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'updatedAt' })
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity('jwks')
|
||||||
|
export class Jwks {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'publicKey' })
|
||||||
|
publicKey: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'privateKey' })
|
||||||
|
privateKey: string;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt' })
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'expiresAt', nullable: true })
|
||||||
|
expiresAt: Date | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||||
|
import { OauthClient } from './OauthClient';
|
||||||
|
import { OauthRefreshToken } from './OauthRefreshToken';
|
||||||
|
import { Session } from './Session';
|
||||||
|
import { User } from './User';
|
||||||
|
|
||||||
|
@Entity('oauthAccessToken')
|
||||||
|
export class OauthAccessToken {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'token', nullable: true, unique: true })
|
||||||
|
token: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'clientId' })
|
||||||
|
clientId: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => OauthClient, { onDelete: 'CASCADE', nullable: false })
|
||||||
|
@JoinColumn({ name: 'clientId', referencedColumnName: 'clientId' })
|
||||||
|
client: OauthClient;
|
||||||
|
|
||||||
|
@Column('text', { name: 'sessionId', nullable: true })
|
||||||
|
sessionId: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => Session, { onDelete: 'SET NULL', nullable: true })
|
||||||
|
@JoinColumn({ name: 'sessionId', referencedColumnName: 'id' })
|
||||||
|
session?: Session;
|
||||||
|
|
||||||
|
@Column('text', { name: 'userId', nullable: true })
|
||||||
|
userId: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { onDelete: 'CASCADE', nullable: true })
|
||||||
|
@JoinColumn({ name: 'userId', referencedColumnName: 'id' })
|
||||||
|
user?: User;
|
||||||
|
|
||||||
|
@Column('text', { name: 'referenceId', nullable: true })
|
||||||
|
referenceId: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'refreshId', nullable: true })
|
||||||
|
refreshId: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => OauthRefreshToken, { onDelete: 'CASCADE', nullable: true })
|
||||||
|
@JoinColumn({ name: 'refreshId', referencedColumnName: 'id' })
|
||||||
|
refresh?: OauthRefreshToken;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'expiresAt', nullable: true })
|
||||||
|
expiresAt: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt', nullable: true })
|
||||||
|
createdAt: Date | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'scopes' })
|
||||||
|
scopes: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
PrimaryColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { User } from './User';
|
||||||
|
|
||||||
|
@Entity('oauthApplication')
|
||||||
|
export class OauthApplication {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'name', nullable: true })
|
||||||
|
name: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'icon', nullable: true })
|
||||||
|
icon: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'metadata', nullable: true })
|
||||||
|
metadata: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'clientId', nullable: true, unique: true })
|
||||||
|
clientId: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'clientSecret', nullable: true })
|
||||||
|
clientSecret: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'redirectUrls', nullable: true })
|
||||||
|
redirectUrls: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'type', nullable: true })
|
||||||
|
type: string | null;
|
||||||
|
|
||||||
|
@Column('boolean', { name: 'disabled', nullable: true, default: false })
|
||||||
|
disabled: boolean | null;
|
||||||
|
|
||||||
|
@Index('oauthApplication_userId_idx')
|
||||||
|
@Column('text', { name: 'userId', nullable: true })
|
||||||
|
userId: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { onDelete: 'CASCADE', nullable: true })
|
||||||
|
@JoinColumn({ name: 'userId', referencedColumnName: 'id' })
|
||||||
|
user?: User;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt', nullable: true })
|
||||||
|
createdAt: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'updatedAt', nullable: true })
|
||||||
|
updatedAt: Date | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||||
|
import { User } from './User';
|
||||||
|
|
||||||
|
@Entity('oauthClient')
|
||||||
|
export class OauthClient {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'clientId', unique: true })
|
||||||
|
clientId: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'clientSecret', nullable: true })
|
||||||
|
clientSecret: string | null;
|
||||||
|
|
||||||
|
@Column('boolean', { name: 'disabled', nullable: true, default: false })
|
||||||
|
disabled: boolean | null;
|
||||||
|
|
||||||
|
@Column('boolean', { name: 'skipConsent', nullable: true })
|
||||||
|
skipConsent: boolean | null;
|
||||||
|
|
||||||
|
@Column('boolean', { name: 'enableEndSession', nullable: true })
|
||||||
|
enableEndSession: boolean | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'subjectType', nullable: true })
|
||||||
|
subjectType: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'scopes', nullable: true })
|
||||||
|
scopes: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'userId', nullable: true })
|
||||||
|
userId: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { onDelete: 'CASCADE', nullable: true })
|
||||||
|
@JoinColumn({ name: 'userId', referencedColumnName: 'id' })
|
||||||
|
user?: User;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt', nullable: true })
|
||||||
|
createdAt: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'updatedAt', nullable: true })
|
||||||
|
updatedAt: Date | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'name', nullable: true })
|
||||||
|
name: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'uri', nullable: true })
|
||||||
|
uri: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'icon', nullable: true })
|
||||||
|
icon: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'contacts', nullable: true })
|
||||||
|
contacts: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'tos', nullable: true })
|
||||||
|
tos: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'policy', nullable: true })
|
||||||
|
policy: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'softwareId', nullable: true })
|
||||||
|
softwareId: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'softwareVersion', nullable: true })
|
||||||
|
softwareVersion: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'softwareStatement', nullable: true })
|
||||||
|
softwareStatement: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'redirectUris' })
|
||||||
|
redirectUris: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'postLogoutRedirectUris', nullable: true })
|
||||||
|
postLogoutRedirectUris: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'tokenEndpointAuthMethod', nullable: true })
|
||||||
|
tokenEndpointAuthMethod: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'grantTypes', nullable: true })
|
||||||
|
grantTypes: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'responseTypes', nullable: true })
|
||||||
|
responseTypes: string | null;
|
||||||
|
|
||||||
|
@Column('boolean', { name: 'public', nullable: true })
|
||||||
|
public: boolean | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'type', nullable: true })
|
||||||
|
type: string | null;
|
||||||
|
|
||||||
|
@Column('boolean', { name: 'requirePKCE', nullable: true })
|
||||||
|
requirePKCE: boolean | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'referenceId', nullable: true })
|
||||||
|
referenceId: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'metadata', nullable: true })
|
||||||
|
metadata: string | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||||
|
import { OauthClient } from './OauthClient';
|
||||||
|
import { User } from './User';
|
||||||
|
|
||||||
|
@Entity('oauthConsent')
|
||||||
|
export class OauthConsent {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'clientId' })
|
||||||
|
clientId: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => OauthClient, { onDelete: 'CASCADE', nullable: false })
|
||||||
|
@JoinColumn({ name: 'clientId', referencedColumnName: 'clientId' })
|
||||||
|
client: OauthClient;
|
||||||
|
|
||||||
|
@Column('text', { name: 'userId', nullable: true })
|
||||||
|
userId: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { onDelete: 'CASCADE', nullable: true })
|
||||||
|
@JoinColumn({ name: 'userId', referencedColumnName: 'id' })
|
||||||
|
user?: User;
|
||||||
|
|
||||||
|
@Column('text', { name: 'referenceId', nullable: true })
|
||||||
|
referenceId: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'scopes' })
|
||||||
|
scopes: string;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt', nullable: true })
|
||||||
|
createdAt: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'updatedAt', nullable: true })
|
||||||
|
updatedAt: Date | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||||
|
import { OauthClient } from './OauthClient';
|
||||||
|
import { Session } from './Session';
|
||||||
|
import { User } from './User';
|
||||||
|
|
||||||
|
@Entity('oauthRefreshToken')
|
||||||
|
export class OauthRefreshToken {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'token', unique: true })
|
||||||
|
token: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'clientId' })
|
||||||
|
clientId: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => OauthClient, { onDelete: 'CASCADE', nullable: false })
|
||||||
|
@JoinColumn({ name: 'clientId', referencedColumnName: 'clientId' })
|
||||||
|
client: OauthClient;
|
||||||
|
|
||||||
|
@Column('text', { name: 'sessionId', nullable: true })
|
||||||
|
sessionId: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => Session, { onDelete: 'SET NULL', nullable: true })
|
||||||
|
@JoinColumn({ name: 'sessionId', referencedColumnName: 'id' })
|
||||||
|
session?: Session;
|
||||||
|
|
||||||
|
@Column('text', { name: 'userId' })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { onDelete: 'CASCADE', nullable: false })
|
||||||
|
@JoinColumn({ name: 'userId', referencedColumnName: 'id' })
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
@Column('text', { name: 'referenceId', nullable: true })
|
||||||
|
referenceId: string | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'expiresAt', nullable: true })
|
||||||
|
expiresAt: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt', nullable: true })
|
||||||
|
createdAt: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'revoked', nullable: true })
|
||||||
|
revoked: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'authTime', nullable: true })
|
||||||
|
authTime: Date | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'scopes' })
|
||||||
|
scopes: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
PrimaryColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { User } from './User';
|
||||||
|
|
||||||
|
@Entity('passkey')
|
||||||
|
export class Passkey {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'name', nullable: true })
|
||||||
|
name: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'publicKey' })
|
||||||
|
publicKey: string;
|
||||||
|
|
||||||
|
@Index('passkey_userId_idx')
|
||||||
|
@Column('text', { name: 'userId' })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { onDelete: 'CASCADE', nullable: false })
|
||||||
|
@JoinColumn({ name: 'userId', referencedColumnName: 'id' })
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
@Index('passkey_credentialID_idx')
|
||||||
|
@Column('text', { name: 'credentialID' })
|
||||||
|
credentialID: string;
|
||||||
|
|
||||||
|
@Column('integer', { name: 'counter' })
|
||||||
|
counter: number;
|
||||||
|
|
||||||
|
@Column('text', { name: 'deviceType' })
|
||||||
|
deviceType: string;
|
||||||
|
|
||||||
|
@Column('boolean', { name: 'backedUp' })
|
||||||
|
backedUp: boolean;
|
||||||
|
|
||||||
|
@Column('text', { name: 'transports', nullable: true })
|
||||||
|
transports: string | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt', nullable: true })
|
||||||
|
createdAt: Date | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'aaguid', nullable: true })
|
||||||
|
aaguid: string | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
PrimaryColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { User } from './User';
|
||||||
|
|
||||||
|
@Entity('session')
|
||||||
|
export class Session {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'expiresAt' })
|
||||||
|
expiresAt: Date;
|
||||||
|
|
||||||
|
@Column('text', { name: 'token', unique: true })
|
||||||
|
token: string;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt' })
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'updatedAt' })
|
||||||
|
updatedAt: Date;
|
||||||
|
|
||||||
|
@Column('text', { name: 'ipAddress', nullable: true })
|
||||||
|
ipAddress: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'userAgent', nullable: true })
|
||||||
|
userAgent: string | null;
|
||||||
|
|
||||||
|
@Index('session_userId_idx')
|
||||||
|
@Column('text', { name: 'userId' })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => User, { onDelete: 'CASCADE', nullable: false })
|
||||||
|
@JoinColumn({ name: 'userId', referencedColumnName: 'id' })
|
||||||
|
user: User;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity('user')
|
||||||
|
export class User {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'name' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'email', unique: true })
|
||||||
|
email: string;
|
||||||
|
|
||||||
|
@Column('boolean', { name: 'emailVerified', default: false })
|
||||||
|
emailVerified: boolean;
|
||||||
|
|
||||||
|
@Column('text', { name: 'image', nullable: true })
|
||||||
|
image: string | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt' })
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'updatedAt' })
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* AUTOGENERATED
|
||||||
|
*/
|
||||||
|
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity('verification')
|
||||||
|
export class Verification {
|
||||||
|
@PrimaryColumn('text')
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Index('verification_identifier_idx')
|
||||||
|
@Column('text', { name: 'identifier' })
|
||||||
|
identifier: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'value' })
|
||||||
|
value: string;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'expiresAt' })
|
||||||
|
expiresAt: Date;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'createdAt' })
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamp', name: 'updatedAt' })
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
DeleteDateColumn,
|
||||||
|
PrimaryColumn,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
// Layer 1 — timestamps only, always present
|
||||||
|
export abstract class TimestampedEntity {
|
||||||
|
@CreateDateColumn({ name: 'created_at' })
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@UpdateDateColumn({ name: 'updated_at' })
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class TimestampedSortableEntity extends TimestampedEntity {
|
||||||
|
@Column('int', { name: 'sort_order', default: 0 })
|
||||||
|
sortOrder: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 2 — adds soft delete
|
||||||
|
export abstract class SoftDeletableEntity extends TimestampedEntity {
|
||||||
|
@DeleteDateColumn({ name: 'deleted_at', nullable: true })
|
||||||
|
deletedAt: Date | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 3a — adds integer PK to timestamped entity
|
||||||
|
export abstract class IntBaseEntity extends TimestampedEntity {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class IntSortableBaseEntity extends IntBaseEntity {
|
||||||
|
@Column('int', { name: 'sort_order', default: 0 })
|
||||||
|
sortOrder: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 3b — adds integer PK + soft delete
|
||||||
|
export abstract class SoftDeletableIntBaseEntity extends SoftDeletableEntity {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 3c — natural/business string PK (e.g. country code, slug)
|
||||||
|
export abstract class StringBaseEntity extends TimestampedEntity {
|
||||||
|
@PrimaryColumn({ name: 'id' })
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class StringSortableBaseEntity extends StringBaseEntity {
|
||||||
|
@Column('int', { name: 'sort_order', default: 0 })
|
||||||
|
sortOrder: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer 3d — natural string PK + soft delete
|
||||||
|
export abstract class SoftDeletableStringBaseEntity extends SoftDeletableEntity {
|
||||||
|
@PrimaryColumn({ name: 'id' })
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Index('idx_mcp_tokens_hash', ['tokenHash'], { unique: true })
|
||||||
|
@Entity('mcp_tokens')
|
||||||
|
export class McpTokens extends IntBaseEntity {
|
||||||
|
@Column({ name: 'name' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name: 'token_hash', unique: true })
|
||||||
|
tokenHash: string;
|
||||||
|
|
||||||
|
@Column({ name: 'token_prefix' })
|
||||||
|
tokenPrefix: string;
|
||||||
|
|
||||||
|
@Column({ name: 'last_used_at', nullable: true })
|
||||||
|
lastUsedAt: Date | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.mcpTokens, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
PrimaryColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Index('idx_ncp_user', ['userId'], {})
|
||||||
|
@Entity('notification_channel_preferences')
|
||||||
|
export class NotificationChannelPreferences {
|
||||||
|
@PrimaryColumn('int', { name: 'user_id' })
|
||||||
|
userId: number;
|
||||||
|
|
||||||
|
@PrimaryColumn({ name: 'event_type' })
|
||||||
|
eventType: string;
|
||||||
|
|
||||||
|
@PrimaryColumn({ name: 'channel' })
|
||||||
|
channel: string;
|
||||||
|
|
||||||
|
@Column({ name: 'enabled', default: true })
|
||||||
|
enabled: boolean;
|
||||||
|
|
||||||
|
@ManyToOne(
|
||||||
|
() => SqliteUsers,
|
||||||
|
(users) => users.notificationChannelPreferences,
|
||||||
|
{
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Index('idx_notifications_target_scope', ['target', 'scope'], {})
|
||||||
|
@Index('idx_notifications_recipient_created', ['recipientId', 'createdAt'], {})
|
||||||
|
@Index(
|
||||||
|
'idx_notifications_recipient',
|
||||||
|
['recipientId', 'isRead', 'createdAt'],
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
@Entity('notifications')
|
||||||
|
export class Notifications extends IntBaseEntity {
|
||||||
|
@Column({ name: 'type' })
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
@Column({ name: 'scope' })
|
||||||
|
scope: string;
|
||||||
|
|
||||||
|
@Column('int', { name: 'target' })
|
||||||
|
target: number;
|
||||||
|
|
||||||
|
@Column('int', { name: 'recipient_id' })
|
||||||
|
recipientId: number;
|
||||||
|
|
||||||
|
@Column({ name: 'title_key' })
|
||||||
|
titleKey: string;
|
||||||
|
|
||||||
|
@Column('simple-json', {
|
||||||
|
name: 'title_params',
|
||||||
|
nullable: true,
|
||||||
|
default: {},
|
||||||
|
})
|
||||||
|
titleParams: Record<string, unknown> | null;
|
||||||
|
|
||||||
|
@Column({ name: 'text_key' })
|
||||||
|
textKey: string;
|
||||||
|
|
||||||
|
@Column('simple-json', {
|
||||||
|
name: 'text_params',
|
||||||
|
nullable: true,
|
||||||
|
default: {},
|
||||||
|
})
|
||||||
|
textParams: Record<string, unknown> | null;
|
||||||
|
|
||||||
|
@Column({ name: 'positive_text_key', nullable: true })
|
||||||
|
positiveTextKey: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'negative_text_key', nullable: true })
|
||||||
|
negativeTextKey: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'positive_callback', nullable: true })
|
||||||
|
positiveCallback: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'negative_callback', nullable: true })
|
||||||
|
negativeCallback: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'response', nullable: true })
|
||||||
|
response: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'navigate_text_key', nullable: true })
|
||||||
|
navigateTextKey: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'navigate_target', nullable: true })
|
||||||
|
navigateTarget: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'is_read', nullable: true, default: false })
|
||||||
|
isRead: boolean | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.notifications, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'recipient_id', referencedColumnName: 'id' }])
|
||||||
|
recipient: SqliteUsers;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.notifications2, {
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'sender_id', referencedColumnName: 'id' }])
|
||||||
|
sender: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
OneToMany,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { OldOauthConsents } from './OldOauthConsents';
|
||||||
|
import { OldOauthTokens } from './OldOauthTokens';
|
||||||
|
import { SqliteUsers } from './SqliteUsers';
|
||||||
|
import { StringBaseEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Index('idx_oauth_clients_client_id', ['clientId'], { unique: true })
|
||||||
|
@Index('idx_oauth_clients_user', ['userId'], {})
|
||||||
|
@Entity('oauth_clients')
|
||||||
|
export class OldOauthClients extends StringBaseEntity {
|
||||||
|
@Column('int', { name: 'user_id', nullable: true })
|
||||||
|
userId: number | null;
|
||||||
|
|
||||||
|
@Column({ name: 'name' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name: 'client_id', unique: true })
|
||||||
|
clientId: string;
|
||||||
|
|
||||||
|
@Column({ name: 'client_secret_hash' })
|
||||||
|
clientSecretHash: string;
|
||||||
|
|
||||||
|
@Column('simple-array', { name: 'redirect_uris', default: [] })
|
||||||
|
redirectUris: string[];
|
||||||
|
|
||||||
|
@Column('simple-array', { name: 'allowed_scopes', default: [] })
|
||||||
|
allowedScopes: string[];
|
||||||
|
|
||||||
|
@Column({ name: 'is_public', default: false })
|
||||||
|
isPublic: boolean;
|
||||||
|
|
||||||
|
@Column({ name: 'created_via', default: 'settings_ui' })
|
||||||
|
createdVia: string;
|
||||||
|
|
||||||
|
@OneToMany(() => OldOauthConsents, (oauthConsents) => oauthConsents.client)
|
||||||
|
oauthConsents: OldOauthConsents[];
|
||||||
|
|
||||||
|
@OneToMany(() => OldOauthTokens, (oauthTokens) => oauthTokens.client)
|
||||||
|
oauthTokens: OldOauthTokens[];
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.oauthClients, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { SqliteUsers } from './SqliteUsers';
|
||||||
|
import { OldOauthClients } from './OldOauthClients';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Entity('oauth_consents')
|
||||||
|
export class OldOauthConsents extends IntBaseEntity {
|
||||||
|
@Column('simple-array', { name: 'scopes', default: [] })
|
||||||
|
scopes: string[];
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.oauthConsents, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
|
||||||
|
@ManyToOne(
|
||||||
|
() => OldOauthClients,
|
||||||
|
(oauthClients) => oauthClients.oauthConsents,
|
||||||
|
{
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
@JoinColumn([{ name: 'client_id', referencedColumnName: 'clientId' }])
|
||||||
|
client: OldOauthClients;
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
OneToMany,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { SqliteUsers } from './SqliteUsers';
|
||||||
|
import { OldOauthClients } from './OldOauthClients';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Index('idx_oauth_tokens_parent', ['parentTokenId'], {})
|
||||||
|
@Index('idx_oauth_tokens_refresh', ['refreshTokenHash'], { unique: true })
|
||||||
|
@Index('idx_oauth_tokens_access', ['accessTokenHash'], { unique: true })
|
||||||
|
@Index('idx_oauth_tokens_user', ['userId'], {})
|
||||||
|
@Entity('oauth_tokens')
|
||||||
|
export class OldOauthTokens extends IntBaseEntity {
|
||||||
|
@Column('int', { name: 'user_id' })
|
||||||
|
userId: number;
|
||||||
|
|
||||||
|
@Column({ name: 'access_token_hash', unique: true })
|
||||||
|
accessTokenHash: string;
|
||||||
|
|
||||||
|
@Column({ name: 'refresh_token_hash', unique: true })
|
||||||
|
refreshTokenHash: string;
|
||||||
|
|
||||||
|
@Column('simple-array', { name: 'scopes', default: [] })
|
||||||
|
scopes: string[];
|
||||||
|
|
||||||
|
@Column('datetime', { name: 'access_token_expires_at' })
|
||||||
|
accessTokenExpiresAt: Date;
|
||||||
|
|
||||||
|
@Column('datetime', { name: 'refresh_token_expires_at' })
|
||||||
|
refreshTokenExpiresAt: Date;
|
||||||
|
|
||||||
|
@Column('datetime', { name: 'revoked_at', nullable: true })
|
||||||
|
revokedAt: Date | null;
|
||||||
|
|
||||||
|
@Column('int', { name: 'parent_token_id', nullable: true })
|
||||||
|
parentTokenId: number | null;
|
||||||
|
|
||||||
|
@Column({ name: 'audience', nullable: true })
|
||||||
|
audience: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => OldOauthTokens, (oauthTokens) => oauthTokens.oauthTokens)
|
||||||
|
@JoinColumn([{ name: 'parent_token_id', referencedColumnName: 'id' }])
|
||||||
|
parentToken: OldOauthTokens;
|
||||||
|
|
||||||
|
@OneToMany(() => OldOauthTokens, (oauthTokens) => oauthTokens.parentToken)
|
||||||
|
oauthTokens: OldOauthTokens[];
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.oauthTokens, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
|
||||||
|
@ManyToOne(
|
||||||
|
() => OldOauthClients,
|
||||||
|
(oauthClients) => oauthClients.oauthTokens,
|
||||||
|
{
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
@JoinColumn([{ name: 'client_id', referencedColumnName: 'clientId' }])
|
||||||
|
client: OldOauthClients;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { SqliteUsers } from './SqliteUsers';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Index('idx_prt_hash', ['tokenHash'], {})
|
||||||
|
@Index('idx_prt_user', ['userId'], {})
|
||||||
|
@Entity('password_reset_tokens')
|
||||||
|
export class OldPasswordResetTokens extends IntBaseEntity {
|
||||||
|
@Column('int', { name: 'user_id' })
|
||||||
|
userId: number;
|
||||||
|
|
||||||
|
@Column({ name: 'token_hash', unique: true })
|
||||||
|
tokenHash: string;
|
||||||
|
|
||||||
|
@Column({ name: 'expires_at' })
|
||||||
|
expiresAt: Date;
|
||||||
|
|
||||||
|
@Column({ name: 'consumed_at', nullable: true })
|
||||||
|
consumedAt: Date | null;
|
||||||
|
|
||||||
|
@Column({ name: 'created_ip', nullable: true })
|
||||||
|
createdIp: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.passwordResetTokens, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,341 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinTable,
|
||||||
|
ManyToMany,
|
||||||
|
OneToMany,
|
||||||
|
OneToOne,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { OldPasswordResetTokens } from './OldPasswordResetTokens';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { Settings } from '../system/Settings';
|
||||||
|
import { Trips } from '../trip/Trips';
|
||||||
|
import { Categories } from '../trip/Categories';
|
||||||
|
import { Tags } from '../trip/Tags';
|
||||||
|
import { TripFiles } from '../trip/files/TripFiles';
|
||||||
|
import { BudgetItems } from '../trip/budget/BudgetItems';
|
||||||
|
import { VacayPlans } from '../vacay/VacayPlans';
|
||||||
|
import { TripMembers } from '../trip/TripMembers';
|
||||||
|
import { VacayPlanMembers } from '../vacay/VacayPlanMembers';
|
||||||
|
import { VacayUserColors } from '../vacay/VacayUserColors';
|
||||||
|
import { VacayUserYears } from '../vacay/VacayUserYears';
|
||||||
|
import { VacayEntries } from '../vacay/VacayEntries';
|
||||||
|
import { CollabNotes } from '../trip/collab/CollabNotes';
|
||||||
|
import { CollabPolls } from '../trip/collab/CollabPolls';
|
||||||
|
import { CollabPollVotes } from '../trip/collab/CollabPollVotes';
|
||||||
|
import { CollabMessages } from '../trip/collab/CollabMessages';
|
||||||
|
import { AssignmentParticipants } from '../trip/AssignmentParticipants';
|
||||||
|
import { AuditLog } from '../system/AuditLog';
|
||||||
|
import { Notifications } from '../notification/Notifications';
|
||||||
|
import { NotificationChannelPreferences } from '../notification/NotificationChannelPreferences';
|
||||||
|
import { BudgetItemMembers } from '../trip/budget/BudgetItemMembers';
|
||||||
|
import { CollabMessageReactions } from '../trip/collab/CollabMessageReactions';
|
||||||
|
import { InviteTokens } from '../system/InviteTokens';
|
||||||
|
import { PackingCategoryAssignees } from '../trip/lists/PackingCategoryAssignees';
|
||||||
|
import { PackingTemplates } from '../trip/lists/PackingTemplates';
|
||||||
|
import { PackingBags } from '../trip/lists/PackingBags';
|
||||||
|
import { VisitedCountries } from '../atlas/VisitedCountries';
|
||||||
|
import { BucketList } from '../atlas/BucketList';
|
||||||
|
import { ShareTokens } from '../trip/ShareTokens';
|
||||||
|
import { McpTokens } from '../mcp/McpTokens';
|
||||||
|
import { TripAlbumLinks } from '../trip/journey/TripAlbumLinks';
|
||||||
|
import { TodoItems } from '../trip/lists/TodoItems';
|
||||||
|
import { TodoCategoryAssignees } from '../trip/lists/TodoCategoryAssignees';
|
||||||
|
import { VisitedRegions } from '../atlas/VisitedRegions';
|
||||||
|
import { OldOauthConsents } from './OldOauthConsents';
|
||||||
|
import { OldOauthTokens } from './OldOauthTokens';
|
||||||
|
import { Journeys } from '../trip/journey/Journeys';
|
||||||
|
import { JourneyEntries } from '../trip/journey/JourneyEntries';
|
||||||
|
import { JourneyContributors } from '../trip/journey/JourneyContributors';
|
||||||
|
import { JourneyShareTokens } from '../trip/journey/JourneyShareTokens';
|
||||||
|
import { TrekPhotos } from '../trip/journey/TrekPhotos';
|
||||||
|
import { TripPhotos } from '../trip/TripPhotos';
|
||||||
|
import { UserNoticeDismissals } from '../system/UserNoticeDismissals';
|
||||||
|
import { IdempotencyKeys } from '../system/IdempotencyKeys';
|
||||||
|
import { OldOauthClients } from './OldOauthClients';
|
||||||
|
|
||||||
|
@Index('idx_users_email', ['email'], {})
|
||||||
|
@Entity('users')
|
||||||
|
export class SqliteUsers extends IntBaseEntity {
|
||||||
|
@Column({ name: 'username', unique: true })
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@Column({ name: 'email', unique: true })
|
||||||
|
email: string;
|
||||||
|
|
||||||
|
@Column({ name: 'password_hash' })
|
||||||
|
passwordHash: string;
|
||||||
|
|
||||||
|
@Column({ name: 'role', default: 'user' })
|
||||||
|
role: string;
|
||||||
|
|
||||||
|
@Column({ name: 'maps_api_key', nullable: true })
|
||||||
|
mapsApiKey: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'unsplash_api_key', nullable: true })
|
||||||
|
unsplashApiKey: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'openweather_api_key', nullable: true })
|
||||||
|
openweatherApiKey: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'avatar', nullable: true })
|
||||||
|
avatar: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'oidc_sub', nullable: true })
|
||||||
|
oidcSub: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'oidc_issuer', nullable: true })
|
||||||
|
oidcIssuer: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'last_login', nullable: true })
|
||||||
|
lastLogin: Date | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'mfa_enabled',
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
mfaEnabled: boolean;
|
||||||
|
|
||||||
|
@Column({ name: 'mfa_secret', nullable: true })
|
||||||
|
mfaSecret: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'mfa_backup_codes', nullable: true })
|
||||||
|
mfaBackupCodes: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'immich_url', nullable: true })
|
||||||
|
immichUrl: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'immich_access_token', nullable: true })
|
||||||
|
immichAccessToken: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'synology_url', nullable: true })
|
||||||
|
synologyUrl: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'synology_username', nullable: true })
|
||||||
|
synologyUsername: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'synology_password', nullable: true })
|
||||||
|
synologyPassword: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'synology_sid', nullable: true })
|
||||||
|
synologySid: string | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'must_change_password',
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
mustChangePassword: boolean;
|
||||||
|
|
||||||
|
@Column('int', { name: 'password_version', default: 0 })
|
||||||
|
passwordVersion: number;
|
||||||
|
|
||||||
|
@Column({ name: 'immich_api_key', nullable: true })
|
||||||
|
immichApiKey: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'synology_skip_ssl', default: false })
|
||||||
|
synologySkipSsl: boolean;
|
||||||
|
|
||||||
|
@Column({ name: 'synology_did', nullable: true })
|
||||||
|
synologyDid: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'first_seen_version', default: '0.0.0' })
|
||||||
|
firstSeenVersion: string;
|
||||||
|
|
||||||
|
@Column('int', { name: 'login_count', default: 0 })
|
||||||
|
loginCount: number;
|
||||||
|
|
||||||
|
@Column({ name: 'immich_auto_upload', default: false })
|
||||||
|
immichAutoUpload: boolean;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => OldPasswordResetTokens,
|
||||||
|
(passwordResetTokens) => passwordResetTokens.user,
|
||||||
|
)
|
||||||
|
passwordResetTokens: OldPasswordResetTokens[];
|
||||||
|
|
||||||
|
@OneToMany(() => Settings, (settings) => settings.user)
|
||||||
|
settings: Settings[];
|
||||||
|
|
||||||
|
@OneToMany(() => Trips, (trips) => trips.user)
|
||||||
|
trips: Trips[];
|
||||||
|
|
||||||
|
@OneToMany(() => Categories, (categories) => categories.user)
|
||||||
|
categories: Categories[];
|
||||||
|
|
||||||
|
@OneToMany(() => Tags, (tags) => tags.user)
|
||||||
|
tags: Tags[];
|
||||||
|
|
||||||
|
@OneToMany(() => TripFiles, (tripFiles) => tripFiles.uploadedBy)
|
||||||
|
tripFiles: TripFiles[];
|
||||||
|
|
||||||
|
@OneToMany(() => TripMembers, (tripMembers) => tripMembers.invitedBy)
|
||||||
|
tripMembers: TripMembers[];
|
||||||
|
|
||||||
|
@OneToMany(() => TripMembers, (tripMembers) => tripMembers.user)
|
||||||
|
tripMembers2: TripMembers[];
|
||||||
|
|
||||||
|
@OneToMany(() => BudgetItems, (budgetItems) => budgetItems.paidByUser)
|
||||||
|
budgetItems: BudgetItems[];
|
||||||
|
|
||||||
|
@OneToOne(() => VacayPlans, (vacayPlans) => vacayPlans.owner)
|
||||||
|
vacayPlans: VacayPlans;
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => VacayPlanMembers,
|
||||||
|
(vacayPlanMembers) => vacayPlanMembers.user,
|
||||||
|
)
|
||||||
|
vacayPlanMembers: VacayPlanMembers[];
|
||||||
|
|
||||||
|
@OneToMany(() => VacayUserColors, (vacayUserColors) => vacayUserColors.user)
|
||||||
|
vacayUserColors: VacayUserColors[];
|
||||||
|
|
||||||
|
@OneToMany(() => VacayUserYears, (vacayUserYears) => vacayUserYears.user)
|
||||||
|
vacayUserYears: VacayUserYears[];
|
||||||
|
|
||||||
|
@OneToMany(() => VacayEntries, (vacayEntries) => vacayEntries.user)
|
||||||
|
vacayEntries: VacayEntries[];
|
||||||
|
|
||||||
|
@OneToMany(() => CollabNotes, (collabNotes) => collabNotes.user)
|
||||||
|
collabNotes: CollabNotes[];
|
||||||
|
|
||||||
|
@OneToMany(() => CollabPolls, (collabPolls) => collabPolls.user)
|
||||||
|
collabPolls: CollabPolls[];
|
||||||
|
|
||||||
|
@OneToMany(() => CollabPollVotes, (collabPollVotes) => collabPollVotes.user)
|
||||||
|
collabPollVotes: CollabPollVotes[];
|
||||||
|
|
||||||
|
@OneToMany(() => CollabMessages, (collabMessages) => collabMessages.user)
|
||||||
|
collabMessages: CollabMessages[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => AssignmentParticipants,
|
||||||
|
(assignmentParticipants) => assignmentParticipants.user,
|
||||||
|
)
|
||||||
|
assignmentParticipants: AssignmentParticipants[];
|
||||||
|
|
||||||
|
@OneToMany(() => AuditLog, (auditLog) => auditLog.user)
|
||||||
|
auditLogs: AuditLog[];
|
||||||
|
|
||||||
|
@OneToMany(() => Notifications, (notifications) => notifications.recipient)
|
||||||
|
notifications: Notifications[];
|
||||||
|
|
||||||
|
@OneToMany(() => Notifications, (notifications) => notifications.sender)
|
||||||
|
notifications2: Notifications[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => NotificationChannelPreferences,
|
||||||
|
(notificationChannelPreferences) => notificationChannelPreferences.user,
|
||||||
|
)
|
||||||
|
notificationChannelPreferences: NotificationChannelPreferences[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => BudgetItemMembers,
|
||||||
|
(budgetItemMembers) => budgetItemMembers.user,
|
||||||
|
)
|
||||||
|
budgetItemMembers: BudgetItemMembers[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => CollabMessageReactions,
|
||||||
|
(collabMessageReactions) => collabMessageReactions.user,
|
||||||
|
)
|
||||||
|
collabMessageReactions: CollabMessageReactions[];
|
||||||
|
|
||||||
|
@OneToMany(() => InviteTokens, (inviteTokens) => inviteTokens.createdBy)
|
||||||
|
inviteTokens: InviteTokens[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => PackingCategoryAssignees,
|
||||||
|
(packingCategoryAssignees) => packingCategoryAssignees.user,
|
||||||
|
)
|
||||||
|
packingCategoryAssignees: PackingCategoryAssignees[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => PackingTemplates,
|
||||||
|
(packingTemplates) => packingTemplates.createdBy,
|
||||||
|
)
|
||||||
|
packingTemplates: PackingTemplates[];
|
||||||
|
|
||||||
|
@OneToMany(() => PackingBags, (packingBags) => packingBags.user)
|
||||||
|
packingBags: PackingBags[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => VisitedCountries,
|
||||||
|
(visitedCountries) => visitedCountries.user,
|
||||||
|
)
|
||||||
|
visitedCountries: VisitedCountries[];
|
||||||
|
|
||||||
|
@OneToMany(() => BucketList, (bucketList) => bucketList.user)
|
||||||
|
bucketLists: BucketList[];
|
||||||
|
|
||||||
|
@OneToMany(() => ShareTokens, (shareTokens) => shareTokens.createdBy)
|
||||||
|
shareTokens: ShareTokens[];
|
||||||
|
|
||||||
|
@OneToMany(() => McpTokens, (mcpTokens) => mcpTokens.user)
|
||||||
|
mcpTokens: McpTokens[];
|
||||||
|
|
||||||
|
@OneToMany(() => TripAlbumLinks, (tripAlbumLinks) => tripAlbumLinks.user)
|
||||||
|
tripAlbumLinks: TripAlbumLinks[];
|
||||||
|
|
||||||
|
@OneToMany(() => TodoItems, (todoItems) => todoItems.assignedUser)
|
||||||
|
todoItems: TodoItems[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => TodoCategoryAssignees,
|
||||||
|
(todoCategoryAssignees) => todoCategoryAssignees.user,
|
||||||
|
)
|
||||||
|
todoCategoryAssignees: TodoCategoryAssignees[];
|
||||||
|
|
||||||
|
@OneToMany(() => VisitedRegions, (visitedRegions) => visitedRegions.user)
|
||||||
|
visitedRegions: VisitedRegions[];
|
||||||
|
|
||||||
|
@ManyToMany(() => PackingBags, (packingBags) => packingBags.users)
|
||||||
|
@JoinTable({
|
||||||
|
name: 'packing_bag_members',
|
||||||
|
joinColumns: [{ name: 'user_id', referencedColumnName: 'id' }],
|
||||||
|
inverseJoinColumns: [{ name: 'bag_id', referencedColumnName: 'id' }],
|
||||||
|
})
|
||||||
|
packingBags2: PackingBags[];
|
||||||
|
|
||||||
|
@OneToMany(() => OldOauthConsents, (oauthConsents) => oauthConsents.user)
|
||||||
|
oauthConsents: OldOauthConsents[];
|
||||||
|
|
||||||
|
@OneToMany(() => OldOauthTokens, (oauthTokens) => oauthTokens.user)
|
||||||
|
oauthTokens: OldOauthTokens[];
|
||||||
|
|
||||||
|
@OneToMany(() => Journeys, (journeys) => journeys.user)
|
||||||
|
journeys: Journeys[];
|
||||||
|
|
||||||
|
@OneToMany(() => JourneyEntries, (journeyEntries) => journeyEntries.author)
|
||||||
|
journeyEntries: JourneyEntries[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => JourneyContributors,
|
||||||
|
(journeyContributors) => journeyContributors.user,
|
||||||
|
)
|
||||||
|
journeyContributors: JourneyContributors[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => JourneyShareTokens,
|
||||||
|
(journeyShareTokens) => journeyShareTokens.createdBy,
|
||||||
|
)
|
||||||
|
journeyShareTokens: JourneyShareTokens[];
|
||||||
|
|
||||||
|
@OneToMany(() => TrekPhotos, (trekPhotos) => trekPhotos.owner)
|
||||||
|
trekPhotos: TrekPhotos[];
|
||||||
|
|
||||||
|
@OneToMany(() => TripPhotos, (tripPhotos) => tripPhotos.user)
|
||||||
|
tripPhotos: TripPhotos[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => UserNoticeDismissals,
|
||||||
|
(userNoticeDismissals) => userNoticeDismissals.user,
|
||||||
|
)
|
||||||
|
userNoticeDismissals: UserNoticeDismissals[];
|
||||||
|
|
||||||
|
@OneToMany(() => IdempotencyKeys, (idempotencyKeys) => idempotencyKeys.user)
|
||||||
|
idempotencyKeys: IdempotencyKeys[];
|
||||||
|
|
||||||
|
@OneToMany(() => OldOauthClients, (oauthClients) => oauthClients.user)
|
||||||
|
oauthClients: OldOauthClients[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { Column, Entity } from 'typeorm';
|
||||||
|
import { StringSortableBaseEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Entity('addons')
|
||||||
|
export class Addons extends StringSortableBaseEntity {
|
||||||
|
@Column({ name: 'name' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name: 'description', nullable: true })
|
||||||
|
description: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'type', default: 'global' })
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
@Column({ name: 'icon', default: 'Puzzle' })
|
||||||
|
icon: string | null;
|
||||||
|
|
||||||
|
@Column('int', { name: 'enabled', default: 0 })
|
||||||
|
enabled: number;
|
||||||
|
|
||||||
|
@Column('simple-json', { name: 'config', nullable: true, default: null })
|
||||||
|
config: Record<string, unknown> | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity('app_settings')
|
||||||
|
export class AppSettings {
|
||||||
|
@PrimaryColumn({ name: 'key' })
|
||||||
|
declare id: string;
|
||||||
|
|
||||||
|
@Column({ name: 'value', nullable: true })
|
||||||
|
value: string | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Index('idx_audit_log_created', ['createdAt'], {})
|
||||||
|
@Entity('audit_log')
|
||||||
|
export class AuditLog extends IntBaseEntity {
|
||||||
|
@Column({ name: 'action' })
|
||||||
|
action: string;
|
||||||
|
|
||||||
|
@Column({ name: 'resource', nullable: true })
|
||||||
|
resource: string | null;
|
||||||
|
|
||||||
|
@Column('simple-json', { name: 'details', nullable: true })
|
||||||
|
details: Record<string, unknown> | null;
|
||||||
|
|
||||||
|
@Column({ name: 'ip', nullable: true })
|
||||||
|
ip: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.auditLogs, {
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { Entity, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { Places } from '../trip/Places';
|
||||||
|
import { Reservations } from '../trip/reservation/Reservations';
|
||||||
|
import { TripFiles } from '../trip/files/TripFiles';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { DayAssignments } from '../trip/DayAssignments';
|
||||||
|
|
||||||
|
@Entity('file_links')
|
||||||
|
export class FileLinks extends IntBaseEntity {
|
||||||
|
@ManyToOne(() => Places, (places) => places.fileLinks, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'place_id', referencedColumnName: 'id' }])
|
||||||
|
place: Places;
|
||||||
|
|
||||||
|
@ManyToOne(
|
||||||
|
() => DayAssignments,
|
||||||
|
(dayAssignments) => dayAssignments.fileLinks,
|
||||||
|
{ onDelete: 'CASCADE' },
|
||||||
|
)
|
||||||
|
@JoinColumn([{ name: 'assignment_id', referencedColumnName: 'id' }])
|
||||||
|
assignment: DayAssignments;
|
||||||
|
|
||||||
|
@ManyToOne(() => Reservations, (reservations) => reservations.fileLinks, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'reservation_id', referencedColumnName: 'id' }])
|
||||||
|
reservation: Reservations;
|
||||||
|
|
||||||
|
@ManyToOne(() => TripFiles, (tripFiles) => tripFiles.fileLinks, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'file_id', referencedColumnName: 'id' }])
|
||||||
|
file: TripFiles;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
PrimaryColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { TimestampedEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Index('idx_idempotency_keys_created', ['createdAt'], {})
|
||||||
|
@Entity('idempotency_keys')
|
||||||
|
export class IdempotencyKeys extends TimestampedEntity {
|
||||||
|
@PrimaryColumn({ name: 'key' })
|
||||||
|
key: string;
|
||||||
|
|
||||||
|
@PrimaryColumn('int', { name: 'user_id' })
|
||||||
|
userId: number;
|
||||||
|
|
||||||
|
@PrimaryColumn({ name: 'method' })
|
||||||
|
method: string;
|
||||||
|
|
||||||
|
@PrimaryColumn('text', { name: 'path' })
|
||||||
|
path: string;
|
||||||
|
|
||||||
|
@Column('int', { name: 'status_code' })
|
||||||
|
statusCode: number;
|
||||||
|
|
||||||
|
@Column('text', { name: 'response_body' })
|
||||||
|
responseBody: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.idempotencyKeys, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Entity('invite_tokens')
|
||||||
|
export class InviteTokens extends IntBaseEntity {
|
||||||
|
@Column({ name: 'token', unique: true })
|
||||||
|
token: string;
|
||||||
|
|
||||||
|
@Column('int', { name: 'max_uses', default: 1 })
|
||||||
|
maxUses: number;
|
||||||
|
|
||||||
|
@Column('int', { name: 'used_count', default: 0 })
|
||||||
|
usedCount: number;
|
||||||
|
|
||||||
|
@Column({ name: 'expires_at', nullable: true })
|
||||||
|
expiresAt: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.inviteTokens, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'created_by', referencedColumnName: 'id' }])
|
||||||
|
createdBy: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity('schema_version')
|
||||||
|
export class SchemaVersion {
|
||||||
|
@PrimaryColumn('int', { name: 'id' })
|
||||||
|
id: number | null;
|
||||||
|
|
||||||
|
@Column('int', { name: 'version' })
|
||||||
|
version: number;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Entity('settings')
|
||||||
|
export class Settings extends IntBaseEntity {
|
||||||
|
@Column({ name: 'key' })
|
||||||
|
key: string;
|
||||||
|
|
||||||
|
@Column({ name: 'value', nullable: true })
|
||||||
|
value: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.settings, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||||
|
import { TimestampedEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Entity('user_notice_dismissals')
|
||||||
|
export class UserNoticeDismissals extends TimestampedEntity {
|
||||||
|
@PrimaryColumn('int', { name: 'user_id' })
|
||||||
|
userId: number;
|
||||||
|
|
||||||
|
@PrimaryColumn({ name: 'notice_id' })
|
||||||
|
noticeId: string;
|
||||||
|
|
||||||
|
@Column('int', { name: 'dismissed_at' })
|
||||||
|
dismissedAt: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.userNoticeDismissals, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { DayAssignments } from './DayAssignments';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Index('idx_assignment_participants_assignment', ['assignmentId'], {})
|
||||||
|
@Entity('assignment_participants')
|
||||||
|
export class AssignmentParticipants extends IntBaseEntity {
|
||||||
|
@Column('int', { name: 'assignment_id' })
|
||||||
|
assignmentId: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.assignmentParticipants, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
|
||||||
|
@ManyToOne(
|
||||||
|
() => DayAssignments,
|
||||||
|
(dayAssignments) => dayAssignments.assignmentParticipants,
|
||||||
|
{ onDelete: 'CASCADE' },
|
||||||
|
)
|
||||||
|
@JoinColumn([{ name: 'assignment_id', referencedColumnName: 'id' }])
|
||||||
|
assignment: DayAssignments;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from 'typeorm';
|
||||||
|
import { Places } from './Places';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Entity('categories')
|
||||||
|
export class Categories extends IntBaseEntity {
|
||||||
|
@Column({ name: 'name' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name: 'color', nullable: true, default: '#6366f1' })
|
||||||
|
color: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'icon', nullable: true, default: '📍' })
|
||||||
|
icon: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.categories, {
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
|
||||||
|
@OneToMany(() => Places, (places) => places.category)
|
||||||
|
places: Places[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { Days } from './Days';
|
||||||
|
import { Places } from './Places';
|
||||||
|
import { Trips } from './Trips';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Index('idx_day_accommodations_end_day_id', ['endDayId'], {})
|
||||||
|
@Index('idx_day_accommodations_start_day_id', ['startDayId'], {})
|
||||||
|
@Index('idx_day_accommodations_trip_id', ['tripId'], {})
|
||||||
|
@Entity('day_accommodations')
|
||||||
|
export class DayAccommodations extends IntBaseEntity {
|
||||||
|
@Column('int', { name: 'trip_id' })
|
||||||
|
tripId: number;
|
||||||
|
|
||||||
|
@Column('int', { name: 'start_day_id' })
|
||||||
|
startDayId: number;
|
||||||
|
|
||||||
|
@Column('int', { name: 'end_day_id' })
|
||||||
|
endDayId: number;
|
||||||
|
|
||||||
|
@Column({ name: 'check_in', nullable: true })
|
||||||
|
checkIn: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'check_in_end', nullable: true })
|
||||||
|
checkInEnd: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'check_out', nullable: true })
|
||||||
|
checkOut: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'confirmation', nullable: true })
|
||||||
|
confirmation: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'notes', nullable: true })
|
||||||
|
notes: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => Days, (days) => days.dayAccommodations, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'end_day_id', referencedColumnName: 'id' }])
|
||||||
|
endDay: Days;
|
||||||
|
|
||||||
|
@ManyToOne(() => Days, (days) => days.dayAccommodations2, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'start_day_id', referencedColumnName: 'id' }])
|
||||||
|
startDay: Days;
|
||||||
|
|
||||||
|
@ManyToOne(() => Places, (places) => places.dayAccommodations, {
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'place_id', referencedColumnName: 'id' }])
|
||||||
|
place: Places;
|
||||||
|
|
||||||
|
@ManyToOne(() => Trips, (trips) => trips.dayAccommodations, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'trip_id', referencedColumnName: 'id' }])
|
||||||
|
trip: Trips;
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
OneToMany,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { Places } from './Places';
|
||||||
|
import { Days } from './Days';
|
||||||
|
import { AssignmentParticipants } from './AssignmentParticipants';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { Reservations } from './reservation/Reservations';
|
||||||
|
import { FileLinks } from '../system/FileLinks';
|
||||||
|
|
||||||
|
@Index('idx_day_assignments_place_id', ['placeId'], {})
|
||||||
|
@Index('idx_day_assignments_day_id', ['dayId'], {})
|
||||||
|
@Entity('day_assignments')
|
||||||
|
export class DayAssignments extends IntBaseEntity {
|
||||||
|
@Column('int', { name: 'day_id' })
|
||||||
|
dayId: number;
|
||||||
|
|
||||||
|
@Column('int', { name: 'place_id' })
|
||||||
|
placeId: number;
|
||||||
|
|
||||||
|
@Column('int', {
|
||||||
|
name: 'order_index',
|
||||||
|
nullable: true,
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
orderIndex: number | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'notes', nullable: true })
|
||||||
|
notes: string | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'reservation_status',
|
||||||
|
nullable: true,
|
||||||
|
default: 'none',
|
||||||
|
})
|
||||||
|
reservationStatus: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'reservation_notes', nullable: true })
|
||||||
|
reservationNotes: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'reservation_datetime', nullable: true })
|
||||||
|
reservationDatetime: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'assignment_time', nullable: true })
|
||||||
|
assignmentTime: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'assignment_end_time', nullable: true })
|
||||||
|
assignmentEndTime: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => Places, (places) => places.dayAssignments, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'place_id', referencedColumnName: 'id' }])
|
||||||
|
place: Places;
|
||||||
|
|
||||||
|
@ManyToOne(() => Days, (days) => days.dayAssignments, { onDelete: 'CASCADE' })
|
||||||
|
@JoinColumn([{ name: 'day_id', referencedColumnName: 'id' }])
|
||||||
|
day: Days;
|
||||||
|
|
||||||
|
@OneToMany(() => Reservations, (reservations) => reservations.assignment)
|
||||||
|
reservations: Reservations[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => AssignmentParticipants,
|
||||||
|
(assignmentParticipants) => assignmentParticipants.assignment,
|
||||||
|
)
|
||||||
|
assignmentParticipants: AssignmentParticipants[];
|
||||||
|
|
||||||
|
@OneToMany(() => FileLinks, (fileLinks) => fileLinks.assignment)
|
||||||
|
fileLinks: FileLinks[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { Trips } from './Trips';
|
||||||
|
import { Days } from './Days';
|
||||||
|
import { IntSortableBaseEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Index('idx_day_notes_day_id', ['dayId'], {})
|
||||||
|
@Entity('day_notes')
|
||||||
|
export class DayNotes extends IntSortableBaseEntity {
|
||||||
|
@Column('int', { name: 'day_id' })
|
||||||
|
dayId: number;
|
||||||
|
|
||||||
|
@Column('text', { name: 'text' })
|
||||||
|
text: string;
|
||||||
|
|
||||||
|
@Column({ name: 'time', nullable: true })
|
||||||
|
time: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'icon', nullable: true, default: '📝' })
|
||||||
|
icon: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => Trips, (trips) => trips.dayNotes, { onDelete: 'CASCADE' })
|
||||||
|
@JoinColumn([{ name: 'trip_id', referencedColumnName: 'id' }])
|
||||||
|
trip: Trips;
|
||||||
|
|
||||||
|
@ManyToOne(() => Days, (days) => days.dayNotes, { onDelete: 'CASCADE' })
|
||||||
|
@JoinColumn([{ name: 'day_id', referencedColumnName: 'id' }])
|
||||||
|
day: Days;
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
OneToMany,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { Trips } from './Trips';
|
||||||
|
import { DayAssignments } from './DayAssignments';
|
||||||
|
import { DayNotes } from './DayNotes';
|
||||||
|
import { DayAccommodations } from './DayAccommodations';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { Photos } from './journey/Photos';
|
||||||
|
import { Reservations } from './reservation/Reservations';
|
||||||
|
import { ReservationDayPositions } from './reservation/ReservationDayPositions';
|
||||||
|
|
||||||
|
@Index('idx_days_trip_id', ['tripId'], {})
|
||||||
|
@Entity('days')
|
||||||
|
export class Days extends IntBaseEntity {
|
||||||
|
@Column('int', { name: 'trip_id' })
|
||||||
|
tripId: number;
|
||||||
|
|
||||||
|
@Column('int', { name: 'day_number' })
|
||||||
|
dayNumber: number;
|
||||||
|
|
||||||
|
@Column({ name: 'date', nullable: true })
|
||||||
|
date: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'notes', nullable: true })
|
||||||
|
notes: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'title', nullable: true })
|
||||||
|
title: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => Trips, (trips) => trips.days, { onDelete: 'CASCADE' })
|
||||||
|
@JoinColumn([{ name: 'trip_id', referencedColumnName: 'id' }])
|
||||||
|
trip: Trips;
|
||||||
|
|
||||||
|
@OneToMany(() => DayAssignments, (dayAssignments) => dayAssignments.day)
|
||||||
|
dayAssignments: DayAssignments[];
|
||||||
|
|
||||||
|
@OneToMany(() => Photos, (photos) => photos.day)
|
||||||
|
photos: Photos[];
|
||||||
|
|
||||||
|
@OneToMany(() => Reservations, (reservations) => reservations.endDay)
|
||||||
|
reservations: Reservations[];
|
||||||
|
|
||||||
|
@OneToMany(() => Reservations, (reservations) => reservations.day)
|
||||||
|
reservations2: Reservations[];
|
||||||
|
|
||||||
|
@OneToMany(() => DayNotes, (dayNotes) => dayNotes.day)
|
||||||
|
dayNotes: DayNotes[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => ReservationDayPositions,
|
||||||
|
(reservationDayPositions) => reservationDayPositions.day,
|
||||||
|
)
|
||||||
|
reservationDayPositions: ReservationDayPositions[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => DayAccommodations,
|
||||||
|
(dayAccommodations) => dayAccommodations.endDay,
|
||||||
|
)
|
||||||
|
dayAccommodations: DayAccommodations[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => DayAccommodations,
|
||||||
|
(dayAccommodations) => dayAccommodations.startDay,
|
||||||
|
)
|
||||||
|
dayAccommodations2: DayAccommodations[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||||
|
import { TimestampedEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Entity('google_place_photo_meta')
|
||||||
|
export class GooglePlacePhotoMeta extends TimestampedEntity {
|
||||||
|
@PrimaryColumn({ name: 'place_id' })
|
||||||
|
placeId: string;
|
||||||
|
|
||||||
|
@Column({ name: 'attribution', nullable: true })
|
||||||
|
attribution: string | null;
|
||||||
|
|
||||||
|
@Column('int', { name: 'fetched_at' })
|
||||||
|
fetchedAt: number;
|
||||||
|
|
||||||
|
@Column('int', { name: 'error_at', nullable: true })
|
||||||
|
errorAt: number | null;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||||
|
import { TimestampedEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Entity('place_details_cache')
|
||||||
|
export class PlaceDetailsCache extends TimestampedEntity {
|
||||||
|
@PrimaryColumn({ name: 'place_id' })
|
||||||
|
placeId: string;
|
||||||
|
|
||||||
|
@PrimaryColumn({ name: 'lang', default: '' })
|
||||||
|
lang: string;
|
||||||
|
|
||||||
|
@PrimaryColumn('int', { name: 'expanded', default: 0 })
|
||||||
|
expanded: number;
|
||||||
|
|
||||||
|
@Column('simple-json', { name: 'payload_json' })
|
||||||
|
payloadJson: Record<string, unknown>;
|
||||||
|
|
||||||
|
@Column('int', { name: 'fetched_at' })
|
||||||
|
fetchedAt: number;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { Places } from './Places';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Index('idx_place_regions_region', ['regionCode'], {})
|
||||||
|
@Index('idx_place_regions_country', ['countryCode'], {})
|
||||||
|
@Entity('place_regions')
|
||||||
|
export class PlaceRegions extends IntBaseEntity {
|
||||||
|
@Column({ name: 'country_code' })
|
||||||
|
countryCode: string;
|
||||||
|
|
||||||
|
@Column({ name: 'region_code' })
|
||||||
|
regionCode: string;
|
||||||
|
|
||||||
|
@Column({ name: 'region_name' })
|
||||||
|
regionName: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => Places, (places) => places.placeRegions, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'place_id', referencedColumnName: 'id' }])
|
||||||
|
place: Places;
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToMany,
|
||||||
|
ManyToOne,
|
||||||
|
OneToMany,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { Categories } from './Categories';
|
||||||
|
import { Trips } from './Trips';
|
||||||
|
import { Tags } from './Tags';
|
||||||
|
import { DayAssignments } from './DayAssignments';
|
||||||
|
import { Photos } from './journey/Photos';
|
||||||
|
import { TripFiles } from './files/TripFiles';
|
||||||
|
import { Reservations } from './reservation/Reservations';
|
||||||
|
import { FileLinks } from '../system/FileLinks';
|
||||||
|
import { PlaceRegions } from './PlaceRegions';
|
||||||
|
import { JourneyEntries } from './journey/JourneyEntries';
|
||||||
|
import { DayAccommodations } from './DayAccommodations';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
|
||||||
|
@Index('idx_places_category_id', ['categoryId'], {})
|
||||||
|
@Index('idx_places_trip_id', ['tripId'], {})
|
||||||
|
@Entity('places')
|
||||||
|
export class Places extends IntBaseEntity {
|
||||||
|
@Column('int', { name: 'trip_id' })
|
||||||
|
tripId: number;
|
||||||
|
|
||||||
|
@Column({ name: 'name' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column('text', { name: 'description', nullable: true })
|
||||||
|
description: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'lat', nullable: true })
|
||||||
|
lat: number | null;
|
||||||
|
|
||||||
|
@Column({ name: 'lng', nullable: true })
|
||||||
|
lng: number | null;
|
||||||
|
|
||||||
|
@Column({ name: 'address', nullable: true })
|
||||||
|
address: string | null;
|
||||||
|
|
||||||
|
@Column('int', { name: 'category_id', nullable: true })
|
||||||
|
categoryId: number | null;
|
||||||
|
|
||||||
|
@Column({ name: 'price', nullable: true })
|
||||||
|
price: number | null;
|
||||||
|
|
||||||
|
@Column({ name: 'currency', nullable: true })
|
||||||
|
currency: string | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'reservation_status',
|
||||||
|
nullable: true,
|
||||||
|
default: 'none',
|
||||||
|
})
|
||||||
|
reservationStatus: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'reservation_notes', nullable: true })
|
||||||
|
reservationNotes: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'reservation_datetime', nullable: true })
|
||||||
|
reservationDatetime: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'place_time', nullable: true })
|
||||||
|
placeTime: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'end_time', nullable: true })
|
||||||
|
endTime: string | null;
|
||||||
|
|
||||||
|
@Column('int', {
|
||||||
|
name: 'duration_minutes',
|
||||||
|
nullable: true,
|
||||||
|
default: 60,
|
||||||
|
})
|
||||||
|
durationMinutes: number | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'notes', nullable: true })
|
||||||
|
notes: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'image_url', nullable: true })
|
||||||
|
imageUrl: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'google_place_id', nullable: true })
|
||||||
|
googlePlaceId: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'website', nullable: true })
|
||||||
|
website: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'phone', nullable: true })
|
||||||
|
phone: string | null;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'transport_mode',
|
||||||
|
nullable: true,
|
||||||
|
default: 'walking',
|
||||||
|
})
|
||||||
|
transportMode: string | null;
|
||||||
|
|
||||||
|
@Column({ name: 'osm_id', nullable: true })
|
||||||
|
osmId: string | null;
|
||||||
|
|
||||||
|
@Column('text', { name: 'route_geometry', nullable: true })
|
||||||
|
routeGeometry: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => Categories, (categories) => categories.places, {
|
||||||
|
onDelete: 'SET NULL',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'category_id', referencedColumnName: 'id' }])
|
||||||
|
category: Categories;
|
||||||
|
|
||||||
|
@ManyToOne(() => Trips, (trips) => trips.places, { onDelete: 'CASCADE' })
|
||||||
|
@JoinColumn([{ name: 'trip_id', referencedColumnName: 'id' }])
|
||||||
|
trip: Trips;
|
||||||
|
|
||||||
|
@ManyToMany(() => Tags, (tags) => tags.places)
|
||||||
|
tags: Tags[];
|
||||||
|
|
||||||
|
@OneToMany(() => DayAssignments, (dayAssignments) => dayAssignments.place)
|
||||||
|
dayAssignments: DayAssignments[];
|
||||||
|
|
||||||
|
@OneToMany(() => Photos, (photos) => photos.place)
|
||||||
|
photos: Photos[];
|
||||||
|
|
||||||
|
@OneToMany(() => TripFiles, (tripFiles) => tripFiles.place)
|
||||||
|
tripFiles: TripFiles[];
|
||||||
|
|
||||||
|
@OneToMany(() => Reservations, (reservations) => reservations.place)
|
||||||
|
reservations: Reservations[];
|
||||||
|
|
||||||
|
@OneToMany(() => FileLinks, (fileLinks) => fileLinks.place)
|
||||||
|
fileLinks: FileLinks[];
|
||||||
|
|
||||||
|
@OneToMany(() => PlaceRegions, (placeRegions) => placeRegions.place)
|
||||||
|
placeRegions: PlaceRegions[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => JourneyEntries,
|
||||||
|
(journeyEntries) => journeyEntries.sourcePlace,
|
||||||
|
)
|
||||||
|
journeyEntries: JourneyEntries[];
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
() => DayAccommodations,
|
||||||
|
(dayAccommodations) => dayAccommodations.place,
|
||||||
|
)
|
||||||
|
dayAccommodations: DayAccommodations[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { Trips } from './Trips';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Index('idx_share_tokens_token', ['token'], {})
|
||||||
|
@Entity('share_tokens')
|
||||||
|
export class ShareTokens extends IntBaseEntity {
|
||||||
|
@Column({ name: 'token', unique: true })
|
||||||
|
token: string;
|
||||||
|
|
||||||
|
@Column({ name: 'share_map', default: true })
|
||||||
|
shareMap: boolean;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'share_bookings',
|
||||||
|
default: true,
|
||||||
|
})
|
||||||
|
shareBookings: boolean;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'share_packing',
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
sharePacking: boolean;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'share_budget',
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
shareBudget: boolean;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
name: 'share_collab',
|
||||||
|
default: false,
|
||||||
|
})
|
||||||
|
shareCollab: boolean;
|
||||||
|
|
||||||
|
@Column({ name: 'expires_at', nullable: true })
|
||||||
|
expiresAt: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.shareTokens)
|
||||||
|
@JoinColumn([{ name: 'created_by', referencedColumnName: 'id' }])
|
||||||
|
createdBy: SqliteUsers;
|
||||||
|
|
||||||
|
@ManyToOne(() => Trips, (trips) => trips.shareTokens, { onDelete: 'CASCADE' })
|
||||||
|
@JoinColumn([{ name: 'trip_id', referencedColumnName: 'id' }])
|
||||||
|
trip: Trips;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
JoinColumn,
|
||||||
|
JoinTable,
|
||||||
|
ManyToMany,
|
||||||
|
ManyToOne,
|
||||||
|
} from 'typeorm';
|
||||||
|
import { Places } from './Places';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Entity('tags')
|
||||||
|
export class Tags extends IntBaseEntity {
|
||||||
|
@Column({ name: 'name' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Column({ name: 'color', nullable: true, default: () => "'#10b981'" })
|
||||||
|
color: string | null;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.tags, { onDelete: 'CASCADE' })
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
|
||||||
|
@ManyToMany(() => Places, (places) => places.tags)
|
||||||
|
@JoinTable({
|
||||||
|
name: 'place_tags',
|
||||||
|
joinColumns: [{ name: 'tag_id', referencedColumnName: 'id' }],
|
||||||
|
inverseJoinColumns: [{ name: 'place_id', referencedColumnName: 'id' }],
|
||||||
|
})
|
||||||
|
places: Places[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
|
||||||
|
import { Trips } from './Trips';
|
||||||
|
import { IntBaseEntity } from '../base/BaseEntity';
|
||||||
|
import { SqliteUsers } from '../old-entities/SqliteUsers';
|
||||||
|
|
||||||
|
@Index('idx_trip_members_user_id', ['userId'], {})
|
||||||
|
@Index('idx_trip_members_trip_id', ['tripId'], {})
|
||||||
|
@Entity('trip_members')
|
||||||
|
export class TripMembers extends IntBaseEntity {
|
||||||
|
@Column('int', { name: 'trip_id' })
|
||||||
|
tripId: number;
|
||||||
|
|
||||||
|
@Column('int', { name: 'user_id' })
|
||||||
|
userId: number;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.tripMembers)
|
||||||
|
@JoinColumn([{ name: 'invited_by', referencedColumnName: 'id' }])
|
||||||
|
invitedBy: SqliteUsers;
|
||||||
|
|
||||||
|
@ManyToOne(() => SqliteUsers, (users) => users.tripMembers2, {
|
||||||
|
onDelete: 'CASCADE',
|
||||||
|
})
|
||||||
|
@JoinColumn([{ name: 'user_id', referencedColumnName: 'id' }])
|
||||||
|
user: SqliteUsers;
|
||||||
|
|
||||||
|
@ManyToOne(() => Trips, (trips) => trips.tripMembers, { onDelete: 'CASCADE' })
|
||||||
|
@JoinColumn([{ name: 'trip_id', referencedColumnName: 'id' }])
|
||||||
|
trip: Trips;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user