Skip to content

Commit

Permalink
Merge pull request #230 from Sphereon-Opensource/develop
Browse files Browse the repository at this point in the history
New release
  • Loading branch information
nklomp authored Aug 1, 2024
2 parents 68cefab + f7cb47b commit 286a17b
Show file tree
Hide file tree
Showing 175 changed files with 8,067 additions and 4,925 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-test-on-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
node-version: '20.x'
cache: 'pnpm'
- name: setup npmrc
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-test-publish-on-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
node-version: '20.x'
cache: 'pnpm'
- run: pnpm install
- run: pnpm build
Expand Down
22 changes: 13 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "@sphereon/sphereon-sdk.workspace",
"private": true,
"version": "0.24.0",
"version": "0.28.0",
"description": "Sphereon SSI SDK (Workspace)",
"repository": "[email protected]:Sphereon-Opensource/SSI-SDK.git",
"author": "Sphereon <[email protected]>",
"license": "Apache-2.0",
"scripts": {
"preinstall": "npx only-allow pnpm",
"build": "rimraf --glob ./packages/*/tsconfig.tsbuildinfo && pnpm build:js && pnpm build:copyfiles && pnpm build:api && pnpm build:schema",
"build": "rimraf --glob ./packages/*/tsconfig.tsbudinfo && 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 @@ -38,7 +38,9 @@
]
},
"dependencies": {
"@veramo/core": "4.2.0"
"@veramo/core": "4.2.0",
"@digitalcredentials/jsonld": "^6.0.0",
"@digitalcredentials/jsonld-signatures": "^9.4.0"
},
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.24.8",
Expand Down Expand Up @@ -77,7 +79,7 @@
"typescript": "5.4.2"
},
"engines": {
"node": ">= 18.0.0"
"node": ">= 20.0.0"
},
"prettier": {
"endOfLine": "auto",
Expand Down Expand Up @@ -111,17 +113,19 @@
"@veramo/url-handler": "4.2.0",
"@sphereon/ssi-types": "workspace:*",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/oid4vci-common": "0.14.0",
"@sphereon/oid4vci-client": "0.14.0",
"@sphereon/oid4vci-issuer": "0.14.0",
"@sphereon/oid4vci-common": "0.15.1-next.9",
"@sphereon/oid4vci-client": "0.15.1-next.9",
"@sphereon/oid4vci-issuer": "0.15.1-next.9",
"@sphereon/pex": "^4.0.1",
"@noble/hashes": "1.2.0",
"debug": "^4.3.5",
"did-jwt": "6.11.6",
"did-jwt-vc": "3.1.3",
"ethr-did": "2.3.9",
"typeorm": "^0.3.20",
"@transmute/jsonld": "^0.0.4",
"jsonld": "link:./node_modules/.pnpm/@digitalcredentials+[email protected]/node_modules/@digitalcredentials/jsonld",
"isomorphic-webcrypto": "link:./node_modules/@sphereon/isomorphic-webcrypto"
"jsonld": "npm:@digitalcredentials/jsonld@^6.0.0",
"node-fetch": "2.7.0"
},
"patchedDependencies": {
"@veramo/[email protected]": "patches/@[email protected]",
Expand Down
216 changes: 159 additions & 57 deletions packages/agent-config/src/dataSources.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,181 @@
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'


const debug = Debug(`sphereon:ssi-sdk:database`)

export class DataSources {
private dataSources = new Map<string, DataSource>()
private configs
get defaultDbType(): SupportedDatabaseType {
return this._defaultDbType;
}

set defaultDbType(value: SupportedDatabaseType) {
this._defaultDbType = value;
}
private dataSources = new Map<string, DataSource>()
private configs = new Map<string, DataSourceOptions>()
private _defaultDbType: SupportedDatabaseType = 'sqlite'

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<string, DataSourceOptions>) {
return new DataSources(configs)
}
public static newInstance(configs?: Map<string, DataSourceOptions>) {
return new DataSources(configs)
}

private constructor(configs?: Map<string, DataSourceOptions>) {
this.configs = configs ?? new Map<string, BaseDataSourceOptions>()
}
private constructor(configs?: Map<string, DataSourceOptions>) {
(configs ?? new Map<string, DataSourceOptions>()).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 as SupportedDatabaseType
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<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`
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 (!this._defaultDbType) {
this._defaultDbType = config.type as SupportedDatabaseType
}
/*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 = 'postgres' | 'sqlite' | 'react-native'
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<DataSource> => {
return DataSources.singleInstance().addConfig(connectionName, opts?.config).getDbConnection(connectionName)
}

export const dropDatabase = async (dbName: string): Promise<void> => {
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<void> => {
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<void> => {
await dropDatabase(dbName);
await getDbConnection(dbName);
};
4 changes: 2 additions & 2 deletions packages/contact-manager-rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
},
"dependencies": {
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk-ext.key-manager": "0.23.0",
"@sphereon/ssi-sdk-ext.key-utils": "0.23.0",
"@sphereon/ssi-sdk-ext.key-manager": "0.24.0",
"@sphereon/ssi-sdk-ext.key-utils": "0.24.0",
"@sphereon/ssi-sdk.contact-manager": "workspace:*",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-sdk.data-store": "workspace:*",
Expand Down
4 changes: 2 additions & 2 deletions packages/contact-manager-rest-api/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { GenericAuthArgs, ISingleEndpointOpts } from '@sphereon/ssi-express-support'
import { IContactManager } from '@sphereon/ssi-sdk.contact-manager'
import { IAgentContext, IDataStore, IDIDManager, IKeyManager } from '@veramo/core'
import { IAgentContext, IDIDManager, IKeyManager } from '@veramo/core'

export type ContactManagerMRestApiFeatures = 'party_read' | 'party_write' | 'party_type_read' | 'identity_read'

Expand All @@ -16,5 +16,5 @@ export interface IContactManagerAPIEndpointOpts {
enableFeatures?: ContactManagerMRestApiFeatures[]
}

export type IRequiredPlugins = IContactManager & IDataStore & IKeyManager & IDIDManager
export type IRequiredPlugins = IContactManager & IKeyManager & IDIDManager
export type IRequiredContext = IAgentContext<IRequiredPlugins>
1 change: 1 addition & 0 deletions packages/credential-store/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Change Log
Loading

0 comments on commit 286a17b

Please sign in to comment.