From dd37e7703289acfd1f3d0afc8945bb7ebbe8d31f Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Wed, 31 Jul 2024 21:29:30 +0200 Subject: [PATCH] feat: expose date(time) types per database. Also enhance the datasources capabilities --- packages/agent-config/src/dataSources.ts | 217 +++++++++++++----- packages/data-store/package.json | 1 + .../src/__tests__/contact.entities.test.ts | 3 + .../src/__tests__/contact.store.test.ts | 2 + .../digitalCredential.entities.test.ts | 2 + .../__tests__/digitalCredential.store.test.ts | 2 + .../__tests__/eventLogger.entities.test.ts | 2 + .../src/__tests__/eventLogger.store.test.ts | 4 +- .../issuanceBranding.entities.test.ts | 2 + .../__tests__/issuanceBranding.store.test.ts | 2 + .../__tests__/machineState.entities.test.ts | 2 + .../src/__tests__/machineState.store.test.ts | 2 + .../src/__tests__/pd-manager.entities.test.ts | 2 + .../src/__tests__/pd-manager.store.test.ts | 2 + .../src/entities/contact/BaseContactEntity.ts | 5 +- .../contact/ContactMetadataItemEntity.ts | 3 +- .../contact/ElectronicAddressEntity.ts | 5 +- .../src/entities/contact/IdentityEntity.ts | 5 +- .../contact/IdentityMetadataItemEntity.ts | 3 +- .../entities/contact/OrganizationEntity.ts | 15 +- .../src/entities/contact/PartyEntity.ts | 5 +- .../contact/PartyRelationshipEntity.ts | 5 +- .../src/entities/contact/PartyTypeEntity.ts | 5 +- .../entities/contact/PhysicalAddressEntity.ts | 5 +- .../DigitalCredentialEntity.ts | 13 +- .../entities/eventLogger/AuditEventEntity.ts | 7 +- .../BaseLocaleBrandingEntity.ts | 5 +- .../CredentialBrandingEntity.ts | 5 +- .../issuanceBranding/IssuerBrandingEntity.ts | 5 +- .../machineState/MachineStateInfoEntity.ts | 9 +- .../PresentationDefinitionItemEntity.ts | 5 +- packages/data-store/tsconfig.json | 3 + pnpm-lock.yaml | 3 + 33 files changed, 251 insertions(+), 105 deletions(-) diff --git a/packages/agent-config/src/dataSources.ts b/packages/agent-config/src/dataSources.ts index f7bd5cd4b..5ca05ed74 100644 --- a/packages/agent-config/src/dataSources.ts +++ b/packages/agent-config/src/dataSources.ts @@ -1,79 +1,182 @@ import Debug from 'debug' -import { DataSource } from 'typeorm' -import { BaseDataSourceOptions } from 'typeorm/data-source/BaseDataSourceOptions' -import { DataSourceOptions } from 'typeorm/data-source/DataSourceOptions' +import {DataSource} from 'typeorm' +import {BaseDataSourceOptions} from 'typeorm/data-source/BaseDataSourceOptions' -const debug = Debug(`demo:databaseService`) +import {DataSourceOptions} from 'typeorm/data-source/DataSourceOptions' +import {DatabaseType} from "typeorm/driver/types/DatabaseType"; + + +const debug = Debug(`sphereon:ssi-sdk:database`) export class DataSources { - private dataSources = new Map() - private configs + get defaultDbType(): SupportedDatabaseType { + return this._defaultDbType; + } + + set defaultDbType(value: SupportedDatabaseType) { + this._defaultDbType = value; + } + private dataSources = new Map() + private configs: Map + private _defaultDbType: SupportedDatabaseType = 'postgres' - private static singleton: DataSources + private static singleton: DataSources - public static singleInstance() { - if (!DataSources.singleton) { - DataSources.singleton = new DataSources() + public static singleInstance() { + if (!DataSources.singleton) { + DataSources.singleton = new DataSources() + } + return DataSources.singleton } - return DataSources.singleton - } - public static newInstance(configs?: Map) { - return new DataSources(configs) - } + public static newInstance(configs?: Map) { + return new DataSources(configs) + } - private constructor(configs?: Map) { - this.configs = configs ?? new Map() - } + private constructor(configs?: Map) { + (configs ?? new Map()).forEach((config, name) => this.addConfig(name, config)) - addConfig(dbName: string, config: DataSourceOptions): this { - this.configs.set(dbName, config) - return this - } + } - deleteConfig(dbName: string): this { - this.configs.delete(dbName) - return this - } + addConfig(dbName: string, config: DataSourceOptions): this { + this.configs.set(dbName, config) + // yes we are aware last one wins + this._defaultDbType = config.type + return this + } - getConfig(dbName: string): BaseDataSourceOptions { - const config = this.configs.get(dbName) - if (!config) { - throw Error(`No DB config found for ${dbName}`) + deleteConfig(dbName: string): this { + this.configs.delete(dbName) + return this + } + has(dbName: string) { + return this.configs.has(dbName) && this.dataSources.has(dbName) } - return config - } - public getDbNames(): string[] { - return [...this.configs.keys()] - } + delete(dbName: string): this { + this.deleteConfig(dbName) + this.dataSources.delete(dbName) + return this + } - async getDbConnection(dbName: string): Promise { - const config = this.getConfig(dbName) - /*if (config.synchronize) { - return Promise.reject( - `WARNING: Automatic migrations need to be disabled in this app! Adjust the database configuration and set synchronize to false` + getConfig(dbName: string): BaseDataSourceOptions { + const config = this.configs.get(dbName) + if (!config) { + throw Error(`No DB config found for ${dbName}`) + } + return config + } + + public getDbNames(): string[] { + return [...this.configs.keys()] + } + + async getDbConnection(dbName: string): Promise { + const config = this.getConfig(dbName) + if (!this._defaultDbType) { + this._defaultDbType = config.type + } + /*if (config.synchronize) { + return Promise.reject( + `WARNING: Automatic migrations need to be disabled in this app! Adjust the database configuration and set synchronize to false` + ) + }*/ + + let dataSource = this.dataSources.get(dbName) + if (dataSource) { + return dataSource + } + + + dataSource = await new DataSource({...(config as DataSourceOptions), name: dbName}).initialize() + this.dataSources.set(dbName, dataSource) + if (config.synchronize) { + debug(`WARNING: Automatic migrations need to be disabled in this app! Adjust the database configuration and set synchronize to false`) + } else if (config.migrationsRun) { + debug( + `Migrations are currently managed from config. Please set migrationsRun and synchronize to false to get consistent behaviour. We run migrations from code explicitly`, ) - }*/ + } else { + debug(`Running ${dataSource.migrations.length} migration(s) from code if needed...`) + await dataSource.runMigrations() + debug(`${dataSource.migrations.length} migration(s) from code were inspected and applied`) + } + return dataSource + } +} - let dataSource = this.dataSources.get(dbName) - if (dataSource) { - return dataSource +export type SupportedDatabaseType = Pick +export type DateTimeType = 'timestamp' | 'datetime' + +export type DateType = 'date' + + +export const getDbType = (opts?: { defaultType: SupportedDatabaseType }): SupportedDatabaseType => { + const type = (typeof process === 'object' ? process?.env?.DB_TYPE : undefined) ?? DataSources.singleInstance().defaultDbType ?? opts?.defaultType + if (!type) { + throw Error(`Could not determine DB type. Please set the DB_TYPE global variable or env var to one of 'postgres' or 'sqlite'`) + } + return type as SupportedDatabaseType +} + + +const typeOrmDateTime = (opts?: { defaultType: SupportedDatabaseType }): DateTimeType => { + switch (getDbType(opts)) { + case "postgres": + return 'timestamp' + case "sqlite": + return 'datetime' + default: + throw Error(`DB type ${getDbType(opts)} not supported`) + } +} + +const typeormDate = (opts?: { defaultType: SupportedDatabaseType }): DateType => { + // The same for both DBs + return 'date' +} +export const TYPEORM_DATE_TIME_TYPE = typeOrmDateTime() + + +export const TYPEORM_DATE_TYPE = typeormDate() + + +/** + * Gets the database connection. + * + * Also makes sure that migrations are run (versioning for DB schema's), so we can properly update over time + * + * @param connectionName The database name + * @param opts + */ +export const getDbConnection = async (connectionName: string, opts?: { + config: BaseDataSourceOptions | any +}): Promise => { + return DataSources.singleInstance().addConfig(connectionName, opts?.config).getDbConnection(connectionName) +} + +export const dropDatabase = async (dbName: string): Promise => { + if (!DataSources.singleInstance().has(dbName)) { + return Promise.reject(Error(`No database present with name: ${dbName}`)); } - dataSource = await new DataSource({ ...(config as DataSourceOptions), name: dbName }).initialize() - this.dataSources.set(dbName, dataSource) - if (config.synchronize) { - debug(`WARNING: Automatic migrations need to be disabled in this app! Adjust the database configuration and set synchronize to false`) - } else if (config.migrationsRun) { - debug( - `Migrations are currently managed from config. Please set migrationsRun and synchronize to false to get consistent behaviour. We run migrations from code explicitly`, - ) + const connection: DataSource = await getDbConnection(dbName); + await connection.dropDatabase(); + DataSources.singleInstance().delete(dbName); +}; + +/** + * Runs a migration down (drops DB schema) + * @param dataSource + */ +export const revertMigration = async (dataSource: DataSource): Promise => { + if (dataSource.isInitialized) { + await dataSource.undoLastMigration() } else { - debug(`Running ${dataSource.migrations.length} migration(s) from code if needed...`) - await dataSource.runMigrations() - debug(`${dataSource.migrations.length} migration(s) from code were inspected and applied`) + console.error('DataSource is not initialized') } - return dataSource - } } +export const resetDatabase = async (dbName: string): Promise => { + await dropDatabase(dbName); + await getDbConnection(dbName); +}; diff --git a/packages/data-store/package.json b/packages/data-store/package.json index 72962a743..106085fe0 100644 --- a/packages/data-store/package.json +++ b/packages/data-store/package.json @@ -16,6 +16,7 @@ "dependencies": { "@sphereon/pex": "^4.0.1", "@sphereon/ssi-sdk-ext.did-utils": "0.23.1-next.42", + "@sphereon/ssi-sdk.agent-config": "workspace:*", "@sphereon/ssi-sdk.core": "workspace:*", "@sphereon/ssi-types": "workspace:*", "@veramo/core": "4.2.0", diff --git a/packages/data-store/src/__tests__/contact.entities.test.ts b/packages/data-store/src/__tests__/contact.entities.test.ts index a4362c6e2..895da780c 100644 --- a/packages/data-store/src/__tests__/contact.entities.test.ts +++ b/packages/data-store/src/__tests__/contact.entities.test.ts @@ -56,6 +56,8 @@ import { physicalAddressEntityFrom, } from '../utils/contact/MappingUtils' import { ContactMetadataItemEntity } from '../entities/contact/ContactMetadataItemEntity' +import { DataSources } from '@sphereon/ssi-sdk.agent-config' + // TODO write test adding two contacts reusing the same contactType @@ -63,6 +65,7 @@ describe('Database entities tests', (): void => { let dbConnection: DataSource beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/contact.store.test.ts b/packages/data-store/src/__tests__/contact.store.test.ts index 83db6f44e..185f1da15 100644 --- a/packages/data-store/src/__tests__/contact.store.test.ts +++ b/packages/data-store/src/__tests__/contact.store.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { DataSource } from 'typeorm' import { DataStoreContactEntities, DataStoreMigrations, IdentityOrigin, MetadataItem, MetadataTypes, PartyOrigin } from '../index' import { ContactStore } from '../contact/ContactStore' @@ -31,6 +32,7 @@ describe('Contact store tests', (): void => { let contactStore: ContactStore beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/digitalCredential.entities.test.ts b/packages/data-store/src/__tests__/digitalCredential.entities.test.ts index 5c54ce8cc..4905f5d2c 100644 --- a/packages/data-store/src/__tests__/digitalCredential.entities.test.ts +++ b/packages/data-store/src/__tests__/digitalCredential.entities.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { DataSource } from 'typeorm' import { CredentialRole, DataStoreDigitalCredentialEntities } from '../index' import { DataStoreDigitalCredentialMigrations } from '../migrations' @@ -17,6 +18,7 @@ describe('Database entities tests', (): void => { let dbConnection: DataSource beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/digitalCredential.store.test.ts b/packages/data-store/src/__tests__/digitalCredential.store.test.ts index d452ef78b..74425f98e 100644 --- a/packages/data-store/src/__tests__/digitalCredential.store.test.ts +++ b/packages/data-store/src/__tests__/digitalCredential.store.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { DataSource } from 'typeorm' import { DataStoreDigitalCredentialMigrations } from '../migrations' import { CredentialRole, DataStoreDigitalCredentialEntities } from '../index' @@ -18,6 +19,7 @@ describe('Database entities tests', (): void => { let digitalCredentialStore: DigitalCredentialStore beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/eventLogger.entities.test.ts b/packages/data-store/src/__tests__/eventLogger.entities.test.ts index 516a175ba..be7245ff9 100644 --- a/packages/data-store/src/__tests__/eventLogger.entities.test.ts +++ b/packages/data-store/src/__tests__/eventLogger.entities.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { PartyCorrelationType } from '@sphereon/ssi-sdk.core' import { ActionType, InitiatorType, LogLevel, SubSystem, System, SystemCorrelationIdType } from '@sphereon/ssi-types' import { DataSource } from 'typeorm' @@ -10,6 +11,7 @@ describe('Database entities tests', (): void => { let dbConnection: DataSource beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/eventLogger.store.test.ts b/packages/data-store/src/__tests__/eventLogger.store.test.ts index 6b33255ae..993140da2 100644 --- a/packages/data-store/src/__tests__/eventLogger.store.test.ts +++ b/packages/data-store/src/__tests__/eventLogger.store.test.ts @@ -1,6 +1,7 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { ActionType, InitiatorType, LogLevel, SubSystem, System, SystemCorrelationIdType } from '@sphereon/ssi-types' import { DataSource } from 'typeorm' -import { DataStoreEventLoggerMigrations } from '../migrations/generic' +import { DataStoreEventLoggerMigrations } from '../migrations' import { DataStoreEventLoggerEntities } from '../index' import { AuditLoggingEvent, PartyCorrelationType } from '@sphereon/ssi-sdk.core' import { EventLoggerStore } from '../eventLogger/EventLoggerStore' @@ -11,6 +12,7 @@ describe('Database entities tests', (): void => { let eventLoggerStore: EventLoggerStore beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/issuanceBranding.entities.test.ts b/packages/data-store/src/__tests__/issuanceBranding.entities.test.ts index 27b71a517..c49c99396 100644 --- a/packages/data-store/src/__tests__/issuanceBranding.entities.test.ts +++ b/packages/data-store/src/__tests__/issuanceBranding.entities.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { DataSource, Repository } from 'typeorm' import { DataStoreMigrations } from '../migrations' import { @@ -20,6 +21,7 @@ describe('Database entities tests', (): void => { let dbConnection: DataSource beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/issuanceBranding.store.test.ts b/packages/data-store/src/__tests__/issuanceBranding.store.test.ts index 18c386307..14890de4e 100644 --- a/packages/data-store/src/__tests__/issuanceBranding.store.test.ts +++ b/packages/data-store/src/__tests__/issuanceBranding.store.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { DataSource } from 'typeorm' import { IssuanceBrandingStore } from '../issuanceBranding/IssuanceBrandingStore' import { DataStoreMigrations } from '../migrations' @@ -31,6 +32,7 @@ describe('Issuance branding store tests', (): void => { let issuanceBrandingStore: IssuanceBrandingStore beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/machineState.entities.test.ts b/packages/data-store/src/__tests__/machineState.entities.test.ts index d3708eb15..4a5344245 100644 --- a/packages/data-store/src/__tests__/machineState.entities.test.ts +++ b/packages/data-store/src/__tests__/machineState.entities.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { DataSource } from 'typeorm' import { MachineStateInfoEntity } from '../entities/machineState/MachineStateInfoEntity' @@ -7,6 +8,7 @@ describe('Machine State Info Database entities tests', (): void => { let dbConnection: DataSource beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/machineState.store.test.ts b/packages/data-store/src/__tests__/machineState.store.test.ts index 5425e8273..02277bcd9 100644 --- a/packages/data-store/src/__tests__/machineState.store.test.ts +++ b/packages/data-store/src/__tests__/machineState.store.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { DataSource } from 'typeorm' import { DataStoreMachineStateEntities, MachineStateStore, StoreMachineStatesFindActiveArgs, StoreMachineStatePersistArgs } from '../index' import { DataStoreMachineStateMigrations } from '../migrations' @@ -7,6 +8,7 @@ describe('Machine State store tests', (): void => { let store: MachineStateStore beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/pd-manager.entities.test.ts b/packages/data-store/src/__tests__/pd-manager.entities.test.ts index 57f14e019..3c9494ada 100644 --- a/packages/data-store/src/__tests__/pd-manager.entities.test.ts +++ b/packages/data-store/src/__tests__/pd-manager.entities.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { DataSource } from 'typeorm' import { PresentationDefinitionItemEntity } from '../entities/presentationDefinition/PresentationDefinitionItemEntity' import { DataStorePresentationDefinitionMigrations } from '../migrations' @@ -7,6 +8,7 @@ describe('PresentationDefinitionItemEntity tests', (): void => { let dbConnection: DataSource beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/__tests__/pd-manager.store.test.ts b/packages/data-store/src/__tests__/pd-manager.store.test.ts index 820f90968..5091f1fc2 100644 --- a/packages/data-store/src/__tests__/pd-manager.store.test.ts +++ b/packages/data-store/src/__tests__/pd-manager.store.test.ts @@ -1,3 +1,4 @@ +import {DataSources} from "@sphereon/ssi-sdk.agent-config"; import { DataSource } from 'typeorm' import { DataStorePresentationDefinitionEntities, DataStorePresentationDefinitionMigrations, PDStore } from '../index' import { GetDefinitionsArgs, NonPersistedPresentationDefinitionItem, PresentationDefinitionItem } from '../types' @@ -7,6 +8,7 @@ describe('PDStore tests', (): void => { let pdStore: PDStore beforeEach(async (): Promise => { + DataSources.singleInstance().defaultDbType = 'sqlite' dbConnection = await new DataSource({ type: 'sqlite', database: ':memory:', diff --git a/packages/data-store/src/entities/contact/BaseContactEntity.ts b/packages/data-store/src/entities/contact/BaseContactEntity.ts index 040c88e24..cb7fffc5d 100644 --- a/packages/data-store/src/entities/contact/BaseContactEntity.ts +++ b/packages/data-store/src/entities/contact/BaseContactEntity.ts @@ -11,6 +11,7 @@ import { TableInheritance, UpdateDateColumn, } from 'typeorm' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { PartyEntity } from './PartyEntity' import { ContactMetadataItemEntity } from './ContactMetadataItemEntity' @@ -20,10 +21,10 @@ export abstract class BaseContactEntity extends BaseEntity { @PrimaryGeneratedColumn('uuid') id!: string - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date @OneToOne(() => PartyEntity, (party: PartyEntity) => party.contact, { diff --git a/packages/data-store/src/entities/contact/ContactMetadataItemEntity.ts b/packages/data-store/src/entities/contact/ContactMetadataItemEntity.ts index 27896f2bd..c54babce4 100644 --- a/packages/data-store/src/entities/contact/ContactMetadataItemEntity.ts +++ b/packages/data-store/src/entities/contact/ContactMetadataItemEntity.ts @@ -1,5 +1,6 @@ import { Entity, Column, PrimaryGeneratedColumn, BaseEntity, ManyToOne, BeforeInsert, BeforeUpdate } from 'typeorm' import { IMetadataEntity, ValidationConstraint } from '../../types' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { BaseContactEntity } from './BaseContactEntity' import { IsNotEmpty, validate, ValidationError } from 'class-validator' import { getConstraint } from '../../utils/ValidatorUtils' @@ -23,7 +24,7 @@ export class ContactMetadataItemEntity extends BaseEntity implements IMetadataEn @Column('numeric', { name: 'numberValue', nullable: true }) numberValue?: number - @Column({ name: 'dateValue', nullable: true }) + @Column({ name: 'dateValue', nullable: true, type: TYPEORM_DATE_TIME_TYPE }) dateValue?: Date @Column('boolean', { name: 'boolValue', nullable: true }) diff --git a/packages/data-store/src/entities/contact/ElectronicAddressEntity.ts b/packages/data-store/src/entities/contact/ElectronicAddressEntity.ts index d427489b3..77d867a6f 100644 --- a/packages/data-store/src/entities/contact/ElectronicAddressEntity.ts +++ b/packages/data-store/src/entities/contact/ElectronicAddressEntity.ts @@ -10,6 +10,7 @@ import { CreateDateColumn, UpdateDateColumn, } from 'typeorm' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { PartyEntity } from './PartyEntity' import { getConstraint } from '../../utils/ValidatorUtils' import { ElectronicAddressType, ValidationConstraint } from '../../types' @@ -41,10 +42,10 @@ export class ElectronicAddressEntity extends BaseEntity { @Column('text', { name: 'tenant_id', nullable: true }) tenantId?: string - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date // By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change. diff --git a/packages/data-store/src/entities/contact/IdentityEntity.ts b/packages/data-store/src/entities/contact/IdentityEntity.ts index 9b69a0885..eb5d586b3 100644 --- a/packages/data-store/src/entities/contact/IdentityEntity.ts +++ b/packages/data-store/src/entities/contact/IdentityEntity.ts @@ -13,6 +13,7 @@ import { BeforeUpdate, } from 'typeorm' import { IsNotEmpty, validate, ValidationError } from 'class-validator' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { CorrelationIdentifierEntity } from './CorrelationIdentifierEntity' import { ConnectionEntity } from './ConnectionEntity' import { IdentityMetadataItemEntity } from './IdentityMetadataItemEntity' @@ -70,10 +71,10 @@ export class IdentityEntity extends BaseEntity { @JoinColumn({ name: 'metadata_id' }) // TODO check in db file metadata!: Array - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false , type: TYPEORM_DATE_TIME_TYPE}) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date @ManyToOne(() => PartyEntity, (party: PartyEntity) => party.identities, { diff --git a/packages/data-store/src/entities/contact/IdentityMetadataItemEntity.ts b/packages/data-store/src/entities/contact/IdentityMetadataItemEntity.ts index 172e61540..4d9539774 100644 --- a/packages/data-store/src/entities/contact/IdentityMetadataItemEntity.ts +++ b/packages/data-store/src/entities/contact/IdentityMetadataItemEntity.ts @@ -1,3 +1,4 @@ +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { Entity, Column, PrimaryGeneratedColumn, BaseEntity, ManyToOne, BeforeInsert, BeforeUpdate } from 'typeorm' import { IMetadataEntity, ValidationConstraint } from '../../types' import { IdentityEntity } from './IdentityEntity' @@ -23,7 +24,7 @@ export class IdentityMetadataItemEntity extends BaseEntity implements IMetadataE @Column('numeric', { name: 'numberValue', nullable: true }) numberValue?: number - @Column({ name: 'dateValue', nullable: true }) + @Column({ name: 'dateValue', nullable: true, type: TYPEORM_DATE_TIME_TYPE }) dateValue?: Date @Column('boolean', { name: 'boolValue', nullable: true }) diff --git a/packages/data-store/src/entities/contact/OrganizationEntity.ts b/packages/data-store/src/entities/contact/OrganizationEntity.ts index 46c45a022..bd79cddc8 100644 --- a/packages/data-store/src/entities/contact/OrganizationEntity.ts +++ b/packages/data-store/src/entities/contact/OrganizationEntity.ts @@ -1,9 +1,8 @@ -import { JoinColumn, OneToOne, Column, ChildEntity, BeforeInsert, BeforeUpdate } from 'typeorm' -import { PartyEntity } from './PartyEntity' -import { BaseContactEntity } from './BaseContactEntity' -import { ValidationConstraint } from '../../types' -import { validate, IsNotEmpty, ValidationError } from 'class-validator' -import { getConstraint } from '../../utils/ValidatorUtils' +import {IsNotEmpty, validate, ValidationError} from 'class-validator' +import {BeforeInsert, BeforeUpdate, ChildEntity, Column} from 'typeorm' +import {ValidationConstraint} from '../../types' +import {getConstraint} from '../../utils/ValidatorUtils' +import {BaseContactEntity} from './BaseContactEntity' @ChildEntity('Organization') export class OrganizationEntity extends BaseContactEntity { @@ -21,10 +20,6 @@ export class OrganizationEntity extends BaseContactEntity { @Column('text', { name: 'tenant_id', nullable: true }) tenantId?: string - @OneToOne(() => PartyEntity) - @JoinColumn({ name: 'party_id' }) - party!: PartyEntity - @BeforeInsert() @BeforeUpdate() async validate(): Promise { diff --git a/packages/data-store/src/entities/contact/PartyEntity.ts b/packages/data-store/src/entities/contact/PartyEntity.ts index 2e93ce6b3..b598318d9 100644 --- a/packages/data-store/src/entities/contact/PartyEntity.ts +++ b/packages/data-store/src/entities/contact/PartyEntity.ts @@ -13,6 +13,7 @@ import { UpdateDateColumn, } from 'typeorm' import { ValidationConstraint } from '../../types' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { IdentityEntity } from './IdentityEntity' import { validate, ValidationError } from 'class-validator' import { PartyTypeEntity } from './PartyTypeEntity' @@ -88,10 +89,10 @@ export class PartyEntity extends BaseEntity { @JoinColumn({ name: 'relationship_id' }) relationships!: Array - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date // By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change. diff --git a/packages/data-store/src/entities/contact/PartyRelationshipEntity.ts b/packages/data-store/src/entities/contact/PartyRelationshipEntity.ts index bcaf655b0..3c3864dc2 100644 --- a/packages/data-store/src/entities/contact/PartyRelationshipEntity.ts +++ b/packages/data-store/src/entities/contact/PartyRelationshipEntity.ts @@ -10,6 +10,7 @@ import { BeforeUpdate, JoinColumn, } from 'typeorm' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { PartyEntity } from './PartyEntity' @Entity('PartyRelationship') @@ -44,10 +45,10 @@ export class PartyRelationshipEntity { @Column('text', { name: 'tenant_id', nullable: true }) tenantId?: string - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date // By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change. diff --git a/packages/data-store/src/entities/contact/PartyTypeEntity.ts b/packages/data-store/src/entities/contact/PartyTypeEntity.ts index e28c40bda..b29ca35bd 100644 --- a/packages/data-store/src/entities/contact/PartyTypeEntity.ts +++ b/packages/data-store/src/entities/contact/PartyTypeEntity.ts @@ -1,4 +1,5 @@ import { BeforeInsert, BeforeUpdate, Column, CreateDateColumn, Entity, Index, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { PartyEntity } from './PartyEntity' import { PartyOrigin, PartyTypeType, ValidationConstraint } from '../../types' import { IsNotEmpty, Validate, validate, ValidationError } from 'class-validator' @@ -34,10 +35,10 @@ export class PartyTypeEntity { }) parties!: Array - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date // By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change. diff --git a/packages/data-store/src/entities/contact/PhysicalAddressEntity.ts b/packages/data-store/src/entities/contact/PhysicalAddressEntity.ts index 9e9c42eb6..b0996864e 100644 --- a/packages/data-store/src/entities/contact/PhysicalAddressEntity.ts +++ b/packages/data-store/src/entities/contact/PhysicalAddressEntity.ts @@ -10,6 +10,7 @@ import { PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { getConstraint } from '../../utils/ValidatorUtils' import { PhysicalAddressType, ValidationConstraint } from '../../types' import { PartyEntity } from './PartyEntity' @@ -66,10 +67,10 @@ export class PhysicalAddressEntity extends BaseEntity { @Column('text', { name: 'partyId', nullable: true }) partyId?: string - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date // By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change. diff --git a/packages/data-store/src/entities/digitalCredential/DigitalCredentialEntity.ts b/packages/data-store/src/entities/digitalCredential/DigitalCredentialEntity.ts index 0af1eb1ec..ae36ff930 100644 --- a/packages/data-store/src/entities/digitalCredential/DigitalCredentialEntity.ts +++ b/packages/data-store/src/entities/digitalCredential/DigitalCredentialEntity.ts @@ -1,5 +1,6 @@ import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm' import { CredentialCorrelationType, CredentialDocumentFormat, CredentialRole, CredentialStateType, DocumentType } from '../../types' +import {TYPEORM_DATE_TIME_TYPE, TYPEORM_DATE_TYPE} from "@sphereon/ssi-sdk.agent-config"; @Entity('DigitalCredential') export class DigitalCredentialEntity extends BaseEntity { @@ -45,21 +46,21 @@ export class DigitalCredentialEntity extends BaseEntity { @Column('text', { name: 'tenant_id', nullable: true }) tenantId?: string - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date - @Column('date', { name: 'valid_until', nullable: true }) + @Column({ name: 'valid_until', nullable: true, type: TYPEORM_DATE_TYPE }) validUntil?: Date - @Column('date', { name: 'valid_from', nullable: true }) + @Column({ name: 'valid_from', nullable: true, type: TYPEORM_DATE_TYPE }) validFrom?: Date - @Column('date', { name: 'verified_at', nullable: true }) + @Column( { name: 'verified_at', nullable: true, type: TYPEORM_DATE_TIME_TYPE }) verifiedAt?: Date - @Column('date', { name: 'revoked_at', nullable: true }) + @Column({ name: 'revoked_at', nullable: true, type: TYPEORM_DATE_TIME_TYPE }) revokedAt?: Date } diff --git a/packages/data-store/src/entities/eventLogger/AuditEventEntity.ts b/packages/data-store/src/entities/eventLogger/AuditEventEntity.ts index 7c2c117c4..592ef8a56 100644 --- a/packages/data-store/src/entities/eventLogger/AuditEventEntity.ts +++ b/packages/data-store/src/entities/eventLogger/AuditEventEntity.ts @@ -2,13 +2,14 @@ import { ActionSubType, ActionType, InitiatorType, LogLevel, SubSystem, System, import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm' import { PartyCorrelationType } from '@sphereon/ssi-sdk.core' import { NonPersistedAuditLoggingEvent } from '../../types' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; @Entity('AuditEvents') export class AuditEventEntity extends BaseEntity { @PrimaryGeneratedColumn('uuid') id!: string - @Column({ name: 'timestamp', nullable: false, unique: false }) + @Column({ name: 'timestamp', nullable: false, unique: false, type: TYPEORM_DATE_TIME_TYPE }) timestamp!: Date @Column('simple-enum', { name: 'level', enum: LogLevel, nullable: false, unique: false }) @@ -59,10 +60,10 @@ export class AuditEventEntity extends BaseEntity { @Column('text', { name: 'diagnosticData', nullable: true, unique: false }) diagnosticData?: string - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date } diff --git a/packages/data-store/src/entities/issuanceBranding/BaseLocaleBrandingEntity.ts b/packages/data-store/src/entities/issuanceBranding/BaseLocaleBrandingEntity.ts index 0753917a7..d9c04d6be 100644 --- a/packages/data-store/src/entities/issuanceBranding/BaseLocaleBrandingEntity.ts +++ b/packages/data-store/src/entities/issuanceBranding/BaseLocaleBrandingEntity.ts @@ -11,6 +11,7 @@ import { TableInheritance, UpdateDateColumn, } from 'typeorm' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { ImageAttributesEntity } from './ImageAttributesEntity' import { BackgroundAttributesEntity } from './BackgroundAttributesEntity' import { TextAttributesEntity } from './TextAttributesEntity' @@ -61,10 +62,10 @@ export class BaseLocaleBrandingEntity extends BaseEntity { @JoinColumn({ name: 'textId' }) text?: TextAttributesEntity - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date // By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change. diff --git a/packages/data-store/src/entities/issuanceBranding/CredentialBrandingEntity.ts b/packages/data-store/src/entities/issuanceBranding/CredentialBrandingEntity.ts index 9e6a65242..5b4db866e 100644 --- a/packages/data-store/src/entities/issuanceBranding/CredentialBrandingEntity.ts +++ b/packages/data-store/src/entities/issuanceBranding/CredentialBrandingEntity.ts @@ -11,6 +11,7 @@ import { UpdateDateColumn, } from 'typeorm' import { ArrayMinSize, IsNotEmpty, validate, ValidationError } from 'class-validator' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { CredentialLocaleBrandingEntity, credentialLocaleBrandingEntityFrom } from './CredentialLocaleBrandingEntity' import { IBasicCredentialBranding, IBasicCredentialLocaleBranding } from '../../types' @@ -42,10 +43,10 @@ export class CredentialBrandingEntity extends BaseEntity { @ArrayMinSize(1, { message: 'localeBranding cannot be empty' }) localeBranding!: Array - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date // By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change. diff --git a/packages/data-store/src/entities/issuanceBranding/IssuerBrandingEntity.ts b/packages/data-store/src/entities/issuanceBranding/IssuerBrandingEntity.ts index f739a1000..3037e8d65 100644 --- a/packages/data-store/src/entities/issuanceBranding/IssuerBrandingEntity.ts +++ b/packages/data-store/src/entities/issuanceBranding/IssuerBrandingEntity.ts @@ -11,6 +11,7 @@ import { UpdateDateColumn, } from 'typeorm' import { ArrayMinSize, IsNotEmpty, validate, ValidationError } from 'class-validator' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; import { IssuerLocaleBrandingEntity, issuerLocaleBrandingEntityFrom } from './IssuerLocaleBrandingEntity' import { IBasicIssuerBranding, IBasicIssuerLocaleBranding } from '../../types' @@ -37,10 +38,10 @@ export class IssuerBrandingEntity extends BaseEntity { @ArrayMinSize(1, { message: 'localeBranding cannot be empty' }) localeBranding!: Array - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date // By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change. diff --git a/packages/data-store/src/entities/machineState/MachineStateInfoEntity.ts b/packages/data-store/src/entities/machineState/MachineStateInfoEntity.ts index 71fe81043..3fe8765ea 100644 --- a/packages/data-store/src/entities/machineState/MachineStateInfoEntity.ts +++ b/packages/data-store/src/entities/machineState/MachineStateInfoEntity.ts @@ -1,4 +1,5 @@ import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryColumn, UpdateDateColumn } from 'typeorm' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; /** * @class MachineStateInfoEntity @@ -38,19 +39,19 @@ export class MachineStateInfoEntity extends BaseEntity { @Column({ name: 'state', type: 'text', nullable: false }) state!: string - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'updated_at', nullable: false }) + @UpdateDateColumn({ name: 'updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) updatedAt!: Date @Column({ name: 'updated_count', type: 'integer', nullable: false }) updatedCount!: number - @Column({ name: 'expires_at', nullable: true }) + @Column({ name: 'expires_at', nullable: true , type: TYPEORM_DATE_TIME_TYPE}) expiresAt?: Date - @Column({ name: 'completed_at', nullable: true }) + @Column({ name: 'completed_at', nullable: true, type: TYPEORM_DATE_TIME_TYPE }) completedAt?: Date @Column({ name: 'tenant_id', type: 'varchar', nullable: true }) diff --git a/packages/data-store/src/entities/presentationDefinition/PresentationDefinitionItemEntity.ts b/packages/data-store/src/entities/presentationDefinition/PresentationDefinitionItemEntity.ts index e6c57ec9e..67b32e9b9 100644 --- a/packages/data-store/src/entities/presentationDefinition/PresentationDefinitionItemEntity.ts +++ b/packages/data-store/src/entities/presentationDefinition/PresentationDefinitionItemEntity.ts @@ -1,5 +1,6 @@ import { BaseEntity, BeforeInsert, BeforeUpdate, Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm' import { IsNotEmpty } from 'class-validator' +import {TYPEORM_DATE_TIME_TYPE} from "@sphereon/ssi-sdk.agent-config"; @Entity('PresentationDefinitionItem') @Index(['version'], { unique: false }) @@ -28,10 +29,10 @@ export class PresentationDefinitionItemEntity extends BaseEntity { @IsNotEmpty({ message: 'A blank definition payload field is not allowed' }) definitionPayload!: string - @CreateDateColumn({ name: 'created_at', nullable: false }) + @CreateDateColumn({ name: 'created_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) createdAt!: Date - @UpdateDateColumn({ name: 'last_updated_at', nullable: false }) + @UpdateDateColumn({ name: 'last_updated_at', nullable: false, type: TYPEORM_DATE_TIME_TYPE }) lastUpdatedAt!: Date // By default, @UpdateDateColumn in TypeORM updates the timestamp only when the entity's top-level properties change. diff --git a/packages/data-store/tsconfig.json b/packages/data-store/tsconfig.json index c489f0f11..6b6bc3493 100644 --- a/packages/data-store/tsconfig.json +++ b/packages/data-store/tsconfig.json @@ -14,6 +14,9 @@ }, { "path": "../ssi-types" + }, + { + "path": "../agent-config" } ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 641913b35..096219d0f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -417,6 +417,9 @@ importers: '@sphereon/ssi-sdk-ext.did-utils': specifier: 0.23.1-next.42 version: 0.23.1-next.42 + '@sphereon/ssi-sdk.agent-config': + specifier: workspace:* + version: link:../agent-config '@sphereon/ssi-sdk.core': specifier: workspace:* version: link:../ssi-sdk-core