diff --git a/back/webmin/schema.graphqls b/back/tests/schema-test.ts similarity index 60% rename from back/webmin/schema.graphqls rename to back/tests/schema-test.ts index 6b30b11f4f6b380a5174b5a209171bef3e65c975..9380234b8d20895a3e71af087f03af1e85599d3d 100644 --- a/back/webmin/schema.graphqls +++ b/back/tests/schema-test.ts @@ -1,40 +1,118 @@ -schema { - query: Query - subscription: Subscription +import "reflect-metadata"; +import {buildSchema} from 'type-graphql' +import {BigResolver} from '../webmin/graphql/resolvers/BigResolver' +import {BigSubscriber} from '../webmin/graphql/subscribers/BigSubscriber' +import {pubsub} from '../webmin/webmin' +import {printSchema} from 'graphql' +import {strictEqual} from 'assert' + +describe('GraphQL schema', () => { + + it('should equal', async () => { + const schemaObj = await buildSchema({ + resolvers: [BigResolver, BigSubscriber], + pubSub: pubsub + }) + + strictEqual(printSchema(schemaObj), `type BlockchainEventType { + bcEvent: String! + block: BlockType! } -type Documents { - blocks: [Block!]! - identities: [PendingIdentity!]! - certifications: [PendingCertification!]! - memberships: [PendingMembership!]! - transactions: [PendingTransaction!]! - peers: [Peer!]! - ws2pHeads: [WS2PHead!]! - ws2pConnections: [WS2PConnection!]! - ws2pDisconnections: [WS2PDisconnection!]! +type BlockTransactionType { + version: Int! + currency: String! + locktime: Int! + hash: String! + blockstamp: String! + blockstampTime: Int! + issuers: [String!]! + inputs: [String!]! + outputs: [String!]! + unlocks: [String!]! + signatures: [String!]! + comment: String! } -type PendingIdentity { - revoked: Boolean! - buid: String! - member: Boolean! - kick: Boolean! - leaving: Boolean - wasMember: Boolean! - pubkey: String! - uid: String! - sig: String! - revocation_sig: String +type BlockType { + version: Int! + number: Int! + currency: String! hash: String! - written: Boolean! - revoked_on: Int - expires_on: Int! - certs: [PendingCertification!]! - memberships: [PendingMembership!]! + inner_hash: String! + signature: String! + previousHash: String + issuer: String! + previousIssuer: String + time: Int! + powMin: Int! + unitbase: Int! + membersCount: Int! + issuersCount: Int! + issuersFrame: Int! + issuersFrameVar: Int! + identities: [String!]! + joiners: [String!]! + actives: [String!]! + leavers: [String!]! + revoked: [String!]! + excluded: [String!]! + certifications: [String!]! + transactions: [BlockTransactionType!]! + medianTime: Int! + nonce: String! + parameters: String + monetaryMass: Int! + dividend: Int + UDTime: Int + writtenOn: Int! + written_on: String +} + +type DocumentsType { + blocks: [BlockType!]! + identities: [PendingIdentityType!]! + certifications: [PendingCertificationType!]! + memberships: [PendingMembershipType!]! + transactions: [PendingTransactionType!]! + peers: [PeerType!]! + ws2pHeads: [WS2PHeadType!]! + ws2pConnections: [WS2PConnectionType!]! + ws2pDisconnections: [WS2PDisconnectionType!]! } -type PendingCertification { +type P2PDataCandidateType { + reserved: Boolean + nbSuccess: Int + isExcluded: Boolean + failures: Int + responseTimes: [Float!]! + p: PeerType + hostName: String + hasAvailableApi: Boolean + apiName: String + avgResponseTime: Float +} + +type P2PDataDetailType { + chunkIndex: Int + nodes: [P2PDataCandidateType!] + node: P2PDataCandidateType +} + +type P2PDataType { + name: String + data: P2PDataDetailType +} + +type PeerType { + hash: String! + pubkey: String! + block: String! + endpoints: [String!]! +} + +type PendingCertificationType { linked: Boolean! written: Boolean! written_block: Int @@ -50,7 +128,26 @@ type PendingCertification { expires_on: Int! } -type PendingMembership { +type PendingIdentityType { + revoked: Boolean! + buid: String! + member: Boolean! + kick: Boolean! + leaving: Boolean + wasMember: Boolean! + pubkey: String! + uid: String! + sig: String! + revocation_sig: String + hash: String! + written: Boolean! + revoked_on: Int + expires_on: Int! + certs: [PendingCertificationType!]! + memberships: [PendingMembershipType!]! +} + +type PendingMembershipType { membership: String! issuer: String! number: Int! @@ -69,7 +166,7 @@ type PendingMembership { block_number: Int } -type PendingTransaction { +type PendingTransactionType { hash: String! block_number: Int locktime: Int! @@ -93,157 +190,72 @@ type PendingTransaction { writtenOn: Int } -type Block { - version: Int! - number: Int! - currency: String! - hash: String! - inner_hash: String! - signature: String! - previousHash: String - issuer: String! - previousIssuer: String - time: Int! - powMin: Int! - unitbase: Int! - membersCount: Int! - issuersCount: Int! - issuersFrame: Int! - issuersFrameVar: Int! - identities: [String!]! - joiners: [String!]! - actives: [String!]! - leavers: [String!]! - revoked: [String!]! - excluded: [String!]! - certifications: [String!]! - transactions: [BlockTransaction!]! - medianTime: Int! - nonce: String! - parameters: String! - monetaryMass: Int! - dividend: Int - UDTime: Int - writtenOn: Int! - written_on: String! -} - -type BlockTransaction { - version: Int! - currency: String! - locktime: Int! - hash: String! - blockstamp: String! - blockstampTime: Int! - issuers: [String!]! - inputs: [String!]! - outputs: [String!]! - unlocks: [String!]! - signatures: [String!]! - comment: String! -} - -type Peer { - hash: String! - pubkey: String! - block: String! - endpoints: [String!]! -} - -type WS2PHead { - message: String! - sig: String! - messageV2: String - sigV2: String - step: Int +type Query { + hello: String + nodeState: String + current: BlockType + heads: [WS2PHeadType!]! + ws2pinfos: WS2PInfosType! + isSyncStarted: Boolean! + stopAndResetData: Boolean! + startNode: Boolean! + synchronize(url: String!): Boolean + uid(pub: String!): String } -type WS2PConnection { - host: String! - port: String! - pub: String! +type SoftVersionType { + software: String! + version: String! + pubkeys: [String!]! } -type WS2PDisconnection { - pub: String +type Subscription { + syncProgress: SyncProgressType + newDocuments: DocumentsType + bcEvents: BlockchainEventType } -type SyncProgress { +type SyncProgressType { download: Float saved: Float applied: Float sandbox: Float peersSync: Float sync: Boolean - p2pData: P2PData + p2pData: P2PDataType error: String } -type P2PData { - name: String - data: P2PDataDetail -} - -type P2PDataDetail { - chunkIndex: Int - nodes: [P2PDataCandidate!] - node: P2PDataCandidate -} - -type P2PDataCandidate { - reserved: Boolean - nbSuccess: Int - isExcluded: Boolean - failures: Int - responseTimes: [Int!] - p: Peer - hostName: String - hasAvailableApi: Boolean - apiName: String - avgResponseTime: Float -} - -type BlockchainEvent { - bcEvent: String! - block: Block! -} - -type WS2PConnectionInfo { +type WS2PConnectionInfoType { pubkey: String ws2pid: String uid: String handle: String } -type SoftVersion { - software: String! - version: String! - pubkeys: [String!]! +type WS2PConnectionType { + host: String! + port: String! + pub: String! } -type WS2PInfos { - softVersions: [SoftVersion!]! - level1: [WS2PConnectionInfo!]! - level2: [WS2PConnectionInfo!]! +type WS2PDisconnectionType { + pub: String } -type Subscription { - syncProgress: SyncProgress - newDocuments: Documents - bcEvents: BlockchainEvent +type WS2PHeadType { + message: String! + sig: String! + messageV2: String + sigV2: String + step: Int } -type Query { - hello: String - nodeState: String - current: Block - heads: [WS2PHead!]! - ws2pinfos: WS2PInfos! - - isSyncStarted: Boolean! - stopAndResetData: Boolean! - startNode: Boolean! - synchronize(url: String!): Boolean - uid(pub: String!): String +type WS2PInfosType { + softVersions: [SoftVersionType!]! + level1: [WS2PConnectionInfoType!]! + level2: [WS2PConnectionInfoType!]! } - +`) + }) +}) \ No newline at end of file diff --git a/back/tsconfig.back.json b/back/tsconfig.back.json index f020cff1cb94f0133610a7a186d4949f91afc3c7..ed2de865244a2e8774ab3f266c2a0d094f1fa9a6 100644 --- a/back/tsconfig.back.json +++ b/back/tsconfig.back.json @@ -10,11 +10,13 @@ "noImplicitAny": true, "noImplicitReturns": true, "skipLibCheck": true, + "emitDecoratorMetadata": true, "experimentalDecorators": true }, "include": [ "*.ts", - "webmin/*.ts", + "webmin/**/*.ts", + "tests/**/*.ts", "../common/*.ts" ], "compileOnSave": true diff --git a/back/webmin/graphql/di/application-context.ts b/back/webmin/graphql/di/application-context.ts new file mode 100644 index 0000000000000000000000000000000000000000..5f5dfc97d720062ba27fc900a0d8d4726e2037fb --- /dev/null +++ b/back/webmin/graphql/di/application-context.ts @@ -0,0 +1,34 @@ +import {Server} from 'duniter/server' + +class LocalApplicationContext { + + private _server: Server + private _startServices: () => Promise<void> + private _stopServices: () => Promise<void> + + set server(value: Server) { + this._server = value + } + + get server(): Server { + return this._server + } + + + get startServices(): () => Promise<void> { + return this._startServices + } + + set startServices(value: () => Promise<void>) { + this._startServices = value + } + get stopServices(): () => Promise<void> { + return this._stopServices + } + + set stopServices(value: () => Promise<void>) { + this._stopServices = value + } +} + +export const ApplicationContext = new LocalApplicationContext() \ No newline at end of file diff --git a/back/webmin/graphql/resolvers/BigResolver.ts b/back/webmin/graphql/resolvers/BigResolver.ts new file mode 100644 index 0000000000000000000000000000000000000000..fee29143eaeadef0228f5546af7f1e021fd62279 --- /dev/null +++ b/back/webmin/graphql/resolvers/BigResolver.ts @@ -0,0 +1,67 @@ +import {BlockType} from '../types/BlockType' +import {WS2PHeadType} from '../types/WS2PHeadType' +import {WS2PInfosType} from '../types/WS2PInfosType' +import {Resolver} from 'type-graphql/dist/decorators/Resolver' +import {Query} from 'type-graphql' +import {gqlNodeStart, gqlNodeState, gqlStopAndResetData} from '../../queries/gql-node-state' +import {ApplicationContext} from '../di/application-context' +import {gqlCurrent} from '../../queries/gql-current' +import {gqlHeads} from '../../queries/gql-heads' +import {gqlWs2pInfos} from '../../queries/gql-ws2p' +import {gqlIsSyncStarted, gqlSynchronize} from '../../queries/gql-synchronize' +import {gqlUid} from '../../queries/gql-uid' +import {Arg} from 'type-graphql/dist/decorators/Arg' + +@Resolver() +export class BigResolver { + + @Query({ nullable: true }) + hello(): string { + return 'Hello from Duniter Web Admin API' + } + + @Query(type => String, { nullable: true }) + async nodeState() { + return await gqlNodeState(ApplicationContext.server)() + } + + @Query(type => BlockType, { nullable: true }) + async current() { + return await gqlCurrent(ApplicationContext.server)() + } + + @Query(type => [WS2PHeadType]) + async heads(): Promise<WS2PHeadType[]> { + return gqlHeads(ApplicationContext.server)() + } + + @Query(type => WS2PInfosType) + ws2pinfos(): Promise<WS2PInfosType> { + return gqlWs2pInfos(ApplicationContext.server)() + } + + @Query(type => Boolean) + isSyncStarted() { + return gqlIsSyncStarted()() + } + + @Query(type => Boolean) + stopAndResetData(): Promise<boolean> { + return gqlStopAndResetData(ApplicationContext.server, ApplicationContext.startServices)() + } + + @Query(type => Boolean) + startNode(): Promise<boolean> { + return gqlNodeStart(ApplicationContext.startServices)() + } + + @Query(type => Boolean, { nullable: true }) + synchronize(@Arg("url") url: string) { + return gqlSynchronize(ApplicationContext.server)(null, { url }) + } + + @Query(type => String, { nullable: true }) + uid(@Arg("pub") pub: string): Promise<string|null> { + return gqlUid(ApplicationContext.server)(null, { pub }) + } +} diff --git a/back/webmin/graphql/subscribers/BigSubscriber.ts b/back/webmin/graphql/subscribers/BigSubscriber.ts new file mode 100644 index 0000000000000000000000000000000000000000..0fb525a9e5fa3d9e4816340c82e9ed15a9b9b835 --- /dev/null +++ b/back/webmin/graphql/subscribers/BigSubscriber.ts @@ -0,0 +1,23 @@ +import {Root, Subscription} from 'type-graphql' +import {GraphQLSubscriptions} from '../../constants' +import {SyncProgressType} from '../types/SyncProgressType' +import {DocumentsType} from '../types/DocumentsType' +import {BlockchainEventType} from '../types/BlockchainEventType' + +export class BigSubscriber { + + @Subscription(type => SyncProgressType, { nullable: true, topics: GraphQLSubscriptions.SYNC_PROGRESS }) + syncProgress(@Root() progress: SyncProgressType): SyncProgressType { + return progress + } + + @Subscription(type => DocumentsType, { nullable: true, topics: GraphQLSubscriptions.NEW_DOCUMENTS }) + newDocuments(@Root() documents: DocumentsType): DocumentsType { + return documents + } + + @Subscription(type => BlockchainEventType, { nullable: true, topics: GraphQLSubscriptions.BC_EVENTS }) + bcEvents(@Root() bcEvents: BlockchainEventType): BlockchainEventType { + return bcEvents + } +} diff --git a/back/webmin/graphql/types/BlockTransactionType.ts b/back/webmin/graphql/types/BlockTransactionType.ts new file mode 100644 index 0000000000000000000000000000000000000000..18d515ae1ebc785e453966d76b25bbaa5f125f06 --- /dev/null +++ b/back/webmin/graphql/types/BlockTransactionType.ts @@ -0,0 +1,19 @@ +import {Int, ObjectType} from 'type-graphql' +import {Field} from 'type-graphql/dist/decorators/Field' + +@ObjectType() +export class BlockTransactionType { + + @Field(type => Int) version: number + @Field() currency?: string + @Field(type => Int) locktime: number + @Field() hash?: string + @Field() blockstamp?: string + @Field(type => Int) blockstampTime: number + @Field(type => [String]) issuers: string[] + @Field(type => [String]) inputs: string[] + @Field(type => [String]) outputs: string[] + @Field(type => [String]) unlocks: string[] + @Field(type => [String]) signatures: string[] + @Field() comment?: string +} diff --git a/back/webmin/graphql/types/BlockType.ts b/back/webmin/graphql/types/BlockType.ts new file mode 100644 index 0000000000000000000000000000000000000000..a78b74b437c3eca53a53d944c33cb69a13161eef --- /dev/null +++ b/back/webmin/graphql/types/BlockType.ts @@ -0,0 +1,38 @@ +import {Field, Int, ObjectType} from 'type-graphql' +import {BlockTransactionType} from './BlockTransactionType' + +@ObjectType() +export class BlockType { + @Field(type => Int) version: number + @Field(type => Int) number: number + @Field() currency: string + @Field() hash: string + @Field() inner_hash: string + @Field() signature: string + @Field({ nullable: true }) previousHash?: string + @Field() issuer: string + @Field({ nullable: true }) previousIssuer?: string + @Field(type => Int) time: number + @Field(type => Int) powMin: number + @Field(type => Int) unitbase: number + @Field(type => Int) membersCount: number + @Field(type => Int) issuersCount: number + @Field(type => Int) issuersFrame: number + @Field(type => Int) issuersFrameVar: number + @Field(type => [String]) identities: string[] + @Field(type => [String]) joiners: string[] + @Field(type => [String]) actives: string[] + @Field(type => [String]) leavers: string[] + @Field(type => [String]) revoked: string[] + @Field(type => [String]) excluded: string[] + @Field(type => [String]) certifications: string[] + @Field(type => [BlockTransactionType]) transactions: BlockTransactionType[] + @Field(type => Int) medianTime: number + @Field() nonce?: string + @Field({ nullable: true }) parameters?: string + @Field(type => Int) monetaryMass: number + @Field(type => Int, { nullable: true }) dividend?: number + @Field(type => Int, { nullable: true }) UDTime?: number + @Field(type => Int) writtenOn: number + @Field({ nullable: true }) written_on?: string +} diff --git a/back/webmin/graphql/types/BlockchainEventType.ts b/back/webmin/graphql/types/BlockchainEventType.ts new file mode 100644 index 0000000000000000000000000000000000000000..8b1c007cde8eeab5151745da9cafb283551d2f1b --- /dev/null +++ b/back/webmin/graphql/types/BlockchainEventType.ts @@ -0,0 +1,9 @@ +import {Field, ObjectType} from 'type-graphql' +import {BlockType} from './BlockType' + +@ObjectType() +export class BlockchainEventType { + + @Field() bcEvent?: string + @Field() block: BlockType +} diff --git a/back/webmin/graphql/types/DocumentsType.ts b/back/webmin/graphql/types/DocumentsType.ts new file mode 100644 index 0000000000000000000000000000000000000000..1e7f1f8ec4eca3cfbe4d970386752a48cd601224 --- /dev/null +++ b/back/webmin/graphql/types/DocumentsType.ts @@ -0,0 +1,24 @@ +import {Field, ObjectType} from 'type-graphql' +import {WS2PDisconnectionType} from './WS2PDisconnectionType' +import {WS2PConnectionType} from './WS2PConnectionType' +import {WS2PHeadType} from './WS2PHeadType' +import {PeerType} from './PeerType' +import {BlockType} from './BlockType' +import {PendingIdentityType} from './PendingIdentityType' +import {PendingCertificationType} from './PendingCertificationType' +import {PendingMembershipType} from './PendingMembershipType' +import {PendingTransactionType} from './PendingTransactionType' + +@ObjectType() +export class DocumentsType { + + @Field(type => [BlockType]) blocks: BlockType[] + @Field(type => [PendingIdentityType]) identities: PendingIdentityType[] + @Field(type => [PendingCertificationType]) certifications: PendingCertificationType[] + @Field(type => [PendingMembershipType]) memberships: PendingMembershipType[] + @Field(type => [PendingTransactionType]) transactions: PendingTransactionType[] + @Field(type => [PeerType]) peers: PeerType[] + @Field(type => [WS2PHeadType]) ws2pHeads: WS2PHeadType[] + @Field(type => [WS2PConnectionType]) ws2pConnections: WS2PConnectionType[] + @Field(type => [WS2PDisconnectionType]) ws2pDisconnections: WS2PDisconnectionType[] +} \ No newline at end of file diff --git a/back/webmin/graphql/types/P2PDataCandidateType.ts b/back/webmin/graphql/types/P2PDataCandidateType.ts new file mode 100644 index 0000000000000000000000000000000000000000..73746798cd73e8026854569fc0fcf97365d15ab4 --- /dev/null +++ b/back/webmin/graphql/types/P2PDataCandidateType.ts @@ -0,0 +1,17 @@ +import {Field, Float, Int, ObjectType} from 'type-graphql' +import {PeerType} from './PeerType' + +@ObjectType() +export class P2PDataCandidateType { + + @Field({ nullable: true }) reserved?: boolean + @Field(type => Int, { nullable: true }) nbSuccess?: number + @Field({ nullable: true }) isExcluded?: boolean + @Field(type => Int, { nullable: true }) failures?: number + @Field(type => [Float]) responseTimes?: number[] + @Field({ nullable: true }) p?: PeerType + @Field({ nullable: true }) hostName?: string + @Field({ nullable: true }) hasAvailableApi?: boolean + @Field({ nullable: true }) apiName?: string + @Field({ nullable: true }) avgResponseTime?: number +} \ No newline at end of file diff --git a/back/webmin/graphql/types/P2PDataDetailType.ts b/back/webmin/graphql/types/P2PDataDetailType.ts new file mode 100644 index 0000000000000000000000000000000000000000..74df95b58e3bb4c1e644eab01b31c4644c67549f --- /dev/null +++ b/back/webmin/graphql/types/P2PDataDetailType.ts @@ -0,0 +1,10 @@ +import {Field, Int, ObjectType} from 'type-graphql' +import {P2PDataCandidateType} from './P2PDataCandidateType' + +@ObjectType() +export class P2PDataDetailType { + + @Field(type => Int, { nullable: true }) chunkIndex?: number + @Field(type => [P2PDataCandidateType], { nullable: true }) nodes?: P2PDataCandidateType[] + @Field({ nullable: true }) node?: P2PDataCandidateType +} \ No newline at end of file diff --git a/back/webmin/graphql/types/P2PDataType.ts b/back/webmin/graphql/types/P2PDataType.ts new file mode 100644 index 0000000000000000000000000000000000000000..dedee4abfd6fd1cf1f5d0d7ad31502a0abfdbf72 --- /dev/null +++ b/back/webmin/graphql/types/P2PDataType.ts @@ -0,0 +1,9 @@ +import {Field, ObjectType} from 'type-graphql' +import {P2PDataDetailType} from './P2PDataDetailType' + +@ObjectType() +export class P2PDataType { + + @Field({ nullable: true }) name?: string + @Field({ nullable: true }) data?: P2PDataDetailType +} \ No newline at end of file diff --git a/back/webmin/graphql/types/PeerType.ts b/back/webmin/graphql/types/PeerType.ts new file mode 100644 index 0000000000000000000000000000000000000000..db6c1ae84f142c17107e9d2d17cbb43c5a128e7c --- /dev/null +++ b/back/webmin/graphql/types/PeerType.ts @@ -0,0 +1,12 @@ +import {Field, ObjectType} from 'type-graphql' + +@ObjectType() +export class PeerType { + + @Field() hash?: string + @Field() pubkey?: string + @Field() block?: string + + @Field(type => [String]) + endpoints?: string[] +} diff --git a/back/webmin/graphql/types/PendingCertificationType.ts b/back/webmin/graphql/types/PendingCertificationType.ts new file mode 100644 index 0000000000000000000000000000000000000000..a77f1616db41f84e6190055b7354de69fdeb50f7 --- /dev/null +++ b/back/webmin/graphql/types/PendingCertificationType.ts @@ -0,0 +1,19 @@ +import {Field, Int, ObjectType} from 'type-graphql' + +@ObjectType() +export class PendingCertificationType { + + @Field() linked?: boolean + @Field() written?: boolean + @Field(type => Int, { nullable: true }) written_block?: number + @Field({ nullable: true }) written_hash?: string + @Field() sig?: string + @Field(type => Int) block_number: number + @Field() block_hash?: string + @Field({ nullable: true }) target?: string + @Field() to?: string + @Field() from?: string + @Field(type => Int) block: number + @Field({ nullable: true }) expired?: boolean + @Field(type => Int) expires_on: number +} diff --git a/back/webmin/graphql/types/PendingIdentityType.ts b/back/webmin/graphql/types/PendingIdentityType.ts new file mode 100644 index 0000000000000000000000000000000000000000..504172d761d6b50a0b516925b53f43100cf3059c --- /dev/null +++ b/back/webmin/graphql/types/PendingIdentityType.ts @@ -0,0 +1,23 @@ +import {Field, Int, ObjectType} from 'type-graphql' +import {PendingCertificationType} from './PendingCertificationType' +import {PendingMembershipType} from './PendingMembershipType' + +@ObjectType() +export class PendingIdentityType { + @Field() revoked?: boolean + @Field() buid?: string + @Field() member?: boolean + @Field() kick?: boolean + @Field({ nullable: true }) leaving?: boolean + @Field() wasMember?: boolean + @Field() pubkey?: string + @Field() uid?: string + @Field() sig?: string + @Field({ nullable: true }) revocation_sig?: string + @Field() hash?: string + @Field() written?: boolean + @Field(type => Int, { nullable: true }) revoked_on?: number + @Field(type => Int) expires_on: number + @Field(type => [PendingCertificationType]) certs: PendingCertificationType[] + @Field(type => [PendingMembershipType]) memberships: PendingMembershipType[] +} diff --git a/back/webmin/graphql/types/PendingMembershipType.ts b/back/webmin/graphql/types/PendingMembershipType.ts new file mode 100644 index 0000000000000000000000000000000000000000..7d8101678011093ab48229507030ee334cc19b1a --- /dev/null +++ b/back/webmin/graphql/types/PendingMembershipType.ts @@ -0,0 +1,21 @@ +import {Field, Int, ObjectType} from 'type-graphql' + +@ObjectType() +export class PendingMembershipType { + @Field() membership?: string + @Field() issuer?: string + @Field(type => Int) number: number + @Field(type => Int) blockNumber: number + @Field() blockHash?: string + @Field() userid?: string + @Field() certts?: string + @Field({ nullable: true }) block?: string + @Field() fpr?: string + @Field() idtyHash?: string + @Field() written?: boolean + @Field(type => Int, { nullable: true }) written_number?: number + @Field(type => Int) expires_on: number + @Field() signature: string + @Field({ nullable: true }) expired?: boolean + @Field(type => Int, { nullable: true }) block_number?: number +} diff --git a/back/webmin/graphql/types/PendingTransactionType.ts b/back/webmin/graphql/types/PendingTransactionType.ts new file mode 100644 index 0000000000000000000000000000000000000000..7c7efa0bb9ccfed7284e2a3843f58480c84f29a5 --- /dev/null +++ b/back/webmin/graphql/types/PendingTransactionType.ts @@ -0,0 +1,26 @@ +import {Field, Int, ObjectType} from 'type-graphql' + +@ObjectType() +export class PendingTransactionType { + @Field() hash?: string + @Field(type => Int, { nullable: true }) block_number?: number + @Field(type => Int) locktime: number + @Field(type => Int) version: number + @Field() currency?: string + @Field() comment?: string + @Field() blockstamp?: string + @Field(type => Int, { nullable: true }) blockstampTime?: number + @Field(type => Int, { nullable: true }) time?: number + @Field(type => [String]) inputs: string[] + @Field(type => [String]) unlocks: string[] + @Field(type => [String]) outputs: string[] + @Field(type => [String]) issuers: string[] + @Field(type => [String]) signatures: string[] + @Field({ nullable: true }) written?: boolean + @Field({ nullable: true }) removed?: boolean + @Field(type => Int, { nullable: true }) received?: number + @Field(type => Int) output_base: number + @Field(type => Int) output_amount: number + @Field({ nullable: true }) written_on?: string + @Field(type => Int, { nullable: true }) writtenOn?: number +} diff --git a/back/webmin/graphql/types/SoftVersionType.ts b/back/webmin/graphql/types/SoftVersionType.ts new file mode 100644 index 0000000000000000000000000000000000000000..007de98bca308808bf8a0a2369791994d9f0ba83 --- /dev/null +++ b/back/webmin/graphql/types/SoftVersionType.ts @@ -0,0 +1,9 @@ +import {Field, ObjectType} from 'type-graphql' + +@ObjectType() +export class SoftVersionType { + + @Field() software?: string + @Field() version?: string + @Field(type => [String]) pubkeys: string[] +} \ No newline at end of file diff --git a/back/webmin/graphql/types/SyncProgressType.ts b/back/webmin/graphql/types/SyncProgressType.ts new file mode 100644 index 0000000000000000000000000000000000000000..32ac3c54a9c94d6b4a9ab2c116db24a3f86b6cd4 --- /dev/null +++ b/back/webmin/graphql/types/SyncProgressType.ts @@ -0,0 +1,15 @@ +import {Field, Float, ObjectType} from 'type-graphql' +import {P2PDataType} from './P2PDataType' + +@ObjectType() +export class SyncProgressType { + + @Field(type => Float, { nullable: true }) download?: number + @Field(type => Float, { nullable: true }) saved?: number + @Field(type => Float, { nullable: true }) applied?: number + @Field(type => Float, { nullable: true }) sandbox?: number + @Field(type => Float, { nullable: true }) peersSync?: number + @Field({ nullable: true }) sync?: boolean + @Field({ nullable: true }) p2pData?: P2PDataType + @Field({ nullable: true }) error?: string +} diff --git a/back/webmin/graphql/types/WS2PConnectionInfoType.ts b/back/webmin/graphql/types/WS2PConnectionInfoType.ts new file mode 100644 index 0000000000000000000000000000000000000000..1ecd4ea04c77891ead3326d663cebe96cc5db644 --- /dev/null +++ b/back/webmin/graphql/types/WS2PConnectionInfoType.ts @@ -0,0 +1,10 @@ +import {Field, ObjectType} from 'type-graphql' + +@ObjectType() +export class WS2PConnectionInfoType { + + @Field({ nullable: true }) pubkey?: string + @Field({ nullable: true }) ws2pid?: string + @Field({ nullable: true }) uid?: string + @Field({ nullable: true }) handle?: string +} \ No newline at end of file diff --git a/back/webmin/graphql/types/WS2PConnectionType.ts b/back/webmin/graphql/types/WS2PConnectionType.ts new file mode 100644 index 0000000000000000000000000000000000000000..4bc3a8d346ccde3c4ffcb922938421c8b8906230 --- /dev/null +++ b/back/webmin/graphql/types/WS2PConnectionType.ts @@ -0,0 +1,9 @@ +import {Field, ObjectType} from 'type-graphql' + +@ObjectType() +export class WS2PConnectionType { + + @Field() host?: string + @Field() port?: string + @Field() pub?: string +} \ No newline at end of file diff --git a/back/webmin/graphql/types/WS2PDisconnectionType.ts b/back/webmin/graphql/types/WS2PDisconnectionType.ts new file mode 100644 index 0000000000000000000000000000000000000000..9ff356620da58aaff8047f8b30d8492c4dfb7282 --- /dev/null +++ b/back/webmin/graphql/types/WS2PDisconnectionType.ts @@ -0,0 +1,6 @@ +import {Field, ObjectType} from 'type-graphql' + +@ObjectType() +export class WS2PDisconnectionType { + @Field({ nullable: true }) pub?: string +} diff --git a/back/webmin/graphql/types/WS2PHeadType.ts b/back/webmin/graphql/types/WS2PHeadType.ts new file mode 100644 index 0000000000000000000000000000000000000000..7aa064ee3745e147ae132b8e93392697efb6b50f --- /dev/null +++ b/back/webmin/graphql/types/WS2PHeadType.ts @@ -0,0 +1,12 @@ +import {ObjectType} from 'type-graphql/dist/decorators/ObjectType' +import {Field, Int} from 'type-graphql' + +@ObjectType() +export class WS2PHeadType { + + @Field() message?: string + @Field() sig?: string + @Field({ nullable: true }) messageV2?: string + @Field({ nullable: true }) sigV2?: string + @Field(type => Int, { nullable: true }) step?: number +} diff --git a/back/webmin/graphql/types/WS2PInfosType.ts b/back/webmin/graphql/types/WS2PInfosType.ts new file mode 100644 index 0000000000000000000000000000000000000000..99b5bacc6c21cb6abe2044b3c4476dbffda6a05f --- /dev/null +++ b/back/webmin/graphql/types/WS2PInfosType.ts @@ -0,0 +1,12 @@ +import {ObjectType} from 'type-graphql' +import {Field} from 'type-graphql/dist/decorators/Field' +import {WS2PConnectionInfoType} from './WS2PConnectionInfoType' +import {SoftVersionType} from './SoftVersionType' + +@ObjectType() +export class WS2PInfosType { + + @Field(type => [SoftVersionType]) softVersions: SoftVersionType[] + @Field(type => [WS2PConnectionInfoType]) level1: WS2PConnectionInfoType[] + @Field(type => [WS2PConnectionInfoType]) level2: WS2PConnectionInfoType[] +} diff --git a/back/webmin/graphql/types/transform/p2p-candidate.transform.ts b/back/webmin/graphql/types/transform/p2p-candidate.transform.ts new file mode 100644 index 0000000000000000000000000000000000000000..eac0dbf63c880c572ae0eb0dbee6ce2a34f998e2 --- /dev/null +++ b/back/webmin/graphql/types/transform/p2p-candidate.transform.ts @@ -0,0 +1,18 @@ +import {P2pCandidate} from 'duniter/app/modules/crawler/lib/sync/p2p/p2p-candidate' +import {P2PDataCandidateType} from '../P2PDataCandidateType' + + +export function transformP2pCandidate(node: P2pCandidate): P2PDataCandidateType { + return { + reserved: (node as any).reserved, + nbSuccess: (node as any).nbSuccess, + isExcluded: (node as any).isExcluded, + failures: (node as any).failures, + responseTimes: (node as any).responseTimes, + p: node.p, + hostName: node.hostName, + hasAvailableApi: node.hasAvailableApi(), + apiName: node.apiName || undefined, + avgResponseTime: node.avgResponseTime(), + }; +} diff --git a/back/webmin/graphql/types/transform/sync-progress.transform.ts b/back/webmin/graphql/types/transform/sync-progress.transform.ts new file mode 100644 index 0000000000000000000000000000000000000000..b13046932e5bfcde501840f5f0a4d2a63232e434 --- /dev/null +++ b/back/webmin/graphql/types/transform/sync-progress.transform.ts @@ -0,0 +1,37 @@ +import {SyncProgress} from '../../../../../common/dto' +import {P2PDataDetailType} from '../P2PDataDetailType' +import {SyncProgressType} from '../SyncProgressType' +import {transformP2pCandidate} from './p2p-candidate.transform' + + +/** + * Transforms the `progress` object from Duniter to our GraphQL type + * @param progress + */ +export function transformSyncProgress(progress: SyncProgress): SyncProgressType { + const p: SyncProgressType = { + download: progress.download, + saved: progress.saved, + applied: progress.applied, + sandbox: progress.sandbox, + peersSync: progress.peersSync, + sync: progress.sync, + error: progress.error, + } + if (progress.p2pData && progress.p2pData.data) { + const data: P2PDataDetailType = { + chunkIndex: progress.p2pData.data.chunkIndex + } + if (progress.p2pData.data.node) { + data.node = transformP2pCandidate(progress.p2pData.data.node) + } + if (progress.p2pData.data.nodes) { + data.nodes = progress.p2pData.data.nodes.map(transformP2pCandidate) + } + p.p2pData = { + name: progress.p2pData.name, + data + } + } + return p +} \ No newline at end of file diff --git a/back/webmin/network.ts b/back/webmin/network.ts index dcdeb09791cf36ee96e1be629fd8a0a68cb59a1d..823061fbb583ca04e3ae4453f80c2b5e97a0592b 100644 --- a/back/webmin/network.ts +++ b/back/webmin/network.ts @@ -5,22 +5,22 @@ import {Server} from 'duniter/server'; import {graphiqlExpress, graphqlExpress,} from 'graphql-server-express'; import {plugModule} from './webmin'; import {execute, subscribe} from 'graphql'; -import bodyParser = require('body-parser') -import cors = require('cors') import * as path from 'path' import {SubscriptionServer} from 'subscriptions-transport-ws' +import bodyParser = require('body-parser') +import cors = require('cors') -export function webminHttpListen( +export async function webminHttpListen( server: Server, port: number, host = 'localhost', startServices: () => Promise<void>, stopServices: () => Promise<void>, -): http.Server { +): Promise<http.Server> { - const schema = plugModule(server, startServices, stopServices) + const schema = await plugModule(server, startServices, stopServices) - const app = express() + const app = (express as any)() app.use('*', cors({ origin: new RegExp(`${host}`) })) @@ -34,9 +34,6 @@ export function webminHttpListen( })) const front = path.join(__dirname, '../..', 'front/dist/front') - app.use(/^\/(run|sync)/, (req, res) => { - res.redirect('/'); - }) app.use(express.static(front)) // Wrap the Express server diff --git a/back/webmin/queries/gql-node-state.ts b/back/webmin/queries/gql-node-state.ts index caa024f0a38ac0a3b4312636fdd75796c7a58fcf..2fda2d31397cbe42a9933249d36b7186c68fd91f 100644 --- a/back/webmin/queries/gql-node-state.ts +++ b/back/webmin/queries/gql-node-state.ts @@ -1,5 +1,4 @@ import {Server} from 'duniter/server' -import {Querable} from 'duniter/app/lib/common-libs/querable' import {getSyncPromise} from './gql-synchronize' let started = false diff --git a/back/webmin/queries/gql-ws2p.ts b/back/webmin/queries/gql-ws2p.ts index 7463d121f76c25bddc9a72c1b0fc5f21d5de5f14..df6044a27e945824a4b9dd15ad206571c794d0f7 100644 --- a/back/webmin/queries/gql-ws2p.ts +++ b/back/webmin/queries/gql-ws2p.ts @@ -1,9 +1,11 @@ import {Server} from 'duniter/server' import {WS2PConnection} from 'duniter/app/modules/ws2p/lib/WS2PConnection' import {softVersions} from '../shared/gql-network' +import {WS2PInfosType} from '../graphql/types/WS2PInfosType' +import {WS2PConnectionInfoType} from '../graphql/types/WS2PConnectionInfoType' export function gqlWs2pInfos(server: Server) { - return async () => { + return async (): Promise<WS2PInfosType> => { if (server.ws2pCluster) { let level1 = await server.ws2pCluster.getLevel1Connections() let level2 = await server.ws2pCluster.getLevel2Connections() @@ -23,8 +25,8 @@ export function gqlWs2pInfos(server: Server) { }) return { softVersions: theSoftVersions, - level1: await level1.map(c => ws2pConnectionToJSON(server, c)), - level2: await level2.map(c => ws2pConnectionToJSON(server, c)) + level1: await Promise.all(level1.map(c => ws2pConnectionToJSON(server, c))), + level2: await Promise.all(level2.map(c => ws2pConnectionToJSON(server, c))) } } else { return { @@ -36,7 +38,7 @@ export function gqlWs2pInfos(server: Server) { } } -async function ws2pConnectionToJSON(server: Server, connection: WS2PConnection|any) { +async function ws2pConnectionToJSON(server: Server, connection: WS2PConnection|any): Promise<WS2PConnectionInfoType> { const pubkey = connection.pubkey const ws2pid = connection.uuid const member = await server.dal.getWrittenIdtyByPubkey(pubkey) diff --git a/back/webmin/subscriptions/gql-events-blockchain.ts b/back/webmin/subscriptions/gql-events-blockchain.ts index 9c8635f5a991347388b8ce227fb5ad61bcbaf98d..a6121e06d8e1b5ae11e483ae8cc7d4d66766a29a 100644 --- a/back/webmin/subscriptions/gql-events-blockchain.ts +++ b/back/webmin/subscriptions/gql-events-blockchain.ts @@ -6,11 +6,7 @@ export function gqlSubscribeBlockchainEvents(server: Server) { server.on('data', async (data: any) => { if (data.bcEvent) { - return pubsub.publish(GraphQLSubscriptions.BC_EVENTS, {bcEvents: data}) + return pubsub.publish(GraphQLSubscriptions.BC_EVENTS, data) } }) - - return { - subscribe: () => pubsub.asyncIterator(GraphQLSubscriptions.BC_EVENTS) - } -} \ No newline at end of file +} diff --git a/back/webmin/subscriptions/gql-events-documents.ts b/back/webmin/subscriptions/gql-events-documents.ts index bd6788111a315cd932cb69f2a1018a9bdd9acf6e..b1fed509c8d71cf90c2bd71293772c51f4d92efb 100644 --- a/back/webmin/subscriptions/gql-events-documents.ts +++ b/back/webmin/subscriptions/gql-events-documents.ts @@ -64,10 +64,6 @@ export function gqlSubscribeDocuments(server: Server) { newDocuments.identities.push(data) } - await pubsub.publish(GraphQLSubscriptions.NEW_DOCUMENTS, { newDocuments }) + await pubsub.publish(GraphQLSubscriptions.NEW_DOCUMENTS, newDocuments) }) - - return { - subscribe: () => pubsub.asyncIterator(GraphQLSubscriptions.NEW_DOCUMENTS) - } } diff --git a/back/webmin/subscriptions/gql-events-sync-progress.ts b/back/webmin/subscriptions/gql-events-sync-progress.ts index b79c325ddc3ac2fe9a98d016361f8d70d3777961..a26c73a996e8ed03b7e761da271e3b8e0e410ce8 100644 --- a/back/webmin/subscriptions/gql-events-sync-progress.ts +++ b/back/webmin/subscriptions/gql-events-sync-progress.ts @@ -1,15 +1,8 @@ import {GraphQLSubscriptions} from '../constants' -import {SyncProgress} from '../../../common/dto' import {pubsub} from '../webmin' +import {SyncProgress} from '../../../common/dto' +import {transformSyncProgress} from '../graphql/types/transform/sync-progress.transform' export function gqlPushSyncProgress(progress: SyncProgress) { - return pubsub.publish(GraphQLSubscriptions.SYNC_PROGRESS, { - syncProgress: progress - }) -} - -export function gqlSubscribeSyncProgress() { - return { - subscribe: () => pubsub.asyncIterator(GraphQLSubscriptions.SYNC_PROGRESS) - } + return pubsub.publish(GraphQLSubscriptions.SYNC_PROGRESS, transformSyncProgress(progress)) } diff --git a/back/webmin/webmin.ts b/back/webmin/webmin.ts index 4e9a5a79e60a22ddd47a024016ec8f11e1ec3804..e02d220630c6ebd11965c14d8f1a8d74695702d5 100644 --- a/back/webmin/webmin.ts +++ b/back/webmin/webmin.ts @@ -1,48 +1,28 @@ -import * as path from 'path'; -import * as fs from 'fs'; -import {makeExecutableSchema} from 'graphql-tools'; +import "reflect-metadata"; import {Server} from 'duniter/server'; import {PubSub} from 'graphql-subscriptions'; -import {gqlUid} from './queries/gql-uid' -import {gqlIsSyncStarted, gqlSynchronize} from './queries/gql-synchronize' -import {gqlNodeStart, gqlNodeState, gqlStopAndResetData} from './queries/gql-node-state' -import {gqlWs2pInfos} from './queries/gql-ws2p' -import {gqlSubscribeSyncProgress} from './subscriptions/gql-events-sync-progress' +import {buildSchema} from 'type-graphql' +import {BigResolver} from './graphql/resolvers/BigResolver' +import {ApplicationContext} from './graphql/di/application-context' +import {BigSubscriber} from './graphql/subscribers/BigSubscriber' import {gqlSubscribeBlockchainEvents} from './subscriptions/gql-events-blockchain' import {gqlSubscribeDocuments} from './subscriptions/gql-events-documents' -import {gqlHeads} from './queries/gql-heads' -import {gqlCurrent} from './queries/gql-current' export const pubsub = new PubSub(); export function plugModule(server: Server, startServices: () => Promise<void>, stopServices: () => Promise<void>) { - return makeExecutableSchema({ + // Dependency Injection + ApplicationContext.server = server + ApplicationContext.startServices = startServices + ApplicationContext.stopServices = stopServices - // Read the GraphQL schema definition - typeDefs: fs.readFileSync(path.join(__dirname, 'schema.graphqls'), 'utf8'), + gqlSubscribeBlockchainEvents(server) + gqlSubscribeDocuments(server) - resolvers: { - - Query: { - hello: () => 'Welcome to Duniter WEBMIN API.', - isSyncStarted: gqlIsSyncStarted(), - current: gqlCurrent(server), - heads: gqlHeads(server), - ws2pinfos: gqlWs2pInfos(server), - nodeState: gqlNodeState(server), - stopAndResetData: gqlStopAndResetData(server, stopServices), - startNode: gqlNodeStart(startServices), - synchronize: gqlSynchronize(server), - uid: gqlUid(server) - }, - - Subscription: { - syncProgress: gqlSubscribeSyncProgress(), - newDocuments: gqlSubscribeDocuments(server), - bcEvents: gqlSubscribeBlockchainEvents(server) - }, - } + return buildSchema({ + resolvers: [BigResolver, BigSubscriber], + pubSub: pubsub }) } diff --git a/common/dto.ts b/common/dto.ts index c2248a5029670ae8943aa4f27013894d96b753a2..87d2d7e8ab14ad472a50b3036e2e52c219e8e9d3 100644 --- a/common/dto.ts +++ b/common/dto.ts @@ -1,3 +1,5 @@ +import {P2pCandidate} from 'duniter/app/modules/crawler/lib/sync/p2p/p2p-candidate' + export interface SyncProgress { download?: number saved?: number @@ -6,7 +8,20 @@ export interface SyncProgress { peersSync?: number sync?: boolean error?: string - p2pData?: any + p2pData?: P2PData +} + +export class P2PData { + + name?: string + data?: P2PDataDetail +} + +export class P2PDataDetail { + + chunkIndex?: number + nodes?: P2pCandidate[] + node?: P2pCandidate } export interface SyncEnding { diff --git a/package.json b/package.json index d0b6703def604216bb9c9033653cabe9dcf60986..e700a73a51c61d5e34c3e1536d57aee289726184 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,8 @@ "version": "0.1.0", "private": true, "scripts": { + "test": "tsc --build back/tsconfig.back.json && mocha back/tests/", + "test:run": "mocha back/tests/", "serve": "vue-cli-service serve", "build": "vue-cli-service build", "dev": "concurrently --kill-others \"tsc --build back/tsconfig.back.json -w\" \"nodemon back/index.js ui\" \"vue-cli-service serve\"", @@ -20,8 +22,10 @@ "graphql-server-express": "^1.4.0", "graphql-subscriptions": "^1.0.0", "graphql-tools": "^4.0.3", + "reflect-metadata": "^0.1.13", "register-service-worker": "^1.6.2", "subscriptions-transport-ws": "^0.9.15", + "type-graphql": "^0.17.3", "vue": "^2.6.10", "vue-apollo": "^3.0.0-beta.11", "vue-class-component": "^7.0.2", @@ -39,6 +43,7 @@ "@types/graphql": "^14.0.3", "@types/js-yaml": "^3.12.0", "@types/minimist": "^1.2.0", + "@types/mocha": "^5.2.6", "@types/node": "^12.0.0", "@types/request-promise": "^4.1.42", "@vue/cli-plugin-pwa": "^3.7.0", @@ -52,6 +57,7 @@ "express-http-proxy": "^1.5.1", "graphql-tag": "^2.9.0", "js-yaml": "^3.12.1", + "mocha": "^6.1.4", "moment": "^2.23.0", "nodemon": "^1.18.9", "querablep": "^0.1.0", @@ -59,6 +65,7 @@ "request-promise": "^4.2.2", "sass": "^1.18.0", "sass-loader": "^7.1.0", + "ts-node": "^8.1.0", "typescript": "^3.4.3", "vue-cli-plugin-apollo": "^0.20.0", "vue-template-compiler": "^2.5.21" diff --git a/src/views/Sync.vue b/src/views/Sync.vue index 2c1985485db8eeb7739d3128358489d2749b046c..cf73e543b99207b7ce7a6c82a1d42054fa733c28 100644 --- a/src/views/Sync.vue +++ b/src/views/Sync.vue @@ -72,9 +72,10 @@ <script lang="ts"> import {Component, Vue} from 'vue-property-decorator'; - import {SyncProgress} from '../../common/dto'; import {RouteNames} from '@/lib/constants'; import SyncProgressBar from '@/components/sync-progress-bar.vue'; + import {P2PDataCandidateType} from "../../back/webmin/graphql/types/P2PDataCandidateType"; + import {SyncProgressType} from "../../back/webmin/graphql/types/SyncProgressType"; @Component({ components: { @@ -96,7 +97,7 @@ } downloadings: SyncChunk[] = [] - p2pCandidates: { [hash: string]: P2pCandidate } = {} + p2pCandidates: { [hash: string]: P2PDataCandidateType } = {} syncFailedNoNodeFound = false syncFailCannotConnectToRemote = false @@ -115,7 +116,7 @@ async mounted() { // Listen to sync events this.$webmin.syncProgress() - .subscribe(async (data: { data: { syncProgress: SyncProgress } }) => { + .subscribe(async (data: { data: { syncProgress: SyncProgressType } }) => { this.applied = data.data.syncProgress.applied || this.applied this.download = data.data.syncProgress.download || this.download this.saved = data.data.syncProgress.saved || this.saved @@ -193,23 +194,9 @@ export interface SyncChunk { chunkIndex: number order: number - downloadingNode?: P2pCandidate + downloadingNode?: P2PDataCandidateType gotten: boolean isDownload: boolean } - export interface SyncCandidate { - c: P2pCandidate - } - - - export class P2pCandidate { - - pubkey: string - hostName: string - hasAvailableApi: boolean - apiName: string - avgResponseTime: number - responseTimes: number[] - } </script> diff --git a/tsconfig.json b/tsconfig.json index 88b61d1ed9bb221cb2cf6aae452400086927a416..a82b7cf410dbe4e98576a4c498ce00c4bd697d62 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "jsx": "preserve", "importHelpers": true, "moduleResolution": "node", + "emitDecoratorMetadata": true, "experimentalDecorators": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/yarn.lock b/yarn.lock index 40d58d08fa8cc43152d9ef2e8557debe0e6c898d..ba951c9025bdd5383a345d68b0b56237d7c3a97c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -301,6 +301,11 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= +"@types/mocha@^5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.6.tgz#b8622d50557dd155e9f2f634b7d68fd38de5e94b" + integrity sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw== + "@types/node@*", "@types/node@^12.0.0": version "12.0.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.0.tgz#d11813b9c0ff8aaca29f04cbc12817f4c7d656e5" @@ -311,6 +316,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.6.tgz#9cbfcb62c50947217f4d88d4d274cc40c22625a9" integrity sha512-Fvm24+u85lGmV4hT5G++aht2C5I4Z4dYlWZIh62FAfFO/TfzXtPpoLI6I7AuBWkIFqZCnhFOoTT7RjjaIL5Fjg== +"@types/node@^11.13.7": + version "11.13.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.10.tgz#4df59e5966b56f512bac98898bcbee5067411f0f" + integrity sha512-leUNzbFTMX94TWaIKz8N15Chu55F9QSH+INKayQr5xpkasBQBRF3qQXfo3/dOnMU/dEIit+Y/SU8HyOjq++GwA== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -344,6 +354,11 @@ "@types/node" "*" "@types/tough-cookie" "*" +"@types/semver@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.0.0.tgz#86ba89f02a414e39c68d02b351872e4ed31bd773" + integrity sha512-OO0srjOGH99a4LUN2its3+r6CBYcplhJ466yLqs+zvAWgphCpS8hYZEZ797tRDP/QKcqTdb/YCN6ifASoAWkrQ== + "@types/serve-static@*": version "1.13.2" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" @@ -790,6 +805,11 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" +ansi-colors@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + ansi-colors@^3.0.0: version "3.2.4" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" @@ -1704,6 +1724,11 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -2157,6 +2182,14 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +class-validator@>=0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.9.1.tgz#d60e58c5d14abca0a41bce38cf792ad4c46d1531" + integrity sha512-3wApflrd3ywVZyx4jaasGoFt8pmo4aGLPPAEKCKCsTRWVGPilahD88q3jQjRQwja50rl9a7rsP5LAxJYwGK8/Q== + dependencies: + google-libphonenumber "^3.1.6" + validator "10.4.0" + clean-css@4.2.x: version "4.2.1" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" @@ -2953,7 +2986,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@^3.0.1, debug@^3.1.0, debug@^3.2.5, debug@^3.2.6: +debug@3.2.6, debug@^3.0.1, debug@^3.1.0, debug@^3.2.5, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -3131,7 +3164,7 @@ dicer@0.3.0: dependencies: streamsearch "0.1.2" -diff@^3.1.0, diff@^3.2.0: +diff@3.5.0, diff@^3.1.0, diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== @@ -3495,7 +3528,7 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -3955,6 +3988,13 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -3962,12 +4002,12 @@ find-up@^2.1.0: dependencies: locate-path "^2.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== +flat@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" + integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== dependencies: - locate-path "^3.0.0" + is-buffer "~2.0.3" flush-write-stream@^1.0.0: version "1.1.1" @@ -4268,6 +4308,18 @@ glob-to-regexp@^0.3.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= +glob@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" @@ -4324,6 +4376,11 @@ globby@^9.2.0: pify "^4.0.1" slash "^2.0.0" +google-libphonenumber@^3.1.6: + version "3.2.2" + resolved "https://registry.yarnpkg.com/google-libphonenumber/-/google-libphonenumber-3.2.2.tgz#3d9d7ba727e99a50812f21b0ed313723b76c5c54" + integrity sha512-ubjGeosYPeusjYbUHy76lCniGTTI0k1rIFc+uKBX+jHQLDmWOSUtlFUxaeoLJ+Y+PAMM6dWp+C1HjHx5BI8kEw== + got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -4404,6 +4461,13 @@ graphql-extensions@^0.0.x, graphql-extensions@~0.0.9: core-js "^2.5.3" source-map-support "^0.5.1" +graphql-query-complexity@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/graphql-query-complexity/-/graphql-query-complexity-0.2.3.tgz#ca26790fd5d22cb3d4ca8f43d19605929d8cf27f" + integrity sha512-XLvEsqGTJmJmgof8u5NjIkBHL75b4Inw1F8JQ3jGRBhr3hVFx6aWOTL7C2aknp1uIh8dRmqwzrb9gas2NLHnfA== + dependencies: + lodash.get "^4.4.2" + graphql-server-express@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphql-server-express/-/graphql-server-express-1.4.0.tgz#f62b49dc70c860b653e76e21defa7f27324b764d" @@ -4411,7 +4475,7 @@ graphql-server-express@^1.4.0: dependencies: apollo-server-express "^1.4.0" -graphql-subscriptions@^1.0.0: +graphql-subscriptions@^1.0.0, graphql-subscriptions@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.1.0.tgz#5f2fa4233eda44cf7570526adfcf3c16937aef11" integrity sha512-6WzlBFC0lWmXJbIVE8OgFgXIP4RJi3OQgTPa0DVMsDXdpRDjTsM1K9wfl5HSYX7R87QAGlvcv2Y4BIZa/ItonA== @@ -4451,6 +4515,11 @@ graphql@^14.0.2, graphql@^14.1.1: dependencies: iterall "^1.2.2" +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + gzip-size@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.0.tgz#2db0396c71f5c902d5cf6b52add5030b93c99bd2" @@ -4621,7 +4690,7 @@ hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" -he@1.2.x, he@^1.1.0: +he@1.2.0, he@1.2.x, he@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== @@ -5068,6 +5137,11 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-buffer@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" @@ -5430,6 +5504,14 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@3.13.1, js-yaml@^3.12.1, js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.9.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@3.8.2: version "3.8.2" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721" @@ -5438,14 +5520,6 @@ js-yaml@3.8.2: argparse "^1.0.7" esprima "^3.1.1" -js-yaml@^3.12.1, js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.9.0: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -5711,6 +5785,11 @@ lodash.defaultsdeep@^4.6.0: resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz#bec1024f85b1bd96cbea405b23c14ad6443a6f81" integrity sha1-vsECT4WxvZbL6kBbI8FK1kQ6b4E= +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + lodash.mapvalues@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" @@ -5776,7 +5855,7 @@ lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.3 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== -log-symbols@^2.2.0: +log-symbols@2.2.0, log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== @@ -6067,7 +6146,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@^3.0.0, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -6152,13 +6231,42 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp@0.5, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" +mocha@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.1.4.tgz#e35fada242d5434a7e163d555c705f6875951640" + integrity sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg== + dependencies: + ansi-colors "3.2.3" + browser-stdout "1.3.1" + debug "3.2.6" + diff "3.5.0" + escape-string-regexp "1.0.5" + find-up "3.0.0" + glob "7.1.3" + growl "1.10.5" + he "1.2.0" + js-yaml "3.13.1" + log-symbols "2.2.0" + minimatch "3.0.4" + mkdirp "0.5.1" + ms "2.1.1" + node-environment-flags "1.0.5" + object.assign "4.1.0" + strip-json-comments "2.0.1" + supports-color "6.0.0" + which "1.3.1" + wide-align "1.1.3" + yargs "13.2.2" + yargs-parser "13.0.0" + yargs-unparser "1.5.0" + moment@2.19.3: version "2.19.3" resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.3.tgz#bdb99d270d6d7fda78cc0fbace855e27fe7da69f" @@ -6207,7 +6315,7 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: +ms@2.1.1, ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== @@ -6350,6 +6458,14 @@ node-abi@^2.7.0: dependencies: semver "^5.4.1" +node-environment-flags@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" + integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== + dependencies: + object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" + node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.3.0: version "2.5.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.5.0.tgz#8028c49fc1191bba56a07adc6e2a954644a48501" @@ -6677,7 +6793,7 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-keys@^1.0.12: +object-keys@^1.0.11, object-keys@^1.0.12: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -6694,6 +6810,16 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" +object.assign@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + object.getownpropertydescriptors@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" @@ -7884,6 +8010,11 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +reflect-metadata@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + regenerate@^1.2.1: version "1.4.0" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" @@ -8294,7 +8425,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0: version "5.7.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== @@ -8994,7 +9125,7 @@ strip-indent@^2.0.0: resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= -strip-json-comments@~2.0.1: +strip-json-comments@2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -9019,6 +9150,13 @@ subscriptions-transport-ws@^0.9.11, subscriptions-transport-ws@^0.9.15, subscrip symbol-observable "^1.0.4" ws "^5.2.0" +supports-color@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== + dependencies: + has-flag "^3.0.0" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -9406,7 +9544,7 @@ ts-loader@^5.3.3: micromatch "^3.1.4" semver "^5.0.1" -ts-node@^8.0.3: +ts-node@^8.0.3, ts-node@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.1.0.tgz#8c4b37036abd448577db22a061fd7a67d47e658e" integrity sha512-34jpuOrxDuf+O6iW1JpgTRDFynUZ1iEqtYruBqh35gICNjN8x+LpVcPAcwzLPi9VU6mdA3ym+x233nZmZp445A== @@ -9475,6 +9613,21 @@ type-fest@^0.4.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== +type-graphql@^0.17.3: + version "0.17.3" + resolved "https://registry.yarnpkg.com/type-graphql/-/type-graphql-0.17.3.tgz#91ee6b3dcc57c34d9b9a1297cbf64e4c57570176" + integrity sha512-/y4xFjAeluoQQR47RPw7cJarmXKDfn0GQFXCeizjYTtzAdcii6RqdnXOMDpsHHvfzeGvE6BUnneJhzekUfV/+A== + dependencies: + "@types/glob" "^7.1.1" + "@types/node" "^11.13.7" + "@types/semver" "^6.0.0" + class-validator ">=0.9.1" + glob "^7.1.3" + graphql-query-complexity "^0.2.3" + graphql-subscriptions "^1.1.0" + semver "^6.0.0" + tslib "^1.9.3" + type-is@^1.6.16, type-is@~1.6.14, type-is@~1.6.16, type-is@~1.6.17: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -9814,6 +9967,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validator@10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-10.4.0.tgz#ee99a44afb3bb5ed350a159f056ca72a204cfc3c" + integrity sha512-Q/wBy3LB1uOyssgNlXSRmaf22NxjvDNZM2MtIQ4jaEOAB61xsh1TQxsq1CgzUMBV1lDrVMogIh8GjG1DYW0zLg== + vary@^1, vary@~1.1.0, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -10132,14 +10290,14 @@ which-pm-runs@^1.0.0: resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= -which@^1.2.9: +which@1.3.1, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" -wide-align@^1.1.0: +wide-align@1.1.3, wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== @@ -10398,6 +10556,14 @@ yallist@^3.0.0, yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== +yargs-parser@13.0.0: + version "13.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b" + integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" @@ -10414,7 +10580,16 @@ yargs-parser@^13.0.0: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@12.0.5, yargs@^12.0.1: +yargs-unparser@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d" + integrity sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw== + dependencies: + flat "^4.1.0" + lodash "^4.17.11" + yargs "^12.0.5" + +yargs@12.0.5, yargs@^12.0.1, yargs@^12.0.5: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== @@ -10432,7 +10607,7 @@ yargs@12.0.5, yargs@^12.0.1: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^13.0.0: +yargs@13.2.2, yargs@^13.0.0: version "13.2.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==