add most entity for switch to sql

This commit is contained in:
Michael Schramm 2021-04-30 09:08:27 +02:00
parent 9b8d0877da
commit 8d05f15b4c
27 changed files with 4936 additions and 4062 deletions

View File

@ -9,7 +9,6 @@ module.exports = {
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'prettier/@typescript-eslint',
],
root: true,
env: {

View File

@ -4,9 +4,22 @@
| ---- | ------------- | ----------- |
| DISABLE_INSTALLATION_METRICS | *not set* | Per default installations are [publishing](./installation.metrics.md) their existence |
| SECRET_KEY | `changeMe` | JWT Secret for authentication |
| MONGODB_URI | `mongodb://localhost/ohmyform` | MongoDB Connection |
| MAILER_URI | `smtp://localhost:1025` | [Mail Connection](https://nodemailer.com/smtp/) |
| MAILER_FROM | `OhMyForm <no-reply@localhost>` | Default From path, make sure that your mail server supports the given from addres |
| CLI | *automatically* | activates pretty print for log output |
| NODE_ENV | `production` | |
## Mailing
| Name | Default Value | Description |
| ---- | ------------- | ----------- |
| MAILER_URI | `smtp://localhost:1025` | [Mail Connection](https://nodemailer.com/smtp/) |
| MAILER_FROM | `OhMyForm <no-reply@localhost>` | Default From path, make sure that your mail server supports the given from addres |
## Database Variables
| Name | Default Value | Description |
| ---- | ------------- | ----------- |
| DB_URI | `sqlite://data.sqlite` | url in the format `TYPE://USER:PASS@HOST:PORT/NAME?EXTRA` ([read more](https://typeorm.io/#/connection-options/common-connection-options)) |
| DB_TABLE_PREFIX | *empty* | prefix all tables if used within same database as other applications. |
| DB_LOGGING | `false` | if `true` all db interactions will be logged to stdout |
| DB_MIGRATE | `true` | can be used in load balanced environments to only allow one container to perform migrations / manually execute migrations

View File

@ -1,15 +1,26 @@
version: "3"
services:
mongo:
image: mongo
ports:
- "27017:27017"
#mongo:
# image: mongo
# ports:
# - "27017:27017"
# volumes:
# - "./data/mongo:/data/db"
db:
image: postgres:10-alpine
volumes:
- "./data/mongo:/data/db"
- ./pg_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: root
POSTGRES_DB: ohmyform
ports:
- "5432:5432"
redis:
image: redis
ports:
- "6379:6379"
- "6003:6379"
# api:
# build: .
# volumes:
@ -30,14 +41,14 @@ services:
image: mailhog/mailhog
ports:
- "6001:8025"
- "1025:1025"
mongoexpress:
image: mongo-express
environment:
ME_CONFIG_MONGODB_SERVER: mongo
ports:
- "6002:8081"
links:
- mongo
depends_on:
- mongo
- "6004:1025"
#mongoexpress:
# image: mongo-express
# environment:
# ME_CONFIG_MONGODB_SERVER: mongo
# ports:
# - "6002:8081"
# links:
# - mongo
# depends_on:
# - mongo

View File

@ -1,6 +1,6 @@
{
"name": "ohmyform-api",
"version": "0.9.7",
"version": "1.0.0-alpha",
"description": "",
"author": "",
"license": "AGPL-3.0-or-later",
@ -19,79 +19,86 @@
"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"
"test:e2e": "jest --config ./test/jest-e2e.json",
"typeorm:sqlite": "cross-env TS_NODE_TRANSPILE_ONLY=true ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js -f ormconfig_sqlite.json",
"typeorm:pg": "cross-env TS_NODE_TRANSPILE_ONLY=true ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js -f ormconfig_pg.json"
},
"dependencies": {
"@nestjs-modules/mailer": "^1.4.2",
"@nestjs/common": "^7.4.4",
"@nestjs/config": "^0.5.0",
"@nestjs/core": "^7.4.4",
"@nestjs/graphql": "^7.6.0",
"@nestjs/jwt": "^7.1.0",
"@nestjs/mongoose": "^7.0.2",
"@nestjs/passport": "^7.1.0",
"@nestjs/platform-express": "^7.4.4",
"@nestjs/serve-static": "^2.1.3",
"@types/html-to-text": "^5.1.1",
"apollo-server-express": "^2.17.0",
"bcrypt": "^5.0.0",
"class-transformer": "^0.3.1",
"class-validator": "^0.12.2",
"commander": "^6.1.0",
"@nestjs-modules/mailer": "^1.6.0",
"@nestjs/common": "^7.6.15",
"@nestjs/config": "^0.6.3",
"@nestjs/core": "^7.6.15",
"@nestjs/graphql": "^7.10.6",
"@nestjs/jwt": "^7.2.0",
"@nestjs/mongoose": "^7.2.4",
"@nestjs/passport": "^7.1.5",
"@nestjs/platform-express": "^7.6.15",
"@nestjs/serve-static": "^2.1.4",
"@nestjs/typeorm": "^7.1.5",
"apollo-server-express": "^2.23.0",
"bcrypt": "^5.0.1",
"class-transformer": "^0.4.0",
"class-validator": "^0.13.1",
"commander": "^7.2.0",
"cors": "^2.8.5",
"cross-env": "^7.0.2",
"dayjs": "^1.8.34",
"graphql": "15.3.0",
"graphql-redis-subscriptions": "^2.2.2",
"graphql-subscriptions": "^1.1.0",
"graphql-tools": "^6.2.0",
"cross-env": "^7.0.3",
"dayjs": "^1.10.4",
"graphql": "15.5.0",
"graphql-redis-subscriptions": "^2.3.1",
"graphql-subscriptions": "^1.2.1",
"graphql-tools": "^7.0.4",
"handlebars": "^4.7.6",
"html-to-text": "^5.1.1",
"inquirer": "^7.3.3",
"ioredis": "^4.17.3",
"html-to-text": "^7.1.1",
"inquirer": "^8.0.0",
"ioredis": "^4.27.1",
"matomo-tracker": "^2.2.4",
"migrate-mongoose": "^4.0.0",
"mjml": "^4.6.3",
"mongoose": "^5.9.29",
"nestjs-console": "^3.1.1",
"nestjs-pino": "^1.2.0",
"nodemailer": "^6.4.11",
"mjml": "^4.9.1",
"mongoose": "^5.12.6",
"mysql2": "^2.2.5",
"nestjs-console": "^4.0.0",
"nestjs-pino": "^1.4.0",
"nodemailer": "^6.6.0",
"passport": "^0.4.1",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"pino-pretty": "^4.2.0",
"pg": "^8.6.0",
"pino-pretty": "^4.7.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^6.6.2"
"rxjs": "^6.6.7",
"sqlite3": "^5.0.2",
"typeorm": "^0.2.32"
},
"devDependencies": {
"@nestjs/cli": "^7.5.1",
"@nestjs/schematics": "^7.1.1",
"@nestjs/testing": "^7.4.4",
"@types/bcrypt": "^3.0.0",
"@types/express": "^4.17.8",
"@types/express-serve-static-core": "^4.17.12",
"@nestjs/cli": "^7.6.0",
"@nestjs/schematics": "^7.3.1",
"@nestjs/testing": "^7.6.15",
"@types/bcrypt": "^3.0.1",
"@types/express": "^4.17.11",
"@types/express-serve-static-core": "^4.17.19",
"@types/handlebars": "^4.1.0",
"@types/html-to-text": "^6.0.0",
"@types/inquirer": "^7.3.1",
"@types/jest": "26.0.12",
"@types/mongoose": "^5.7.36",
"@types/node": "^14.6.2",
"@types/passport-jwt": "^3.0.3",
"@types/jest": "26.0.23",
"@types/mongoose": "^5.10.5",
"@types/node": "^15.0.1",
"@types/passport-jwt": "^3.0.5",
"@types/passport-local": "^1.0.33",
"@types/supertest": "^2.0.10",
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.1",
"eslint": "^7.8.1",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.22.0",
"jest": "^26.4.2",
"prettier": "^2.1.1",
"supertest": "^4.0.2",
"ts-jest": "26.3.0",
"ts-loader": "^8.0.3",
"ts-node": "^9.0.0",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
"eslint": "^7.25.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.22.1",
"jest": "^26.6.3",
"prettier": "^2.2.1",
"supertest": "^6.1.3",
"ts-jest": "26.5.5",
"ts-loader": "^9.1.1",
"ts-node": "^9.1.1",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.0.2"
"typescript": "^4.2.4"
},
"jest": {
"moduleFileExtensions": [

View File

@ -6,12 +6,15 @@ import { JwtModule, JwtModuleOptions } from '@nestjs/jwt';
import { MongooseModule } from '@nestjs/mongoose';
import { MongooseModuleOptions } from '@nestjs/mongoose/dist/interfaces/mongoose-options.interface';
import { ServeStaticModule } from '@nestjs/serve-static';
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm'
import crypto from 'crypto';
import { Request } from 'express-serve-static-core';
import { IncomingHttpHeaders } from 'http';
import { ConsoleModule } from 'nestjs-console';
import { LoggerModule, Params as LoggerModuleParams } from 'nestjs-pino/dist';
import { join } from 'path';
import { DatabaseType } from 'typeorm'
import { entities } from './entity'
import { schema } from './schema';
export const LoggerConfig: LoggerModuleParams = {
@ -103,6 +106,22 @@ export const imports = [
return { req }
},
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService): TypeOrmModuleOptions => ({
name: 'ohmyform',
url: configService.get<string>('DB_URI', 'sqlite://data.sqlite') as any,
entityPrefix: configService.get<string>('DB_TABLE_PREFIX', ''),
logging: configService.get<string>('DB_LOGGING', 'false') === 'true',
entities,
migrationsTableName: 'nest_migrations',
migrations: [
`${__dirname}/**/migrations/**/*{.ts,.js}`,
],
migrationsRun: configService.get<boolean>('DB_MIGRATE', true),
}),
}),
MongooseModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],

View File

@ -0,0 +1,25 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
@Entity({ name: 'button' })
export class ButtonEntity {
@PrimaryGeneratedColumn()
public id: number
@Column({ nullable: true })
readonly url?: string
@Column({ nullable: true })
readonly action?: string
@Column()
readonly text: string
@Column({ nullable: true })
readonly bgColor?: string
@Column({ nullable: true })
readonly activeColor?: string
@Column({ nullable: true })
readonly color?: string
}

View File

@ -0,0 +1,3 @@
export class AnalyticsEmbedded {
readonly gaCode?: string
}

View File

@ -0,0 +1,8 @@
export class ColorsEmbedded {
readonly background: string
readonly question: string
readonly answer: string
readonly button: string
readonly buttonActive: string
readonly buttonText: string
}

View File

@ -0,0 +1,7 @@
import { ColorsEmbedded } from './form.design.colors.embedded'
export class DesignEmbedded {
colors: ColorsEmbedded
font?: string
}

View File

@ -0,0 +1,4 @@
export class DeviceEmbedded {
readonly type?: string
readonly name?: string
}

View File

@ -0,0 +1,4 @@
export class GeoLocationEmbedded {
readonly country?: string
readonly city?: string
}

View File

@ -0,0 +1,8 @@
import { FormFieldEntity } from '../form.field.entity'
export class LogicEmbedded {
readonly formula?: string
readonly hide?: boolean
readonly jumpTo?: FormFieldEntity
readonly enabled?: boolean
}

View File

@ -0,0 +1,4 @@
export class RatingEmbedded {
readonly steps?: number
readonly shape?: string
}

72
src/entity/form.entity.ts Normal file
View File

@ -0,0 +1,72 @@
import {
Column,
CreateDateColumn,
Entity,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn, UpdateDateColumn
} from 'typeorm'
import { AnalyticsEmbedded } from './embedded/analytics.embedded'
import { DesignEmbedded } from './embedded/design.embedded'
import { FormFieldEntity } from './form.field.entity'
import { FormHookEntity } from './form.hook.entity'
import { FormNotificationEntity } from './form.notification.entity'
import { SubmissionEntity } from './submission.entity'
import { VisitorEntity } from './visitor.entity'
import { PageEntity } from './page.entity'
import { UserEntity } from './user.entity'
@Entity({ name: 'form' })
export class FormEntity {
@PrimaryGeneratedColumn()
public id: number
@Column()
public title: string
@Column({ length: 10 })
public language: string
@Column(() => AnalyticsEmbedded)
public analytics: AnalyticsEmbedded
@OneToMany(() => VisitorEntity, visitor => visitor.form)
public visitors: VisitorEntity[]
@OneToMany(() => SubmissionEntity, submission => submission.form)
public submissions: SubmissionEntity[]
@OneToMany(() => FormFieldEntity, field => field.form)
public fields: FormFieldEntity[]
@OneToMany(() => FormHookEntity, field => field.form)
public hooks: FormHookEntity[]
@ManyToOne(() => UserEntity)
public admin: UserEntity
@ManyToOne(() => PageEntity)
public startPage: PageEntity;
@ManyToOne(() => PageEntity)
public endPage: PageEntity;
@OneToMany(() => FormNotificationEntity, notification => notification.form)
public notifications: FormNotificationEntity[]
@Column()
public showFooter: boolean;
@Column()
public isLive: boolean;
@Column(() => DesignEmbedded)
public design: DesignEmbedded;
@CreateDateColumn()
public created: Date
@UpdateDateColumn()
public lastModified: Date
}

View File

@ -0,0 +1,45 @@
import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm'
import { LogicEmbedded } from './embedded/logic.embedded'
import { RatingEmbedded } from './embedded/rating.embedded'
import { FormEntity } from './form.entity'
import { FormFieldLogicEntity } from './form.field.logic.entity'
import { FormFieldOptionEntity } from './form.field.option.entity'
@Entity({ name: 'form_field' })
export class FormFieldEntity {
@PrimaryGeneratedColumn()
public id: number
@ManyToOne(() => FormEntity, form => form.fields)
public form: FormEntity
@Column()
public title: string
@Column({ type: 'text' })
public description: string
@Column({ nullable: true })
public slug?: string
@OneToMany(() => FormFieldLogicEntity, logic => logic.field)
public logic: FormFieldLogicEntity[]
@Column(() => RatingEmbedded)
public rating: RatingEmbedded = new RatingEmbedded()
@OneToMany(() => FormFieldOptionEntity, option => option.field)
public options?: FormFieldOptionEntity[]
@Column()
public required: boolean
@Column()
public disabled: boolean
@Column()
public type: string
@Column()
public value: string
}

View File

@ -0,0 +1,34 @@
import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm'
import { FormFieldEntity } from './form.field.entity'
type LogicAction = 'visible' | 'require' | 'disable' | 'jumpTo'
@Entity({ name: 'form_field_logic' })
export class FormFieldLogicEntity {
@PrimaryGeneratedColumn()
public id: number
@ManyToOne(() => FormFieldEntity, field => field.options)
public field: FormFieldEntity
@Column()
public formula: string
@Column({ type: 'varchar', length: 10 })
public action: LogicAction
@Column({ nullable: true })
public visible?: boolean
@Column({ nullable: true })
public require?: boolean
@Column({ nullable: true })
public disable?: boolean
@ManyToOne(() => FormFieldEntity)
public jumpTo?: FormFieldEntity
@Column()
public enabled: boolean
}

View File

@ -0,0 +1,20 @@
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
import { FormFieldEntity } from './form.field.entity'
@Entity({ name: 'form_field_option' })
export class FormFieldOptionEntity {
@PrimaryGeneratedColumn()
public id: number
@ManyToOne(() => FormFieldEntity, field => field.options)
public field: FormFieldEntity
@Column({ nullable: true })
public key?: string
@Column({ nullable: true })
public title?: string
@Column()
public value: string
}

View File

@ -0,0 +1,20 @@
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
import { FormEntity } from './form.entity'
@Entity({ name: 'form_hook' })
export class FormHookEntity {
@PrimaryGeneratedColumn()
public id: number
@ManyToOne(() => FormEntity, form => form.hooks)
public form: FormEntity
@Column()
readonly enabled: boolean
@Column()
readonly url: string
@Column({ nullable: true })
readonly format?: string
}

View File

@ -0,0 +1,33 @@
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
import { FormEntity } from './form.entity'
import { FormFieldEntity } from './form.field.entity'
@Entity({ name: 'form_notification' })
export class FormNotificationEntity {
@PrimaryGeneratedColumn()
public id: number
@ManyToOne(() => FormEntity, form => form.notifications)
public form: FormEntity
@Column({ nullable: true })
readonly subject?: string
@Column({ nullable: true })
readonly htmlTemplate?: string
@Column()
readonly enabled: boolean
@ManyToOne(() => FormFieldEntity)
readonly fromField?: FormFieldEntity
@ManyToOne(() => FormFieldEntity)
readonly toField?: FormFieldEntity
@Column({ nullable: true })
readonly toEmail?: string
@Column({ nullable: true })
readonly fromEmail?: string
}

27
src/entity/index.ts Normal file
View File

@ -0,0 +1,27 @@
import { ButtonEntity } from './button.entity'
import { FormEntity } from './form.entity'
import { FormFieldEntity } from './form.field.entity'
import { FormFieldLogicEntity } from './form.field.logic.entity'
import { FormFieldOptionEntity } from './form.field.option.entity'
import { FormHookEntity } from './form.hook.entity'
import { FormNotificationEntity } from './form.notification.entity'
import { PageEntity } from './page.entity'
import { SubmissionEntity } from './submission.entity'
import { SubmissionFieldEntity } from './submission.field.entity'
import { UserEntity } from './user.entity'
import { VisitorEntity } from './visitor.entity'
export const entities = [
ButtonEntity,
FormEntity,
FormFieldEntity,
FormFieldLogicEntity,
FormFieldOptionEntity,
FormHookEntity,
FormNotificationEntity,
PageEntity,
SubmissionEntity,
SubmissionFieldEntity,
UserEntity,
VisitorEntity,
]

22
src/entity/page.entity.ts Normal file
View File

@ -0,0 +1,22 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
import { ButtonEntity } from './button.entity'
@Entity({ name: 'page' })
export class PageEntity {
@PrimaryGeneratedColumn()
public id: number
@Column()
readonly show: boolean
@Column({ nullable: true })
readonly title?: string
@Column({ type: 'text', nullable: true })
readonly paragraph?: string
@Column({ nullable: true })
readonly buttonText?: string
readonly buttons: ButtonEntity[]
}

View File

@ -0,0 +1,25 @@
import { Entity, PrimaryGeneratedColumn } from 'typeorm'
import { DeviceEmbedded } from './embedded/device.embedded'
import { GeoLocationEmbedded } from './embedded/geo.location.embedded'
import { FormEntity } from './form.entity'
import { SubmissionFieldEntity } from './submission.field.entity'
import { UserEntity } from './user.entity'
@Entity({ name: 'submission' })
export class SubmissionEntity {
@PrimaryGeneratedColumn()
public id: number
readonly fields: SubmissionFieldEntity[]
readonly form: FormEntity
readonly ipAddr: string
readonly tokenHash: string
readonly geoLocation: GeoLocationEmbedded
readonly device: DeviceEmbedded
readonly timeElapsed: number
readonly percentageComplete: number
readonly user?: UserEntity
readonly created: Date
readonly lastModified: Date
}

View File

@ -0,0 +1,13 @@
import { Entity, PrimaryGeneratedColumn } from 'typeorm'
import { FormFieldDocument } from '../schema/form.field.schema'
import { FormFieldEntity } from './form.field.entity'
@Entity({ name: 'submission_field' })
export class SubmissionFieldEntity {
@PrimaryGeneratedColumn()
public id: number
readonly field: FormFieldEntity
readonly fieldType: string
readonly fieldValue: any
}

29
src/entity/user.entity.ts Normal file
View File

@ -0,0 +1,29 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
import { rolesType } from '../config/roles'
@Entity({ name: 'user' })
export class UserEntity {
@PrimaryGeneratedColumn()
public id: number
public firstName?: string
public lastName?: string
@Column({ length: 255, unique: true })
public email: string
@Column({ length: 255, unique: true })
public username: string
public passwordHash: string
public salt: string
public provider: string
public roles: rolesType
public language: string
public resetPasswordToken?: string
public resetPasswordExpires?: Date
public token?: string
public apiKey?: string
public created: Date
public lastModified: Date
}

View File

@ -0,0 +1,26 @@
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
import { FormFieldDocument } from '../schema/form.field.schema'
import { FormEntity } from './form.entity'
import { FormFieldEntity } from './form.field.entity'
@Entity({ name: 'form_visitor' })
export class VisitorEntity {
@PrimaryGeneratedColumn()
public id: number
@ManyToOne(() => FormEntity, form => form.visitors)
public form: FormEntity
@ManyToOne(() => FormEntity, form => form.visitors)
public submission: FormEntity
@Column({ nullable: true })
readonly referrer?: string
readonly timeElapsed: number
readonly isSubmitted: boolean
readonly language: string
readonly ipAddr: string
readonly deviceType: string
readonly userAgent: string
}

View File

@ -0,0 +1,82 @@
import { MigrationInterface, QueryRunner, Table } from "typeorm"
export class initial1619723437787 implements MigrationInterface {
name = 'initial1619723437787'
public async up(queryRunner: QueryRunner): Promise<void> {
if (queryRunner.connection.driver.options.type !== 'sqlite') {
await queryRunner.query(`CREATE TABLE "button" ("id" SERIAL NOT NULL, "url" VARCHAR, "action" VARCHAR, "text" VARCHAR NOT NULL, "bgColor" VARCHAR, "activeColor" VARCHAR, "color" VARCHAR, CONSTRAINT "PK_a4df4e4f7a5882bc94442d3f209" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "form_field_logic" ("id" SERIAL NOT NULL, "formula" VARCHAR NOT NULL, "action" VARCHAR(10) NOT NULL, "visible" boolean, "require" boolean, "disable" boolean, "enabled" boolean NOT NULL, "fieldId" integer, "jumpToId" integer, CONSTRAINT "PK_c40e7f583854ff1b60900d8cf1b" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "form_field_option" ("id" SERIAL NOT NULL, "key" VARCHAR, "title" VARCHAR, "value" VARCHAR NOT NULL, "fieldId" integer, CONSTRAINT "PK_812955356e516819e37b64bf39b" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "form_field" ("id" SERIAL NOT NULL, "title" VARCHAR NOT NULL, "description" text NOT NULL, "slug" VARCHAR, "required" boolean NOT NULL, "disabled" boolean NOT NULL, "type" VARCHAR NOT NULL, "value" VARCHAR NOT NULL, "formId" integer, CONSTRAINT "PK_135904ddb60085b07254ea4f485" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "form_hook" ("id" SERIAL NOT NULL, "enabled" boolean NOT NULL, "url" VARCHAR NOT NULL, "format" VARCHAR, "formId" integer, CONSTRAINT "PK_4b63bd9ff09f7b3e5c4a41fcbec" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "form_notification" ("id" SERIAL NOT NULL, "subject" VARCHAR, "htmlTemplate" VARCHAR, "enabled" boolean NOT NULL, "toEmail" VARCHAR, "fromEmail" VARCHAR, "formId" integer, "fromFieldId" integer, "toFieldId" integer, CONSTRAINT "PK_935306529aed07c9f6628f6e24f" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "submission" ("id" SERIAL NOT NULL, CONSTRAINT "PK_7faa571d0e4a7076e85890c9bd0" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "form_visitor" ("id" SERIAL NOT NULL, "referrer" VARCHAR, "formId" integer, "submissionId" integer, CONSTRAINT "PK_74224dc63e13cf5cb5f0420e65b" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "page" ("id" SERIAL NOT NULL, "show" boolean NOT NULL, "title" VARCHAR, "paragraph" text, "buttonText" VARCHAR, CONSTRAINT "PK_742f4117e065c5b6ad21b37ba1f" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "user" ("id" SERIAL NOT NULL, "email" VARCHAR(255) NOT NULL, "username" VARCHAR(255) NOT NULL, CONSTRAINT "UQ_e12875dfb3b1d92d7d7c5377e22" UNIQUE ("email"), CONSTRAINT "UQ_78a916df40e02a9deb1c4b75edb" UNIQUE ("username"), CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "form" ("id" SERIAL NOT NULL, "title" VARCHAR NOT NULL, "language" VARCHAR(10) NOT NULL, "showFooter" boolean NOT NULL, "isLive" boolean NOT NULL, "created" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "lastModified" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "adminId" integer, "startPageId" integer, "endPageId" integer, CONSTRAINT "PK_8f72b95aa2f8ba82cf95dc7579e" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "submission_field" ("id" SERIAL NOT NULL, CONSTRAINT "PK_5443f5f769fce3107982c16e0b5" PRIMARY KEY ("id"))`);
await queryRunner.query(`ALTER TABLE "form_field_logic" ADD CONSTRAINT "FK_6098b83f6759445d8cfdd03d545" FOREIGN KEY ("fieldId") REFERENCES "form_field"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form_field_logic" ADD CONSTRAINT "FK_4a8019f2b753cfb3216dc3001a6" FOREIGN KEY ("jumpToId") REFERENCES "form_field"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form_field_option" ADD CONSTRAINT "FK_c4484ad12c2c56db31dffdbfe97" FOREIGN KEY ("fieldId") REFERENCES "form_field"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form_field" ADD CONSTRAINT "FK_2d83d8a334dd66445db13f92b77" FOREIGN KEY ("formId") REFERENCES "form"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form_hook" ADD CONSTRAINT "FK_bbeb4d224d8857fd5a458538a30" FOREIGN KEY ("formId") REFERENCES "form"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form_notification" ADD CONSTRAINT "FK_a9ed55144108ded893b502d6321" FOREIGN KEY ("formId") REFERENCES "form"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form_notification" ADD CONSTRAINT "FK_0876741ce2acdaee4553d7a3bbd" FOREIGN KEY ("fromFieldId") REFERENCES "form_field"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form_notification" ADD CONSTRAINT "FK_4915ebae53e09b732322d0ff6ed" FOREIGN KEY ("toFieldId") REFERENCES "form_field"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form_visitor" ADD CONSTRAINT "FK_72ade6c3a3e55d1fce94300f8b6" FOREIGN KEY ("formId") REFERENCES "form"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form_visitor" ADD CONSTRAINT "FK_cc7e7beb67c46f65d57289b121d" FOREIGN KEY ("submissionId") REFERENCES "form"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form" ADD CONSTRAINT "FK_a7cb33580bca2b362e5e34fdfcd" FOREIGN KEY ("adminId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form" ADD CONSTRAINT "FK_023d9cf1d97e93facc96c86ca70" FOREIGN KEY ("startPageId") REFERENCES "page"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "form" ADD CONSTRAINT "FK_e5d158932e43cfbf9958931ee01" FOREIGN KEY ("endPageId") REFERENCES "page"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
} else {
await queryRunner.query(`CREATE TABLE "button" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "url" varchar, "action" varchar, "text" varchar NOT NULL, "bgColor" varchar, "activeColor" varchar, "color" varchar)`);
await queryRunner.query(`CREATE TABLE "submission" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL)`);
await queryRunner.query(`CREATE TABLE "page" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "show" boolean NOT NULL, "title" varchar, "paragraph" text, "buttonText" varchar)`);
await queryRunner.query(`CREATE TABLE "user" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255) NOT NULL, "username" varchar(255) NOT NULL, CONSTRAINT "UQ_78a916df40e02a9deb1c4b75edb" UNIQUE ("username"), CONSTRAINT "UQ_e12875dfb3b1d92d7d7c5377e22" UNIQUE ("email"))`);
await queryRunner.query(`CREATE TABLE "form" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar NOT NULL, "language" varchar(10) NOT NULL, "showFooter" boolean NOT NULL, "isLive" boolean NOT NULL, "created" datetime NOT NULL DEFAULT (datetime('now')), "lastModified" datetime NOT NULL DEFAULT (datetime('now')), "adminId" integer, "startPageId" integer, "endPageId" integer, CONSTRAINT "FK_a7cb33580bca2b362e5e34fdfcd" FOREIGN KEY ("adminId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_023d9cf1d97e93facc96c86ca70" FOREIGN KEY ("startPageId") REFERENCES "page" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_e5d158932e43cfbf9958931ee01" FOREIGN KEY ("endPageId") REFERENCES "page" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`CREATE TABLE "submission_field" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL)`);
await queryRunner.query(`CREATE TABLE "form_field_logic" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "formula" varchar NOT NULL, "action" varchar(10) NOT NULL, "visible" boolean, "require" boolean, "disable" boolean, "enabled" boolean NOT NULL, "fieldId" integer, "jumpToId" integer, CONSTRAINT "FK_6098b83f6759445d8cfdd03d545" FOREIGN KEY ("fieldId") REFERENCES "form_field" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_4a8019f2b753cfb3216dc3001a6" FOREIGN KEY ("jumpToId") REFERENCES "form_field" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`CREATE TABLE "form_field_option" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "key" varchar, "title" varchar, "value" varchar NOT NULL, "fieldId" integer, CONSTRAINT "FK_c4484ad12c2c56db31dffdbfe97" FOREIGN KEY ("fieldId") REFERENCES "form_field" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`CREATE TABLE "form_field" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar NOT NULL, "description" text NOT NULL, "slug" varchar, "required" boolean NOT NULL, "disabled" boolean NOT NULL, "type" varchar NOT NULL, "value" varchar NOT NULL, "formId" integer, CONSTRAINT "FK_2d83d8a334dd66445db13f92b77" FOREIGN KEY ("formId") REFERENCES "form" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`CREATE TABLE "form_hook" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "enabled" boolean NOT NULL, "url" varchar NOT NULL, "format" varchar, "formId" integer, CONSTRAINT "FK_bbeb4d224d8857fd5a458538a30" FOREIGN KEY ("formId") REFERENCES "form" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`CREATE TABLE "form_notification" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "subject" varchar, "htmlTemplate" varchar, "enabled" boolean NOT NULL, "toEmail" varchar, "fromEmail" varchar, "formId" integer, "fromFieldId" integer, "toFieldId" integer, CONSTRAINT "FK_a9ed55144108ded893b502d6321" FOREIGN KEY ("formId") REFERENCES "form" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_0876741ce2acdaee4553d7a3bbd" FOREIGN KEY ("fromFieldId") REFERENCES "form_field" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_4915ebae53e09b732322d0ff6ed" FOREIGN KEY ("toFieldId") REFERENCES "form_field" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
await queryRunner.query(`CREATE TABLE "form_visitor" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "referrer" varchar, "formId" integer, "submissionId" integer, CONSTRAINT "FK_72ade6c3a3e55d1fce94300f8b6" FOREIGN KEY ("formId") REFERENCES "form" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_cc7e7beb67c46f65d57289b121d" FOREIGN KEY ("submissionId") REFERENCES "form" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
}
}
public async down(queryRunner: QueryRunner): Promise<void> {
if (queryRunner.connection.driver.options.type !== 'sqlite') {
await queryRunner.query(`ALTER TABLE "form" DROP CONSTRAINT "FK_e5d158932e43cfbf9958931ee01"`);
await queryRunner.query(`ALTER TABLE "form" DROP CONSTRAINT "FK_023d9cf1d97e93facc96c86ca70"`);
await queryRunner.query(`ALTER TABLE "form" DROP CONSTRAINT "FK_a7cb33580bca2b362e5e34fdfcd"`);
await queryRunner.query(`ALTER TABLE "form_visitor" DROP CONSTRAINT "FK_cc7e7beb67c46f65d57289b121d"`);
await queryRunner.query(`ALTER TABLE "form_visitor" DROP CONSTRAINT "FK_72ade6c3a3e55d1fce94300f8b6"`);
await queryRunner.query(`ALTER TABLE "form_notification" DROP CONSTRAINT "FK_4915ebae53e09b732322d0ff6ed"`);
await queryRunner.query(`ALTER TABLE "form_notification" DROP CONSTRAINT "FK_0876741ce2acdaee4553d7a3bbd"`);
await queryRunner.query(`ALTER TABLE "form_notification" DROP CONSTRAINT "FK_a9ed55144108ded893b502d6321"`);
await queryRunner.query(`ALTER TABLE "form_hook" DROP CONSTRAINT "FK_bbeb4d224d8857fd5a458538a30"`);
await queryRunner.query(`ALTER TABLE "form_field" DROP CONSTRAINT "FK_2d83d8a334dd66445db13f92b77"`);
await queryRunner.query(`ALTER TABLE "form_field_option" DROP CONSTRAINT "FK_c4484ad12c2c56db31dffdbfe97"`);
await queryRunner.query(`ALTER TABLE "form_field_logic" DROP CONSTRAINT "FK_4a8019f2b753cfb3216dc3001a6"`);
await queryRunner.query(`ALTER TABLE "form_field_logic" DROP CONSTRAINT "FK_6098b83f6759445d8cfdd03d545"`);
}
await queryRunner.query(`DROP TABLE "submission_field"`);
await queryRunner.query(`DROP TABLE "form"`);
await queryRunner.query(`DROP TABLE "user"`);
await queryRunner.query(`DROP TABLE "page"`);
await queryRunner.query(`DROP TABLE "form_visitor"`);
await queryRunner.query(`DROP TABLE "submission"`);
await queryRunner.query(`DROP TABLE "form_notification"`);
await queryRunner.query(`DROP TABLE "form_hook"`);
await queryRunner.query(`DROP TABLE "form_field"`);
await queryRunner.query(`DROP TABLE "form_field_option"`);
await queryRunner.query(`DROP TABLE "form_field_logic"`);
await queryRunner.query(`DROP TABLE "button"`);
}
}

8282
yarn.lock

File diff suppressed because it is too large Load Diff