feat(api): add subscription server and client services and interfaces (#1470)
* feat(api): add subscription server and client services and interfaces * fix(api): linter issues * feat(models): add subscription invitations * feat(api): add subscriptions invitation operations on server side * fix(api): linter issues
This commit is contained in:
BIN
.yarn/cache/@eslint-eslintrc-npm-1.3.1-f9e7aea43c-9844dcc58a.zip
vendored
Normal file
BIN
.yarn/cache/@eslint-eslintrc-npm-1.3.1-f9e7aea43c-9844dcc58a.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@humanwhocodes-module-importer-npm-1.0.1-9d07ed2e4a-0fd22007db.zip
vendored
Normal file
BIN
.yarn/cache/@humanwhocodes-module-importer-npm-1.0.1-9d07ed2e4a-0fd22007db.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/eslint-npm-8.23.0-4ce1a8504a-ff6075daa2.zip
vendored
Normal file
BIN
.yarn/cache/eslint-npm-8.23.0-4ce1a8504a-ff6075daa2.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/espree-npm-9.4.0-0371ef3614-2e3020dde6.zip
vendored
Normal file
BIN
.yarn/cache/espree-npm-9.4.0-0371ef3614-2e3020dde6.zip
vendored
Normal file
Binary file not shown.
@@ -22,12 +22,14 @@
|
|||||||
"prebuild": "yarn clean",
|
"prebuild": "yarn clean",
|
||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json",
|
||||||
"lint": "eslint . --ext .ts",
|
"lint": "eslint . --ext .ts",
|
||||||
|
"lint:fix": "eslint . --ext .ts --fix",
|
||||||
"test": "jest spec --coverage"
|
"test": "jest spec --coverage"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^28.1.5",
|
"@types/jest": "^28.1.5",
|
||||||
"@types/lodash": "^4.14.182",
|
"@types/lodash": "^4.14.182",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
||||||
|
"eslint": "^8.23.0",
|
||||||
"eslint-plugin-prettier": "*",
|
"eslint-plugin-prettier": "*",
|
||||||
"jest": "^28.1.2",
|
"jest": "^28.1.2",
|
||||||
"ts-jest": "^28.0.5"
|
"ts-jest": "^28.0.5"
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
|
||||||
|
import { SubscriptionServerInterface } from '../../Server/Subscription/SubscriptionServerInterface'
|
||||||
|
|
||||||
|
import { SubscriptionApiService } from './SubscriptionApiService'
|
||||||
|
|
||||||
|
describe('SubscriptionApiService', () => {
|
||||||
|
let subscriptionServer: SubscriptionServerInterface
|
||||||
|
|
||||||
|
const createService = () => new SubscriptionApiService(subscriptionServer)
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
subscriptionServer = {} as jest.Mocked<SubscriptionServerInterface>
|
||||||
|
subscriptionServer.invite = jest.fn().mockReturnValue({
|
||||||
|
data: { success: true, sharedSubscriptionInvitationUuid: '1-2-3' },
|
||||||
|
} as jest.Mocked<SubscriptionInviteResponse>)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should invite a user', async () => {
|
||||||
|
const response = await createService().invite('test@test.te')
|
||||||
|
|
||||||
|
expect(response).toEqual({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
sharedSubscriptionInvitationUuid: '1-2-3',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
expect(subscriptionServer.invite).toHaveBeenCalledWith({
|
||||||
|
api: '20200115',
|
||||||
|
identifier: 'test@test.te',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not invite a user if it is already inviting', async () => {
|
||||||
|
const service = createService()
|
||||||
|
Object.defineProperty(service, 'inviting', {
|
||||||
|
get: () => true,
|
||||||
|
})
|
||||||
|
|
||||||
|
let error = null
|
||||||
|
try {
|
||||||
|
await service.invite('test@test.te')
|
||||||
|
} catch (caughtError) {
|
||||||
|
error = caughtError
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).not.toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not invite a user if the server fails', async () => {
|
||||||
|
subscriptionServer.invite = jest.fn().mockImplementation(() => {
|
||||||
|
throw new Error('Oops')
|
||||||
|
})
|
||||||
|
|
||||||
|
let error = null
|
||||||
|
try {
|
||||||
|
await createService().invite('test@test.te')
|
||||||
|
} catch (caughtError) {
|
||||||
|
error = caughtError
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).not.toBeNull()
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { ErrorMessage } from '../../Error/ErrorMessage'
|
||||||
|
import { ApiCallError } from '../../Error/ApiCallError'
|
||||||
|
import { ApiVersion } from '../../Api/ApiVersion'
|
||||||
|
import { ApiEndpointParam } from '../../Request/ApiEndpointParam'
|
||||||
|
import { SubscriptionApiServiceInterface } from './SubscriptionApiServiceInterface'
|
||||||
|
import { SubscriptionServerInterface } from '../../Server/Subscription/SubscriptionServerInterface'
|
||||||
|
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
|
||||||
|
|
||||||
|
export class SubscriptionApiService implements SubscriptionApiServiceInterface {
|
||||||
|
private inviting: boolean
|
||||||
|
|
||||||
|
constructor(private subscriptionServer: SubscriptionServerInterface) {
|
||||||
|
this.inviting = false
|
||||||
|
}
|
||||||
|
|
||||||
|
async invite(inviteeEmail: string): Promise<SubscriptionInviteResponse> {
|
||||||
|
if (this.inviting) {
|
||||||
|
throw new ApiCallError(ErrorMessage.InvitingInProgress)
|
||||||
|
}
|
||||||
|
this.inviting = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await this.subscriptionServer.invite({
|
||||||
|
[ApiEndpointParam.ApiVersion]: ApiVersion.v0,
|
||||||
|
identifier: inviteeEmail,
|
||||||
|
})
|
||||||
|
|
||||||
|
this.inviting = false
|
||||||
|
|
||||||
|
return response
|
||||||
|
} catch (error) {
|
||||||
|
throw new ApiCallError(ErrorMessage.GenericFail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
|
||||||
|
|
||||||
|
export interface SubscriptionApiServiceInterface {
|
||||||
|
invite(inviteeEmail: string): Promise<SubscriptionInviteResponse>
|
||||||
|
}
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
|
export * from './Subscription/SubscriptionApiService'
|
||||||
|
export * from './Subscription/SubscriptionApiServiceInterface'
|
||||||
export * from './User/UserApiService'
|
export * from './User/UserApiService'
|
||||||
export * from './User/UserApiServiceInterface'
|
export * from './User/UserApiServiceInterface'
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
export enum ErrorMessage {
|
export enum ErrorMessage {
|
||||||
|
InvitingInProgress = 'An existing invitation request is already in progress.',
|
||||||
RegistrationInProgress = 'An existing registration request is already in progress.',
|
RegistrationInProgress = 'An existing registration request is already in progress.',
|
||||||
GenericRegistrationFail = 'A server error occurred while trying to register. Please try again.',
|
GenericRegistrationFail = 'A server error occurred while trying to register. Please try again.',
|
||||||
RateLimited = 'Too many successive server requests. Please wait a few minutes and try again.',
|
RateLimited = 'Too many successive server requests. Please wait a few minutes and try again.',
|
||||||
InsufficientPasswordMessage = 'Your password must be at least %LENGTH% characters in length. For your security, please choose a longer password or, ideally, a passphrase, and try again.',
|
InsufficientPasswordMessage = 'Your password must be at least %LENGTH% characters in length. For your security, please choose a longer password or, ideally, a passphrase, and try again.',
|
||||||
PasscodeRequired = 'Your passcode is required in order to register for an account.',
|
PasscodeRequired = 'Your passcode is required in order to register for an account.',
|
||||||
|
GenericFail = 'A server error occurred. Please try again.',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Uuid } from '@standardnotes/common'
|
||||||
|
|
||||||
|
import { ApiEndpointParam } from '../ApiEndpointParam'
|
||||||
|
import { ApiVersion } from '../../Api/ApiVersion'
|
||||||
|
|
||||||
|
export type SubscriptionInviteAcceptRequestParams = {
|
||||||
|
[ApiEndpointParam.ApiVersion]: ApiVersion.v0
|
||||||
|
inviteUuid: Uuid
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Uuid } from '@standardnotes/common'
|
||||||
|
|
||||||
|
import { ApiEndpointParam } from '../ApiEndpointParam'
|
||||||
|
import { ApiVersion } from '../../Api/ApiVersion'
|
||||||
|
|
||||||
|
export type SubscriptionInviteCancelRequestParams = {
|
||||||
|
[ApiEndpointParam.ApiVersion]: ApiVersion.v0
|
||||||
|
inviteUuid: Uuid
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Uuid } from '@standardnotes/common'
|
||||||
|
|
||||||
|
import { ApiEndpointParam } from '../ApiEndpointParam'
|
||||||
|
import { ApiVersion } from '../../Api/ApiVersion'
|
||||||
|
|
||||||
|
export type SubscriptionInviteDeclineRequestParams = {
|
||||||
|
[ApiEndpointParam.ApiVersion]: ApiVersion.v0
|
||||||
|
inviteUuid: Uuid
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { ApiEndpointParam } from '../ApiEndpointParam'
|
||||||
|
import { ApiVersion } from '../../Api/ApiVersion'
|
||||||
|
|
||||||
|
export type SubscriptionInviteListRequestParams = {
|
||||||
|
[ApiEndpointParam.ApiVersion]: ApiVersion.v0
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { ApiEndpointParam } from '../ApiEndpointParam'
|
||||||
|
import { ApiVersion } from '../../Api/ApiVersion'
|
||||||
|
|
||||||
|
export type SubscriptionInviteRequestParams = {
|
||||||
|
[ApiEndpointParam.ApiVersion]: ApiVersion.v0
|
||||||
|
identifier: string
|
||||||
|
[additionalParam: string]: unknown
|
||||||
|
}
|
||||||
@@ -1,2 +1,7 @@
|
|||||||
export * from './ApiEndpointParam'
|
export * from './ApiEndpointParam'
|
||||||
|
export * from './Subscription/SubscriptionInviteAcceptRequestParams'
|
||||||
|
export * from './Subscription/SubscriptionInviteCancelRequestParams'
|
||||||
|
export * from './Subscription/SubscriptionInviteDeclineRequestParams'
|
||||||
|
export * from './Subscription/SubscriptionInviteListRequestParams'
|
||||||
|
export * from './Subscription/SubscriptionInviteRequestParams'
|
||||||
export * from './User/UserRegistrationRequestParams'
|
export * from './User/UserRegistrationRequestParams'
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
import { SubscriptionInviteAcceptResponseBody } from './SubscriptionInviteAcceptResponseBody'
|
||||||
|
|
||||||
|
export interface SubscriptionInviteAcceptResponse extends HttpResponse {
|
||||||
|
data: SubscriptionInviteAcceptResponseBody | HttpErrorResponseBody
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export type SubscriptionInviteAcceptResponseBody = {
|
||||||
|
success: boolean
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
import { SubscriptionInviteCancelResponseBody } from './SubscriptionInviteCancelResponseBody'
|
||||||
|
|
||||||
|
export interface SubscriptionInviteCancelResponse extends HttpResponse {
|
||||||
|
data: SubscriptionInviteCancelResponseBody | HttpErrorResponseBody
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export type SubscriptionInviteCancelResponseBody = {
|
||||||
|
success: boolean
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
import { SubscriptionInviteDeclineResponseBody } from './SubscriptionInviteDeclineResponseBody'
|
||||||
|
|
||||||
|
export interface SubscriptionInviteDeclineResponse extends HttpResponse {
|
||||||
|
data: SubscriptionInviteDeclineResponseBody | HttpErrorResponseBody
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export type SubscriptionInviteDeclineResponseBody = {
|
||||||
|
success: boolean
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
import { SubscriptionInviteListResponseBody } from './SubscriptionInviteListResponseBody'
|
||||||
|
|
||||||
|
export interface SubscriptionInviteListResponse extends HttpResponse {
|
||||||
|
data: SubscriptionInviteListResponseBody | HttpErrorResponseBody
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { Invitation } from '@standardnotes/models'
|
||||||
|
|
||||||
|
export type SubscriptionInviteListResponseBody = {
|
||||||
|
invitations: Array<Invitation>
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { HttpErrorResponseBody } from '../../Http/HttpErrorResponseBody'
|
||||||
|
import { HttpResponse } from '../../Http/HttpResponse'
|
||||||
|
import { SubscriptionInviteResponseBody } from './SubscriptionInviteResponseBody'
|
||||||
|
|
||||||
|
export interface SubscriptionInviteResponse extends HttpResponse {
|
||||||
|
data: SubscriptionInviteResponseBody | HttpErrorResponseBody
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Uuid } from '@standardnotes/common'
|
||||||
|
|
||||||
|
export type SubscriptionInviteResponseBody =
|
||||||
|
| {
|
||||||
|
success: true
|
||||||
|
sharedSubscriptionInvitationUuid: Uuid
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
success: false
|
||||||
|
}
|
||||||
@@ -1,2 +1,12 @@
|
|||||||
|
export * from './Subscription/SubscriptionInviteAcceptResponse'
|
||||||
|
export * from './Subscription/SubscriptionInviteAcceptResponseBody'
|
||||||
|
export * from './Subscription/SubscriptionInviteCancelResponse'
|
||||||
|
export * from './Subscription/SubscriptionInviteCancelResponseBody'
|
||||||
|
export * from './Subscription/SubscriptionInviteDeclineResponse'
|
||||||
|
export * from './Subscription/SubscriptionInviteDeclineResponseBody'
|
||||||
|
export * from './Subscription/SubscriptionInviteListResponse'
|
||||||
|
export * from './Subscription/SubscriptionInviteListResponseBody'
|
||||||
|
export * from './Subscription/SubscriptionInviteResponse'
|
||||||
|
export * from './Subscription/SubscriptionInviteResponseBody'
|
||||||
export * from './User/UserRegistrationResponse'
|
export * from './User/UserRegistrationResponse'
|
||||||
export * from './User/UserRegistrationResponseBody'
|
export * from './User/UserRegistrationResponseBody'
|
||||||
|
|||||||
15
packages/api/src/Domain/Server/Subscription/Paths.ts
Normal file
15
packages/api/src/Domain/Server/Subscription/Paths.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { Uuid } from '@standardnotes/common'
|
||||||
|
|
||||||
|
const SharingPaths = {
|
||||||
|
invite: '/v1/subscription-invites',
|
||||||
|
acceptInvite: (inviteUuid: Uuid) => `/v1/subscription-invites/${inviteUuid}/accept`,
|
||||||
|
declineInvite: (inviteUuid: Uuid) => `/v1/subscription-invites/${inviteUuid}/decline`,
|
||||||
|
cancelInvite: (inviteUuid: Uuid) => `/v1/subscription-invites/${inviteUuid}`,
|
||||||
|
listInvites: '/v1/subscription-invites',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Paths = {
|
||||||
|
v1: {
|
||||||
|
...SharingPaths,
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
import { Invitation } from '@standardnotes/models'
|
||||||
|
|
||||||
|
import { ApiVersion } from '../../Api'
|
||||||
|
import { HttpServiceInterface } from '../../Http'
|
||||||
|
import { SubscriptionInviteResponse } from '../../Response'
|
||||||
|
import { SubscriptionInviteAcceptResponse } from '../../Response/Subscription/SubscriptionInviteAcceptResponse'
|
||||||
|
import { SubscriptionInviteCancelResponse } from '../../Response/Subscription/SubscriptionInviteCancelResponse'
|
||||||
|
import { SubscriptionInviteDeclineResponse } from '../../Response/Subscription/SubscriptionInviteDeclineResponse'
|
||||||
|
import { SubscriptionInviteListResponse } from '../../Response/Subscription/SubscriptionInviteListResponse'
|
||||||
|
import { SubscriptionServer } from './SubscriptionServer'
|
||||||
|
|
||||||
|
describe('SubscriptionServer', () => {
|
||||||
|
let httpService: HttpServiceInterface
|
||||||
|
|
||||||
|
const createServer = () => new SubscriptionServer(httpService)
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
httpService = {} as jest.Mocked<HttpServiceInterface>
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should invite a user to a shared subscription', async () => {
|
||||||
|
httpService.post = jest.fn().mockReturnValue({
|
||||||
|
data: { success: true, sharedSubscriptionInvitationUuid: '1-2-3' },
|
||||||
|
} as jest.Mocked<SubscriptionInviteResponse>)
|
||||||
|
|
||||||
|
const response = await createServer().invite({
|
||||||
|
api: ApiVersion.v0,
|
||||||
|
identifier: 'test@test.te',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response).toEqual({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
sharedSubscriptionInvitationUuid: '1-2-3',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should accept an invite to a shared subscription', async () => {
|
||||||
|
httpService.get = jest.fn().mockReturnValue({
|
||||||
|
data: { success: true },
|
||||||
|
} as jest.Mocked<SubscriptionInviteAcceptResponse>)
|
||||||
|
|
||||||
|
const response = await createServer().acceptInvite({
|
||||||
|
api: ApiVersion.v0,
|
||||||
|
inviteUuid: '1-2-3',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response).toEqual({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should decline an invite to a shared subscription', async () => {
|
||||||
|
httpService.get = jest.fn().mockReturnValue({
|
||||||
|
data: { success: true },
|
||||||
|
} as jest.Mocked<SubscriptionInviteDeclineResponse>)
|
||||||
|
|
||||||
|
const response = await createServer().declineInvite({
|
||||||
|
api: ApiVersion.v0,
|
||||||
|
inviteUuid: '1-2-3',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response).toEqual({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should cancel an invite to a shared subscription', async () => {
|
||||||
|
httpService.delete = jest.fn().mockReturnValue({
|
||||||
|
data: { success: true },
|
||||||
|
} as jest.Mocked<SubscriptionInviteCancelResponse>)
|
||||||
|
|
||||||
|
const response = await createServer().cancelInvite({
|
||||||
|
api: ApiVersion.v0,
|
||||||
|
inviteUuid: '1-2-3',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response).toEqual({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should list invitations to a shared subscription', async () => {
|
||||||
|
httpService.get = jest.fn().mockReturnValue({
|
||||||
|
data: { invitations: [{} as jest.Mocked<Invitation>] },
|
||||||
|
} as jest.Mocked<SubscriptionInviteListResponse>)
|
||||||
|
|
||||||
|
const response = await createServer().listInvites({
|
||||||
|
api: ApiVersion.v0,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response).toEqual({
|
||||||
|
data: {
|
||||||
|
invitations: [{} as jest.Mocked<Invitation>],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { HttpServiceInterface } from '../../Http/HttpServiceInterface'
|
||||||
|
import { SubscriptionInviteAcceptRequestParams } from '../../Request/Subscription/SubscriptionInviteAcceptRequestParams'
|
||||||
|
import { SubscriptionInviteCancelRequestParams } from '../../Request/Subscription/SubscriptionInviteCancelRequestParams'
|
||||||
|
import { SubscriptionInviteDeclineRequestParams } from '../../Request/Subscription/SubscriptionInviteDeclineRequestParams'
|
||||||
|
import { SubscriptionInviteListRequestParams } from '../../Request/Subscription/SubscriptionInviteListRequestParams'
|
||||||
|
import { SubscriptionInviteRequestParams } from '../../Request/Subscription/SubscriptionInviteRequestParams'
|
||||||
|
import { SubscriptionInviteAcceptResponse } from '../../Response/Subscription/SubscriptionInviteAcceptResponse'
|
||||||
|
import { SubscriptionInviteCancelResponse } from '../../Response/Subscription/SubscriptionInviteCancelResponse'
|
||||||
|
import { SubscriptionInviteDeclineResponse } from '../../Response/Subscription/SubscriptionInviteDeclineResponse'
|
||||||
|
import { SubscriptionInviteListResponse } from '../../Response/Subscription/SubscriptionInviteListResponse'
|
||||||
|
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
|
||||||
|
|
||||||
|
import { Paths } from './Paths'
|
||||||
|
import { SubscriptionServerInterface } from './SubscriptionServerInterface'
|
||||||
|
|
||||||
|
export class SubscriptionServer implements SubscriptionServerInterface {
|
||||||
|
constructor(private httpService: HttpServiceInterface) {}
|
||||||
|
|
||||||
|
async acceptInvite(params: SubscriptionInviteAcceptRequestParams): Promise<SubscriptionInviteAcceptResponse> {
|
||||||
|
const response = await this.httpService.get(Paths.v1.acceptInvite(params.inviteUuid), params)
|
||||||
|
|
||||||
|
return response as SubscriptionInviteAcceptResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
async declineInvite(params: SubscriptionInviteDeclineRequestParams): Promise<SubscriptionInviteDeclineResponse> {
|
||||||
|
const response = await this.httpService.get(Paths.v1.declineInvite(params.inviteUuid), params)
|
||||||
|
|
||||||
|
return response as SubscriptionInviteDeclineResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
async cancelInvite(params: SubscriptionInviteCancelRequestParams): Promise<SubscriptionInviteCancelResponse> {
|
||||||
|
const response = await this.httpService.delete(Paths.v1.cancelInvite(params.inviteUuid), params)
|
||||||
|
|
||||||
|
return response as SubscriptionInviteCancelResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
async listInvites(params: SubscriptionInviteListRequestParams): Promise<SubscriptionInviteListResponse> {
|
||||||
|
const response = await this.httpService.get(Paths.v1.listInvites, params)
|
||||||
|
|
||||||
|
return response as SubscriptionInviteListResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
async invite(params: SubscriptionInviteRequestParams): Promise<SubscriptionInviteResponse> {
|
||||||
|
const response = await this.httpService.post(Paths.v1.invite, params)
|
||||||
|
|
||||||
|
return response as SubscriptionInviteResponse
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { SubscriptionInviteAcceptRequestParams } from '../../Request/Subscription/SubscriptionInviteAcceptRequestParams'
|
||||||
|
import { SubscriptionInviteCancelRequestParams } from '../../Request/Subscription/SubscriptionInviteCancelRequestParams'
|
||||||
|
import { SubscriptionInviteDeclineRequestParams } from '../../Request/Subscription/SubscriptionInviteDeclineRequestParams'
|
||||||
|
import { SubscriptionInviteListRequestParams } from '../../Request/Subscription/SubscriptionInviteListRequestParams'
|
||||||
|
import { SubscriptionInviteRequestParams } from '../../Request/Subscription/SubscriptionInviteRequestParams'
|
||||||
|
import { SubscriptionInviteAcceptResponse } from '../../Response/Subscription/SubscriptionInviteAcceptResponse'
|
||||||
|
import { SubscriptionInviteCancelResponse } from '../../Response/Subscription/SubscriptionInviteCancelResponse'
|
||||||
|
import { SubscriptionInviteDeclineResponse } from '../../Response/Subscription/SubscriptionInviteDeclineResponse'
|
||||||
|
import { SubscriptionInviteListResponse } from '../../Response/Subscription/SubscriptionInviteListResponse'
|
||||||
|
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
|
||||||
|
|
||||||
|
export interface SubscriptionServerInterface {
|
||||||
|
invite(params: SubscriptionInviteRequestParams): Promise<SubscriptionInviteResponse>
|
||||||
|
acceptInvite(params: SubscriptionInviteAcceptRequestParams): Promise<SubscriptionInviteAcceptResponse>
|
||||||
|
declineInvite(params: SubscriptionInviteDeclineRequestParams): Promise<SubscriptionInviteDeclineResponse>
|
||||||
|
cancelInvite(params: SubscriptionInviteCancelRequestParams): Promise<SubscriptionInviteCancelResponse>
|
||||||
|
listInvites(params: SubscriptionInviteListRequestParams): Promise<SubscriptionInviteListResponse>
|
||||||
|
}
|
||||||
15
packages/models/src/Domain/Api/Subscription/Invitation.ts
Normal file
15
packages/models/src/Domain/Api/Subscription/Invitation.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { InvitationStatus } from './InvitationStatus'
|
||||||
|
import { InviteeIdentifierType } from './InviteeIdentifierType'
|
||||||
|
import { InviterIdentifierType } from './InviterIdentifierType'
|
||||||
|
|
||||||
|
export type Invitation = {
|
||||||
|
uuid: string
|
||||||
|
inviterIdentifier: string
|
||||||
|
inviterIdentifierType: InviterIdentifierType
|
||||||
|
inviteeIdentifier: string
|
||||||
|
inviteeIdentifierType: InviteeIdentifierType
|
||||||
|
status: InvitationStatus
|
||||||
|
subscriptionId: number
|
||||||
|
createdAt: number
|
||||||
|
updatedAt: number
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export enum InvitationStatus {
|
||||||
|
Sent = 'sent',
|
||||||
|
Canceled = 'canceled',
|
||||||
|
Accepted = 'accepted',
|
||||||
|
Declined = 'declined',
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export enum InviteeIdentifierType {
|
||||||
|
Email = 'email',
|
||||||
|
Hash = 'hash',
|
||||||
|
Uuid = 'uuid',
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export enum InviterIdentifierType {
|
||||||
|
Email = 'email',
|
||||||
|
Uuid = 'uuid',
|
||||||
|
}
|
||||||
@@ -24,6 +24,10 @@ export * from './Abstract/Contextual/SessionHistory'
|
|||||||
export * from './Abstract/Item'
|
export * from './Abstract/Item'
|
||||||
export * from './Abstract/Payload'
|
export * from './Abstract/Payload'
|
||||||
export * from './Abstract/TransferPayload'
|
export * from './Abstract/TransferPayload'
|
||||||
|
export * from './Api/Subscription/Invitation'
|
||||||
|
export * from './Api/Subscription/InvitationStatus'
|
||||||
|
export * from './Api/Subscription/InviteeIdentifierType'
|
||||||
|
export * from './Api/Subscription/InviterIdentifierType'
|
||||||
export * from './Local/KeyParams/RootKeyParamsInterface'
|
export * from './Local/KeyParams/RootKeyParamsInterface'
|
||||||
export * from './Local/RootKey/KeychainTypes'
|
export * from './Local/RootKey/KeychainTypes'
|
||||||
export * from './Local/RootKey/RootKeyContent'
|
export * from './Local/RootKey/RootKeyContent'
|
||||||
|
|||||||
85
yarn.lock
85
yarn.lock
@@ -3463,6 +3463,23 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@eslint/eslintrc@npm:^1.3.1":
|
||||||
|
version: 1.3.1
|
||||||
|
resolution: "@eslint/eslintrc@npm:1.3.1"
|
||||||
|
dependencies:
|
||||||
|
ajv: ^6.12.4
|
||||||
|
debug: ^4.3.2
|
||||||
|
espree: ^9.4.0
|
||||||
|
globals: ^13.15.0
|
||||||
|
ignore: ^5.2.0
|
||||||
|
import-fresh: ^3.2.1
|
||||||
|
js-yaml: ^4.1.0
|
||||||
|
minimatch: ^3.1.2
|
||||||
|
strip-json-comments: ^3.1.1
|
||||||
|
checksum: 9844dcc58a44399649926d5a17a2d53d529b80d3e8c3e9d0964ae198bac77ee6bb1cf44940f30cd9c2e300f7568ec82500be42ace6cacefb08aebf9905fe208e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@expo/react-native-action-sheet@npm:^3.13.0":
|
"@expo/react-native-action-sheet@npm:^3.13.0":
|
||||||
version: 3.13.0
|
version: 3.13.0
|
||||||
resolution: "@expo/react-native-action-sheet@npm:3.13.0"
|
resolution: "@expo/react-native-action-sheet@npm:3.13.0"
|
||||||
@@ -3538,6 +3555,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@humanwhocodes/module-importer@npm:^1.0.1":
|
||||||
|
version: 1.0.1
|
||||||
|
resolution: "@humanwhocodes/module-importer@npm:1.0.1"
|
||||||
|
checksum: 0fd22007db8034a2cdf2c764b140d37d9020bbfce8a49d3ec5c05290e77d4b0263b1b972b752df8c89e5eaa94073408f2b7d977aed131faf6cf396ebb5d7fb61
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@humanwhocodes/object-schema@npm:^1.2.0, @humanwhocodes/object-schema@npm:^1.2.1":
|
"@humanwhocodes/object-schema@npm:^1.2.0, @humanwhocodes/object-schema@npm:^1.2.1":
|
||||||
version: 1.2.1
|
version: 1.2.1
|
||||||
resolution: "@humanwhocodes/object-schema@npm:1.2.1"
|
resolution: "@humanwhocodes/object-schema@npm:1.2.1"
|
||||||
@@ -6216,6 +6240,7 @@ __metadata:
|
|||||||
"@types/jest": ^28.1.5
|
"@types/jest": ^28.1.5
|
||||||
"@types/lodash": ^4.14.182
|
"@types/lodash": ^4.14.182
|
||||||
"@typescript-eslint/eslint-plugin": ^5.30.0
|
"@typescript-eslint/eslint-plugin": ^5.30.0
|
||||||
|
eslint: ^8.23.0
|
||||||
eslint-plugin-prettier: "*"
|
eslint-plugin-prettier: "*"
|
||||||
jest: ^28.1.2
|
jest: ^28.1.2
|
||||||
reflect-metadata: ^0.1.13
|
reflect-metadata: ^0.1.13
|
||||||
@@ -18026,6 +18051,55 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"eslint@npm:^8.23.0":
|
||||||
|
version: 8.23.0
|
||||||
|
resolution: "eslint@npm:8.23.0"
|
||||||
|
dependencies:
|
||||||
|
"@eslint/eslintrc": ^1.3.1
|
||||||
|
"@humanwhocodes/config-array": ^0.10.4
|
||||||
|
"@humanwhocodes/gitignore-to-minimatch": ^1.0.2
|
||||||
|
"@humanwhocodes/module-importer": ^1.0.1
|
||||||
|
ajv: ^6.10.0
|
||||||
|
chalk: ^4.0.0
|
||||||
|
cross-spawn: ^7.0.2
|
||||||
|
debug: ^4.3.2
|
||||||
|
doctrine: ^3.0.0
|
||||||
|
escape-string-regexp: ^4.0.0
|
||||||
|
eslint-scope: ^7.1.1
|
||||||
|
eslint-utils: ^3.0.0
|
||||||
|
eslint-visitor-keys: ^3.3.0
|
||||||
|
espree: ^9.4.0
|
||||||
|
esquery: ^1.4.0
|
||||||
|
esutils: ^2.0.2
|
||||||
|
fast-deep-equal: ^3.1.3
|
||||||
|
file-entry-cache: ^6.0.1
|
||||||
|
find-up: ^5.0.0
|
||||||
|
functional-red-black-tree: ^1.0.1
|
||||||
|
glob-parent: ^6.0.1
|
||||||
|
globals: ^13.15.0
|
||||||
|
globby: ^11.1.0
|
||||||
|
grapheme-splitter: ^1.0.4
|
||||||
|
ignore: ^5.2.0
|
||||||
|
import-fresh: ^3.0.0
|
||||||
|
imurmurhash: ^0.1.4
|
||||||
|
is-glob: ^4.0.0
|
||||||
|
js-yaml: ^4.1.0
|
||||||
|
json-stable-stringify-without-jsonify: ^1.0.1
|
||||||
|
levn: ^0.4.1
|
||||||
|
lodash.merge: ^4.6.2
|
||||||
|
minimatch: ^3.1.2
|
||||||
|
natural-compare: ^1.4.0
|
||||||
|
optionator: ^0.9.1
|
||||||
|
regexpp: ^3.2.0
|
||||||
|
strip-ansi: ^6.0.1
|
||||||
|
strip-json-comments: ^3.1.0
|
||||||
|
text-table: ^0.2.0
|
||||||
|
bin:
|
||||||
|
eslint: bin/eslint.js
|
||||||
|
checksum: ff6075daa28d817a7ac4508f31bc108a04d9ab5056608c8651b5bf9cfea5d708ca16dea6cdab2c3c0ae99b0bf0e726af8504eaa8e17c8e12e242cb68237ead64
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"espree@npm:^7.3.0, espree@npm:^7.3.1":
|
"espree@npm:^7.3.0, espree@npm:^7.3.1":
|
||||||
version: 7.3.1
|
version: 7.3.1
|
||||||
resolution: "espree@npm:7.3.1"
|
resolution: "espree@npm:7.3.1"
|
||||||
@@ -18059,6 +18133,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"espree@npm:^9.4.0":
|
||||||
|
version: 9.4.0
|
||||||
|
resolution: "espree@npm:9.4.0"
|
||||||
|
dependencies:
|
||||||
|
acorn: ^8.8.0
|
||||||
|
acorn-jsx: ^5.3.2
|
||||||
|
eslint-visitor-keys: ^3.3.0
|
||||||
|
checksum: 2e3020dde67892d2ba3632413b44d0dc31d92c29ce72267d7ec24216a562f0a6494d3696e2fa39a3ec8c0e0088d773947ab2925fbb716801a11eb8dd313ac89c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"esprima@npm:^4.0.0, esprima@npm:^4.0.1, esprima@npm:~4.0.0":
|
"esprima@npm:^4.0.0, esprima@npm:^4.0.1, esprima@npm:~4.0.0":
|
||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
resolution: "esprima@npm:4.0.1"
|
resolution: "esprima@npm:4.0.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user