-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #230 from Sphereon-Opensource/develop
New release
- Loading branch information
Showing
175 changed files
with
8,067 additions
and
4,925 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", | ||
|
@@ -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", | ||
|
@@ -77,7 +79,7 @@ | |
"typescript": "5.4.2" | ||
}, | ||
"engines": { | ||
"node": ">= 18.0.0" | ||
"node": ">= 20.0.0" | ||
}, | ||
"prettier": { | ||
"endOfLine": "auto", | ||
|
@@ -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]", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Change Log |
Oops, something went wrong.