Skip to content

Commit

Permalink
Merge branch 'develop' into feature/DPP-1
Browse files Browse the repository at this point in the history
# Conflicts:
#	packages/data-store/src/index.ts
#	packages/data-store/src/migrations/generic/index.ts
#	packages/data-store/src/types/index.ts
#	pnpm-lock.yaml
  • Loading branch information
Brummos committed Sep 12, 2023
2 parents 321ea76 + fe2c566 commit 6109ded
Show file tree
Hide file tree
Showing 86 changed files with 6,044 additions and 1,421 deletions.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"license": "Apache-2.0",
"scripts": {
"preinstall": "npx only-allow pnpm",
"build": "pnpm build:js && pnpm build:copyfiles && pnpm build:api && pnpm build:schema",
"build": "rimraf --glob ./packages/*/tsconfig.tsbuildinfo && pnpm build:js && pnpm build:copyfiles && pnpm build:api && pnpm build:schema",
"build:clean": "lerna clean -y && pnpm install && lerna run build:clean --concurrency 1 && pnpm build:copyfiles && pnpm build:schema",
"build:js": "pnpm -r --stream build",
"build:api": "pnpm -r --stream extract-api",
Expand Down Expand Up @@ -109,13 +109,14 @@
"@veramo/remote-server": "4.2.0",
"@veramo/selective-disclosure": "4.2.0",
"@veramo/url-handler": "4.2.0",
"@sphereon/ssi-types": "workspace:^",
"@sphereon/ssi-sdk.core": "workspace:^",
"@sphereon/ssi-types": "workspace:*",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-sdk-ext.did-provider-key": "0.14.1-next.3",
"@noble/hashes": "1.2.0",
"did-jwt": "6.11.6",
"did-jwt-vc": "3.1.3",
"ethr-did": "2.3.9",
"typeorm": "0.3.17",
"@mattrglobal/[email protected]>jsonld": "4.0.1",
"jsonld": "link:./node_modules/.pnpm/@[email protected]/node_modules/@digitalcredentials/jsonld",
"isomorphic-webcrypto": "link:./node_modules/@sphereon/isomorphic-webcrypto"
Expand Down
5 changes: 4 additions & 1 deletion packages/agent-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
"@veramo/core": "4.2.0",
"jsonpointer": "^5.0.1",
"typeorm": "^0.3.12",
"debug": "^4.3.4",
"url-parse": "^1.5.10",
"yaml": "^2.2.2"
},
"devDependencies": {
"@types/url-parse": "^1.4.8"
"@types/url-parse": "^1.4.8",
"@types/debug": "^4.1.8",
"typescript": "4.9.5"
},
"files": [
"dist/**/*",
Expand Down
79 changes: 79 additions & 0 deletions packages/agent-config/src/dataSources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import Debug from 'debug'
import { DataSource } from 'typeorm'
import { BaseDataSourceOptions } from 'typeorm/data-source/BaseDataSourceOptions'
import { DataSourceOptions } from 'typeorm/data-source/DataSourceOptions'

const debug = Debug(`demo:databaseService`)

export class DataSources {
private dataSources = new Map<string, DataSource>()
private configs

private static singleton: DataSources

public static singleInstance() {
if (!DataSources.singleton) {
DataSources.singleton = new DataSources()
}
return DataSources.singleton
}

public static newInstance(configs?: Map<string, DataSourceOptions>) {
return new DataSources(configs)
}

private constructor(configs?: Map<string, DataSourceOptions>) {
this.configs = configs ?? new Map<string, BaseDataSourceOptions>()
}

addConfig(dbName: string, config: DataSourceOptions): this {
this.configs.set(dbName, config)
return this
}

deleteConfig(dbName: string): this {
this.configs.delete(dbName)
return this
}

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<DataSource> {
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`
)
}*/

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
}
}
1 change: 1 addition & 0 deletions packages/agent-config/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* @public
*/
export * from './dataSources'
export * from './agentCreator'
export * from './objectCreator'
export * from './generic'
1 change: 1 addition & 0 deletions packages/agent-config/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
"experimentalDecorators": true,
"rootDir": "src",
"outDir": "dist",
"declarationDir": "dist",
Expand Down
6 changes: 3 additions & 3 deletions packages/contact-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sphereon/ssi-sdk.data-store": "workspace:^",
"@sphereon/ssi-sdk.data-store": "workspace:*",
"cross-fetch": "^3.1.8",
"typeorm": "^0.3.12"
},
"devDependencies": {
"@sphereon/ssi-sdk.agent-config": "workspace:^",
"@sphereon/ssi-sdk.data-store": "workspace:^",
"@sphereon/ssi-sdk.agent-config": "workspace:*",
"@sphereon/ssi-sdk.data-store": "workspace:*",
"@veramo/remote-client": "4.2.0",
"@veramo/remote-server": "4.2.0"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/data-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc --build",
"typeorm": "ts-node --project ./tsconfig.json -r tsconfig-paths/register ../../node_modules/typeorm/cli.js --config src/migrations/internal-migrations-ormconfig.ts",
"typeorm": "ts-node --project ./tsconfig.json -r tsconfig-paths/register ../../node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/typeorm/cli.js --config src/migrations/internal-migrations-ormconfig.ts",
"typeorm-sqlite:migration:generate": "pnpm run typeorm -- migration:generate -c migration-sqlite -d src/migrations/sqlite -n",
"typeorm-sqlite:migration:run": "pnpm run typeorm -- migration:run -c migration-sqlite",
"typeorm-postgres:migration:generate": "pnpm run typeorm -- migration:generate -c migration-postgres -d src/migrations/postgres -n",
"typeorm-postgres:migration:run": "pnpm run typeorm -- migration:run -c migration-postgres"
},
"dependencies": {
"@sphereon/ssi-types": "workspace:^",
"@sphereon/ssi-types": "workspace:*",
"@veramo/core": "4.2.0",
"class-validator": "^0.14.0",
"debug": "^4.3.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
IIssuer,
OriginalVerifiableCredential,
StatusListCredentialIdMode,
StatusListDriverType,
StatusListIndexingDirection,
StatusListType,
StatusPurpose2021,
} from '@sphereon/ssi-types'
import { ProofFormat } from '@veramo/core'
import { BaseEntity, Column, Entity, OneToMany, PrimaryColumn, Unique } from 'typeorm'
import { StatusListEntryEntity } from './StatusList2021EntryEntity'

@Entity('StatusList')
@Unique('UQ_correlationId', ['correlationId'])
export class StatusListEntity extends BaseEntity {
@PrimaryColumn({ name: 'id', type: 'varchar' })
id!: string

@Column({ name: 'correlationId', type: 'varchar', nullable: false })
correlationId!: string

@Column({ name: 'length', nullable: false, unique: false })
length!: number

@Column({
name: 'issuer',
type: 'text',
nullable: false,
unique: false,
transformer: {
from(value: string): string | IIssuer {
if (value?.trim()?.startsWith('{')) {
return JSON.parse(value)
}
return value
},
to(value: string | IIssuer): string {
if (typeof value === 'string') {
return value
}
return JSON.stringify(value)
},
},
})
issuer!: string | IIssuer

@Column('simple-enum', { name: 'type', enum: StatusListType, nullable: false, default: StatusListType.StatusList2021 })
type!: StatusListType

@Column('simple-enum', { name: 'driverType', enum: StatusListDriverType, nullable: false, default: StatusListDriverType.AGENT_TYPEORM })
driverType!: StatusListDriverType

@Column('simple-enum', {
name: 'credentialIdMode',
enum: StatusListCredentialIdMode,
nullable: false,
default: StatusListCredentialIdMode.ISSUANCE,
})
credentialIdMode!: StatusListCredentialIdMode

@Column({ type: 'varchar', name: 'proofFormat', enum: ['lds', 'jwt'], nullable: false, default: 'lds' })
proofFormat!: ProofFormat

@Column({ type: 'varchar', name: 'indexingDirection', enum: ['rightToLeft'], nullable: false, default: 'rightToLeft' })
indexingDirection!: StatusListIndexingDirection

@Column({ type: 'varchar', name: 'statusPurpose', nullable: false, default: 'revocation' })
statusPurpose!: StatusPurpose2021

@Column({
name: 'statusListCredential',
type: 'text',
nullable: true,
unique: false,
transformer: {
from(value: string): OriginalVerifiableCredential {
if (value?.startsWith('ey')) {
return value
}
return JSON.parse(value)
},
to(value: OriginalVerifiableCredential): string {
if (typeof value === 'string') {
return value
}
return JSON.stringify(value)
},
},
})
statusListCredential?: OriginalVerifiableCredential

@OneToMany((type) => StatusListEntryEntity, (entry) => entry.statusList)
statusListEntries!: StatusListEntryEntity[]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Validate } from 'class-validator'
import { BaseEntity, Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm'
import { IsNonEmptyStringConstraint } from '../validators'
import { StatusListEntity } from './StatusList2021Entity'

@Entity('StatusListEntry')
// @Unique('uq_credential_statuslist', ['statusList', 'credentialId']) // disabled because one prop can be null
// @Unique('uq_credentialHash_statuslistId', ['statusList', 'credentialHash']) // disabled because one prop can be null
export class StatusListEntryEntity extends BaseEntity {
@PrimaryColumn({ name: 'statusListId', type: 'varchar' })
@ManyToOne(() => StatusListEntity, (statusList) => statusList.statusListEntries)
statusList!: StatusListEntity

@PrimaryColumn({ name: 'statusListIndex', nullable: false, unique: false })
@Validate(IsNonEmptyStringConstraint, { message: 'Status list index is required' })
statusListIndex!: number

@Column({ name: 'credentialId', nullable: true })
credentialId?: string

@Column({ name: 'credentialHash', length: 128, nullable: true, unique: false })
credentialHash?: string

@Column({ name: 'correlationId', length: 255, nullable: true, unique: false })
correlationId?: string

@Column({ name: 'value', length: 50, nullable: true, unique: false })
value?: string
}
13 changes: 13 additions & 0 deletions packages/data-store/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { ImageDimensionsEntity, imageDimensionsEntityFrom } from './entities/iss
import { IssuerLocaleBrandingEntity, issuerLocaleBrandingEntityFrom } from './entities/issuanceBranding/IssuerLocaleBrandingEntity'
import { IssuerBrandingEntity, issuerBrandingEntityFrom } from './entities/issuanceBranding/IssuerBrandingEntity'
import { TextAttributesEntity, textAttributesEntityFrom } from './entities/issuanceBranding/TextAttributesEntity'
import { StatusListEntity } from './entities/statusList2021/StatusList2021Entity'
import { StatusListEntryEntity } from './entities/statusList2021/StatusList2021EntryEntity'
import { IStatusListEntity, IStatusListEntryEntity } from './types'
import { PartyRelationshipEntity } from './entities/contact/PartyRelationshipEntity'
import { PartyTypeEntity } from './entities/contact/PartyTypeEntity'
import { OrganizationEntity } from './entities/contact/OrganizationEntity'
Expand All @@ -25,6 +28,7 @@ export { ContactStore } from './contact/ContactStore'
export { AbstractContactStore } from './contact/AbstractContactStore'
export { AbstractIssuanceBrandingStore } from './issuanceBranding/AbstractIssuanceBrandingStore'
export { IssuanceBrandingStore } from './issuanceBranding/IssuanceBrandingStore'
export { StatusListStore } from './statusList/StatusListStore'
export { DataStoreMigrations } from './migrations'
export * from './types'
export * from './utils/contact/MappingUtils'
Expand Down Expand Up @@ -58,6 +62,11 @@ export const DataStoreIssuanceBrandingEntities = [
IssuerLocaleBrandingEntity,
]

export const DataStoreStatusListEntities = [StatusListEntity, StatusListEntryEntity]

// All entities combined if a party wants to enable them all at once
export const DataStoreEntities = [...DataStoreContactEntities, ...DataStoreIssuanceBrandingEntities, ...DataStoreStatusListEntities]

export {
BaseConfigEntity,
ConnectionEntity,
Expand Down Expand Up @@ -85,4 +94,8 @@ export {
textAttributesEntityFrom,
issuerLocaleBrandingEntityFrom,
credentialLocaleBrandingEntityFrom,
IStatusListEntity,
IStatusListEntryEntity,
StatusListEntity,
StatusListEntryEntity,
}
54 changes: 54 additions & 0 deletions packages/data-store/src/migrations/generic/3-CreateStatusList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Debug from 'debug'
import { MigrationInterface, QueryRunner } from 'typeorm'
import { CreateStatusList1693866470001 } from '../postgres/CreateStatusList1693866470001-CreateStatusList'
import { CreateStatusList1693866470002 } from '../sqlite/1693866470000-CreateStatusList'

const debug = Debug('sphereon:ssi-sdk:migrations')

export class CreateStatusList1693866470000 implements MigrationInterface {
name = 'CreateStatusList1693866470000'

public async up(queryRunner: QueryRunner): Promise<void> {
debug('migration: creating issuance branding tables')
const dbType = queryRunner.connection.driver.options.type
if (dbType === 'postgres') {
debug('using postgres migration file')
const mig = new CreateStatusList1693866470001()
const up = await mig.up(queryRunner)
debug('Migration statements executed')
return up
} else if (dbType === 'sqlite' || 'react-native') {
debug('using sqlite/react-native migration file')
const mig = new CreateStatusList1693866470002()
const up = await mig.up(queryRunner)
debug('Migration statements executed')
return up
} else {
return Promise.reject(
"Migrations are currently only supported for sqlite, react-native and postgres. Please run your database without migrations and with 'migrationsRun: false' and 'synchronize: true' for now"
)
}
}

public async down(queryRunner: QueryRunner): Promise<void> {
debug('migration: reverting issuance branding tables')
const dbType = queryRunner.connection.driver.options.type
if (dbType === 'postgres') {
debug('using postgres migration file')
const mig = new CreateStatusList1693866470002()
const down = await mig.down(queryRunner)
debug('Migration statements executed')
return down
} else if (dbType === 'sqlite' || 'react-native') {
debug('using sqlite/react-native migration file')
const mig = new CreateStatusList1693866470002()
const down = await mig.down(queryRunner)
debug('Migration statements executed')
return down
} else {
return Promise.reject(
"Migrations are currently only supported for sqlite, react-native and postgres. Please run your database without migrations and with 'migrationsRun: false' and 'synchronize: true' for now"
)
}
}
}
Loading

0 comments on commit 6109ded

Please sign in to comment.