gergo/workspacesMultiRegion (#3477)
* feat(webhook-service): learn to speak multi region * feat(fileimport-service): talk multi region to me * feat(fileuploads, blobs): multi region * feat(workspaces): update delet workspace with billing and regions * fix typo * feat(workspaces): remove old billing resolvers * test(workspaces): fix tests * fix(workspaces): remove unused schema
This commit is contained in:
Родитель
381c4e2a85
Коммит
e30b8c83b9
|
@ -226,60 +226,6 @@ input PendingWorkspaceCollaboratorsFilter {
|
|||
search: String
|
||||
}
|
||||
|
||||
type WorkspaceVersionsCount {
|
||||
"""
|
||||
Total number of versions of all projects in the workspace
|
||||
"""
|
||||
current: Int!
|
||||
"""
|
||||
Maximum number of version of all projects in the workspace with no additional cost
|
||||
"""
|
||||
max: Int!
|
||||
}
|
||||
|
||||
enum Currency {
|
||||
GBP
|
||||
USD
|
||||
EUR
|
||||
}
|
||||
|
||||
type WorkspaceCostItem {
|
||||
count: Int!
|
||||
name: String!
|
||||
cost: Float!
|
||||
label: String!
|
||||
}
|
||||
|
||||
type WorkspaceCostDiscount {
|
||||
name: String!
|
||||
amount: Float!
|
||||
}
|
||||
|
||||
type WorkspaceCost {
|
||||
"""
|
||||
Estimated cost of the workspace with no discount applied
|
||||
"""
|
||||
subTotal: Float!
|
||||
"""
|
||||
Currency of the price
|
||||
"""
|
||||
currency: Currency!
|
||||
items: [WorkspaceCostItem!]!
|
||||
"""
|
||||
Discount applied to the total
|
||||
"""
|
||||
discount: WorkspaceCostDiscount
|
||||
"""
|
||||
Total cost with discount applied
|
||||
"""
|
||||
total: Float!
|
||||
}
|
||||
|
||||
type WorkspaceBilling {
|
||||
versionsCount: WorkspaceVersionsCount!
|
||||
cost: WorkspaceCost!
|
||||
}
|
||||
|
||||
type Workspace {
|
||||
id: ID!
|
||||
name: String!
|
||||
|
@ -324,10 +270,6 @@ type Workspace {
|
|||
filter: WorkspaceProjectsFilter
|
||||
): ProjectCollection!
|
||||
"""
|
||||
Billing data for Workspaces beta
|
||||
"""
|
||||
billing: WorkspaceBilling @hasWorkspaceRole(role: MEMBER)
|
||||
"""
|
||||
Information about the workspace's SSO configuration and the current user's SSO session, if present
|
||||
"""
|
||||
sso: WorkspaceSso
|
||||
|
|
|
@ -56,7 +56,6 @@ generates:
|
|||
ProjectAutomationsUpdatedMessage: '@/modules/automate/helpers/graphTypes#ProjectAutomationsUpdatedMessageGraphQLReturn'
|
||||
UserAutomateInfo: '@/modules/automate/helpers/graphTypes#UserAutomateInfoGraphQLReturn'
|
||||
Workspace: '@/modules/workspacesCore/helpers/graphTypes#WorkspaceGraphQLReturn'
|
||||
WorkspaceBilling: '@/modules/workspacesCore/helpers/graphTypes#WorkspaceBillingGraphQLReturn'
|
||||
WorkspaceSso: '@/modules/workspacesCore/helpers/graphTypes#WorkspaceSsoGraphQLReturn'
|
||||
WorkspaceMutations: '@/modules/workspacesCore/helpers/graphTypes#WorkspaceMutationsGraphQLReturn'
|
||||
WorkspaceInviteMutations: '@/modules/workspacesCore/helpers/graphTypes#WorkspaceInviteMutationsGraphQLReturn'
|
||||
|
|
|
@ -5,7 +5,7 @@ import { CommentReplyAuthorCollectionGraphQLReturn, CommentGraphQLReturn } from
|
|||
import { PendingStreamCollaboratorGraphQLReturn } from '@/modules/serverinvites/helpers/graphTypes';
|
||||
import { FileUploadGraphQLReturn } from '@/modules/fileuploads/helpers/types';
|
||||
import { AutomateFunctionGraphQLReturn, AutomateFunctionReleaseGraphQLReturn, AutomationGraphQLReturn, AutomationRevisionGraphQLReturn, AutomationRevisionFunctionGraphQLReturn, AutomateRunGraphQLReturn, AutomationRunTriggerGraphQLReturn, AutomationRevisionTriggerDefinitionGraphQLReturn, AutomateFunctionRunGraphQLReturn, TriggeredAutomationsStatusGraphQLReturn, ProjectAutomationMutationsGraphQLReturn, ProjectTriggeredAutomationsStatusUpdatedMessageGraphQLReturn, ProjectAutomationsUpdatedMessageGraphQLReturn, UserAutomateInfoGraphQLReturn } from '@/modules/automate/helpers/graphTypes';
|
||||
import { WorkspaceGraphQLReturn, WorkspaceBillingGraphQLReturn, WorkspaceSsoGraphQLReturn, WorkspaceMutationsGraphQLReturn, WorkspaceInviteMutationsGraphQLReturn, WorkspaceProjectMutationsGraphQLReturn, PendingWorkspaceCollaboratorGraphQLReturn, WorkspaceCollaboratorGraphQLReturn, ProjectRoleGraphQLReturn } from '@/modules/workspacesCore/helpers/graphTypes';
|
||||
import { WorkspaceGraphQLReturn, WorkspaceSsoGraphQLReturn, WorkspaceMutationsGraphQLReturn, WorkspaceInviteMutationsGraphQLReturn, WorkspaceProjectMutationsGraphQLReturn, PendingWorkspaceCollaboratorGraphQLReturn, WorkspaceCollaboratorGraphQLReturn, ProjectRoleGraphQLReturn } from '@/modules/workspacesCore/helpers/graphTypes';
|
||||
import { WorkspaceBillingMutationsGraphQLReturn } from '@/modules/gatekeeper/helpers/graphTypes';
|
||||
import { WebhookGraphQLReturn } from '@/modules/webhooks/helpers/graphTypes';
|
||||
import { SmartTextEditorValueGraphQLReturn } from '@/modules/core/services/richTextEditorService';
|
||||
|
@ -4029,8 +4029,6 @@ export type Workspace = {
|
|||
__typename?: 'Workspace';
|
||||
/** Regions available to the workspace for project data residency */
|
||||
availableRegions: Array<ServerRegionItem>;
|
||||
/** Billing data for Workspaces beta */
|
||||
billing?: Maybe<WorkspaceBilling>;
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
customerPortalUrl?: Maybe<Scalars['String']['output']>;
|
||||
/** Selected fallback when `logo` not set */
|
||||
|
@ -4092,12 +4090,6 @@ export type WorkspaceTeamArgs = {
|
|||
limit?: Scalars['Int']['input'];
|
||||
};
|
||||
|
||||
export type WorkspaceBilling = {
|
||||
__typename?: 'WorkspaceBilling';
|
||||
cost: WorkspaceCost;
|
||||
versionsCount: WorkspaceVersionsCount;
|
||||
};
|
||||
|
||||
export type WorkspaceBillingMutations = {
|
||||
__typename?: 'WorkspaceBillingMutations';
|
||||
cancelCheckoutSession: Scalars['Boolean']['output'];
|
||||
|
@ -4792,7 +4784,6 @@ export type ResolversTypes = {
|
|||
WebhookEventCollection: ResolverTypeWrapper<WebhookEventCollection>;
|
||||
WebhookUpdateInput: WebhookUpdateInput;
|
||||
Workspace: ResolverTypeWrapper<WorkspaceGraphQLReturn>;
|
||||
WorkspaceBilling: ResolverTypeWrapper<WorkspaceBillingGraphQLReturn>;
|
||||
WorkspaceBillingMutations: ResolverTypeWrapper<WorkspaceBillingMutationsGraphQLReturn>;
|
||||
WorkspaceCollaborator: ResolverTypeWrapper<WorkspaceCollaboratorGraphQLReturn>;
|
||||
WorkspaceCollaboratorCollection: ResolverTypeWrapper<Omit<WorkspaceCollaboratorCollection, 'items'> & { items: Array<ResolversTypes['WorkspaceCollaborator']> }>;
|
||||
|
@ -5053,7 +5044,6 @@ export type ResolversParentTypes = {
|
|||
WebhookEventCollection: WebhookEventCollection;
|
||||
WebhookUpdateInput: WebhookUpdateInput;
|
||||
Workspace: WorkspaceGraphQLReturn;
|
||||
WorkspaceBilling: WorkspaceBillingGraphQLReturn;
|
||||
WorkspaceBillingMutations: WorkspaceBillingMutationsGraphQLReturn;
|
||||
WorkspaceCollaborator: WorkspaceCollaboratorGraphQLReturn;
|
||||
WorkspaceCollaboratorCollection: Omit<WorkspaceCollaboratorCollection, 'items'> & { items: Array<ResolversParentTypes['WorkspaceCollaborator']> };
|
||||
|
@ -6467,7 +6457,6 @@ export type WebhookEventCollectionResolvers<ContextType = GraphQLContext, Parent
|
|||
|
||||
export type WorkspaceResolvers<ContextType = GraphQLContext, ParentType extends ResolversParentTypes['Workspace'] = ResolversParentTypes['Workspace']> = {
|
||||
availableRegions?: Resolver<Array<ResolversTypes['ServerRegionItem']>, ParentType, ContextType>;
|
||||
billing?: Resolver<Maybe<ResolversTypes['WorkspaceBilling']>, ParentType, ContextType>;
|
||||
createdAt?: Resolver<ResolversTypes['DateTime'], ParentType, ContextType>;
|
||||
customerPortalUrl?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
||||
defaultLogoIndex?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
||||
|
@ -6493,12 +6482,6 @@ export type WorkspaceResolvers<ContextType = GraphQLContext, ParentType extends
|
|||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type WorkspaceBillingResolvers<ContextType = GraphQLContext, ParentType extends ResolversParentTypes['WorkspaceBilling'] = ResolversParentTypes['WorkspaceBilling']> = {
|
||||
cost?: Resolver<ResolversTypes['WorkspaceCost'], ParentType, ContextType>;
|
||||
versionsCount?: Resolver<ResolversTypes['WorkspaceVersionsCount'], ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type WorkspaceBillingMutationsResolvers<ContextType = GraphQLContext, ParentType extends ResolversParentTypes['WorkspaceBillingMutations'] = ResolversParentTypes['WorkspaceBillingMutations']> = {
|
||||
cancelCheckoutSession?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType, RequireFields<WorkspaceBillingMutationsCancelCheckoutSessionArgs, 'input'>>;
|
||||
createCheckoutSession?: Resolver<ResolversTypes['CheckoutSession'], ParentType, ContextType, RequireFields<WorkspaceBillingMutationsCreateCheckoutSessionArgs, 'input'>>;
|
||||
|
@ -6763,7 +6746,6 @@ export type Resolvers<ContextType = GraphQLContext> = {
|
|||
WebhookEvent?: WebhookEventResolvers<ContextType>;
|
||||
WebhookEventCollection?: WebhookEventCollectionResolvers<ContextType>;
|
||||
Workspace?: WorkspaceResolvers<ContextType>;
|
||||
WorkspaceBilling?: WorkspaceBillingResolvers<ContextType>;
|
||||
WorkspaceBillingMutations?: WorkspaceBillingMutationsResolvers<ContextType>;
|
||||
WorkspaceCollaborator?: WorkspaceCollaboratorResolvers<ContextType>;
|
||||
WorkspaceCollaboratorCollection?: WorkspaceCollaboratorCollectionResolvers<ContextType>;
|
||||
|
|
|
@ -4010,8 +4010,6 @@ export type Workspace = {
|
|||
__typename?: 'Workspace';
|
||||
/** Regions available to the workspace for project data residency */
|
||||
availableRegions: Array<ServerRegionItem>;
|
||||
/** Billing data for Workspaces beta */
|
||||
billing?: Maybe<WorkspaceBilling>;
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
customerPortalUrl?: Maybe<Scalars['String']['output']>;
|
||||
/** Selected fallback when `logo` not set */
|
||||
|
@ -4073,12 +4071,6 @@ export type WorkspaceTeamArgs = {
|
|||
limit?: Scalars['Int']['input'];
|
||||
};
|
||||
|
||||
export type WorkspaceBilling = {
|
||||
__typename?: 'WorkspaceBilling';
|
||||
cost: WorkspaceCost;
|
||||
versionsCount: WorkspaceVersionsCount;
|
||||
};
|
||||
|
||||
export type WorkspaceBillingMutations = {
|
||||
__typename?: 'WorkspaceBillingMutations';
|
||||
cancelCheckoutSession: Scalars['Boolean']['output'];
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export const WORKSPACE_MAX_PROJECTS_VERSIONS = 500
|
|
@ -30,7 +30,7 @@ import {
|
|||
deleteInviteFactory as deleteInviteFromDbFactory,
|
||||
queryAllUserResourceInvitesFactory,
|
||||
queryAllResourceInvitesFactory,
|
||||
markInviteUpdatedfactory,
|
||||
markInviteUpdatedFactory,
|
||||
deleteServerOnlyInvitesFactory,
|
||||
updateAllInviteTargetsFactory
|
||||
} from '@/modules/serverinvites/repositories/serverInvites'
|
||||
|
@ -384,7 +384,7 @@ export = {
|
|||
}),
|
||||
findUserByTarget: findUserByTargetFactory({ db }),
|
||||
findInvite: findInviteFactory({ db }),
|
||||
markInviteUpdated: markInviteUpdatedfactory({ db }),
|
||||
markInviteUpdated: markInviteUpdatedFactory({ db }),
|
||||
getUser,
|
||||
getServerInfo
|
||||
})
|
||||
|
|
|
@ -501,7 +501,7 @@ export const findInviteByTokenFactory =
|
|||
return (await q) || null
|
||||
}
|
||||
|
||||
export const markInviteUpdatedfactory =
|
||||
export const markInviteUpdatedFactory =
|
||||
({ db }: { db: Knex }): MarkInviteUpdated =>
|
||||
async ({ inviteId }) => {
|
||||
const cols = ServerInvites.with({ withoutTablePrefix: true }).col
|
||||
|
|
|
@ -239,10 +239,6 @@ export type EmitWorkspaceEvent = <TEvent extends WorkspaceEvents>(args: {
|
|||
payload: EventBusPayloads[TEvent]
|
||||
}) => Promise<void>
|
||||
|
||||
export type CountProjectsVersionsByWorkspaceId = (args: {
|
||||
workspaceId: string
|
||||
}) => Promise<number>
|
||||
|
||||
export type CountWorkspaceRoleWithOptionalProjectRole = (args: {
|
||||
workspaceId: string
|
||||
workspaceRole: WorkspaceRoles
|
||||
|
|
|
@ -113,3 +113,9 @@ export class WorkspaceDomainsInvalidState extends BaseError {
|
|||
static code = 'WORKSPACE_NO_VERIFIED_DOMAINS'
|
||||
static statusCode = 500
|
||||
}
|
||||
|
||||
export class WorkspacePaidPlanActiveError extends BaseError {
|
||||
static defaultMessage = 'Workspace has an active paid plan, cancel it first'
|
||||
static code = 'WORKSPACE_PAID_PLAN_ACTIVE'
|
||||
static statusCode = 400
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import {
|
|||
findInviteFactory,
|
||||
findUserByTargetFactory,
|
||||
insertInviteAndDeleteOldFactory,
|
||||
markInviteUpdatedfactory,
|
||||
markInviteUpdatedFactory,
|
||||
queryAllResourceInvitesFactory,
|
||||
queryAllUserResourceInvitesFactory,
|
||||
updateAllInviteTargetsFactory
|
||||
|
@ -49,6 +49,7 @@ import {
|
|||
WorkspaceInvalidRoleError,
|
||||
WorkspaceJoinNotAllowedError,
|
||||
WorkspaceNotFoundError,
|
||||
WorkspacePaidPlanActiveError,
|
||||
WorkspacesNotAuthorizedError,
|
||||
WorkspacesNotYetImplementedError
|
||||
} from '@/modules/workspaces/errors/workspace'
|
||||
|
@ -68,11 +69,9 @@ import {
|
|||
getWorkspaceDomainsFactory,
|
||||
getUserDiscoverableWorkspacesFactory,
|
||||
getWorkspaceWithDomainsFactory,
|
||||
countProjectsVersionsByWorkspaceIdFactory,
|
||||
countWorkspaceRoleWithOptionalProjectRoleFactory,
|
||||
getUserIdsWithRoleInWorkspaceFactory,
|
||||
getWorkspaceRoleForUserFactory,
|
||||
getWorkspaceBySlugFactory
|
||||
getWorkspaceBySlugFactory,
|
||||
countDomainsByWorkspaceIdFactory
|
||||
} from '@/modules/workspaces/repositories/workspaces'
|
||||
import {
|
||||
buildWorkspaceInviteEmailContentsFactory,
|
||||
|
@ -106,7 +105,12 @@ import {
|
|||
getPaginatedWorkspaceTeamFactory,
|
||||
getWorkspacesForUserFactory
|
||||
} from '@/modules/workspaces/services/retrieval'
|
||||
import { Roles, WorkspaceRoles, removeNullOrUndefinedKeys } from '@speckle/shared'
|
||||
import {
|
||||
Roles,
|
||||
WorkspaceRoles,
|
||||
removeNullOrUndefinedKeys,
|
||||
throwUncoveredError
|
||||
} from '@speckle/shared'
|
||||
import { chunk } from 'lodash'
|
||||
import {
|
||||
findEmailsByUserIdFactory,
|
||||
|
@ -118,11 +122,6 @@ import {
|
|||
import { joinWorkspaceFactory } from '@/modules/workspaces/services/join'
|
||||
import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userEmails'
|
||||
import { requestNewEmailVerificationFactory } from '@/modules/emails/services/verification/request'
|
||||
import { WORKSPACE_MAX_PROJECTS_VERSIONS } from '@/modules/gatekeeper/domain/constants'
|
||||
import {
|
||||
getWorkspaceCostFactory,
|
||||
getWorkspaceCostItemsFactory
|
||||
} from '@/modules/workspaces/services/cost'
|
||||
import {
|
||||
deleteWorkspaceDomainFactory,
|
||||
isUserWorkspaceDomainPolicyCompliantFactory
|
||||
|
@ -162,7 +161,7 @@ import {
|
|||
} from '@/modules/core/services/ratelimiter'
|
||||
import { RateLimitError } from '@/modules/core/errors/ratelimit'
|
||||
import { ProjectsEmitter } from '@/modules/core/events/projectsEmitter'
|
||||
import { getDb } from '@/modules/multiregion/dbSelector'
|
||||
import { getDb, getRegionDb } from '@/modules/multiregion/dbSelector'
|
||||
import { createNewProjectFactory } from '@/modules/core/services/projects'
|
||||
import {
|
||||
deleteProjectFactory,
|
||||
|
@ -184,6 +183,8 @@ import {
|
|||
import { getDecryptor } from '@/modules/workspaces/helpers/sso'
|
||||
import { getDefaultRegionFactory } from '@/modules/workspaces/repositories/regions'
|
||||
import { storeModelFactory } from '@/modules/core/repositories/models'
|
||||
import { getWorkspacePlanFactory } from '@/modules/gatekeeper/repositories/billing'
|
||||
import { Knex } from 'knex'
|
||||
|
||||
const eventBus = getEventBus()
|
||||
const getServerInfo = getServerInfoFactory({ db })
|
||||
|
@ -241,7 +242,6 @@ const buildCreateAndSendWorkspaceInvite = () =>
|
|||
getUser,
|
||||
getServerInfo
|
||||
})
|
||||
const deleteStream = deleteStreamFactory({ db })
|
||||
const saveActivity = saveActivityFactory({ db })
|
||||
const validateStreamAccess = validateStreamAccessFactory({ authorizeResolver })
|
||||
const isStreamCollaborator = isStreamCollaboratorFactory({
|
||||
|
@ -448,18 +448,51 @@ export = FF_WORKSPACES_MODULE_ENABLED
|
|||
context.resourceAccessRules
|
||||
)
|
||||
|
||||
// Delete workspace and associated resources (i.e. invites)
|
||||
const deleteWorkspace = deleteWorkspaceFactory({
|
||||
deleteWorkspace: repoDeleteWorkspaceFactory({ db }),
|
||||
deleteProject: deleteStream,
|
||||
deleteAllResourceInvites: deleteAllResourceInvitesFactory({ db }),
|
||||
queryAllWorkspaceProjects: queryAllWorkspaceProjectsFactory({
|
||||
getStreams: legacyGetStreamsFactory({ db })
|
||||
}),
|
||||
deleteSsoProvider: deleteSsoProviderFactory({ db })
|
||||
})
|
||||
const workspacePlan = await getWorkspacePlanFactory({ db })({ workspaceId })
|
||||
if (workspacePlan) {
|
||||
switch (workspacePlan.name) {
|
||||
case 'team':
|
||||
case 'pro':
|
||||
case 'business':
|
||||
switch (workspacePlan.status) {
|
||||
case 'cancelationScheduled':
|
||||
case 'valid':
|
||||
case 'paymentFailed':
|
||||
throw new WorkspacePaidPlanActiveError()
|
||||
case 'canceled':
|
||||
case 'trial':
|
||||
case 'expired':
|
||||
break
|
||||
default:
|
||||
throwUncoveredError(workspacePlan)
|
||||
}
|
||||
case 'unlimited':
|
||||
case 'academia':
|
||||
break
|
||||
default:
|
||||
throwUncoveredError(workspacePlan)
|
||||
}
|
||||
}
|
||||
|
||||
await deleteWorkspace({ workspaceId })
|
||||
const deleteWorkspaceFrom = (db: Knex) =>
|
||||
deleteWorkspaceFactory({
|
||||
deleteWorkspace: repoDeleteWorkspaceFactory({ db }),
|
||||
deleteProject: deleteStreamFactory({ db }),
|
||||
deleteAllResourceInvites: deleteAllResourceInvitesFactory({ db }),
|
||||
queryAllWorkspaceProjects: queryAllWorkspaceProjectsFactory({
|
||||
getStreams: legacyGetStreamsFactory({ db })
|
||||
}),
|
||||
deleteSsoProvider: deleteSsoProviderFactory({ db })
|
||||
})
|
||||
|
||||
// this should be turned into a get all regions and map over the regions...
|
||||
const region = await getDefaultRegionFactory({ db })({ workspaceId })
|
||||
if (region) {
|
||||
const regionDb = await getRegionDb({ regionKey: region.key })
|
||||
await deleteWorkspaceFrom(regionDb)({ workspaceId })
|
||||
}
|
||||
|
||||
await deleteWorkspaceFrom(db)({ workspaceId })
|
||||
|
||||
return true
|
||||
},
|
||||
|
@ -570,7 +603,7 @@ export = FF_WORKSPACES_MODULE_ENABLED
|
|||
)
|
||||
await deleteWorkspaceDomainFactory({
|
||||
deleteWorkspaceDomain: repoDeleteWorkspaceDomainFactory({ db }),
|
||||
countDomainsByWorkspaceId: countProjectsVersionsByWorkspaceIdFactory({
|
||||
countDomainsByWorkspaceId: countDomainsByWorkspaceIdFactory({
|
||||
db
|
||||
}),
|
||||
updateWorkspace: updateWorkspaceFactory({
|
||||
|
@ -656,7 +689,7 @@ export = FF_WORKSPACES_MODULE_ENABLED
|
|||
db,
|
||||
filterQuery: workspaceInviteValidityFilter
|
||||
}),
|
||||
markInviteUpdated: markInviteUpdatedfactory({ db }),
|
||||
markInviteUpdated: markInviteUpdatedFactory({ db }),
|
||||
getUser,
|
||||
getServerInfo
|
||||
})
|
||||
|
@ -956,35 +989,12 @@ export = FF_WORKSPACES_MODULE_ENABLED
|
|||
domains: async (parent) => {
|
||||
return await getWorkspaceDomainsFactory({ db })({ workspaceIds: [parent.id] })
|
||||
},
|
||||
billing: (parent) => ({ parent }),
|
||||
sso: async (parent) => {
|
||||
return await getWorkspaceSsoProviderRecordFactory({ db })({
|
||||
workspaceId: parent.id
|
||||
})
|
||||
}
|
||||
},
|
||||
WorkspaceBilling: {
|
||||
versionsCount: async ({ parent }) => {
|
||||
const workspaceId = parent.id
|
||||
return {
|
||||
current: await countProjectsVersionsByWorkspaceIdFactory({ db })({
|
||||
workspaceId
|
||||
}),
|
||||
max: WORKSPACE_MAX_PROJECTS_VERSIONS
|
||||
}
|
||||
},
|
||||
cost: async ({ parent }) => {
|
||||
const workspaceId = parent.id
|
||||
return getWorkspaceCostFactory({
|
||||
getWorkspaceCostItems: getWorkspaceCostItemsFactory({
|
||||
countRole: countWorkspaceRoleWithOptionalProjectRoleFactory({ db }),
|
||||
getUserIdsWithRoleInWorkspace: getUserIdsWithRoleInWorkspaceFactory({
|
||||
db
|
||||
})
|
||||
})
|
||||
})({ workspaceId })
|
||||
}
|
||||
},
|
||||
WorkspaceSso: {
|
||||
provider: async ({ workspaceId }) => {
|
||||
const provider = await getWorkspaceSsoProviderFactory({
|
||||
|
|
|
@ -6,7 +6,6 @@ import {
|
|||
} from '@/modules/workspacesCore/domain/types'
|
||||
import {
|
||||
CountDomainsByWorkspaceId,
|
||||
CountProjectsVersionsByWorkspaceId,
|
||||
CountWorkspaceRoleWithOptionalProjectRole,
|
||||
DeleteWorkspace,
|
||||
DeleteWorkspaceDomain,
|
||||
|
@ -42,7 +41,6 @@ import {
|
|||
ServerAcl,
|
||||
ServerInvites,
|
||||
StreamAcl,
|
||||
StreamCommits,
|
||||
Streams,
|
||||
Users
|
||||
} from '@/modules/core/dbSchema'
|
||||
|
@ -388,18 +386,6 @@ export const getWorkspaceWithDomainsFactory =
|
|||
} as Workspace & { domains: WorkspaceDomain[] }
|
||||
}
|
||||
|
||||
export const countProjectsVersionsByWorkspaceIdFactory =
|
||||
({ db }: { db: Knex }): CountProjectsVersionsByWorkspaceId =>
|
||||
async ({ workspaceId }) => {
|
||||
const [res] = await tables
|
||||
.streams(db)
|
||||
.join(StreamCommits.name, StreamCommits.col.streamId, Streams.col.id)
|
||||
.where({ workspaceId })
|
||||
.count(StreamCommits.col.commitId)
|
||||
|
||||
return parseInt(res.count.toString())
|
||||
}
|
||||
|
||||
export const getUserIdsWithRoleInWorkspaceFactory =
|
||||
({ db }: { db: Knex }): GetUserIdsWithRoleInWorkspace =>
|
||||
async ({ workspaceId, workspaceRole }, options) => {
|
||||
|
|
|
@ -1,168 +0,0 @@
|
|||
import {
|
||||
CountWorkspaceRoleWithOptionalProjectRole,
|
||||
GetUserIdsWithRoleInWorkspace
|
||||
} from '@/modules/workspaces/domain/operations'
|
||||
import { Roles, throwUncoveredError } from '@speckle/shared'
|
||||
|
||||
type KnownWorkspaceCostItemNames =
|
||||
| 'workspace-members'
|
||||
| 'free-guests'
|
||||
| 'read-write-guests'
|
||||
| 'read-only-guests'
|
||||
|
||||
type KnownCurrencies = 'GBP'
|
||||
|
||||
type WorkspaceCostItem = {
|
||||
name: KnownWorkspaceCostItemNames
|
||||
description: string
|
||||
count: number
|
||||
cost: number
|
||||
label: string
|
||||
}
|
||||
|
||||
const getWorkspaceCostItemCost = ({
|
||||
name
|
||||
}: {
|
||||
name: KnownWorkspaceCostItemNames
|
||||
currency?: KnownCurrencies
|
||||
}): number => {
|
||||
switch (name) {
|
||||
case 'workspace-members':
|
||||
return 49
|
||||
case 'free-guests':
|
||||
return 0
|
||||
case 'read-write-guests':
|
||||
return 15
|
||||
case 'read-only-guests':
|
||||
return 5
|
||||
default:
|
||||
throwUncoveredError(name)
|
||||
}
|
||||
}
|
||||
|
||||
type GetWorkspaceCostItems = (args: {
|
||||
workspaceId: string
|
||||
}) => Promise<WorkspaceCostItem[]>
|
||||
|
||||
export const getWorkspaceCostItemsFactory =
|
||||
({
|
||||
countRole,
|
||||
getUserIdsWithRoleInWorkspace
|
||||
}: {
|
||||
countRole: CountWorkspaceRoleWithOptionalProjectRole
|
||||
getUserIdsWithRoleInWorkspace: GetUserIdsWithRoleInWorkspace
|
||||
}): GetWorkspaceCostItems =>
|
||||
async ({ workspaceId }) => {
|
||||
const freeGuestsIds = await getUserIdsWithRoleInWorkspace(
|
||||
{
|
||||
workspaceId,
|
||||
workspaceRole: Roles.Workspace.Guest
|
||||
},
|
||||
{ limit: 10 }
|
||||
)
|
||||
const [adminCount, memberCount, writeGuestCount, readGuestCount] =
|
||||
await Promise.all([
|
||||
countRole({ workspaceId, workspaceRole: Roles.Workspace.Admin }),
|
||||
countRole({ workspaceId, workspaceRole: Roles.Workspace.Member }),
|
||||
countRole({
|
||||
workspaceId,
|
||||
workspaceRole: Roles.Workspace.Guest,
|
||||
projectRole: Roles.Stream.Contributor,
|
||||
skipUserIds: freeGuestsIds
|
||||
}),
|
||||
countRole({
|
||||
workspaceId,
|
||||
workspaceRole: Roles.Workspace.Guest,
|
||||
projectRole: Roles.Stream.Reviewer,
|
||||
skipUserIds: freeGuestsIds
|
||||
})
|
||||
])
|
||||
|
||||
const workspaceCostItems: WorkspaceCostItem[] = []
|
||||
|
||||
const workspaceMembersCount = adminCount + memberCount
|
||||
const freeGuestsCount = freeGuestsIds.length
|
||||
|
||||
workspaceCostItems.push({
|
||||
name: 'workspace-members',
|
||||
description: 'General workspace member',
|
||||
count: workspaceMembersCount,
|
||||
cost: getWorkspaceCostItemCost({ name: 'workspace-members' }),
|
||||
label: `${workspaceMembersCount} workspace ${
|
||||
workspaceMembersCount === 1 ? 'member' : 'members'
|
||||
}`
|
||||
})
|
||||
workspaceCostItems.push({
|
||||
name: 'free-guests',
|
||||
description: 'The first 10 workspace guests are free',
|
||||
count: freeGuestsCount,
|
||||
cost: getWorkspaceCostItemCost({ name: 'free-guests' }),
|
||||
label: `${freeGuestsCount}/10 free ${freeGuestsCount === 1 ? 'guest' : 'guests'}`
|
||||
})
|
||||
workspaceCostItems.push({
|
||||
name: 'read-write-guests',
|
||||
description: 'Workspace guests with write access to minimum 1 workspace project',
|
||||
count: writeGuestCount,
|
||||
cost: getWorkspaceCostItemCost({ name: 'read-write-guests' }),
|
||||
label: `${writeGuestCount} read/write ${
|
||||
writeGuestCount === 1 ? 'guest' : 'guests'
|
||||
}`
|
||||
})
|
||||
workspaceCostItems.push({
|
||||
name: 'read-only-guests',
|
||||
description: 'Workspace guests with only read access to some workspace projects',
|
||||
count: readGuestCount,
|
||||
cost: getWorkspaceCostItemCost({ name: 'read-only-guests' }),
|
||||
label: `${readGuestCount} read only ${readGuestCount === 1 ? 'guest' : 'guests'}`
|
||||
})
|
||||
|
||||
return workspaceCostItems
|
||||
}
|
||||
|
||||
type WorkspaceDiscount = {
|
||||
name: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
type WorkspaceCost = {
|
||||
subTotal: number
|
||||
currency: KnownCurrencies
|
||||
items: WorkspaceCostItem[]
|
||||
total: number
|
||||
discount?: WorkspaceDiscount
|
||||
}
|
||||
|
||||
export const calculateWorkspaceTotalCost = ({
|
||||
subTotal,
|
||||
discount
|
||||
}: Pick<WorkspaceCost, 'subTotal' | 'discount'>) => {
|
||||
if (!discount) {
|
||||
return subTotal
|
||||
}
|
||||
return subTotal * discount?.amount
|
||||
}
|
||||
|
||||
export const getWorkspaceCostFactory =
|
||||
({
|
||||
getWorkspaceCostItems,
|
||||
discount
|
||||
}: {
|
||||
getWorkspaceCostItems: GetWorkspaceCostItems
|
||||
discount?: WorkspaceDiscount
|
||||
}) =>
|
||||
async ({ workspaceId }: { workspaceId: string }): Promise<WorkspaceCost> => {
|
||||
const items = await getWorkspaceCostItems({ workspaceId })
|
||||
|
||||
const subTotal = items.reduce((acc, { cost, count }) => acc + cost * count, 0)
|
||||
|
||||
return {
|
||||
currency: 'GBP',
|
||||
items,
|
||||
subTotal,
|
||||
discount,
|
||||
total: calculateWorkspaceTotalCost({
|
||||
subTotal,
|
||||
discount
|
||||
})
|
||||
}
|
||||
}
|
|
@ -31,31 +31,6 @@ export const basicPendingWorkspaceCollaboratorFragment = gql`
|
|||
}
|
||||
`
|
||||
|
||||
export const workspaceBillingFragment = gql`
|
||||
fragment WorkspaceBilling on Workspace {
|
||||
billing {
|
||||
versionsCount {
|
||||
current
|
||||
max
|
||||
}
|
||||
cost {
|
||||
subTotal
|
||||
currency
|
||||
items {
|
||||
count
|
||||
name
|
||||
cost
|
||||
label
|
||||
}
|
||||
discount {
|
||||
name
|
||||
amount
|
||||
}
|
||||
total
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
export const workspaceProjectsFragment = gql`
|
||||
fragment WorkspaceProjects on ProjectCollection {
|
||||
items {
|
||||
|
@ -122,17 +97,6 @@ export const getWorkspaceWithTeamQuery = gql`
|
|||
${basicPendingWorkspaceCollaboratorFragment}
|
||||
`
|
||||
|
||||
export const getWorkspaceWithBillingQuery = gql`
|
||||
query GetWorkspaceWithBilling($workspaceId: String!) {
|
||||
workspace(id: $workspaceId) {
|
||||
...BasicWorkspace
|
||||
...WorkspaceBilling
|
||||
}
|
||||
}
|
||||
${basicWorkspaceFragment}
|
||||
${workspaceBillingFragment}
|
||||
`
|
||||
|
||||
export const getWorkspaceWithProjectsQuery = gql`
|
||||
query GetWorkspaceWithProjects($workspaceId: String!) {
|
||||
workspace(id: $workspaceId) {
|
||||
|
|
|
@ -23,9 +23,6 @@ import {
|
|||
UpdateWorkspaceDocument,
|
||||
UpdateWorkspaceRoleDocument,
|
||||
ActiveUserLeaveWorkspaceDocument,
|
||||
GetWorkspaceWithBillingDocument,
|
||||
CreateObjectDocument,
|
||||
CreateProjectVersionDocument,
|
||||
GetWorkspaceWithProjectsDocument,
|
||||
AddWorkspaceDomainDocument,
|
||||
DeleteWorkspaceDomainDocument,
|
||||
|
@ -50,62 +47,9 @@ import {
|
|||
} from '@/modules/core/helpers/testHelpers'
|
||||
import { getWorkspaceFactory } from '@/modules/workspaces/repositories/workspaces'
|
||||
import { grantStreamPermissionsFactory } from '@/modules/core/repositories/streams'
|
||||
import { getPaginatedStreamBranchesFactory } from '@/modules/core/services/branch/retrieval'
|
||||
import {
|
||||
getPaginatedStreamBranchesPageFactory,
|
||||
getStreamBranchCountFactory
|
||||
} from '@/modules/core/repositories/branches'
|
||||
|
||||
const getBranchesByStreamId = getPaginatedStreamBranchesFactory({
|
||||
getPaginatedStreamBranchesPage: getPaginatedStreamBranchesPageFactory({ db }),
|
||||
getStreamBranchCount: getStreamBranchCountFactory({ db })
|
||||
})
|
||||
const grantStreamPermissions = grantStreamPermissionsFactory({ db })
|
||||
|
||||
const createProjectWithVersions =
|
||||
({ apollo }: { apollo: TestApolloServer }) =>
|
||||
async ({
|
||||
workspaceId,
|
||||
versionsCount
|
||||
}: {
|
||||
workspaceId: string
|
||||
versionsCount: number
|
||||
}) => {
|
||||
const resProject1 = await apollo.execute(CreateWorkspaceProjectDocument, {
|
||||
input: {
|
||||
name: createRandomPassword(),
|
||||
workspaceId
|
||||
}
|
||||
})
|
||||
expect(resProject1).to.not.haveGraphQLErrors()
|
||||
const project1Id = resProject1.data!.workspaceMutations.projects.create.id
|
||||
|
||||
const {
|
||||
items: [model1]
|
||||
} = await getBranchesByStreamId(project1Id, { limit: 1, cursor: null })
|
||||
expect(model1).to.exist
|
||||
|
||||
const resObj1 = await apollo.execute(CreateObjectDocument, {
|
||||
input: {
|
||||
streamId: project1Id,
|
||||
objects: [{ some: 'obj' }]
|
||||
}
|
||||
})
|
||||
expect(resObj1).to.not.haveGraphQLErrors()
|
||||
|
||||
await Promise.all(
|
||||
new Array(versionsCount).fill(0).map(async () => {
|
||||
const res = await apollo.execute(CreateProjectVersionDocument, {
|
||||
input: {
|
||||
projectId: project1Id,
|
||||
modelId: model1.id,
|
||||
objectId: resObj1.data!.objectCreate[0]
|
||||
}
|
||||
})
|
||||
expect(res).to.not.haveGraphQLErrors()
|
||||
})
|
||||
)
|
||||
}
|
||||
describe('Workspaces GQL CRUD', () => {
|
||||
let apollo: TestApolloServer
|
||||
|
||||
|
@ -544,159 +488,53 @@ describe('Workspaces GQL CRUD', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('query workspace.billing', () => {
|
||||
it('should return workspace version limits', async () => {
|
||||
await createProjectWithVersions({ apollo })({
|
||||
workspaceId: workspace.id,
|
||||
versionsCount: 3
|
||||
})
|
||||
await createProjectWithVersions({ apollo })({
|
||||
workspaceId: workspace.id,
|
||||
versionsCount: 2
|
||||
})
|
||||
|
||||
const res = await apollo.execute(GetWorkspaceWithBillingDocument, {
|
||||
workspaceId: workspace.id
|
||||
})
|
||||
|
||||
expect(res).to.not.haveGraphQLErrors()
|
||||
expect(res.data?.workspace.billing?.versionsCount).to.deep.equal({
|
||||
current: 5,
|
||||
max: 500
|
||||
})
|
||||
})
|
||||
|
||||
it('should return workspace cost', async () => {
|
||||
const createRes = await apollo.execute(CreateWorkspaceDocument, {
|
||||
input: {
|
||||
name: createRandomString(),
|
||||
slug: cryptoRandomString({ length: 10 })
|
||||
}
|
||||
})
|
||||
expect(createRes).to.not.haveGraphQLErrors()
|
||||
const workspaceId = createRes.data!.workspaceMutations.create.id
|
||||
const workspace = (await getWorkspaceFactory({ db })({
|
||||
workspaceId
|
||||
})) as unknown as BasicTestWorkspace
|
||||
|
||||
const member = {
|
||||
id: createRandomString(),
|
||||
name: createRandomPassword(),
|
||||
email: createRandomEmail()
|
||||
}
|
||||
const freeGuests = new Array(10).fill(0).map(() => ({
|
||||
id: createRandomString(),
|
||||
name: createRandomPassword(),
|
||||
email: createRandomEmail()
|
||||
}))
|
||||
const guestWithWritePermission = {
|
||||
id: createRandomString(),
|
||||
name: createRandomPassword(),
|
||||
email: createRandomEmail()
|
||||
}
|
||||
const viewer = {
|
||||
id: createRandomString(),
|
||||
name: createRandomPassword(),
|
||||
email: createRandomEmail()
|
||||
}
|
||||
const viewer2 = {
|
||||
id: createRandomString(),
|
||||
name: createRandomPassword(),
|
||||
email: createRandomEmail()
|
||||
}
|
||||
|
||||
// first 10 users
|
||||
await createTestUsers(freeGuests)
|
||||
for (const guest of freeGuests) {
|
||||
await assignToWorkspace(workspace, guest, Roles.Workspace.Guest)
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
createTestUser(member),
|
||||
createTestUser(guestWithWritePermission),
|
||||
createTestUser(viewer),
|
||||
createTestUser(viewer2)
|
||||
])
|
||||
|
||||
await assignToWorkspace(workspace, member, Roles.Workspace.Member)
|
||||
await assignToWorkspace(
|
||||
workspace,
|
||||
guestWithWritePermission,
|
||||
Roles.Workspace.Guest
|
||||
)
|
||||
await assignToWorkspace(workspace, viewer, Roles.Workspace.Guest)
|
||||
await assignToWorkspace(workspace, viewer2, Roles.Workspace.Guest)
|
||||
|
||||
const resProject1 = await apollo.execute(CreateWorkspaceProjectDocument, {
|
||||
input: {
|
||||
name: createRandomPassword(),
|
||||
workspaceId
|
||||
}
|
||||
})
|
||||
expect(resProject1).to.not.haveGraphQLErrors()
|
||||
const project1Id = resProject1.data!.workspaceMutations.projects.create.id
|
||||
|
||||
await Promise.all([
|
||||
grantStreamPermissions({
|
||||
streamId: project1Id,
|
||||
userId: guestWithWritePermission.id,
|
||||
role: Roles.Stream.Contributor
|
||||
}),
|
||||
grantStreamPermissions({
|
||||
streamId: project1Id,
|
||||
userId: viewer.id,
|
||||
role: Roles.Stream.Reviewer
|
||||
}),
|
||||
grantStreamPermissions({
|
||||
streamId: project1Id,
|
||||
userId: viewer2.id,
|
||||
role: Roles.Stream.Reviewer
|
||||
})
|
||||
])
|
||||
|
||||
const res = await apollo.execute(GetWorkspaceWithBillingDocument, {
|
||||
workspaceId
|
||||
})
|
||||
|
||||
expect(res).to.not.haveGraphQLErrors()
|
||||
const { subTotal, currency, items, total, discount } =
|
||||
res.data?.workspace.billing?.cost || {}
|
||||
expect(subTotal).to.equal(49 + 49 + 15 + 2 * 5)
|
||||
expect(currency).to.equal('GBP')
|
||||
expect(items).to.deep.equal([
|
||||
{
|
||||
name: 'workspace-members',
|
||||
count: 2,
|
||||
cost: 49,
|
||||
label: '2 workspace members'
|
||||
},
|
||||
{
|
||||
name: 'free-guests',
|
||||
count: 10,
|
||||
cost: 0,
|
||||
label: '10/10 free guests'
|
||||
},
|
||||
{
|
||||
name: 'read-write-guests',
|
||||
count: 1,
|
||||
cost: 15,
|
||||
label: '1 read/write guest'
|
||||
},
|
||||
{
|
||||
name: 'read-only-guests',
|
||||
count: 2,
|
||||
cost: 5,
|
||||
label: '2 read only guests'
|
||||
}
|
||||
])
|
||||
expect(discount).to.deep.equal(null)
|
||||
expect(total).to.equal(123)
|
||||
})
|
||||
})
|
||||
|
||||
describe('query activeUser.workspaces', () => {
|
||||
it('should return all workspaces for a user', async () => {
|
||||
const res = await apollo.execute(GetActiveUserWorkspacesDocument, {})
|
||||
const testUser: BasicTestUser = {
|
||||
id: '',
|
||||
name: 'John Speckle',
|
||||
email: 'foobar@example.org',
|
||||
role: Roles.Server.Admin,
|
||||
verified: true
|
||||
}
|
||||
|
||||
await createTestUser(testUser)
|
||||
const testApollo: TestApolloServer = await testApolloServer({
|
||||
context: await createTestContext({
|
||||
auth: true,
|
||||
userId: testUser.id,
|
||||
token: '',
|
||||
role: testUser.role,
|
||||
scopes: AllScopes
|
||||
})
|
||||
})
|
||||
|
||||
const workspace1: BasicTestWorkspace = {
|
||||
id: '',
|
||||
ownerId: '',
|
||||
name: 'Workspace A',
|
||||
slug: cryptoRandomString({ length: 10 })
|
||||
}
|
||||
|
||||
const workspace2: BasicTestWorkspace = {
|
||||
id: '',
|
||||
ownerId: '',
|
||||
name: 'Workspace A',
|
||||
slug: cryptoRandomString({ length: 10 })
|
||||
}
|
||||
|
||||
const workspace3: BasicTestWorkspace = {
|
||||
id: '',
|
||||
ownerId: '',
|
||||
name: 'Workspace A',
|
||||
slug: cryptoRandomString({ length: 10 })
|
||||
}
|
||||
|
||||
await createTestWorkspace(workspace1, testUser)
|
||||
await createTestWorkspace(workspace2, testUser)
|
||||
await createTestWorkspace(workspace3, testUser)
|
||||
|
||||
const res = await testApollo.execute(GetActiveUserWorkspacesDocument, {})
|
||||
expect(res).to.not.haveGraphQLErrors()
|
||||
// TODO: this test depends on the previous tests
|
||||
expect(res.data?.activeUser?.workspaces?.items?.length).to.equal(3)
|
||||
|
@ -786,7 +624,7 @@ describe('Workspaces GQL CRUD', () => {
|
|||
}
|
||||
|
||||
before(async () => {
|
||||
await createTestWorkspace(workspace, testAdminUser)
|
||||
await createTestWorkspace(workspace, testAdminUser, { addPlan: false })
|
||||
|
||||
workspaceProject.workspaceId = workspace.id
|
||||
|
||||
|
@ -820,6 +658,22 @@ describe('Workspaces GQL CRUD', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('should fail to delete a paid workspace', async () => {
|
||||
const paidWorkspace = {
|
||||
id: '',
|
||||
name: 'test ws',
|
||||
slug: cryptoRandomString({ length: 10 }),
|
||||
ownerId: ''
|
||||
}
|
||||
|
||||
await createTestWorkspace(paidWorkspace, testAdminUser, { addPlan: true })
|
||||
const deleteRes = await apollo.execute(DeleteWorkspaceDocument, {
|
||||
workspaceId: paidWorkspace.id
|
||||
})
|
||||
|
||||
expect(deleteRes).to.haveGraphQLErrors('Workspace has an active paid plan')
|
||||
})
|
||||
|
||||
it('should delete the workspace', async () => {
|
||||
const deleteRes = await apollo.execute(DeleteWorkspaceDocument, {
|
||||
workspaceId: workspace.id
|
||||
|
@ -833,18 +687,25 @@ describe('Workspaces GQL CRUD', () => {
|
|||
})
|
||||
|
||||
it('should throw if non-workspace-admin triggers delete', async () => {
|
||||
const memberApollo: TestApolloServer = (apollo = await testApolloServer({
|
||||
const nonPaidWorkspace = {
|
||||
id: '',
|
||||
name: 'test ws',
|
||||
slug: cryptoRandomString({ length: 10 }),
|
||||
ownerId: ''
|
||||
}
|
||||
await createTestWorkspace(nonPaidWorkspace, testAdminUser, { addPlan: false })
|
||||
const memberApollo: TestApolloServer = await testApolloServer({
|
||||
context: await createTestContext({
|
||||
auth: true,
|
||||
userId: testAdminUser.id,
|
||||
userId: testMemberUser.id,
|
||||
token: '',
|
||||
role: testAdminUser.role,
|
||||
role: testMemberUser.role,
|
||||
scopes: AllScopes
|
||||
})
|
||||
}))
|
||||
})
|
||||
|
||||
const res = await memberApollo.execute(DeleteWorkspaceDocument, {
|
||||
workspaceId: workspace.id
|
||||
workspaceId: nonPaidWorkspace.id
|
||||
})
|
||||
|
||||
expect(res).to.haveGraphQLErrors('not authorized')
|
||||
|
|
|
@ -4011,8 +4011,6 @@ export type Workspace = {
|
|||
__typename?: 'Workspace';
|
||||
/** Regions available to the workspace for project data residency */
|
||||
availableRegions: Array<ServerRegionItem>;
|
||||
/** Billing data for Workspaces beta */
|
||||
billing?: Maybe<WorkspaceBilling>;
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
customerPortalUrl?: Maybe<Scalars['String']['output']>;
|
||||
/** Selected fallback when `logo` not set */
|
||||
|
@ -4074,12 +4072,6 @@ export type WorkspaceTeamArgs = {
|
|||
limit?: Scalars['Int']['input'];
|
||||
};
|
||||
|
||||
export type WorkspaceBilling = {
|
||||
__typename?: 'WorkspaceBilling';
|
||||
cost: WorkspaceCost;
|
||||
versionsCount: WorkspaceVersionsCount;
|
||||
};
|
||||
|
||||
export type WorkspaceBillingMutations = {
|
||||
__typename?: 'WorkspaceBillingMutations';
|
||||
cancelCheckoutSession: Scalars['Boolean']['output'];
|
||||
|
@ -4467,8 +4459,6 @@ export type BasicWorkspaceFragment = { __typename?: 'Workspace', id: string, nam
|
|||
|
||||
export type BasicPendingWorkspaceCollaboratorFragment = { __typename?: 'PendingWorkspaceCollaborator', id: string, inviteId: string, workspaceId: string, workspaceName: string, title: string, role: string, token?: string | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string }, user?: { __typename?: 'LimitedUser', id: string, name: string } | null };
|
||||
|
||||
export type WorkspaceBillingFragment = { __typename?: 'Workspace', billing?: { __typename?: 'WorkspaceBilling', versionsCount: { __typename?: 'WorkspaceVersionsCount', current: number, max: number }, cost: { __typename?: 'WorkspaceCost', subTotal: number, currency: Currency, total: number, items: Array<{ __typename?: 'WorkspaceCostItem', count: number, name: string, cost: number, label: string }>, discount?: { __typename?: 'WorkspaceCostDiscount', name: string, amount: number } | null } } | null };
|
||||
|
||||
export type WorkspaceProjectsFragment = { __typename?: 'ProjectCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Project', id: string }> };
|
||||
|
||||
export type CreateWorkspaceInviteMutationVariables = Exact<{
|
||||
|
@ -4494,13 +4484,6 @@ export type GetWorkspaceWithTeamQueryVariables = Exact<{
|
|||
|
||||
export type GetWorkspaceWithTeamQuery = { __typename?: 'Query', workspace: { __typename?: 'Workspace', id: string, name: string, slug: string, updatedAt: string, createdAt: string, role?: string | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, inviteId: string, workspaceId: string, workspaceName: string, title: string, role: string, token?: string | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string }, user?: { __typename?: 'LimitedUser', id: string, name: string } | null }> | null } };
|
||||
|
||||
export type GetWorkspaceWithBillingQueryVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetWorkspaceWithBillingQuery = { __typename?: 'Query', workspace: { __typename?: 'Workspace', id: string, name: string, slug: string, updatedAt: string, createdAt: string, role?: string | null, billing?: { __typename?: 'WorkspaceBilling', versionsCount: { __typename?: 'WorkspaceVersionsCount', current: number, max: number }, cost: { __typename?: 'WorkspaceCost', subTotal: number, currency: Currency, total: number, items: Array<{ __typename?: 'WorkspaceCostItem', count: number, name: string, cost: number, label: string }>, discount?: { __typename?: 'WorkspaceCostDiscount', name: string, amount: number } | null } } | null } };
|
||||
|
||||
export type GetWorkspaceWithProjectsQueryVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
@ -5246,7 +5229,6 @@ export type MoveProjectToWorkspaceMutation = { __typename?: 'Mutation', workspac
|
|||
|
||||
export const BasicWorkspaceFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicWorkspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]} as unknown as DocumentNode<BasicWorkspaceFragment, unknown>;
|
||||
export const BasicPendingWorkspaceCollaboratorFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicPendingWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingWorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceName"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"token"}}]}}]} as unknown as DocumentNode<BasicPendingWorkspaceCollaboratorFragment, unknown>;
|
||||
export const WorkspaceBillingFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceBilling"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"billing"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"versionsCount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"current"}},{"kind":"Field","name":{"kind":"Name","value":"max"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cost"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subTotal"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"cost"}},{"kind":"Field","name":{"kind":"Name","value":"label"}}]}},{"kind":"Field","name":{"kind":"Name","value":"discount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"}}]}}]}}]}}]} as unknown as DocumentNode<WorkspaceBillingFragment, unknown>;
|
||||
export const WorkspaceProjectsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceProjects"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProjectCollection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]} as unknown as DocumentNode<WorkspaceProjectsFragment, unknown>;
|
||||
export const BasicStreamAccessRequestFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicStreamAccessRequestFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"StreamAccessRequest"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"requester"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"requesterId"}},{"kind":"Field","name":{"kind":"Name","value":"streamId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]} as unknown as DocumentNode<BasicStreamAccessRequestFieldsFragment, unknown>;
|
||||
export const TestAutomateFunctionFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestAutomateFunction"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"repo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"owner"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isFeatured"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"releases"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"5"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"versionTag"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"inputSchema"}},{"kind":"Field","name":{"kind":"Name","value":"commitId"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"automationCount"}},{"kind":"Field","name":{"kind":"Name","value":"supportedSourceApps"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}}]}}]} as unknown as DocumentNode<TestAutomateFunctionFragment, unknown>;
|
||||
|
@ -5268,7 +5250,6 @@ export const CreateObjectDocument = {"kind":"Document","definitions":[{"kind":"O
|
|||
export const CreateWorkspaceInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateWorkspaceInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceInviteCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"invites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"create"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"workspaceId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicWorkspace"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicPendingWorkspaceCollaborator"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicWorkspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicPendingWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingWorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceName"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"token"}}]}}]} as unknown as DocumentNode<CreateWorkspaceInviteMutation, CreateWorkspaceInviteMutationVariables>;
|
||||
export const BatchCreateWorkspaceInvitesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"BatchCreateWorkspaceInvites"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceInviteCreateInput"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"invites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"batchCreate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"workspaceId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}},{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicWorkspace"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicPendingWorkspaceCollaborator"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicWorkspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicPendingWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingWorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceName"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"token"}}]}}]} as unknown as DocumentNode<BatchCreateWorkspaceInvitesMutation, BatchCreateWorkspaceInvitesMutationVariables>;
|
||||
export const GetWorkspaceWithTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceWithTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicWorkspace"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicPendingWorkspaceCollaborator"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicWorkspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicPendingWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingWorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceName"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"token"}}]}}]} as unknown as DocumentNode<GetWorkspaceWithTeamQuery, GetWorkspaceWithTeamQueryVariables>;
|
||||
export const GetWorkspaceWithBillingDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceWithBilling"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicWorkspace"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkspaceBilling"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicWorkspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceBilling"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"billing"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"versionsCount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"current"}},{"kind":"Field","name":{"kind":"Name","value":"max"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cost"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subTotal"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"cost"}},{"kind":"Field","name":{"kind":"Name","value":"label"}}]}},{"kind":"Field","name":{"kind":"Name","value":"discount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"amount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"total"}}]}}]}}]}}]} as unknown as DocumentNode<GetWorkspaceWithBillingQuery, GetWorkspaceWithBillingQueryVariables>;
|
||||
export const GetWorkspaceWithProjectsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceWithProjects"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicWorkspace"}},{"kind":"Field","name":{"kind":"Name","value":"projects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkspaceProjects"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicWorkspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkspaceProjects"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProjectCollection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]} as unknown as DocumentNode<GetWorkspaceWithProjectsQuery, GetWorkspaceWithProjectsQueryVariables>;
|
||||
export const CancelWorkspaceInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CancelWorkspaceInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"inviteId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"invites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cancel"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"workspaceId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}},{"kind":"Argument","name":{"kind":"Name","value":"inviteId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"inviteId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicWorkspace"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"BasicPendingWorkspaceCollaborator"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicWorkspace"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Workspace"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BasicPendingWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PendingWorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceName"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"token"}}]}}]} as unknown as DocumentNode<CancelWorkspaceInviteMutation, CancelWorkspaceInviteMutationVariables>;
|
||||
export const UseWorkspaceInviteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UseWorkspaceInvite"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceInviteUseInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"invites"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"use"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]}}]}}]} as unknown as DocumentNode<UseWorkspaceInviteMutation, UseWorkspaceInviteMutationVariables>;
|
||||
|
|
Загрузка…
Ссылка в новой задаче