diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2018-04-02 04:15:27 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2018-04-02 04:15:27 +0900 |
| commit | cd2542e0fd8578f6e41114ffebbda1f16f7d04ce (patch) | |
| tree | c339b7808fc2a3d72ae30cb86ddb7b9c21852652 /src/remote/activitypub/resolver.ts | |
| parent | Refactor (diff) | |
| download | sharkey-cd2542e0fd8578f6e41114ffebbda1f16f7d04ce.tar.gz sharkey-cd2542e0fd8578f6e41114ffebbda1f16f7d04ce.tar.bz2 sharkey-cd2542e0fd8578f6e41114ffebbda1f16f7d04ce.zip | |
Refactor
Diffstat (limited to 'src/remote/activitypub/resolver.ts')
| -rw-r--r-- | src/remote/activitypub/resolver.ts | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/remote/activitypub/resolver.ts b/src/remote/activitypub/resolver.ts new file mode 100644 index 0000000000..ebfe25fe7e --- /dev/null +++ b/src/remote/activitypub/resolver.ts @@ -0,0 +1,97 @@ +import RemoteUserObject from '../../models/remote-user-object'; +import { IObject } from './type'; +const request = require('request-promise-native'); + +type IResult = { + resolver: Resolver; + object: IObject; +}; + +export default class Resolver { + private requesting: Set<string>; + + constructor(iterable?: Iterable<string>) { + this.requesting = new Set(iterable); + } + + private async resolveUnrequestedOne(value) { + if (typeof value !== 'string') { + return { resolver: this, object: value }; + } + + const resolver = new Resolver(this.requesting); + + resolver.requesting.add(value); + + const object = await request({ + url: value, + headers: { + Accept: 'application/activity+json, application/ld+json' + }, + json: true + }); + + if (object === null || ( + Array.isArray(object['@context']) ? + !object['@context'].includes('https://www.w3.org/ns/activitystreams') : + object['@context'] !== 'https://www.w3.org/ns/activitystreams' + )) { + throw new Error(); + } + + return { resolver, object }; + } + + private async resolveCollection(value) { + if (Array.isArray(value)) { + return value; + } + + const resolved = typeof value === 'string' ? + await this.resolveUnrequestedOne(value) : + value; + + switch (resolved.type) { + case 'Collection': + return resolved.items; + + case 'OrderedCollection': + return resolved.orderedItems; + + default: + return [resolved]; + } + } + + public async resolve(value): Promise<Array<Promise<IResult>>> { + const collection = await this.resolveCollection(value); + + return collection + .filter(element => !this.requesting.has(element)) + .map(this.resolveUnrequestedOne.bind(this)); + } + + public resolveOne(value) { + if (this.requesting.has(value)) { + throw new Error(); + } + + return this.resolveUnrequestedOne(value); + } + + public async resolveRemoteUserObjects(value) { + const collection = await this.resolveCollection(value); + + return collection.filter(element => !this.requesting.has(element)).map(element => { + if (typeof element === 'string') { + const object = RemoteUserObject.findOne({ uri: element }); + + if (object !== null) { + return object; + } + } + + return this.resolveUnrequestedOne(element); + }); + } +} |