-
Notifications
You must be signed in to change notification settings - Fork 204
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: expose featureRegistry & add some e2e tests * feat: add synchronous feature query Signed-off-by: Ariel Gentile <[email protected]> BREAKING CHANGE: - `queryFeatures` method parameters have been unified to a single `QueryFeaturesOptions` object that requires specification of Discover Features protocol to be used. - `isProtocolSupported` has been replaced by the more general synchronous mode of `queryFeatures`, which works when `awaitDisclosures` in options is set. Instead of returning a boolean, it returns an object with matching features - Custom modules implementing protocols must register them in Feature Registry in order to let them be discovered by other agents (this can be done in module `register(dependencyManager, featureRegistry)` method)
- Loading branch information
Showing
70 changed files
with
2,213 additions
and
247 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 |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import type { FeatureQuery, Feature } from './models' | ||
|
||
import { injectable } from 'tsyringe' | ||
|
||
@injectable() | ||
class FeatureRegistry { | ||
private features: Feature[] = [] | ||
|
||
/** | ||
* Register a single or set of Features on the registry | ||
* | ||
* @param features set of {Feature} objects or any inherited class | ||
*/ | ||
public register(...features: Feature[]) { | ||
for (const feature of features) { | ||
const index = this.features.findIndex((item) => item.type === feature.type && item.id === feature.id) | ||
|
||
if (index > -1) { | ||
this.features[index] = this.features[index].combine(feature) | ||
} else { | ||
this.features.push(feature) | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Perform a set of queries in the registry, supporting wildcards (*) as | ||
* expressed in Aries RFC 0557. | ||
* | ||
* @see https://github.com/hyperledger/aries-rfcs/blob/560ffd23361f16a01e34ccb7dcc908ec28c5ddb1/features/0557-discover-features-v2/README.md | ||
* | ||
* @param queries set of {FeatureQuery} objects to query features | ||
* @returns array containing all matching features (can be empty) | ||
*/ | ||
public query(...queries: FeatureQuery[]) { | ||
const output = [] | ||
for (const query of queries) { | ||
const items = this.features.filter((item) => item.type === query.featureType) | ||
// An * will return all features of a given type (e.g. all protocols, all goal codes, all AIP configs) | ||
if (query.match === '*') { | ||
output.push(...items) | ||
// An string ending with * will return a family of features of a certain type | ||
// (e.g. all versions of a given protocol, all subsets of an AIP, etc.) | ||
} else if (query.match.endsWith('*')) { | ||
const match = query.match.slice(0, -1) | ||
output.push(...items.filter((m) => m.id.startsWith(match))) | ||
// Exact matching (single feature) | ||
} else { | ||
output.push(...items.filter((m) => m.id === query.match)) | ||
} | ||
} | ||
return output | ||
} | ||
} | ||
|
||
export { FeatureRegistry } |
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,58 @@ | ||
import { Expose } from 'class-transformer' | ||
import { IsString } from 'class-validator' | ||
|
||
import { AriesFrameworkError } from '../../../error' | ||
import { JsonTransformer } from '../../../utils/JsonTransformer' | ||
|
||
export interface FeatureOptions { | ||
id: string | ||
type: string | ||
} | ||
|
||
export class Feature { | ||
public id!: string | ||
|
||
public constructor(props: FeatureOptions) { | ||
if (props) { | ||
this.id = props.id | ||
this.type = props.type | ||
} | ||
} | ||
|
||
@IsString() | ||
@Expose({ name: 'feature-type' }) | ||
public readonly type!: string | ||
|
||
/** | ||
* Combine this feature with another one, provided both are from the same type | ||
* and have the same id | ||
* | ||
* @param feature object to combine with this one | ||
* @returns a new object resulting from the combination between this and feature | ||
*/ | ||
public combine(feature: this) { | ||
if (feature.id !== this.id) { | ||
throw new AriesFrameworkError('Can only combine with a feature with the same id') | ||
} | ||
|
||
const obj1 = JsonTransformer.toJSON(this) | ||
const obj2 = JsonTransformer.toJSON(feature) | ||
|
||
for (const key in obj2) { | ||
try { | ||
if (Array.isArray(obj2[key])) { | ||
obj1[key] = [...new Set([...obj1[key], ...obj2[key]])] | ||
} else { | ||
obj1[key] = obj2[key] | ||
} | ||
} catch (e) { | ||
obj1[key] = obj2[key] | ||
} | ||
} | ||
return JsonTransformer.fromJSON(obj1, Feature) | ||
} | ||
|
||
public toJSON(): Record<string, unknown> { | ||
return JsonTransformer.toJSON(this) | ||
} | ||
} |
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,23 @@ | ||
import { Expose } from 'class-transformer' | ||
import { IsString } from 'class-validator' | ||
|
||
export interface FeatureQueryOptions { | ||
featureType: string | ||
match: string | ||
} | ||
|
||
export class FeatureQuery { | ||
public constructor(options: FeatureQueryOptions) { | ||
if (options) { | ||
this.featureType = options.featureType | ||
this.match = options.match | ||
} | ||
} | ||
|
||
@Expose({ name: 'feature-type' }) | ||
@IsString() | ||
public featureType!: string | ||
|
||
@IsString() | ||
public match!: string | ||
} |
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,13 @@ | ||
import type { FeatureOptions } from './Feature' | ||
|
||
import { Feature } from './Feature' | ||
|
||
export type GoalCodeOptions = Omit<FeatureOptions, 'type'> | ||
|
||
export class GoalCode extends Feature { | ||
public constructor(props: GoalCodeOptions) { | ||
super({ ...props, type: GoalCode.type }) | ||
} | ||
|
||
public static readonly type = 'goal-code' | ||
} |
13 changes: 13 additions & 0 deletions
13
packages/core/src/agent/models/features/GovernanceFramework.ts
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,13 @@ | ||
import type { FeatureOptions } from './Feature' | ||
|
||
import { Feature } from './Feature' | ||
|
||
export type GovernanceFrameworkOptions = Omit<FeatureOptions, 'type'> | ||
|
||
export class GovernanceFramework extends Feature { | ||
public constructor(props: GovernanceFrameworkOptions) { | ||
super({ ...props, type: GovernanceFramework.type }) | ||
} | ||
|
||
public static readonly type = 'gov-fw' | ||
} |
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,25 @@ | ||
import type { FeatureOptions } from './Feature' | ||
|
||
import { IsOptional, IsString } from 'class-validator' | ||
|
||
import { Feature } from './Feature' | ||
|
||
export interface ProtocolOptions extends Omit<FeatureOptions, 'type'> { | ||
roles?: string[] | ||
} | ||
|
||
export class Protocol extends Feature { | ||
public constructor(props: ProtocolOptions) { | ||
super({ ...props, type: Protocol.type }) | ||
|
||
if (props) { | ||
this.roles = props.roles | ||
} | ||
} | ||
|
||
public static readonly type = 'protocol' | ||
|
||
@IsString({ each: true }) | ||
@IsOptional() | ||
public roles?: string[] | ||
} |
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,5 @@ | ||
export * from './Feature' | ||
export * from './FeatureQuery' | ||
export * from './GoalCode' | ||
export * from './GovernanceFramework' | ||
export * from './Protocol' |
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,2 @@ | ||
export * from './features' | ||
export * from './InboundMessageContext' |
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
Oops, something went wrong.