diff --git a/packages/frontend-2/components/project/VisibilitySelect.vue b/packages/frontend-2/components/project/VisibilitySelect.vue
index 42d7a3c4e..73d089a31 100644
--- a/packages/frontend-2/components/project/VisibilitySelect.vue
+++ b/packages/frontend-2/components/project/VisibilitySelect.vue
@@ -38,38 +38,43 @@
diff --git a/packages/frontend-2/components/project/model-page/dialog/embed/Embed.vue b/packages/frontend-2/components/project/model-page/dialog/embed/Embed.vue
index 89809cc00..dc2e96638 100644
--- a/packages/frontend-2/components/project/model-page/dialog/embed/Embed.vue
+++ b/packages/frontend-2/components/project/model-page/dialog/embed/Embed.vue
@@ -89,13 +89,16 @@
diff --git a/packages/frontend-2/components/project/page/settings/general/block/Discussions.vue b/packages/frontend-2/components/project/page/settings/general/block/Discussions.vue
index dc32dc4fa..9cc314e9c 100644
--- a/packages/frontend-2/components/project/page/settings/general/block/Discussions.vue
+++ b/packages/frontend-2/components/project/page/settings/general/block/Discussions.vue
@@ -18,7 +18,10 @@
diff --git a/packages/frontend-2/lib/auth/helpers/authPolicies.ts b/packages/frontend-2/lib/auth/helpers/authPolicies.ts
deleted file mode 100644
index 975502bf2..000000000
--- a/packages/frontend-2/lib/auth/helpers/authPolicies.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import type { NuxtApp } from '#app'
-import type {
- ApolloQueryResult,
- MaybeMasked,
- OperationVariables,
- QueryOptions
-} from '@apollo/client/core'
-
-export type AuthLoaderDependencies = {
- nuxtApp: NuxtApp
- /**
- * Use this to query GQL, instead of taking apollo client from nuxtApp. This ensures
- * appropriate caching settings
- */
- query: (
- options: QueryOptions
- ) => Promise>>
-}
-
-export type AuthLoaderFactory = (deps: AuthLoaderDependencies) => T
-
-/**
- * Can be used in auth policy checks to reference the active user's id, whatever it is,
- * without having to resolve it
- */
-export const ActiveUserId = '__APP_ACTIVE_USER_ID__'
diff --git a/packages/frontend-2/lib/common/generated/gql/gql.ts b/packages/frontend-2/lib/common/generated/gql/gql.ts
index 32facd897..aeceefaf7 100644
--- a/packages/frontend-2/lib/common/generated/gql/gql.ts
+++ b/packages/frontend-2/lib/common/generated/gql/gql.ts
@@ -88,7 +88,7 @@ type Documents = {
"\n fragment ProjectPageModelsCardDeleteDialog on Model {\n id\n name\n }\n": typeof types.ProjectPageModelsCardDeleteDialogFragmentDoc,
"\n fragment ProjectPageModelsCardRenameDialog on Model {\n id\n name\n description\n }\n": typeof types.ProjectPageModelsCardRenameDialogFragmentDoc,
"\n query ProjectPageSettingsGeneral($projectId: String!) {\n project(id: $projectId) {\n id\n ...ProjectPageSettingsGeneralBlockProjectInfo_Project\n ...ProjectPageSettingsGeneralBlockAccess_Project\n ...ProjectPageSettingsGeneralBlockDiscussions_Project\n ...ProjectPageSettingsGeneralBlockLeave_Project\n ...ProjectPageSettingsGeneralBlockDelete_Project\n ...ProjectPageTeamInternals_Project\n }\n }\n": typeof types.ProjectPageSettingsGeneralDocument,
- "\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc,
+ "\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n workspaceId\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n ...ProjectsDeleteDialog_Project\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockDiscussions_Project on Project {\n id\n visibility\n allowPublicComments\n permissions {\n canUpdateAllowPublicComments {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageSettingsGeneralBlockDiscussions_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockLeave_Project on Project {\n id\n name\n role\n team {\n role\n user {\n ...LimitedUserAvatar\n role\n }\n }\n workspace {\n id\n }\n permissions {\n canLeave {\n ...FullPermissionCheckResult\n }\n }\n }\n": typeof types.ProjectPageSettingsGeneralBlockLeave_ProjectFragmentDoc,
@@ -499,7 +499,7 @@ const documents: Documents = {
"\n fragment ProjectPageModelsCardDeleteDialog on Model {\n id\n name\n }\n": types.ProjectPageModelsCardDeleteDialogFragmentDoc,
"\n fragment ProjectPageModelsCardRenameDialog on Model {\n id\n name\n description\n }\n": types.ProjectPageModelsCardRenameDialogFragmentDoc,
"\n query ProjectPageSettingsGeneral($projectId: String!) {\n project(id: $projectId) {\n id\n ...ProjectPageSettingsGeneralBlockProjectInfo_Project\n ...ProjectPageSettingsGeneralBlockAccess_Project\n ...ProjectPageSettingsGeneralBlockDiscussions_Project\n ...ProjectPageSettingsGeneralBlockLeave_Project\n ...ProjectPageSettingsGeneralBlockDelete_Project\n ...ProjectPageTeamInternals_Project\n }\n }\n": types.ProjectPageSettingsGeneralDocument,
- "\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc,
+ "\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n workspaceId\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockDelete_Project on Project {\n ...ProjectsDeleteDialog_Project\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockDiscussions_Project on Project {\n id\n visibility\n allowPublicComments\n permissions {\n canUpdateAllowPublicComments {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageSettingsGeneralBlockDiscussions_ProjectFragmentDoc,
"\n fragment ProjectPageSettingsGeneralBlockLeave_Project on Project {\n id\n name\n role\n team {\n role\n user {\n ...LimitedUserAvatar\n role\n }\n }\n workspace {\n id\n }\n permissions {\n canLeave {\n ...FullPermissionCheckResult\n }\n }\n }\n": types.ProjectPageSettingsGeneralBlockLeave_ProjectFragmentDoc,
@@ -1149,7 +1149,7 @@ export function graphql(source: "\n query ProjectPageSettingsGeneral($projectId
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
-export function graphql(source: "\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n"): (typeof documents)["\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n"];
+export function graphql(source: "\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n workspaceId\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n"): (typeof documents)["\n fragment ProjectPageSettingsGeneralBlockAccess_Project on Project {\n id\n visibility\n workspaceId\n permissions {\n canUpdate {\n ...FullPermissionCheckResult\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
diff --git a/packages/frontend-2/lib/common/generated/gql/graphql.ts b/packages/frontend-2/lib/common/generated/gql/graphql.ts
index e1d2e0542..a7d0bd309 100644
--- a/packages/frontend-2/lib/common/generated/gql/graphql.ts
+++ b/packages/frontend-2/lib/common/generated/gql/graphql.ts
@@ -2067,7 +2067,7 @@ export type Project = {
versions: VersionCollection;
/** Return metadata about resources being requested in the viewer */
viewerResources: Array;
- visibility: SimpleProjectVisibility;
+ visibility: ProjectVisibility;
webhooks: WebhookCollection;
workspace?: Maybe;
workspaceId?: Maybe;
@@ -2688,9 +2688,14 @@ export const ProjectVersionsUpdatedMessageType = {
export type ProjectVersionsUpdatedMessageType = typeof ProjectVersionsUpdatedMessageType[keyof typeof ProjectVersionsUpdatedMessageType];
export const ProjectVisibility = {
+ /** Only accessible to explicit collaborators */
Private: 'PRIVATE',
+ /** Accessible to everyone (even non-logged in users) */
Public: 'PUBLIC',
- Unlisted: 'UNLISTED'
+ /** Legacy - same as public */
+ Unlisted: 'UNLISTED',
+ /** Accessible to everyone in the project's workspace */
+ Workspace: 'WORKSPACE'
} as const;
export type ProjectVisibility = typeof ProjectVisibility[keyof typeof ProjectVisibility];
@@ -3240,13 +3245,6 @@ export type SetPrimaryUserEmailInput = {
id: Scalars['ID']['input'];
};
-/** Visibility without the "discoverable" option */
-export const SimpleProjectVisibility = {
- Private: 'PRIVATE',
- Unlisted: 'UNLISTED'
-} as const;
-
-export type SimpleProjectVisibility = typeof SimpleProjectVisibility[keyof typeof SimpleProjectVisibility];
export type SmartTextEditorValue = {
__typename?: 'SmartTextEditorValue';
/** File attachments, if any */
@@ -3323,6 +3321,7 @@ export type Stream = {
/**
* Whether the stream (if public) can be found on public stream exploration pages
* and searches
+ * @deprecated Discoverability as a feature has been removed.
*/
isDiscoverable: Scalars['Boolean']['output'];
/** Whether the stream can be viewed by non-contributors */
@@ -5193,7 +5192,7 @@ export type HeaderWorkspaceSwitcherHeaderExpiredSso_LimitedWorkspaceFragment = {
export type HeaderWorkspaceSwitcherHeaderWorkspace_WorkspaceFragment = { __typename?: 'Workspace', id: string, name: string, logo?: string | null, role?: string | null, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans } | null, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number } };
-export type HeaderNavShare_ProjectFragment = { __typename?: 'Project', id: string, visibility: SimpleProjectVisibility, role?: string | null };
+export type HeaderNavShare_ProjectFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility, role?: string | null };
export type HeaderNavNotificationsProjectInvite_PendingStreamCollaboratorFragment = { __typename?: 'PendingStreamCollaborator', id: string, projectId: string, projectName: string, token?: string | null, workspaceSlug?: string | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null }, user?: { __typename?: 'LimitedUser', id: string } | null };
@@ -5213,9 +5212,9 @@ export type InviteDialogProjectRowProjectCollaboratorsQuery = { __typename?: 'Qu
export type ProjectModelPageHeaderProjectFragment = { __typename?: 'Project', id: string, name: string, model: { __typename?: 'Model', id: string, name: string, description?: string | null }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, role?: string | null } | null };
-export type ProjectModelPageVersionsPaginationFragment = { __typename?: 'Project', id: string, visibility: SimpleProjectVisibility, role?: string | null, model: { __typename?: 'Model', id: string, versions: { __typename?: 'VersionCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Version', id: string, message?: string | null, createdAt: string, previewUrl: string, referencedObject?: string | null, sourceApplication?: string | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'VersionPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } } };
+export type ProjectModelPageVersionsPaginationFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility, role?: string | null, model: { __typename?: 'Model', id: string, versions: { __typename?: 'VersionCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Version', id: string, message?: string | null, createdAt: string, previewUrl: string, referencedObject?: string | null, sourceApplication?: string | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'VersionPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } } };
-export type ProjectModelPageVersionsProjectFragment = { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, role?: string | null, model: { __typename?: 'Model', id: string, name: string, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, versions: { __typename?: 'VersionCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Version', id: string, message?: string | null, createdAt: string, previewUrl: string, referencedObject?: string | null, sourceApplication?: string | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'VersionPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null, role?: string | null } | null };
+export type ProjectModelPageVersionsProjectFragment = { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, role?: string | null, model: { __typename?: 'Model', id: string, name: string, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, versions: { __typename?: 'VersionCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Version', id: string, message?: string | null, createdAt: string, previewUrl: string, referencedObject?: string | null, sourceApplication?: string | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'VersionPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null, role?: string | null } | null };
export type ProjectModelPageDialogDeleteVersionFragment = { __typename?: 'Version', id: string, message?: string | null };
@@ -5223,7 +5222,7 @@ export type ProjectModelPageDialogEditMessageVersionFragment = { __typename?: 'V
export type ProjectModelPageDialogMoveToVersionFragment = { __typename?: 'Version', id: string, message?: string | null };
-export type ProjectsModelPageEmbed_ProjectFragment = { __typename?: 'Project', id: string, visibility: SimpleProjectVisibility, role?: string | null };
+export type ProjectsModelPageEmbed_ProjectFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility, role?: string | null };
export type ProjectModelPageVersionsCardVersionFragment = { __typename?: 'Version', id: string, message?: string | null, createdAt: string, previewUrl: string, referencedObject?: string | null, sourceApplication?: string | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'VersionPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
@@ -5241,9 +5240,9 @@ export type ProjectPageAutomationFunctions_AutomationFragment = { __typename?: '
export type ProjectPageAutomationHeader_AutomationFragment = { __typename?: 'Automation', id: string, name: string, enabled: boolean, isTestAutomation: boolean, currentRevision?: { __typename?: 'AutomationRevision', id: string, triggerDefinitions: Array<{ __typename?: 'VersionCreatedTriggerDefinition', model?: { __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null }> } | null };
-export type ProjectPageAutomationHeader_ProjectFragment = { __typename?: 'Project', id: string, role?: string | null, workspaceId?: string | null, visibility: SimpleProjectVisibility, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
+export type ProjectPageAutomationHeader_ProjectFragment = { __typename?: 'Project', id: string, role?: string | null, workspaceId?: string | null, visibility: ProjectVisibility, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
-export type ProjectPageAutomationModels_ProjectFragment = { __typename?: 'Project', id: string, role?: string | null, visibility: SimpleProjectVisibility, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
+export type ProjectPageAutomationModels_ProjectFragment = { __typename?: 'Project', id: string, role?: string | null, visibility: ProjectVisibility, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
export type ProjectPageAutomationRuns_AutomationFragment = { __typename?: 'Automation', id: string, name: string, enabled: boolean, isTestAutomation: boolean, runs: { __typename?: 'AutomateRunCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'AutomateRun', id: string, status: AutomateRunStatus, createdAt: string, updatedAt: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', statusMessage?: string | null, id: string, status: AutomateRunStatus }>, trigger: { __typename?: 'VersionCreatedTrigger', version?: { __typename?: 'Version', id: string } | null, model?: { __typename?: 'Model', id: string } | null } }> }, currentRevision?: { __typename?: 'AutomationRevision', functions: Array<{ __typename?: 'AutomationRevisionFunction', release: { __typename?: 'AutomateFunctionRelease', function: { __typename?: 'AutomateFunction', id: string, name: string } } }> } | null };
@@ -5277,15 +5276,15 @@ export type ProjectDiscussionsPageResults_ProjectFragment = { __typename?: 'Proj
export type ProjectPageModelsActionsFragment = { __typename?: 'Model', id: string, name: string, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
-export type ProjectPageModelsActions_ProjectFragment = { __typename?: 'Project', id: string, visibility: SimpleProjectVisibility, role?: string | null, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
+export type ProjectPageModelsActions_ProjectFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility, role?: string | null, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
-export type ProjectPageModelsCardProjectFragment = { __typename?: 'Project', id: string, role?: string | null, visibility: SimpleProjectVisibility, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
+export type ProjectPageModelsCardProjectFragment = { __typename?: 'Project', id: string, role?: string | null, visibility: ProjectVisibility, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
export type ProjectModelsPageHeader_ProjectFragment = { __typename?: 'Project', id: string, name: string, sourceApps: Array, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, workspace?: { __typename?: 'Workspace', id: string, role?: string | null, slug: string, name: string, readOnly: boolean, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans } | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
-export type ProjectModelsPageResults_ProjectFragment = { __typename?: 'Project', id: string, role?: string | null, visibility: SimpleProjectVisibility, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string } | null, modelCount: { __typename?: 'ModelCollection', totalCount: number }, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
+export type ProjectModelsPageResults_ProjectFragment = { __typename?: 'Project', id: string, role?: string | null, visibility: ProjectVisibility, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string } | null, modelCount: { __typename?: 'ModelCollection', totalCount: number }, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
-export type ProjectPageModelsStructureItem_ProjectFragment = { __typename?: 'Project', id: string, visibility: SimpleProjectVisibility, role?: string | null, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
+export type ProjectPageModelsStructureItem_ProjectFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility, role?: string | null, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
export type SingleLevelModelTreeItemFragment = { __typename?: 'ModelsTreeItem', id: string, name: string, fullName: string, hasChildren: boolean, updatedAt: string, model?: { __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null };
@@ -5298,13 +5297,13 @@ export type ProjectPageSettingsGeneralQueryVariables = Exact<{
}>;
-export type ProjectPageSettingsGeneralQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, allowPublicComments: boolean, role?: string | null, permissions: { __typename?: 'ProjectPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdateAllowPublicComments: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canLeave: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number } } };
+export type ProjectPageSettingsGeneralQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, workspaceId?: string | null, allowPublicComments: boolean, role?: string | null, permissions: { __typename?: 'ProjectPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdateAllowPublicComments: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canLeave: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number } } };
-export type ProjectPageSettingsGeneralBlockAccess_ProjectFragment = { __typename?: 'Project', id: string, visibility: SimpleProjectVisibility, permissions: { __typename?: 'ProjectPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
+export type ProjectPageSettingsGeneralBlockAccess_ProjectFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility, workspaceId?: string | null, permissions: { __typename?: 'ProjectPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
export type ProjectPageSettingsGeneralBlockDelete_ProjectFragment = { __typename?: 'Project', id: string, name: string, role?: string | null, permissions: { __typename?: 'ProjectPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, models: { __typename?: 'ModelCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null, versions: { __typename?: 'VersionCollection', totalCount: number } };
-export type ProjectPageSettingsGeneralBlockDiscussions_ProjectFragment = { __typename?: 'Project', id: string, visibility: SimpleProjectVisibility, allowPublicComments: boolean, permissions: { __typename?: 'ProjectPermissionChecks', canUpdateAllowPublicComments: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
+export type ProjectPageSettingsGeneralBlockDiscussions_ProjectFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility, allowPublicComments: boolean, permissions: { __typename?: 'ProjectPermissionChecks', canUpdateAllowPublicComments: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
export type ProjectPageSettingsGeneralBlockLeave_ProjectFragment = { __typename?: 'Project', id: string, name: string, role?: string | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, workspace?: { __typename?: 'Workspace', id: string } | null, permissions: { __typename?: 'ProjectPermissionChecks', canLeave: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
@@ -5312,15 +5311,15 @@ export type ProjectPageSettingsGeneralBlockProjectInfo_ProjectFragment = { __typ
export type ProjectPageSettingsWebhooks_ProjectFragment = { __typename?: 'Project', id: string, permissions: { __typename?: 'ProjectPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
-export type ProjectsPageTeamDialogManagePermissions_ProjectFragment = { __typename?: 'Project', id: string, visibility: SimpleProjectVisibility, role?: string | null };
+export type ProjectsPageTeamDialogManagePermissions_ProjectFragment = { __typename?: 'Project', id: string, visibility: ProjectVisibility, role?: string | null };
export type ProjectsDashboard_UserProjectCollectionFragment = { __typename?: 'UserProjectCollection', numberOfHidden: number };
export type ProjectsDashboard_UserFragment = { __typename?: 'User', permissions: { __typename?: 'RootPermissionChecks', canCreatePersonalProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
-export type ProjectsDashboardFilledProjectFragment = { __typename?: 'ProjectCollection', items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: SimpleProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> };
+export type ProjectsDashboardFilledProjectFragment = { __typename?: 'ProjectCollection', items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> };
-export type ProjectsDashboardFilledUserFragment = { __typename?: 'UserProjectCollection', items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: SimpleProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> };
+export type ProjectsDashboardFilledUserFragment = { __typename?: 'UserProjectCollection', items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> };
export type ProjectsDeleteDialog_ProjectFragment = { __typename?: 'Project', id: string, name: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null, versions: { __typename?: 'VersionCollection', totalCount: number } };
@@ -5336,7 +5335,7 @@ export type SettingsServerRegionsAddEditDialog_ServerRegionItemFragment = { __ty
export type SettingsServerRegionsTable_ServerRegionItemFragment = { __typename?: 'ServerRegionItem', id: string, name: string, key: string, description?: string | null };
-export type SettingsSharedProjects_ProjectFragment = { __typename?: 'Project', id: string, name: string, visibility: SimpleProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null };
+export type SettingsSharedProjects_ProjectFragment = { __typename?: 'Project', id: string, name: string, visibility: ProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null };
export type SettingsUserProfileChangePassword_UserFragment = { __typename?: 'User', id: string, email?: string | null };
@@ -5376,7 +5375,7 @@ export type SettingsWorkspacesSecurityDomainRemoveDialog_WorkspaceFragment = { _
export type SettingsWorkspacesSecuritySsoWrapper_WorkspaceFragment = { __typename?: 'Workspace', id: string, role?: string | null, slug: string, hasAccessToSSO: boolean, sso?: { __typename?: 'WorkspaceSso', provider?: { __typename?: 'WorkspaceSsoProvider', id: string, name: string, clientId: string, issuerUrl: string } | null } | null };
-export type ModelPageProjectFragment = { __typename?: 'Project', id: string, createdAt: string, name: string, visibility: SimpleProjectVisibility, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, role?: string | null } | null };
+export type ModelPageProjectFragment = { __typename?: 'Project', id: string, createdAt: string, name: string, visibility: ProjectVisibility, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, role?: string | null } | null };
export type ViewerCommentThreadDataFragment = { __typename?: 'Comment', id: string, permissions: { __typename?: 'CommentPermissionChecks', canArchive: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
@@ -5394,7 +5393,7 @@ export type WorkspaceDashboard_WorkspaceFragment = { __typename?: 'Workspace', i
export type WorkspaceDashboardHeader_WorkspaceFragment = { __typename?: 'Workspace', id: string, role?: string | null, slug: string, name: string, domainBasedMembershipProtectionEnabled: boolean, team: { __typename?: 'WorkspaceCollaboratorCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }> }, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string, role: string, email?: string | null }> | null, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', totalCount: number, items: Array<{ __typename?: 'WorkspaceJoinRequest', status: WorkspaceJoinRequestStatus, id: string }> } | null, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans, status: WorkspacePlanStatuses, createdAt: string } | null, permissions: { __typename?: 'WorkspacePermissionChecks', canCreateProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveProjectToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, subscription?: { __typename?: 'WorkspaceSubscription', billingInterval: BillingInterval, currentBillingCycleEnd: string } | null, domains?: Array<{ __typename?: 'WorkspaceDomain', domain: string, id: string }> | null };
-export type WorkspaceDashboardProjectList_ProjectCollectionFragment = { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: SimpleProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> };
+export type WorkspaceDashboardProjectList_ProjectCollectionFragment = { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> };
export type WorkspaceDashboardProjectList_WorkspaceFragment = { __typename?: 'Workspace', id: string, name: string, slug: string, role?: string | null, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans } | null, permissions: { __typename?: 'WorkspacePermissionChecks', canCreateProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveProjectToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
@@ -5785,19 +5784,19 @@ export type NavigationWorkspaceInvitesQuery = { __typename?: 'Query', activeUser
export type ProjectPageTeamInternals_ProjectFragment = { __typename?: 'Project', id: string, role?: string | null, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, user: { __typename?: 'LimitedUser', id: string, role?: string | null, name: string, avatar?: string | null } }> };
-export type ProjectPageTeamDialogFragment = { __typename?: 'Project', id: string, name: string, role?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, inviteId: string, role: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null };
+export type ProjectPageTeamDialogFragment = { __typename?: 'Project', id: string, name: string, role?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, inviteId: string, role: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null };
-export type ProjectDashboardItemNoModelsFragment = { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: SimpleProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
+export type ProjectDashboardItemNoModelsFragment = { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
-export type ProjectDashboardItemFragment = { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: SimpleProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
+export type ProjectDashboardItemFragment = { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
export type PendingFileUploadFragment = { __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string };
export type ProjectPageLatestItemsModelItemFragment = { __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
-export type ProjectUpdatableMetadataFragment = { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, allowPublicComments: boolean, permissions: { __typename?: 'ProjectPermissionChecks', canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdateAllowPublicComments: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canLeave: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
+export type ProjectUpdatableMetadataFragment = { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, permissions: { __typename?: 'ProjectPermissionChecks', canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdateAllowPublicComments: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canLeave: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
-export type ProjectPageLatestItemsModelsFragment = { __typename?: 'Project', id: string, role?: string | null, visibility: SimpleProjectVisibility, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string } | null, modelCount: { __typename?: 'ModelCollection', totalCount: number }, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
+export type ProjectPageLatestItemsModelsFragment = { __typename?: 'Project', id: string, role?: string | null, visibility: ProjectVisibility, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string } | null, modelCount: { __typename?: 'ModelCollection', totalCount: number }, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
export type ProjectPageLatestItemsCommentsFragment = { __typename?: 'Project', id: string, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number } };
@@ -5815,14 +5814,14 @@ export type CreateProjectMutationVariables = Exact<{
}>;
-export type CreateProjectMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', create: { __typename?: 'Project', id: string, createdAt: string, role?: string | null, name: string, description?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, updatedAt: string, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, versions: { __typename?: 'VersionCollection', totalCount: number } } } };
+export type CreateProjectMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', create: { __typename?: 'Project', id: string, createdAt: string, role?: string | null, name: string, description?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, updatedAt: string, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, versions: { __typename?: 'VersionCollection', totalCount: number } } } };
export type CreateWorkspaceProjectMutationVariables = Exact<{
input: WorkspaceProjectCreateInput;
}>;
-export type CreateWorkspaceProjectMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', projects: { __typename?: 'WorkspaceProjectMutations', create: { __typename?: 'Project', id: string, createdAt: string, role?: string | null, name: string, description?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, updatedAt: string, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, versions: { __typename?: 'VersionCollection', totalCount: number } } } } };
+export type CreateWorkspaceProjectMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', projects: { __typename?: 'WorkspaceProjectMutations', create: { __typename?: 'Project', id: string, createdAt: string, role?: string | null, name: string, description?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, updatedAt: string, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, versions: { __typename?: 'VersionCollection', totalCount: number } } } } };
export type UpdateModelMutationVariables = Exact<{
input: UpdateModelInput;
@@ -5858,7 +5857,7 @@ export type InviteProjectUserMutationVariables = Exact<{
}>;
-export type InviteProjectUserMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', invites: { __typename?: 'ProjectInviteMutations', batchCreate: { __typename?: 'Project', id: string, name: string, role?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, inviteId: string, role: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null } } } };
+export type InviteProjectUserMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', invites: { __typename?: 'ProjectInviteMutations', batchCreate: { __typename?: 'Project', id: string, name: string, role?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, inviteId: string, role: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null } } } };
export type InviteWorkspaceProjectUserMutationVariables = Exact<{
projectId: Scalars['ID']['input'];
@@ -5866,7 +5865,7 @@ export type InviteWorkspaceProjectUserMutationVariables = Exact<{
}>;
-export type InviteWorkspaceProjectUserMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', invites: { __typename?: 'ProjectInviteMutations', createForWorkspace: { __typename?: 'Project', id: string, name: string, role?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, inviteId: string, role: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null } } } };
+export type InviteWorkspaceProjectUserMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', invites: { __typename?: 'ProjectInviteMutations', createForWorkspace: { __typename?: 'Project', id: string, name: string, role?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, inviteId: string, role: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null } } } };
export type CancelProjectInviteMutationVariables = Exact<{
projectId: Scalars['ID']['input'];
@@ -5874,14 +5873,14 @@ export type CancelProjectInviteMutationVariables = Exact<{
}>;
-export type CancelProjectInviteMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', invites: { __typename?: 'ProjectInviteMutations', cancel: { __typename?: 'Project', id: string, name: string, role?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, inviteId: string, role: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null } } } };
+export type CancelProjectInviteMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', invites: { __typename?: 'ProjectInviteMutations', cancel: { __typename?: 'Project', id: string, name: string, role?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, inviteId: string, role: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null } } } };
export type UpdateProjectMetadataMutationVariables = Exact<{
update: ProjectUpdateInput;
}>;
-export type UpdateProjectMetadataMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', update: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, allowPublicComments: boolean, permissions: { __typename?: 'ProjectPermissionChecks', canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdateAllowPublicComments: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canLeave: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } } };
+export type UpdateProjectMetadataMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', update: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, permissions: { __typename?: 'ProjectPermissionChecks', canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdateAllowPublicComments: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canLeave: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } } };
export type DeleteProjectMutationVariables = Exact<{
id: Scalars['String']['input'];
@@ -6015,7 +6014,7 @@ export type ProjectsDashboardQueryQueryVariables = Exact<{
}>;
-export type ProjectsDashboardQueryQuery = { __typename?: 'Query', activeUser?: { __typename?: 'User', id: string, projects: { __typename?: 'UserProjectCollection', cursor?: string | null, totalCount: number, numberOfHidden: number, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: SimpleProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, expiredSsoSessions: Array<{ __typename?: 'LimitedWorkspace', id: string, slug: string, name: string, logo?: string | null }>, permissions: { __typename?: 'RootPermissionChecks', canCreatePersonalProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null };
+export type ProjectsDashboardQueryQuery = { __typename?: 'Query', activeUser?: { __typename?: 'User', id: string, projects: { __typename?: 'UserProjectCollection', cursor?: string | null, totalCount: number, numberOfHidden: number, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, expiredSsoSessions: Array<{ __typename?: 'LimitedWorkspace', id: string, slug: string, name: string, logo?: string | null }>, permissions: { __typename?: 'RootPermissionChecks', canCreatePersonalProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null };
export type ProjectPageQueryQueryVariables = Exact<{
id: Scalars['String']['input'];
@@ -6023,7 +6022,7 @@ export type ProjectPageQueryQueryVariables = Exact<{
}>;
-export type ProjectPageQueryQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, createdAt: string, role?: string | null, name: string, description?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, versions: { __typename?: 'VersionCollection', totalCount: number } }, projectInvite?: { __typename?: 'PendingStreamCollaborator', id: string, projectId: string, projectName: string, token?: string | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null }, user?: { __typename?: 'LimitedUser', id: string } | null } | null };
+export type ProjectPageQueryQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, createdAt: string, role?: string | null, name: string, description?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, versions: { __typename?: 'VersionCollection', totalCount: number } }, projectInvite?: { __typename?: 'PendingStreamCollaborator', id: string, projectId: string, projectName: string, token?: string | null, invitedBy: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null }, user?: { __typename?: 'LimitedUser', id: string } | null } | null };
export type ProjectLatestModelsQueryVariables = Exact<{
projectId: Scalars['String']['input'];
@@ -6090,7 +6089,7 @@ export type ProjectModelCheckQueryVariables = Exact<{
}>;
-export type ProjectModelCheckQuery = { __typename?: 'Query', project: { __typename?: 'Project', visibility: SimpleProjectVisibility, model: { __typename?: 'Model', id: string } } };
+export type ProjectModelCheckQuery = { __typename?: 'Query', project: { __typename?: 'Project', visibility: ProjectVisibility, model: { __typename?: 'Model', id: string } } };
export type ProjectModelPageQueryVariables = Exact<{
projectId: Scalars['String']['input'];
@@ -6099,7 +6098,7 @@ export type ProjectModelPageQueryVariables = Exact<{
}>;
-export type ProjectModelPageQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, role?: string | null, model: { __typename?: 'Model', id: string, name: string, description?: string | null, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, versions: { __typename?: 'VersionCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Version', id: string, message?: string | null, createdAt: string, previewUrl: string, referencedObject?: string | null, sourceApplication?: string | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'VersionPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null, role?: string | null } | null } };
+export type ProjectModelPageQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, role?: string | null, model: { __typename?: 'Model', id: string, name: string, description?: string | null, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, versions: { __typename?: 'VersionCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Version', id: string, message?: string | null, createdAt: string, previewUrl: string, referencedObject?: string | null, sourceApplication?: string | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'VersionPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, logo?: string | null, role?: string | null } | null } };
export type ProjectModelVersionsQueryVariables = Exact<{
projectId: Scalars['String']['input'];
@@ -6108,14 +6107,14 @@ export type ProjectModelVersionsQueryVariables = Exact<{
}>;
-export type ProjectModelVersionsQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, visibility: SimpleProjectVisibility, role?: string | null, model: { __typename?: 'Model', id: string, versions: { __typename?: 'VersionCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Version', id: string, message?: string | null, createdAt: string, previewUrl: string, referencedObject?: string | null, sourceApplication?: string | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'VersionPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } } } };
+export type ProjectModelVersionsQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, visibility: ProjectVisibility, role?: string | null, model: { __typename?: 'Model', id: string, versions: { __typename?: 'VersionCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Version', id: string, message?: string | null, createdAt: string, previewUrl: string, referencedObject?: string | null, sourceApplication?: string | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'VersionPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } } } };
export type ProjectModelsPageQueryVariables = Exact<{
projectId: Scalars['String']['input'];
}>;
-export type ProjectModelsPageQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, sourceApps: Array, role?: string | null, visibility: SimpleProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, workspace?: { __typename?: 'Workspace', id: string, role?: string | null, slug: string, name: string, readOnly: boolean, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans } | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, modelCount: { __typename?: 'ModelCollection', totalCount: number } } };
+export type ProjectModelsPageQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, sourceApps: Array, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, workspace?: { __typename?: 'Workspace', id: string, role?: string | null, slug: string, name: string, readOnly: boolean, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans } | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, modelCount: { __typename?: 'ModelCollection', totalCount: number } } };
export type ProjectDiscussionsPageQueryVariables = Exact<{
projectId: Scalars['String']['input'];
@@ -6146,7 +6145,7 @@ export type ProjectAutomationPageQueryVariables = Exact<{
}>;
-export type ProjectAutomationPageQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, workspaceId?: string | null, role?: string | null, visibility: SimpleProjectVisibility, automation: { __typename?: 'Automation', id: string, name: string, enabled: boolean, isTestAutomation: boolean, permissions: { __typename?: 'AutomationPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, currentRevision?: { __typename?: 'AutomationRevision', id: string, triggerDefinitions: Array<{ __typename?: 'VersionCreatedTriggerDefinition', type: AutomateRunTriggerType, model?: { __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null }>, functions: Array<{ __typename?: 'AutomationRevisionFunction', parameters?: {} | null, release: { __typename?: 'AutomateFunctionRelease', id: string, inputSchema?: {} | null, versionTag: string, createdAt: string, function: { __typename?: 'AutomateFunction', id: string, name: string, isFeatured: boolean, description: string, logo?: string | null, releases: { __typename?: 'AutomateFunctionReleaseCollection', items: Array<{ __typename?: 'AutomateFunctionRelease', id: string }> }, repo: { __typename?: 'BasicGitRepositoryMetadata', id: string, url: string, owner: string, name: string } } } }> } | null, runs: { __typename?: 'AutomateRunCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'AutomateRun', id: string, status: AutomateRunStatus, createdAt: string, updatedAt: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', statusMessage?: string | null, id: string, status: AutomateRunStatus }>, trigger: { __typename?: 'VersionCreatedTrigger', version?: { __typename?: 'Version', id: string } | null, model?: { __typename?: 'Model', id: string } | null } }> } }, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null } };
+export type ProjectAutomationPageQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, workspaceId?: string | null, role?: string | null, visibility: ProjectVisibility, automation: { __typename?: 'Automation', id: string, name: string, enabled: boolean, isTestAutomation: boolean, permissions: { __typename?: 'AutomationPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, currentRevision?: { __typename?: 'AutomationRevision', id: string, triggerDefinitions: Array<{ __typename?: 'VersionCreatedTriggerDefinition', type: AutomateRunTriggerType, model?: { __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null }>, functions: Array<{ __typename?: 'AutomationRevisionFunction', parameters?: {} | null, release: { __typename?: 'AutomateFunctionRelease', id: string, inputSchema?: {} | null, versionTag: string, createdAt: string, function: { __typename?: 'AutomateFunction', id: string, name: string, isFeatured: boolean, description: string, logo?: string | null, releases: { __typename?: 'AutomateFunctionReleaseCollection', items: Array<{ __typename?: 'AutomateFunctionRelease', id: string }> }, repo: { __typename?: 'BasicGitRepositoryMetadata', id: string, url: string, owner: string, name: string } } } }> } | null, runs: { __typename?: 'AutomateRunCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'AutomateRun', id: string, status: AutomateRunStatus, createdAt: string, updatedAt: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', statusMessage?: string | null, id: string, status: AutomateRunStatus }>, trigger: { __typename?: 'VersionCreatedTrigger', version?: { __typename?: 'Version', id: string } | null, model?: { __typename?: 'Model', id: string } | null } }> } }, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null } };
export type ProjectAutomationPagePaginatedRunsQueryVariables = Exact<{
projectId: Scalars['String']['input'];
@@ -6193,7 +6192,7 @@ export type OnProjectUpdatedSubscriptionVariables = Exact<{
}>;
-export type OnProjectUpdatedSubscription = { __typename?: 'Subscription', projectUpdated: { __typename?: 'ProjectUpdatedMessage', id: string, type: ProjectUpdatedMessageType, project?: { __typename?: 'Project', id: string, createdAt: string, name: string, updatedAt: string, role?: string | null, description?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, versions: { __typename?: 'VersionCollection', totalCount: number } } | null } };
+export type OnProjectUpdatedSubscription = { __typename?: 'Subscription', projectUpdated: { __typename?: 'ProjectUpdatedMessage', id: string, type: ProjectUpdatedMessageType, project?: { __typename?: 'Project', id: string, createdAt: string, name: string, updatedAt: string, role?: string | null, description?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, versions: { __typename?: 'VersionCollection', totalCount: number } } | null } };
export type OnProjectModelsUpdateSubscriptionVariables = Exact<{
id: Scalars['String']['input'];
@@ -6314,7 +6313,7 @@ export type AdminPanelProjectsListQueryVariables = Exact<{
}>;
-export type AdminPanelProjectsListQuery = { __typename?: 'Query', admin: { __typename?: 'AdminQueries', projectList: { __typename?: 'ProjectCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, visibility: SimpleProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null }> } }, activeUser?: { __typename?: 'User', permissions: { __typename?: 'RootPermissionChecks', canCreatePersonalProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null };
+export type AdminPanelProjectsListQuery = { __typename?: 'Query', admin: { __typename?: 'AdminQueries', projectList: { __typename?: 'ProjectCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, visibility: ProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null }> } }, activeUser?: { __typename?: 'User', permissions: { __typename?: 'RootPermissionChecks', canCreatePersonalProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null };
export type AdminPanelInvitesListQueryVariables = Exact<{
limit: Scalars['Int']['input'];
@@ -6518,7 +6517,7 @@ export type SettingsWorkspacesProjectsQueryVariables = Exact<{
}>;
-export type SettingsWorkspacesProjectsQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, name: string, slug: string, role?: string | null, projects: { __typename?: 'ProjectCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, visibility: SimpleProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null }> }, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans } | null, permissions: { __typename?: 'WorkspacePermissionChecks', canCreateProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } };
+export type SettingsWorkspacesProjectsQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, name: string, slug: string, role?: string | null, projects: { __typename?: 'ProjectCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, visibility: ProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null }> }, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans } | null, permissions: { __typename?: 'WorkspacePermissionChecks', canCreateProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } };
export type SettingsWorkspaceSecurityQueryVariables = Exact<{
slug: Scalars['String']['input'];
@@ -6555,7 +6554,7 @@ export type UpdateLegacyProjectsExplainerMutation = { __typename?: 'Mutation', a
export type OnUserProjectsUpdateSubscriptionVariables = Exact<{ [key: string]: never; }>;
-export type OnUserProjectsUpdateSubscription = { __typename?: 'Subscription', userProjectsUpdated: { __typename?: 'UserProjectsUpdatedMessage', type: UserProjectsUpdatedMessageType, id: string, project?: { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: SimpleProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null } };
+export type OnUserProjectsUpdateSubscription = { __typename?: 'Subscription', userProjectsUpdated: { __typename?: 'UserProjectsUpdatedMessage', type: UserProjectsUpdatedMessageType, id: string, project?: { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null } };
export type UpdateUserMutationVariables = Exact<{
input: UserUpdateInput;
@@ -6654,7 +6653,7 @@ export type ViewerLoadedResourcesQueryVariables = Exact<{
}>;
-export type ViewerLoadedResourcesQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, role?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, createdAt: string, name: string, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, updatedAt: string, loadedVersion: { __typename?: 'VersionCollection', items: Array<{ __typename?: 'Version', id: string, message?: string | null, referencedObject?: string | null, sourceApplication?: string | null, createdAt: string, previewUrl: string, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null }> }, versions: { __typename?: 'VersionCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Version', id: string, message?: string | null, referencedObject?: string | null, sourceApplication?: string | null, createdAt: string, previewUrl: string, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null }> } }> }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, role?: string | null } | null, modelCount: { __typename?: 'ModelCollection', totalCount: number }, permissions: { __typename?: 'ProjectPermissionChecks', canCreateComment: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canBroadcastActivity: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRequestRender: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } };
+export type ViewerLoadedResourcesQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, role?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, createdAt: string, name: string, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, updatedAt: string, loadedVersion: { __typename?: 'VersionCollection', items: Array<{ __typename?: 'Version', id: string, message?: string | null, referencedObject?: string | null, sourceApplication?: string | null, createdAt: string, previewUrl: string, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null }> }, versions: { __typename?: 'VersionCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Version', id: string, message?: string | null, referencedObject?: string | null, sourceApplication?: string | null, createdAt: string, previewUrl: string, authorUser?: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } | null }> } }> }, workspace?: { __typename?: 'Workspace', id: string, readOnly: boolean, slug: string, name: string, role?: string | null } | null, modelCount: { __typename?: 'ModelCollection', totalCount: number }, permissions: { __typename?: 'ProjectPermissionChecks', canCreateComment: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canBroadcastActivity: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRequestRender: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } };
export type ViewerModelVersionsQueryVariables = Exact<{
projectId: Scalars['String']['input'];
@@ -6727,7 +6726,7 @@ export type OnWorkspaceProjectsUpdateSubscriptionVariables = Exact<{
}>;
-export type OnWorkspaceProjectsUpdateSubscription = { __typename?: 'Subscription', workspaceProjectsUpdated: { __typename?: 'WorkspaceProjectsUpdatedMessage', projectId: string, workspaceId: string, type: WorkspaceProjectsUpdatedMessageType, project?: { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: SimpleProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null } };
+export type OnWorkspaceProjectsUpdateSubscription = { __typename?: 'Subscription', workspaceProjectsUpdated: { __typename?: 'WorkspaceProjectsUpdatedMessage', projectId: string, workspaceId: string, type: WorkspaceProjectsUpdatedMessageType, project?: { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null } };
export type WorkspaceHasCustomDataResidency_WorkspaceFragment = { __typename?: 'Workspace', id: string, defaultRegion?: { __typename?: 'ServerRegionItem', id: string, name: string } | null };
@@ -6874,7 +6873,7 @@ export type WorkspaceProjectsQueryQueryVariables = Exact<{
}>;
-export type WorkspaceProjectsQueryQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, projects: { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: SimpleProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } } };
+export type WorkspaceProjectsQueryQuery = { __typename?: 'Query', workspaceBySlug: { __typename?: 'Workspace', id: string, projects: { __typename?: 'ProjectCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, role?: string | null, visibility: ProjectVisibility, models: { __typename?: 'ModelCollection', totalCount: number, items: Array<{ __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, readOnly: boolean } | null, pendingImportedModels: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', id: string, name: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } }> } } };
export type WorkspaceFunctionsQueryQueryVariables = Exact<{
workspaceSlug: Scalars['String']['input'];
@@ -7071,15 +7070,15 @@ export type AutomateFunctionPageWorkspaceQueryVariables = Exact<{
export type AutomateFunctionPageWorkspaceQuery = { __typename?: 'Query', workspace: { __typename?: 'Workspace', id: string, name: string, slug: string } };
-export type ProjectPageProjectFragment = { __typename?: 'Project', id: string, createdAt: string, role?: string | null, name: string, description?: string | null, allowPublicComments: boolean, visibility: SimpleProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, versions: { __typename?: 'VersionCollection', totalCount: number } };
+export type ProjectPageProjectFragment = { __typename?: 'Project', id: string, createdAt: string, role?: string | null, name: string, description?: string | null, allowPublicComments: boolean, visibility: ProjectVisibility, modelCount: { __typename?: 'ModelCollection', totalCount: number }, commentThreadCount: { __typename?: 'ProjectCommentCollection', totalCount: number }, workspace?: { __typename?: 'Workspace', id: string, slug: string, name: string, logo?: string | null, role?: string | null } | null, permissions: { __typename?: 'ProjectPermissionChecks', canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canMoveToWorkspace: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, invitedTeam?: Array<{ __typename?: 'PendingStreamCollaborator', id: string, title: string, role: string, inviteId: string, user?: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } | null }> | null, team: Array<{ __typename?: 'ProjectCollaborator', role: string, seatType?: WorkspaceSeatType | null, workspaceRole?: string | null, id: string, user: { __typename?: 'LimitedUser', role?: string | null, id: string, name: string, avatar?: string | null } }>, versions: { __typename?: 'VersionCollection', totalCount: number } };
export type ProjectPageAutomationPage_AutomationFragment = { __typename?: 'Automation', id: string, name: string, enabled: boolean, isTestAutomation: boolean, permissions: { __typename?: 'AutomationPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, currentRevision?: { __typename?: 'AutomationRevision', id: string, triggerDefinitions: Array<{ __typename?: 'VersionCreatedTriggerDefinition', type: AutomateRunTriggerType, model?: { __typename?: 'Model', id: string, name: string, displayName: string, previewUrl?: string | null, createdAt: string, updatedAt: string, description?: string | null, versionCount: { __typename?: 'VersionCollection', totalCount: number }, commentThreadCount: { __typename?: 'CommentCollection', totalCount: number }, pendingImportedVersions: Array<{ __typename?: 'FileUpload', id: string, projectId: string, modelName: string, convertedStatus: number, convertedMessage?: string | null, uploadDate: string, convertedLastUpdate: string, fileType: string, fileName: string }>, automationsStatus?: { __typename?: 'TriggeredAutomationsStatus', id: string, automationRuns: Array<{ __typename?: 'AutomateRun', id: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', id: string, updatedAt: string, status: AutomateRunStatus, results?: {} | null, statusMessage?: string | null, contextView?: string | null, createdAt: string, function?: { __typename?: 'AutomateFunction', id: string, logo?: string | null, name: string } | null }>, automation: { __typename?: 'Automation', id: string, name: string } }> } | null, permissions: { __typename?: 'ModelPermissionChecks', canUpdate: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canCreateVersion: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } } | null }>, functions: Array<{ __typename?: 'AutomationRevisionFunction', parameters?: {} | null, release: { __typename?: 'AutomateFunctionRelease', id: string, inputSchema?: {} | null, versionTag: string, createdAt: string, function: { __typename?: 'AutomateFunction', id: string, name: string, isFeatured: boolean, description: string, logo?: string | null, releases: { __typename?: 'AutomateFunctionReleaseCollection', items: Array<{ __typename?: 'AutomateFunctionRelease', id: string }> }, repo: { __typename?: 'BasicGitRepositoryMetadata', id: string, url: string, owner: string, name: string } } } }> } | null, runs: { __typename?: 'AutomateRunCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'AutomateRun', id: string, status: AutomateRunStatus, createdAt: string, updatedAt: string, functionRuns: Array<{ __typename?: 'AutomateFunctionRun', statusMessage?: string | null, id: string, status: AutomateRunStatus }>, trigger: { __typename?: 'VersionCreatedTrigger', version?: { __typename?: 'Version', id: string } | null, model?: { __typename?: 'Model', id: string } | null } }> } };
-export type ProjectPageAutomationPage_ProjectFragment = { __typename?: 'Project', id: string, workspaceId?: string | null, role?: string | null, visibility: SimpleProjectVisibility, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
+export type ProjectPageAutomationPage_ProjectFragment = { __typename?: 'Project', id: string, workspaceId?: string | null, role?: string | null, visibility: ProjectVisibility, permissions: { __typename?: 'ProjectPermissionChecks', canCreateModel: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', id: string, slug: string } | null };
export type ProjectPageSettingsTab_ProjectFragment = { __typename?: 'Project', id: string, name: string, permissions: { __typename?: 'ProjectPermissionChecks', canReadWebhooks: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
-export type SettingsServerProjects_ProjectCollectionFragment = { __typename?: 'ProjectCollection', totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, visibility: SimpleProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null }> };
+export type SettingsServerProjects_ProjectCollectionFragment = { __typename?: 'ProjectCollection', totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, visibility: ProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null }> };
export type SettingsServerProjects_UserFragment = { __typename?: 'User', permissions: { __typename?: 'RootPermissionChecks', canCreatePersonalProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
@@ -7092,7 +7091,7 @@ export type SettingsWorkspacesGeneral_WorkspaceFragment = { __typename?: 'Worksp
export type SettingsWorkspacesMembersCounts_WorkspaceFragment = { __typename?: 'Workspace', id: string, role?: string | null, invitedTeam?: Array<{ __typename?: 'PendingWorkspaceCollaborator', id: string }> | null, adminWorkspacesJoinRequests?: { __typename?: 'WorkspaceJoinRequestCollection', items: Array<{ __typename?: 'WorkspaceJoinRequest', id: string, status: WorkspaceJoinRequestStatus }> } | null };
-export type SettingsWorkspacesProjects_ProjectCollectionFragment = { __typename?: 'ProjectCollection', totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, visibility: SimpleProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null }> };
+export type SettingsWorkspacesProjects_ProjectCollectionFragment = { __typename?: 'ProjectCollection', totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, visibility: ProjectVisibility, createdAt: string, updatedAt: string, role?: string | null, models: { __typename?: 'ModelCollection', totalCount: number }, versions: { __typename?: 'VersionCollection', totalCount: number }, team: Array<{ __typename?: 'ProjectCollaborator', id: string, user: { __typename?: 'LimitedUser', name: string, id: string, avatar?: string | null } }>, permissions: { __typename?: 'ProjectPermissionChecks', canDelete: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canReadSettings: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null }, canRead: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } }, workspace?: { __typename?: 'Workspace', slug: string, id: string } | null }> };
export type SettingsWorkspacesProjects_WorkspaceFragment = { __typename?: 'Workspace', id: string, name: string, slug: string, role?: string | null, plan?: { __typename?: 'WorkspacePlan', name: WorkspacePlans } | null, permissions: { __typename?: 'WorkspacePermissionChecks', canCreateProject: { __typename?: 'PermissionCheckResult', authorized: boolean, code: string, message: string, payload?: {} | null } } };
@@ -7167,7 +7166,7 @@ export const ProjectPageModelsCardDeleteDialogFragmentDoc = {"kind":"Document","
export const ProjectPageModelsActionsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsActions"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}},{"kind":"Field","name":{"kind":"Name","value":"canDelete"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}},{"kind":"Field","name":{"kind":"Name","value":"canCreateVersion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}}]} as unknown as DocumentNode;
export const ProjectPageLatestItemsModelItemFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageLatestItemsModelItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","alias":{"kind":"Name","value":"versionCount"},"name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"commentThreadCount"},"name":{"kind":"Name","value":"commentThreads"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pendingImportedVersions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"1"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PendingFileUpload"}}]}},{"kind":"Field","name":{"kind":"Name","value":"previewUrl"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsActions"}},{"kind":"Field","name":{"kind":"Name","value":"automationsStatus"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"}}]}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}},{"kind":"Field","name":{"kind":"Name","value":"canDelete"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FunctionRunStatusForSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"FunctionRunStatusForSummary"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"results"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"statusMessage"}},{"kind":"Field","name":{"kind":"Name","value":"contextView"}},{"kind":"Field","name":{"kind":"Name","value":"function"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PendingFileUpload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FileUpload"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"projectId"}},{"kind":"Field","name":{"kind":"Name","value":"modelName"}},{"kind":"Field","name":{"kind":"Name","value":"convertedStatus"}},{"kind":"Field","name":{"kind":"Name","value":"convertedMessage"}},{"kind":"Field","name":{"kind":"Name","value":"uploadDate"}},{"kind":"Field","name":{"kind":"Name","value":"convertedLastUpdate"}},{"kind":"Field","name":{"kind":"Name","value":"fileType"}},{"kind":"Field","name":{"kind":"Name","value":"fileName"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsActions"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}},{"kind":"Field","name":{"kind":"Name","value":"canDelete"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}},{"kind":"Field","name":{"kind":"Name","value":"canCreateVersion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"}}]}}]} as unknown as DocumentNode;
export const SingleLevelModelTreeItemFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SingleLevelModelTreeItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ModelsTreeItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"model"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageLatestItemsModelItem"}}]}},{"kind":"Field","name":{"kind":"Name","value":"hasChildren"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PendingFileUpload"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FileUpload"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"projectId"}},{"kind":"Field","name":{"kind":"Name","value":"modelName"}},{"kind":"Field","name":{"kind":"Name","value":"convertedStatus"}},{"kind":"Field","name":{"kind":"Name","value":"convertedMessage"}},{"kind":"Field","name":{"kind":"Name","value":"uploadDate"}},{"kind":"Field","name":{"kind":"Name","value":"convertedLastUpdate"}},{"kind":"Field","name":{"kind":"Name","value":"fileType"}},{"kind":"Field","name":{"kind":"Name","value":"fileName"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageModelsActions"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}},{"kind":"Field","name":{"kind":"Name","value":"canDelete"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}},{"kind":"Field","name":{"kind":"Name","value":"canCreateVersion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FunctionRunStatusForSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"FunctionRunStatusForSummary"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateFunctionRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"results"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"statusMessage"}},{"kind":"Field","name":{"kind":"Name","value":"contextView"}},{"kind":"Field","name":{"kind":"Name","value":"function"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AutomateRun"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"functionRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRun"}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomationsStatusOrderedRuns_AutomationRun"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"automationRuns"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialogRunsRows_AutomateRun"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TriggeredAutomationsStatus"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"TriggeredAutomationsStatusSummary"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatus"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageLatestItemsModelItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Model"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","alias":{"kind":"Name","value":"versionCount"},"name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"commentThreadCount"},"name":{"kind":"Name","value":"commentThreads"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pendingImportedVersions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"1"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PendingFileUpload"}}]}},{"kind":"Field","name":{"kind":"Name","value":"previewUrl"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardRenameDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsCardDeleteDialog"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageModelsActions"}},{"kind":"Field","name":{"kind":"Name","value":"automationsStatus"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AutomateRunsTriggerStatus_TriggeredAutomationsStatus"}}]}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}},{"kind":"Field","name":{"kind":"Name","value":"canDelete"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}}]} as unknown as DocumentNode;
-export const ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}}]} as unknown as DocumentNode;
+export const ProjectPageSettingsGeneralBlockAccess_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}}]} as unknown as DocumentNode;
export const ProjectsDeleteDialog_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsDeleteDialog_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]} as unknown as DocumentNode;
export const ProjectPageSettingsGeneralBlockDelete_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsDeleteDialog_Project"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsDeleteDialog_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}}]} as unknown as DocumentNode;
export const ProjectPageSettingsGeneralBlockDiscussions_ProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllowPublicComments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}}]} as unknown as DocumentNode;
@@ -7295,7 +7294,7 @@ export const AutomationCreateDialogFunctionsSearchDocument = {"kind":"Document",
export const InviteDialogProjectRowProjectCollaboratorsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"InviteDialogProjectRowProjectCollaborators"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"InvitableCollaboratorsFilter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"invitableCollaborators"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"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"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode;
export const ProjectPageCollaboratorsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectPageCollaborators"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceTeamFilter"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"InviteDialogProject_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageCollaborators_Project"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SettingsWorkspacesMembersTableHeader_Workspace"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageCollaborators_WorkspaceCollaborator"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LimitedUserAvatar"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"InviteDialogWorkspace_Workspace"},"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":"domainBasedMembershipProtectionEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"domains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"seatType"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceRole"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"InviteDialogProject_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","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":"role"}},{"kind":"Field","name":{"kind":"Name","value":"domainBasedMembershipProtectionEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"domains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageCollaborators_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SettingsWorkspacesMembersTableHeader_Workspace"},"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":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"InviteDialogWorkspace_Workspace"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageCollaborators_WorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"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":"avatar"}}]}}]}}]} as unknown as DocumentNode;
export const InvitableCollaboratorsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"InvitableCollaborators"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"InvitableCollaboratorsFilter"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"invitableCollaborators"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}}],"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":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceRole"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"workspaceId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}}]}]}}]}}]}}]}}]}}]} as unknown as DocumentNode;
-export const ProjectPageSettingsGeneralDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectPageSettingsGeneral"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockProjectInfo_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockLeave_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LimitedUserAvatar"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsDeleteDialog_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockProjectInfo_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllowPublicComments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockLeave_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canLeave"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsDeleteDialog_Project"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"seatType"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceRole"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}}]}}]} as unknown as DocumentNode;
+export const ProjectPageSettingsGeneralDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectPageSettingsGeneral"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockProjectInfo_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockLeave_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"FullPermissionCheckResult"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PermissionCheckResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"authorized"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LimitedUserAvatar"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectsDeleteDialog_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"models"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockProjectInfo_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockAccess_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDiscussions_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"allowPublicComments"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllowPublicComments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockLeave_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canLeave"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageSettingsGeneralBlockDelete_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsDeleteDialog_Project"}},{"kind":"Field","name":{"kind":"Name","value":"permissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"canUpdate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"FullPermissionCheckResult"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ProjectPageTeamInternals_Project"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"invitedTeam"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"inviteId"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"seatType"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceRole"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"LimitedUserAvatar"}}]}}]}}]}}]} as unknown as DocumentNode;
export const ActiveUserMainMetadataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ActiveUserMainMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"emails"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}}]}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"isOnboardingFinished"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}},{"kind":"Field","name":{"kind":"Name","value":"notificationPreferences"}},{"kind":"Field","name":{"kind":"Name","value":"versions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"0"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}}]} as unknown as DocumentNode;
export const ActiveUserProjectsToMoveDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ActiveUserProjectsToMove"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UserProjectsFilter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"projects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}}]} as unknown as DocumentNode;
export const FinishOnboardingDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"FinishOnboarding"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OnboardingCompletionInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUserMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"finishOnboarding"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]}}]} as unknown as DocumentNode;
diff --git a/packages/frontend-2/lib/projects/helpers/visibility.ts b/packages/frontend-2/lib/projects/helpers/visibility.ts
new file mode 100644
index 000000000..88a3acef7
--- /dev/null
+++ b/packages/frontend-2/lib/projects/helpers/visibility.ts
@@ -0,0 +1,26 @@
+import { throwUncoveredError } from '@speckle/shared'
+import { ProjectVisibility } from '~/lib/common/generated/gql/graphql'
+
+export const SupportedProjectVisibility = {
+ Public: ProjectVisibility.Public,
+ Private: ProjectVisibility.Private,
+ Workspace: ProjectVisibility.Workspace
+}
+
+export type SupportedProjectVisibility =
+ (typeof SupportedProjectVisibility)[keyof typeof SupportedProjectVisibility]
+
+export const castToSupportedVisibility = (
+ visibility: ProjectVisibility
+): SupportedProjectVisibility => {
+ switch (visibility) {
+ case ProjectVisibility.Public:
+ case ProjectVisibility.Unlisted:
+ return SupportedProjectVisibility.Public
+ case ProjectVisibility.Private:
+ case ProjectVisibility.Workspace:
+ return visibility
+ default:
+ throwUncoveredError(visibility)
+ }
+}
diff --git a/packages/frontend-2/middleware/requireValidModel.ts b/packages/frontend-2/middleware/requireValidModel.ts
index cbaa3770a..47b57c12d 100644
--- a/packages/frontend-2/middleware/requireValidModel.ts
+++ b/packages/frontend-2/middleware/requireValidModel.ts
@@ -1,4 +1,7 @@
-import { SimpleProjectVisibility } from '~/lib/common/generated/gql/graphql'
+import {
+ castToSupportedVisibility,
+ SupportedProjectVisibility
+} from '~/lib/projects/helpers/visibility'
import { WorkspaceSsoErrorCodes } from '~/lib/workspaces/helpers/types'
import { useApolloClientFromNuxt } from '~~/lib/common/composables/graphql'
import {
@@ -43,10 +46,10 @@ export default defineNuxtRouteMiddleware(async (to) => {
return
}
- // If project is public or link shareable, allow access
+ // If project is public, allow access
if (
- // data.project.visibility === SimpleProjectVisibility.Public ||
- data.project.visibility === SimpleProjectVisibility.Unlisted
+ castToSupportedVisibility(data.project.visibility) ===
+ SupportedProjectVisibility.Public
) {
return
}
diff --git a/packages/server/assets/core/typedefs/projects.graphql b/packages/server/assets/core/typedefs/projects.graphql
index d44cf3eb5..9272a02c2 100644
--- a/packages/server/assets/core/typedefs/projects.graphql
+++ b/packages/server/assets/core/typedefs/projects.graphql
@@ -7,17 +7,22 @@ extend type Query {
}
enum ProjectVisibility {
+ """
+ Only accessible to explicit collaborators
+ """
PRIVATE
+ """
+ Legacy - same as public
+ """
UNLISTED
+ """
+ Accessible to everyone (even non-logged in users)
+ """
PUBLIC
-}
-
-"""
-Visibility without the "discoverable" option
-"""
-enum SimpleProjectVisibility {
- PRIVATE
- UNLISTED
+ """
+ Accessible to everyone in the project's workspace
+ """
+ WORKSPACE
}
"""
@@ -175,7 +180,7 @@ type Project {
id: ID!
name: String!
description: String
- visibility: SimpleProjectVisibility!
+ visibility: ProjectVisibility!
allowPublicComments: Boolean!
"""
Active user's role for this project. `null` if request is not authenticated, or the project is not explicitly shared with you.
diff --git a/packages/server/assets/core/typedefs/streams.graphql b/packages/server/assets/core/typedefs/streams.graphql
index d179e527c..2379a8796 100644
--- a/packages/server/assets/core/typedefs/streams.graphql
+++ b/packages/server/assets/core/typedefs/streams.graphql
@@ -61,6 +61,7 @@ type Stream {
and searches
"""
isDiscoverable: Boolean!
+ @deprecated(reason: "Discoverability as a feature has been removed.")
allowPublicComments: Boolean!
"""
Your role for this stream. `null` if request is not authenticated, or the stream is not explicitly shared with you.
diff --git a/packages/server/modules/cli/commands/db/seed/commits.ts b/packages/server/modules/cli/commands/db/seed/commits.ts
index 5e01cfc5e..d62e8726f 100644
--- a/packages/server/modules/cli/commands/db/seed/commits.ts
+++ b/packages/server/modules/cli/commands/db/seed/commits.ts
@@ -9,6 +9,7 @@ import { BasicTestCommit, createTestCommits } from '@/test/speckle-helpers/commi
import dayjs from 'dayjs'
import { times } from 'lodash'
import { CommandModule } from 'yargs'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
const command: CommandModule<
unknown,
@@ -49,7 +50,7 @@ const command: CommandModule<
if (!stream?.id) {
throw new StreamNotFoundError(`Stream with ID ${streamId} not found`)
}
- if (!stream.isPublic && !stream.role) {
+ if (stream.visibility !== ProjectRecordVisibility.Public && !stream.role) {
throw new ForbiddenError(
`Commit author does not have access to the specified stream ${streamId}`
)
diff --git a/packages/server/modules/comments/services/management.ts b/packages/server/modules/comments/services/management.ts
index 839995369..a709644b0 100644
--- a/packages/server/modules/comments/services/management.ts
+++ b/packages/server/modules/comments/services/management.ts
@@ -1,7 +1,4 @@
-import { ensureError, Roles, SpeckleViewer } from '@speckle/shared'
-import { AuthContext } from '@/modules/shared/authz'
-import { ForbiddenError } from '@/modules/shared/errors'
-import { StreamInvalidAccessError } from '@/modules/core/errors/stream'
+import { ensureError, SpeckleViewer } from '@speckle/shared'
import {
CreateCommentInput,
CreateCommentReplyInput,
@@ -18,7 +15,6 @@ import {
formatSerializedViewerState,
inputToDataStruct
} from '@/modules/comments/services/data'
-import { adminOverrideEnabled } from '@/modules/shared/helpers/envHelper'
import {
ArchiveCommentAndNotify,
CreateCommentReplyAndNotify,
@@ -38,57 +34,6 @@ import {
import { GetStream } from '@/modules/core/domain/streams/operations'
import { EventBusEmit } from '@/modules/shared/services/eventBus'
import { CommentEvents } from '@/modules/comments/domain/events'
-import { authorizeResolver } from '@/modules/shared'
-
-type AuthorizeProjectCommentsAccessDeps = {
- getStream: GetStream
- adminOverrideEnabled: typeof adminOverrideEnabled
-}
-
-export const authorizeProjectCommentsAccessFactory =
- (deps: AuthorizeProjectCommentsAccessDeps) =>
- async (params: {
- projectId: string
- authCtx: AuthContext
- requireProjectRole?: boolean
- }) => {
- const { projectId, authCtx, requireProjectRole } = params
- if (authCtx.role === Roles.Server.ArchivedUser) {
- throw new ForbiddenError('You are not authorized')
- }
-
- const project = await deps.getStream({
- streamId: projectId,
- userId: authCtx.userId
- })
- if (!project) {
- throw new StreamInvalidAccessError('Stream not found')
- }
-
- let success = true
- if (!project.isPublic && !authCtx.auth) success = false
- if (!project.isPublic && !project.role) success = false
- if (requireProjectRole && !project.role && !project.allowPublicComments)
- success = false
- if (deps.adminOverrideEnabled() && authCtx.role === Roles.Server.Admin)
- success = true
-
- // TODO: Until we do canCommentCreate & canCommentRead, fallback:
- if (authCtx.userId && (!requireProjectRole || project.allowPublicComments)) {
- try {
- await authorizeResolver(authCtx.userId, projectId, Roles.Stream.Reviewer, null)
- success = true
- } catch {
- // suppress
- }
- }
-
- if (!success) {
- throw new StreamInvalidAccessError('You are not authorized')
- }
-
- return project
- }
export const createCommentThreadAndNotifyFactory =
(deps: {
diff --git a/packages/server/modules/comments/tests/comments.graph.spec.ts b/packages/server/modules/comments/tests/comments.graph.spec.ts
index 60cf702f8..c161fe223 100644
--- a/packages/server/modules/comments/tests/comments.graph.spec.ts
+++ b/packages/server/modules/comments/tests/comments.graph.spec.ts
@@ -300,7 +300,11 @@ const testResult = (
) => void
) => {
if (shouldSucceed) {
- expect(result.errors, 'This should not have failed').to.not.exist
+ expect(
+ result.errors,
+ 'This should not have failed and yet we found errors: ' +
+ JSON.stringify(result.errors)
+ ).to.not.exist
successTests(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
result as SetNonNullable>, 'data'>
diff --git a/packages/server/modules/core/dbSchema.ts b/packages/server/modules/core/dbSchema.ts
index cf02d1ab3..8056a470d 100644
--- a/packages/server/modules/core/dbSchema.ts
+++ b/packages/server/modules/core/dbSchema.ts
@@ -266,14 +266,13 @@ export const Streams = buildTableHelper(
'id',
'name',
'description',
- 'isPublic',
'clonedFrom',
'createdAt',
'updatedAt',
'allowPublicComments',
- 'isDiscoverable',
'workspaceId',
- 'regionKey'
+ 'regionKey',
+ 'visibility'
],
StreamsMeta
)
diff --git a/packages/server/modules/core/domain/projects/operations.ts b/packages/server/modules/core/domain/projects/operations.ts
index 11167950b..88a41f347 100644
--- a/packages/server/modules/core/domain/projects/operations.ts
+++ b/packages/server/modules/core/domain/projects/operations.ts
@@ -5,7 +5,7 @@ import { MaybeNullOrUndefined, StreamRoles } from '@speckle/shared'
export type GetProject = (args: { projectId: string }) => Promise
export type UpdateProject = (args: {
- projectUpdate: Pick
+ projectUpdate: Pick & Partial
}) => Promise
export type StoreProjectRole = (args: {
@@ -38,7 +38,7 @@ export type GetRolesByUserId = ({
workspaceId?: string
}) => Promise[]>
-export type ProjectVisibility = 'PRIVATE' | 'PUBLIC' | 'UNLISTED'
+export type ProjectVisibility = 'PRIVATE' | 'PUBLIC' | 'UNLISTED' | 'WORKSPACE'
export type ProjectCreateArgs = {
description?: MaybeNullOrUndefined
diff --git a/packages/server/modules/core/domain/streams/operations.ts b/packages/server/modules/core/domain/streams/operations.ts
index 9588d1cd7..90220dba2 100644
--- a/packages/server/modules/core/domain/streams/operations.ts
+++ b/packages/server/modules/core/domain/streams/operations.ts
@@ -23,12 +23,13 @@ import type express from 'express'
import { ProjectCreateArgs } from '@/modules/core/domain/projects/operations'
import { ServerInviteRecord } from '@/modules/serverinvites/domain/types'
import type { Logger } from 'pino'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
export type LegacyGetStreams = (params: {
cursor?: string | Date | null | undefined
limit: number
orderBy?: string | null | undefined
- visibility?: string | null | undefined
+ visibility?: ProjectRecordVisibility | 'all' | null | undefined
searchQuery?: string | null | undefined
streamIdWhitelist?: string[] | null | undefined
workspaceIdWhitelist?: string[] | null | undefined
diff --git a/packages/server/modules/core/graph/generated/graphql.ts b/packages/server/modules/core/graph/generated/graphql.ts
index c3add11c1..ed3708335 100644
--- a/packages/server/modules/core/graph/generated/graphql.ts
+++ b/packages/server/modules/core/graph/generated/graphql.ts
@@ -2090,7 +2090,7 @@ export type Project = {
versions: VersionCollection;
/** Return metadata about resources being requested in the viewer */
viewerResources: Array;
- visibility: SimpleProjectVisibility;
+ visibility: ProjectVisibility;
webhooks: WebhookCollection;
workspace?: Maybe;
workspaceId?: Maybe;
@@ -2711,9 +2711,14 @@ export const ProjectVersionsUpdatedMessageType = {
export type ProjectVersionsUpdatedMessageType = typeof ProjectVersionsUpdatedMessageType[keyof typeof ProjectVersionsUpdatedMessageType];
export const ProjectVisibility = {
+ /** Only accessible to explicit collaborators */
Private: 'PRIVATE',
+ /** Accessible to everyone (even non-logged in users) */
Public: 'PUBLIC',
- Unlisted: 'UNLISTED'
+ /** Legacy - same as public */
+ Unlisted: 'UNLISTED',
+ /** Accessible to everyone in the project's workspace */
+ Workspace: 'WORKSPACE'
} as const;
export type ProjectVisibility = typeof ProjectVisibility[keyof typeof ProjectVisibility];
@@ -3263,13 +3268,6 @@ export type SetPrimaryUserEmailInput = {
id: Scalars['ID']['input'];
};
-/** Visibility without the "discoverable" option */
-export const SimpleProjectVisibility = {
- Private: 'PRIVATE',
- Unlisted: 'UNLISTED'
-} as const;
-
-export type SimpleProjectVisibility = typeof SimpleProjectVisibility[keyof typeof SimpleProjectVisibility];
export type SmartTextEditorValue = {
__typename?: 'SmartTextEditorValue';
/** File attachments, if any */
@@ -3346,6 +3344,7 @@ export type Stream = {
/**
* Whether the stream (if public) can be found on public stream exploration pages
* and searches
+ * @deprecated Discoverability as a feature has been removed.
*/
isDiscoverable: Scalars['Boolean']['output'];
/** Whether the stream can be viewed by non-contributors */
@@ -5424,7 +5423,6 @@ export type ResolversTypes = {
ServerWorkspacesInfo: ResolverTypeWrapper;
SessionPaymentStatus: SessionPaymentStatus;
SetPrimaryUserEmailInput: SetPrimaryUserEmailInput;
- SimpleProjectVisibility: SimpleProjectVisibility;
SmartTextEditorValue: ResolverTypeWrapper;
SortDirection: SortDirection;
Stream: ResolverTypeWrapper;
@@ -6668,7 +6666,7 @@ export type ProjectResolvers>;
versions?: Resolver>;
viewerResources?: Resolver, ParentType, ContextType, RequireFields>;
- visibility?: Resolver;
+ visibility?: Resolver;
webhooks?: Resolver>;
workspace?: Resolver, ParentType, ContextType>;
workspaceId?: Resolver, ParentType, ContextType>;
diff --git a/packages/server/modules/core/graph/resolvers/projects.ts b/packages/server/modules/core/graph/resolvers/projects.ts
index c4880b738..9ffaf4ea9 100644
--- a/packages/server/modules/core/graph/resolvers/projects.ts
+++ b/packages/server/modules/core/graph/resolvers/projects.ts
@@ -7,7 +7,6 @@ import {
} from '@/modules/comments/repositories/comments'
import { RateLimitError } from '@/modules/core/errors/ratelimit'
import {
- ProjectVisibility,
Resolvers,
TokenResourceIdentifierType
} from '@/modules/core/graph/generated/graphql'
@@ -116,6 +115,8 @@ import { requestNewEmailVerificationFactory } from '@/modules/emails/services/ve
import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories'
import { renderEmail } from '@/modules/emails/services/emailRendering'
import { sendEmail } from '@/modules/emails/services/sending'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
+import { mapDbToGqlProjectVisibility } from '@/modules/core/helpers/project'
const getServerInfo = getServerInfoFactory({ db })
const getUsers = getUsersFactory({ db })
@@ -251,6 +252,12 @@ const getUserStreamsCount = getUserStreamsCountFactory({ db })
export = {
Query: {
async project(_parent, args, context) {
+ throwIfResourceAccessNotAllowed({
+ resourceId: args.id,
+ resourceType: TokenResourceIdentifierType.Project,
+ resourceAccessRules: context.resourceAccessRules
+ })
+
const canQuery = await context.authPolicies.project.canRead({
projectId: args.id,
userId: context.userId
@@ -259,8 +266,7 @@ export = {
const project = await getStream({ streamId: args.id })
- // TODO: Should scopes & token resource access rules be checked in authz policy?
- if (!project?.isPublic && !project?.isDiscoverable) {
+ if (project?.visibility !== ProjectRecordVisibility.Public) {
await validateScopes(context.scopes, Scopes.Streams.Read)
}
@@ -614,12 +620,9 @@ export = {
.streams.getSourceApps.load(parent.id) || []
)
},
-
async visibility(parent) {
- const { isPublic } = parent
-
- // Ignore discoverability for now
- return isPublic ? ProjectVisibility.Unlisted : ProjectVisibility.Private
+ const { visibility } = parent
+ return mapDbToGqlProjectVisibility(visibility)
}
},
PendingStreamCollaborator: {
diff --git a/packages/server/modules/core/graph/resolvers/streams.ts b/packages/server/modules/core/graph/resolvers/streams.ts
index 4619cfed4..2511a3c58 100644
--- a/packages/server/modules/core/graph/resolvers/streams.ts
+++ b/packages/server/modules/core/graph/resolvers/streams.ts
@@ -36,12 +36,16 @@ import {
updateStreamAndNotifyFactory,
updateStreamRoleAndNotifyFactory
} from '@/modules/core/services/streams/management'
-import { Roles, Scopes } from '@speckle/shared'
+import { Nullable, Roles, Scopes } from '@speckle/shared'
import { StreamNotFoundError } from '@/modules/core/errors/stream'
import { throwForNotHavingServerRole } from '@/modules/shared/authz'
import { RateLimitError } from '@/modules/core/errors/ratelimit'
-import { toProjectIdWhitelist, isResourceAllowed } from '@/modules/core/helpers/token'
+import {
+ toProjectIdWhitelist,
+ isResourceAllowed,
+ throwIfResourceAccessNotAllowed
+} from '@/modules/core/helpers/token'
import {
Resolvers,
TokenResourceIdentifierType
@@ -97,6 +101,7 @@ import { requestNewEmailVerificationFactory } from '@/modules/emails/services/ve
import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories'
import { renderEmail } from '@/modules/emails/services/emailRendering'
import { sendEmail } from '@/modules/emails/services/sending'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
const getServerInfo = getServerInfoFactory({ db })
const getUsers = getUsersFactory({ db })
@@ -228,6 +233,12 @@ const getUserStreamsCount = getUserStreamsCountFactory({ db })
export = {
Query: {
async stream(_, args, context) {
+ throwIfResourceAccessNotAllowed({
+ resourceId: args.id,
+ resourceType: TokenResourceIdentifierType.Project,
+ resourceAccessRules: context.resourceAccessRules
+ })
+
const stream = await getStream({ streamId: args.id, userId: context.userId })
if (!stream) {
throw new StreamNotFoundError('Stream not found')
@@ -240,7 +251,7 @@ export = {
context.resourceAccessRules
)
- if (!stream.isPublic) {
+ if (stream.visibility !== ProjectRecordVisibility.Public) {
await throwForNotHavingServerRole(context, Roles.Server.Guest)
await validateScopes(context.scopes, Scopes.Streams.Read)
}
@@ -303,7 +314,7 @@ export = {
orderBy: args.orderBy,
publicOnly: null,
searchQuery: args.query,
- visibility: args.visibility,
+ visibility: args.visibility as Nullable,
streamIdWhitelist: toProjectIdWhitelist(ctx.resourceAccessRules),
cursor: null
})
@@ -312,6 +323,10 @@ export = {
},
Stream: {
+ isPublic(parent) {
+ return parent.visibility === ProjectRecordVisibility.Public
+ },
+ isDiscoverable: () => false,
async collaborators(parent, _args, ctx) {
const collaborators = await ctx.loaders.streams.getCollaborators.load(parent.id)
@@ -357,13 +372,6 @@ export = {
return (await ctx.loaders.streams.getFavoritesCount.load(streamId)) || 0
},
- async isDiscoverable(parent) {
- const { isPublic, isDiscoverable } = parent
-
- if (!isPublic) return false
- return isDiscoverable
- },
-
async role(parent, _args, ctx) {
// If role already resolved, return that
const role = get(parent, 'role') as string | undefined
diff --git a/packages/server/modules/core/graph/resolvers/users.ts b/packages/server/modules/core/graph/resolvers/users.ts
index 0d339e42e..3b99094e9 100644
--- a/packages/server/modules/core/graph/resolvers/users.ts
+++ b/packages/server/modules/core/graph/resolvers/users.ts
@@ -50,6 +50,7 @@ import { metaHelpers } from '@/modules/core/helpers/meta'
import { asOperation } from '@/modules/shared/command'
import { setUserOnboardingChoicesFactory } from '@/modules/core/services/users/tracking'
import { getMixpanelClient } from '@/modules/shared/utils/mixpanel'
+import { throwIfAuthNotOk } from '@/modules/shared/helpers/errorHelper'
const getUser = legacyGetUserFactory({ db })
const getUserByEmail = legacyGetUserByEmailFactory({ db })
@@ -147,7 +148,7 @@ export = {
return { cursor, items: users }
},
- async users(_parent, args) {
+ async users(_parent, args, context) {
if (args.input.query.length < 1)
throw new BadRequestError('Search query must be at least 1 character.')
@@ -156,6 +157,14 @@ export = {
'Cannot return more than 100 items, please use pagination.'
)
+ if (args.input.projectId) {
+ const canRead = await context.authPolicies.project.canRead({
+ projectId: args.input.projectId,
+ userId: context.userId
+ })
+ throwIfAuthNotOk(canRead)
+ }
+
const { cursor, users } = await lookupUsers(args.input)
return { cursor, items: users }
},
diff --git a/packages/server/modules/core/helpers/project.ts b/packages/server/modules/core/helpers/project.ts
new file mode 100644
index 000000000..fb2e8a114
--- /dev/null
+++ b/packages/server/modules/core/helpers/project.ts
@@ -0,0 +1,43 @@
+import { ProjectCreateArgs } from '@/modules/core/domain/projects/operations'
+import {
+ ProjectVisibility,
+ StreamCreateInput
+} from '@/modules/core/graph/generated/graphql'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
+import { throwUncoveredError } from '@speckle/shared'
+import { has } from 'lodash'
+
+export const isProjectCreateInput = (
+ i: StreamCreateInput | ProjectCreateArgs
+): i is ProjectCreateArgs => has(i, 'visibility')
+
+export const mapGqlToDbProjectVisibility = (
+ visibility: ProjectVisibility
+): ProjectRecordVisibility => {
+ switch (visibility) {
+ case ProjectVisibility.Public:
+ case ProjectVisibility.Unlisted:
+ return ProjectRecordVisibility.Public
+ case ProjectVisibility.Private:
+ return ProjectRecordVisibility.Private
+ case ProjectVisibility.Workspace:
+ return ProjectRecordVisibility.Workspace
+ default:
+ throwUncoveredError(visibility)
+ }
+}
+
+export const mapDbToGqlProjectVisibility = (
+ visibility: ProjectRecordVisibility
+): ProjectVisibility => {
+ switch (visibility) {
+ case ProjectRecordVisibility.Public:
+ return ProjectVisibility.Public
+ case ProjectRecordVisibility.Private:
+ return ProjectVisibility.Private
+ case ProjectRecordVisibility.Workspace:
+ return ProjectVisibility.Workspace
+ default:
+ throwUncoveredError(visibility)
+ }
+}
diff --git a/packages/server/modules/core/helpers/stream.ts b/packages/server/modules/core/helpers/stream.ts
deleted file mode 100644
index 2355f4b59..000000000
--- a/packages/server/modules/core/helpers/stream.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { ProjectCreateArgs } from '@/modules/core/domain/projects/operations'
-import { StreamCreateInput } from '@/modules/core/graph/generated/graphql'
-import { has } from 'lodash'
-
-export const isProjectCreateInput = (
- i: StreamCreateInput | ProjectCreateArgs
-): i is ProjectCreateArgs => has(i, 'visibility')
diff --git a/packages/server/modules/core/helpers/types.ts b/packages/server/modules/core/helpers/types.ts
index ac22dabfe..13337ebf1 100644
--- a/packages/server/modules/core/helpers/types.ts
+++ b/packages/server/modules/core/helpers/types.ts
@@ -43,18 +43,34 @@ export type ServerAclRecord = {
role: string
}
+export const ProjectRecordVisibility = {
+ Public: 'public',
+ Private: 'private',
+ Workspace: 'workspace'
+}
+
+export type ProjectRecordVisibility =
+ (typeof ProjectRecordVisibility)[keyof typeof ProjectRecordVisibility]
+
export type StreamRecord = {
id: string
name: string
description: Nullable
- isPublic: boolean
clonedFrom: Nullable
createdAt: Date
updatedAt: Date
allowPublicComments: boolean
- isDiscoverable: boolean
workspaceId: Nullable
regionKey: Nullable
+ visibility: ProjectRecordVisibility
+ /**
+ * @deprecated No longer used, about to be removed
+ */
+ isDiscoverable: boolean
+ /**
+ * @deprecated No longer used, about to be removed
+ */
+ isPublic: boolean
}
export type StreamAclRecord = {
diff --git a/packages/server/modules/core/migrations/20250506114120_add_streams_visibility_col.ts b/packages/server/modules/core/migrations/20250506114120_add_streams_visibility_col.ts
new file mode 100644
index 000000000..91e68a310
--- /dev/null
+++ b/packages/server/modules/core/migrations/20250506114120_add_streams_visibility_col.ts
@@ -0,0 +1,55 @@
+import { Knex } from 'knex'
+
+const tableName = 'streams'
+const isPublicCol = 'isPublic'
+// const isDiscoverableCol = 'isDiscoverable'
+const visibilityCol = 'visibility'
+const workspaceIdCol = 'workspaceId'
+
+export async function up(knex: Knex): Promise {
+ // Add new col
+ await knex.schema.alterTable(tableName, (table) => {
+ table.string(visibilityCol).defaultTo('private').notNullable()
+ })
+
+ // Migrate isPublic -> visibility
+ await knex.raw(`
+ UPDATE "${tableName}"
+ SET "${visibilityCol}" =
+ CASE
+ WHEN "${isPublicCol}" = true THEN 'public'
+ WHEN "${isPublicCol}" = false AND "${workspaceIdCol}" IS NULL THEN 'private'
+ WHEN "${isPublicCol}" = false AND "${workspaceIdCol}" IS NOT NULL THEN 'workspace'
+ END;
+ `)
+
+ // // Drop old cols - Do this separately to avoid backwards incompatible changes
+ // await knex.schema.alterTable(tableName, (table) => {
+ // table.dropColumn(isPublicCol)
+ // table.dropColumn(isDiscoverableCol)
+ // })
+}
+
+export async function down(knex: Knex): Promise {
+ // // Re-introduce old cols
+ // await knex.schema.alterTable(tableName, (table) => {
+ // table.boolean(isPublicCol).defaultTo(true)
+ // table.boolean(isDiscoverableCol).defaultTo(false).notNullable()
+ // })
+
+ // Migrate visibility -> isPublic
+ await knex.raw(`
+ UPDATE "${tableName}"
+ SET "${isPublicCol}" =
+ CASE
+ WHEN "${visibilityCol}" = 'public' THEN true
+ WHEN "${visibilityCol}" = 'private' THEN false
+ WHEN "${visibilityCol}" = 'workspace' THEN false
+ END;
+ `)
+
+ // Drop new col
+ await knex.schema.alterTable(tableName, (table) => {
+ table.dropColumn(visibilityCol)
+ })
+}
diff --git a/packages/server/modules/core/repositories/commits.ts b/packages/server/modules/core/repositories/commits.ts
index 2fab3a141..13274fb77 100644
--- a/packages/server/modules/core/repositories/commits.ts
+++ b/packages/server/modules/core/repositories/commits.ts
@@ -11,6 +11,7 @@ import {
BranchCommitRecord,
BranchRecord,
CommitRecord,
+ ProjectRecordVisibility,
StreamAclRecord,
StreamCommitRecord
} from '@/modules/core/helpers/types'
@@ -527,7 +528,7 @@ export const getUserStreamCommitCountsFactory =
if (publicOnly) {
q.join(Streams.name, Streams.col.id, StreamAcl.col.resourceId)
q.andWhere((q1) => {
- q1.where(Streams.col.isPublic, true).orWhere(Streams.col.isDiscoverable, true)
+ q1.where(Streams.col.visibility, ProjectRecordVisibility.Public)
})
}
@@ -560,7 +561,7 @@ export const getUserAuthoredCommitCountsFactory =
q.join(StreamCommits.name, StreamCommits.col.commitId, Commits.col.id)
q.join(Streams.name, Streams.col.id, StreamCommits.col.streamId)
q.andWhere((q1) => {
- q1.where(Streams.col.isPublic, true).orWhere(Streams.col.isDiscoverable, true)
+ q1.where(Streams.col.visibility, ProjectRecordVisibility.Public)
})
}
@@ -610,7 +611,7 @@ const getCommitsByUserIdBaseFactory =
.leftJoin('users', 'commits.author', 'users.id')
.where('author', userId)
- if (publicOnly) query.andWhere('streams.isPublic', true)
+ if (publicOnly) query.andWhere('streams.visibility', ProjectRecordVisibility.Public)
if (streamIdWhitelist?.length) query.whereIn('streams.streamId', streamIdWhitelist)
return query
diff --git a/packages/server/modules/core/repositories/streams.ts b/packages/server/modules/core/repositories/streams.ts
index 02cadc776..b08428f46 100644
--- a/packages/server/modules/core/repositories/streams.ts
+++ b/packages/server/modules/core/repositories/streams.ts
@@ -7,6 +7,7 @@ import _, {
isObjectLike,
isUndefined,
mapValues,
+ omit,
omitBy,
reduce,
toNumber
@@ -25,6 +26,7 @@ import {
import { InvalidArgumentError, LogicError } from '@/modules/shared/errors'
import { Roles, StreamRoles } from '@/modules/core/helpers/mainConstants'
import {
+ ProjectRecordVisibility,
StreamAclRecord,
StreamCommitRecord,
StreamFavoriteRecord,
@@ -47,7 +49,10 @@ import {
import dayjs from 'dayjs'
import cryptoRandomString from 'crypto-random-string'
import { Knex } from 'knex'
-import { isProjectCreateInput } from '@/modules/core/helpers/stream'
+import {
+ isProjectCreateInput,
+ mapGqlToDbProjectVisibility
+} from '@/modules/core/helpers/project'
import {
StreamAccessUpdateError,
StreamNotFoundError,
@@ -59,8 +64,7 @@ import {
DeleteProjectRole,
UpdateProject,
GetRolesByUserId,
- UpsertProjectRole,
- ProjectVisibility
+ UpsertProjectRole
} from '@/modules/core/domain/projects/operations'
import {
StreamWithCommitId,
@@ -243,7 +247,9 @@ const getFavoritedStreamsQueryBaseFactory =
.andOnVal(StreamAcl.col.userId, userId)
)
.andWhere((q) =>
- q.where(Streams.col.isPublic, true).orWhereNotNull(StreamAcl.col.resourceId)
+ q
+ .where(Streams.col.visibility, ProjectRecordVisibility.Public)
+ .orWhereNotNull(StreamAcl.col.resourceId)
)
if (streamIdWhitelist?.length) {
@@ -406,7 +412,10 @@ export const canUserFavoriteStreamFactory =
})
.where(Streams.col.id, streamId)
.andWhere(function () {
- this.where(Streams.col.isPublic, true).orWhereNotNull(StreamAcl.col.resourceId)
+ this.where(
+ Streams.col.visibility,
+ ProjectRecordVisibility.Public
+ ).orWhereNotNull(StreamAcl.col.resourceId)
})
.limit(1)
@@ -469,8 +478,8 @@ const buildDiscoverableStreamsBaseQueryFactory =
const q = tables
.streams(deps.db)
.select(Streams.cols)
- .where(Streams.col.isDiscoverable, true)
- .andWhere(Streams.col.isPublic, true)
+ .andWhere(Streams.col.visibility, ProjectRecordVisibility.Public)
+ .andWhere(false) // TODO: No such thing as discoverability anymore, just return nothing
if (params.streamIdWhitelist?.length) {
q.whereIn(Streams.col.id, params.streamIdWhitelist)
@@ -715,7 +724,9 @@ const getUserStreamsQueryBaseFactory =
/**
* implicit access rules:
* 1. user must have an explicit stream role OR
- * 2. user must be a non-guest member of the project's workspace
+ * 2. if project is in a workspace that the user is in:
+ * - user must be a workspace admin OR
+ * - project must not be fully private and user is non-workspace-guest
*/
query
.leftJoin(WorkspaceAcl.name, (j2) => {
@@ -726,11 +737,18 @@ const getUserStreamsQueryBaseFactory =
})
.andWhere((w1) => {
w1.whereNotNull(StreamAcl.col.role).orWhere((w2) => {
- w2.whereNotNull(WorkspaceAcl.col.role).andWhere(
- WorkspaceAcl.col.role,
- '!=',
- Roles.Workspace.Guest
- )
+ // Implicit workspace role conditions
+ w2.whereNotNull(WorkspaceAcl.col.role).andWhere((w2) => {
+ w2.andWhere(WorkspaceAcl.col.role, Roles.Workspace.Admin).orWhere(
+ (w4) => {
+ w4.where(
+ WorkspaceAcl.col.role,
+ '!=',
+ Roles.Workspace.Guest
+ ).andWhereNot(Streams.col.visibility, ProjectRecordVisibility.Private)
+ }
+ )
+ })
})
})
} else {
@@ -774,9 +792,8 @@ const getUserStreamsQueryBaseFactory =
}
if (forOtherUser) {
- query
- .andWhere(Streams.col.isDiscoverable, true)
- .andWhere(Streams.col.isPublic, true)
+ // TODO: How did this work before discoverability?
+ query.andWhere(Streams.col.visibility, ProjectRecordVisibility.Public)
}
if (searchQuery) {
@@ -876,15 +893,16 @@ export const createStreamFactory =
const { name, description } = input
const { ownerId, trx } = options || {}
- let shouldBePublic: boolean, shouldBeDiscoverable: boolean
+ let visibility: ProjectRecordVisibility
if (isProjectCreateInput(input)) {
- shouldBeDiscoverable = input.visibility === 'PUBLIC'
- const publicVisibilities: ProjectVisibility[] = ['PUBLIC', 'UNLISTED']
- shouldBePublic =
- !input.visibility || publicVisibilities.includes(input.visibility)
+ visibility = mapGqlToDbProjectVisibility(
+ input.visibility || (input.workspaceId ? 'WORKSPACE' : 'PRIVATE')
+ )
} else {
- shouldBePublic = input.isPublic !== false
- shouldBeDiscoverable = input.isDiscoverable !== false && shouldBePublic
+ visibility =
+ input.isPublic !== false
+ ? ProjectRecordVisibility.Public
+ : ProjectRecordVisibility.Private
}
const workspaceId = 'workspaceId' in input ? input.workspaceId : null
@@ -895,8 +913,7 @@ export const createStreamFactory =
id,
name: name || generateProjectName(),
description: description || '',
- isPublic: shouldBePublic,
- isDiscoverable: shouldBeDiscoverable,
+ visibility,
updatedAt: knex.fn.now(),
workspaceId: workspaceId || null,
regionKey
@@ -945,7 +962,7 @@ export const getUserStreamCountsFactory =
if (publicOnly) {
q.join(Streams.name, Streams.col.id, StreamAcl.col.resourceId).andWhere((q1) => {
- q1.where(Streams.col.isPublic, true).orWhere(Streams.col.isDiscoverable, true)
+ q1.where(Streams.col.visibility, ProjectRecordVisibility.Public)
})
}
@@ -1017,18 +1034,23 @@ export const updateStreamFactory =
)
if (isProjectUpdateInput(update)) {
- if (has(validUpdate, 'visibility')) {
- validUpdate.isPublic = update.visibility !== 'PRIVATE'
- validUpdate.isDiscoverable = update.visibility === 'PUBLIC'
- delete validUpdate['visibility'] // cause it's not a real column
+ if (has(update, 'visibility')) {
+ validUpdate.visibility = mapGqlToDbProjectVisibility(
+ update.visibility || 'PRIVATE'
+ )
}
} else {
- if (has(validUpdate, 'isPublic') && !validUpdate.isPublic) {
- validUpdate.isDiscoverable = false
+ if (has(update, 'isPublic')) {
+ validUpdate.visibility = update.isPublic
+ ? ProjectRecordVisibility.Public
+ : ProjectRecordVisibility.Private
}
}
- if (has(validUpdate, 'isPublic') && !validUpdate.isPublic) {
+ if (
+ has(validUpdate, 'visibility') &&
+ validUpdate.visibility !== ProjectRecordVisibility.Public
+ ) {
validUpdate.allowPublicComments = false
} else if (
has(validUpdate, 'allowPublicComments') &&
@@ -1037,8 +1059,9 @@ export const updateStreamFactory =
validUpdate.isPublic = true
}
- // Ignore discoverability for now
+ // Remove non-existant fields
delete validUpdate['isDiscoverable']
+ delete validUpdate['isPublic']
if (!Object.keys(validUpdate).length) return null
@@ -1057,7 +1080,14 @@ export const updateStreamFactory =
export const updateProjectFactory =
({ db }: { db: Knex }): UpdateProject =>
async ({ projectUpdate }) => {
- const updatedStream = await updateStreamFactory({ db })(projectUpdate)
+ const [updatedStream] = await tables
+ .streams(db)
+ .returning('*')
+ .where({ id: projectUpdate.id })
+ .update({
+ ...omit(projectUpdate, ['id']),
+ updatedAt: knex.fn.now()
+ })
if (!updatedStream) {
throw new StreamUpdateError('Stream was not updated.')
@@ -1337,13 +1367,18 @@ export const legacyGetStreamsFactory =
}
if (visibility && visibility !== 'all') {
- if (!['private', 'public'].includes(visibility))
+ if (
+ ![
+ ProjectRecordVisibility.Private,
+ ProjectRecordVisibility.Public,
+ ProjectRecordVisibility.Workspace
+ ].includes(visibility)
+ )
throw new LogicError(
- 'Stream visibility should be either private, public or all'
+ 'Stream visibility should be either private, public, workspace or all'
)
- const isPublic = visibility === 'public'
const publicFunc: Knex.QueryCallback = function () {
- this.where({ isPublic })
+ this.where({ visibility })
}
query.andWhere(publicFunc)
}
diff --git a/packages/server/modules/core/repositories/users.ts b/packages/server/modules/core/repositories/users.ts
index f347e9f5b..8a2b1964e 100644
--- a/packages/server/modules/core/repositories/users.ts
+++ b/packages/server/modules/core/repositories/users.ts
@@ -7,6 +7,7 @@ import {
knex
} from '@/modules/core/dbSchema'
import {
+ ProjectRecordVisibility,
ServerAclRecord,
StreamAclRecord,
StreamRecord,
@@ -526,7 +527,9 @@ export const lookupUsersFactory =
if (projectId) {
// Workspace implicit roles logic:
// - User must have an explicit stream acl OR
- // - User must have a project workspace acl w/ non-guest role
+ // - User must have a project workspace acl AND:
+ // - must be a workspace admin
+ // - or must be a workspace member and the project must not be fully private
query
.innerJoin(Streams.name, (j1) => {
j1.onVal(Streams.col.id, projectId)
@@ -544,11 +547,20 @@ export const lookupUsersFactory =
)
})
.andWhere((w1) => {
- w1.whereNotNull(StreamAcl.col.role).orWhere(
- WorkspaceAcl.col.role,
- '!=',
- Roles.Workspace.Guest
- )
+ w1.whereNotNull(StreamAcl.col.role).orWhere((w2) => {
+ // Implicit workspace role conditions
+ w2.whereNotNull(WorkspaceAcl.col.role).andWhere((w2) => {
+ w2.andWhere(WorkspaceAcl.col.role, Roles.Workspace.Admin).orWhere(
+ (w4) => {
+ w4.where(
+ WorkspaceAcl.col.role,
+ '!=',
+ Roles.Workspace.Guest
+ ).andWhereNot(Streams.col.visibility, ProjectRecordVisibility.Private)
+ }
+ )
+ })
+ })
})
}
diff --git a/packages/server/modules/core/services/admin.ts b/packages/server/modules/core/services/admin.ts
index 5518d8567..2aec05ce5 100644
--- a/packages/server/modules/core/services/admin.ts
+++ b/packages/server/modules/core/services/admin.ts
@@ -8,12 +8,14 @@ import {
CountUsers,
ListPaginatedUsersPage
} from '@/modules/core/domain/users/operations'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import {
CountServerInvites,
QueryServerInvites
} from '@/modules/serverinvites/domain/operations'
import { ServerInviteRecord } from '@/modules/serverinvites/domain/types'
import { BaseError } from '@/modules/shared/errors/base'
+import { Nullable } from '@speckle/shared'
class CursorParsingError extends BaseError {
static defaultMessage = 'Invalid cursor provided'
@@ -86,6 +88,7 @@ export const adminProjectListFactory =
const parsedCursor = args.cursor ? parseCursorToDate(args.cursor) : null
const { streams, totalCount, cursorDate } = await deps.getStreams({
...args,
+ visibility: args.visibility as Nullable,
searchQuery: args.query,
cursor: parsedCursor,
streamIdWhitelist: args.streamIdWhitelist,
diff --git a/packages/server/modules/core/services/projects.ts b/packages/server/modules/core/services/projects.ts
index bd151794c..546d6bcce 100644
--- a/packages/server/modules/core/services/projects.ts
+++ b/packages/server/modules/core/services/projects.ts
@@ -4,7 +4,6 @@ import {
CreateProject,
DeleteProject,
GetProject,
- ProjectVisibility,
StoreModel,
StoreProject,
StoreProjectRole
@@ -12,6 +11,8 @@ import {
import { Project } from '@/modules/core/domain/streams/types'
import { RegionalProjectCreationError } from '@/modules/core/errors/projects'
import { StreamNotFoundError } from '@/modules/core/errors/stream'
+import { ProjectVisibility } from '@/modules/core/graph/generated/graphql'
+import { mapGqlToDbProjectVisibility } from '@/modules/core/helpers/project'
import { isTestEnv } from '@/modules/shared/helpers/envHelper'
import { EventBusEmit } from '@/modules/shared/services/eventBus'
import { retry } from '@lifeomic/attempt'
@@ -35,24 +36,24 @@ export const createNewProjectFactory =
storeModel: StoreModel
}): CreateProject =>
async ({ description, name, regionKey, visibility, workspaceId, ownerId }) => {
- const publicVisibilities: ProjectVisibility[] = ['PUBLIC', 'UNLISTED']
- const isPublic = !visibility || publicVisibilities.includes(visibility)
-
- // const isDiscoverable = visibility === 'PUBLIC'
- const isDiscoverable = false // discoverability disabled for now
+ visibility =
+ visibility ||
+ (workspaceId ? ProjectVisibility.Workspace : ProjectVisibility.Private)
const project: Project = {
id: cryptoRandomString({ length: 10 }),
name: name || generateProjectName(),
description: description || '',
- isPublic,
- isDiscoverable,
+ visibility: mapGqlToDbProjectVisibility(visibility),
createdAt: new Date(),
clonedFrom: null,
updatedAt: new Date(),
workspaceId: workspaceId || null,
regionKey: regionKey || null,
- allowPublicComments: false
+ allowPublicComments: false,
+ // TODO: Will be removed in a moment
+ isPublic: false,
+ isDiscoverable: false
}
await storeProject({ project })
@@ -94,7 +95,7 @@ export const createNewProjectFactory =
input: {
description: project.description,
name: project.name,
- visibility: isPublic ? 'PUBLIC' : isDiscoverable ? 'UNLISTED' : 'PRIVATE'
+ visibility
}
}
})
diff --git a/packages/server/modules/core/services/streams/auth.ts b/packages/server/modules/core/services/streams/auth.ts
index 0b225d210..d111fbb35 100644
--- a/packages/server/modules/core/services/streams/auth.ts
+++ b/packages/server/modules/core/services/streams/auth.ts
@@ -3,6 +3,7 @@ import {
ValidatePermissionsReadStream,
ValidatePermissionsWriteStream
} from '@/modules/core/domain/streams/operations'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import { throwForNotHavingServerRole } from '@/modules/shared/authz'
import { AuthorizeResolver, ValidateScopes } from '@/modules/shared/domain/operations'
import { DatabaseError } from '@/modules/shared/errors'
@@ -16,7 +17,8 @@ export const validatePermissionsReadStreamFactory =
}): ValidatePermissionsReadStream =>
async (streamId, req) => {
const stream = await deps.getStream({ streamId, userId: req.context.userId })
- if (stream?.isPublic) return { result: true, status: 200 }
+ if (stream?.visibility === ProjectRecordVisibility.Public)
+ return { result: true, status: 200 }
try {
await throwForNotHavingServerRole(req.context, Roles.Server.Guest)
@@ -28,31 +30,29 @@ export const validatePermissionsReadStreamFactory =
if (!stream) return { result: false, status: 404 }
- if (!stream.isPublic && req.context.auth === false) {
+ if (req.context.auth === false) {
req.log.debug('User is not authenticated, so cannot read from non-public stream.')
return { result: false, status: 401 }
}
- if (!stream.isPublic) {
- try {
- await deps.validateScopes(req.context.scopes, Scopes.Streams.Read)
- } catch (e) {
- req.log.info({ err: e }, 'Error while validating scopes')
- return { result: false, status: 401 }
- }
+ try {
+ await deps.validateScopes(req.context.scopes, Scopes.Streams.Read)
+ } catch (e) {
+ req.log.info({ err: e }, 'Error while validating scopes')
+ return { result: false, status: 401 }
+ }
- try {
- await deps.authorizeResolver(
- req.context.userId,
- streamId,
- Roles.Stream.Reviewer,
- req.context.resourceAccessRules
- )
- } catch (e) {
- if (e instanceof DatabaseError) return { result: false, status: 500 }
- req.log.info({ err: e }, 'Error while checking stream contributor role')
- return { result: false, status: 401 }
- }
+ try {
+ await deps.authorizeResolver(
+ req.context.userId,
+ streamId,
+ Roles.Stream.Reviewer,
+ req.context.resourceAccessRules
+ )
+ } catch (e) {
+ if (e instanceof DatabaseError) return { result: false, status: 500 }
+ req.log.info({ err: e }, 'Error while checking stream contributor role')
+ return { result: false, status: 401 }
}
return { result: true, status: 200 }
}
diff --git a/packages/server/modules/core/services/streams/clone.ts b/packages/server/modules/core/services/streams/clone.ts
index b527bcb2c..56330a697 100644
--- a/packages/server/modules/core/services/streams/clone.ts
+++ b/packages/server/modules/core/services/streams/clone.ts
@@ -43,6 +43,7 @@ import {
import { GetUser } from '@/modules/core/domain/users/operations'
import { EventBusEmit } from '@/modules/shared/services/eventBus'
import { ProjectEvents } from '@/modules/core/domain/projects/events'
+import { mapDbToGqlProjectVisibility } from '@/modules/core/helpers/project'
type CloneStreamInitialState = {
user: UserWithOptionalRole
@@ -124,8 +125,7 @@ const cloneStreamEntityFactory =
{
name: targetStream.name,
description: targetStream.description,
- isPublic: targetStream.isPublic,
- isDiscoverable: targetStream.isDiscoverable
+ visibility: mapDbToGqlProjectVisibility(targetStream.visibility)
},
{
ownerId: user.id,
diff --git a/packages/server/modules/core/services/streams/management.ts b/packages/server/modules/core/services/streams/management.ts
index a813f0f36..7976fdd74 100644
--- a/packages/server/modules/core/services/streams/management.ts
+++ b/packages/server/modules/core/services/streams/management.ts
@@ -11,7 +11,7 @@ import {
StreamNotFoundError,
StreamUpdateError
} from '@/modules/core/errors/stream'
-import { isProjectCreateInput } from '@/modules/core/helpers/stream'
+import { isProjectCreateInput } from '@/modules/core/helpers/project'
import { has } from 'lodash'
import { isNewResourceAllowed } from '@/modules/core/helpers/token'
import {
diff --git a/packages/server/modules/core/tests/discoverableStreams.spec.ts b/packages/server/modules/core/tests/discoverableStreams.spec.ts
deleted file mode 100644
index 8bf44e3d4..000000000
--- a/packages/server/modules/core/tests/discoverableStreams.spec.ts
+++ /dev/null
@@ -1,384 +0,0 @@
-import { buildApolloServer } from '@/app'
-import { db } from '@/db/knex'
-import { Streams, Users } from '@/modules/core/dbSchema'
-import {
- getStreamFactory,
- setStreamFavoritedFactory
-} from '@/modules/core/repositories/streams'
-import { Nullable, Optional } from '@/modules/shared/helpers/typeHelper'
-import { BasicTestUser, createTestUsers } from '@/test/authHelper'
-import {
- DiscoverableStreamsSortType,
- SortDirection
-} from '@/test/graphql/generated/graphql'
-import {
- createStream,
- readDiscoverableStreams,
- updateStream
-} from '@/test/graphql/streams'
-import {
- createAuthedTestContext,
- createTestContext,
- ServerAndContext
-} from '@/test/graphqlHelper'
-import { truncateTables } from '@/test/hooks'
-import { BasicTestStream, createTestStream } from '@/test/speckle-helpers/streamHelper'
-import { wait } from '@speckle/shared'
-import { expect } from 'chai'
-import dayjs from 'dayjs'
-import { shuffle } from 'lodash'
-
-const READABLE_DISCOVERABLE_STREAM_COUNT = 15
-
-const cleanup = async () => await truncateTables([Streams.name, Users.name])
-const getStream = getStreamFactory({ db })
-const setStreamFavorited = setStreamFavoritedFactory({ db })
-
-// Discoverability currently disabled
-describe.skip('Discoverable streams', () => {
- let apollo: ServerAndContext
-
- const me: BasicTestUser = {
- name: 'itsaa meeee',
- email: 'me@gimail.com',
- password: 'whateveridontcare',
- id: ''
- }
-
- const otherGuy: BasicTestUser = {
- name: 'otherr guyyyy1',
- email: 'otherguy1@gimail.com',
- password: 'whateveridontcare',
- id: ''
- }
-
- const favoriterGuy1: BasicTestUser = {
- name: 'favoriter guy1',
- email: 'favoriterguy1@gimail.com',
- password: 'whateveridontcare',
- id: ''
- }
-
- const favoriterGuy2: BasicTestUser = {
- name: 'favoriter guy2',
- email: 'favoriterguy2@gimail.com',
- password: 'whateveridontcare',
- id: ''
- }
-
- const favoriterGuy3: BasicTestUser = {
- name: 'favoriter guy3',
- email: 'favoriterguy3@gimail.com',
- password: 'whateveridontcare',
- id: ''
- }
-
- const allUsers = [me, otherGuy, favoriterGuy1, favoriterGuy2, favoriterGuy3]
-
- const readableDiscoverableStreams: BasicTestStream[] = []
-
- before(async () => {
- await cleanup()
-
- // Seeding users
- await createTestUsers(allUsers)
-
- // Seeding streams (sequentially to ensure different created dates)
- for (let i = 0; i < READABLE_DISCOVERABLE_STREAM_COUNT; i++) {
- const owner = i % 2 === 0 ? me : otherGuy
- const newStream: BasicTestStream = {
- name: 'Readable Discoverable Stream ' + i,
- isPublic: true,
- isDiscoverable: true,
- id: '',
- ownerId: ''
- }
- readableDiscoverableStreams.push(newStream)
- await createTestStream(newStream, owner)
- await wait(5)
- }
-
- // Favoriting some of them - stream with 5 favorites, stream with 4 favorites, then 3 and so on...
- const favoriters = shuffle(allUsers.slice())
- const favoritableStreams = shuffle(readableDiscoverableStreams.slice())
-
- for (let i = favoriters.length; i > 0; i--) {
- const currentFavoriters = favoriters.slice(0, i)
- const currentStream = favoritableStreams.pop()
-
- while (currentStream && currentFavoriters.length > 0) {
- const favoriter = currentFavoriters.pop()
- if (!favoriter) break
-
- await setStreamFavorited({
- streamId: currentStream.id,
- userId: favoriter.id,
- favorited: true
- })
- await wait(5)
- }
- }
-
- apollo = {
- apollo: await buildApolloServer(),
- context: await createTestContext()
- }
- })
-
- after(async () => {
- await cleanup()
- })
-
- it('can be retrieved', async () => {
- const { data, errors } = await readDiscoverableStreams(apollo, {
- limit: READABLE_DISCOVERABLE_STREAM_COUNT
- })
-
- expect(errors).to.be.not.ok
- expect(data?.discoverableStreams).to.be.ok
- expect(data?.discoverableStreams?.totalCount).to.eq(
- READABLE_DISCOVERABLE_STREAM_COUNT
- )
- expect(data?.discoverableStreams?.items?.length).to.eq(
- READABLE_DISCOVERABLE_STREAM_COUNT
- )
- expect(data?.discoverableStreams?.cursor).to.be.ok
-
- const someItem = data?.discoverableStreams?.items?.[0]
- expect(someItem?.id).to.be.ok
- expect(someItem?.isDiscoverable).to.be.ok
- })
-
- const sortTypeDataset = [
- { display: 'created date', sortType: DiscoverableStreamsSortType.CreatedDate },
- { display: 'favorites count', sortType: DiscoverableStreamsSortType.FavoritesCount }
- ]
- const sortDirectionDataset = [
- { display: 'ascending', sortDir: SortDirection.Asc },
- { display: 'descending', sortDir: SortDirection.Desc }
- ]
-
- sortTypeDataset.forEach(({ display: sortTypeDisplay, sortType }) => {
- sortDirectionDataset.forEach(({ display: sortDirDisplay, sortDir }) => {
- it(`can be retrieved properly paginated & sorted by ${sortDirDisplay} ${sortTypeDisplay}`, async () => {
- const limit = Math.max(Math.floor(READABLE_DISCOVERABLE_STREAM_COUNT / 3), 1)
-
- const collectedItems = []
- let currentSortByValue: Optional = undefined
- let cursor: Nullable = null
-
- const retrieveAndTestPage = async (cursor: Nullable) => {
- const { data, errors } = await readDiscoverableStreams(apollo, {
- limit,
- cursor,
- sort: {
- type: sortType,
- direction: sortDir
- }
- })
-
- expect(errors).to.be.not.ok
- expect(data?.discoverableStreams?.totalCount).to.eq(
- READABLE_DISCOVERABLE_STREAM_COUNT
- )
-
- const items = data?.discoverableStreams?.items || []
- const hasMorePages = items.length === limit
- const newCursor = data?.discoverableStreams?.cursor
-
- for (const currentItem of items) {
- collectedItems.push(currentItem)
-
- let sortByValue: string | number
- if (sortType === DiscoverableStreamsSortType.CreatedDate) {
- sortByValue = currentItem.createdAt
- } else if (sortType === DiscoverableStreamsSortType.FavoritesCount) {
- sortByValue = currentItem.favoritesCount
- } else {
- throw new Error('Unexpected sort type')
- }
-
- if (!currentSortByValue) {
- currentSortByValue = sortByValue
- continue
- }
-
- const previousValue = currentSortByValue
- const currentValue = sortByValue
- if (sortType === DiscoverableStreamsSortType.CreatedDate) {
- if (sortDir === SortDirection.Asc) {
- expect(dayjs(currentValue).isAfter(dayjs(previousValue))).to.be.true
- } else {
- expect(dayjs(previousValue).isAfter(dayjs(currentValue))).to.be.true
- }
- } else if (sortType === DiscoverableStreamsSortType.FavoritesCount) {
- if (sortDir === SortDirection.Asc) {
- expect(currentValue).is.greaterThanOrEqual(previousValue as number)
- } else {
- expect(previousValue).is.greaterThanOrEqual(currentValue as number)
- }
- } else {
- throw new Error('Unexpected sort type')
- }
- }
-
- return { hasMorePages, newCursor }
- }
-
- let failsafe = 10
- while (failsafe > 0) {
- const testResult = await retrieveAndTestPage(cursor)
- cursor = testResult.newCursor as Nullable
-
- if (!testResult.hasMorePages) break
- failsafe--
- }
-
- if (failsafe <= 0)
- throw new Error(
- 'Pagination failsafe triggered! Possible infinite loop encountered.'
- )
-
- expect(collectedItems.length).to.eq(READABLE_DISCOVERABLE_STREAM_COUNT)
- })
- })
- })
-
- describe('when authenticated', () => {
- let apollo: ServerAndContext
-
- before(async () => {
- apollo = {
- apollo: await buildApolloServer(),
- context: await createAuthedTestContext(me.id)
- }
- })
-
- it('can be retrieved with role properly filled out', async () => {
- const { data, errors } = await readDiscoverableStreams(apollo, {
- limit: READABLE_DISCOVERABLE_STREAM_COUNT
- })
-
- expect(errors).to.be.not.ok
- expect(data?.discoverableStreams?.totalCount).to.eq(
- READABLE_DISCOVERABLE_STREAM_COUNT
- )
-
- const items = data?.discoverableStreams?.items || []
- const someHaveRole = items.some((i) => !!i.role)
- expect(someHaveRole).to.be.true
- })
-
- it('can be created', async () => {
- const { errors, data } = await createStream(apollo, {
- stream: {
- name: 'some rando stream',
- isPublic: true,
- isDiscoverable: true
- }
- })
-
- expect(errors).to.not.be.ok
- expect(data).to.be.ok
- expect(data?.streamCreate).to.be.ok
-
- const streamId = data?.streamCreate as string
- const streamData = await getStream({ streamId })
-
- expect(streamData).to.be.ok
- expect(streamData?.isDiscoverable).to.be.true
- expect(streamData?.isPublic).to.be.true
- })
-
- const cantMakeDiscoverableDataset = [
- { display: 'isDiscoverable set to false', isDiscoverable: false, isPublic: true },
- { display: 'isPublic is set to false', isDiscoverable: true, isPublic: false }
- ]
- cantMakeDiscoverableDataset.forEach(({ display, isDiscoverable, isPublic }) => {
- it(`cant be created discoverable if ${display}`, async () => {
- const { errors, data } = await createStream(apollo, {
- stream: {
- isPublic,
- isDiscoverable
- }
- })
-
- expect(errors).to.not.be.ok
- expect(data).to.be.ok
- expect(data?.streamCreate).to.be.ok
-
- const streamId = data?.streamCreate as string
- const streamData = await getStream({ streamId })
-
- expect(streamData).to.be.ok
- expect(streamData?.isDiscoverable).to.be.false
- expect(streamData?.isPublic).to.eq(isPublic)
- })
- })
-
- describe('and being updated', () => {
- const updateableStream: BasicTestStream = {
- name: 'ill be getting updated a lot',
- isPublic: false,
- isDiscoverable: false,
- id: '',
- ownerId: ''
- }
-
- beforeEach(async () => {
- // re-create for each test
- await createTestStream(updateableStream, me)
- })
-
- it('can be updated to be discoverable or not', async () => {
- const testWithDiscoverable = async (val: boolean) => {
- const { errors, data } = await updateStream(apollo, {
- stream: {
- id: updateableStream.id,
- isPublic: val,
- isDiscoverable: val
- }
- })
-
- expect(errors).to.not.be.ok
- expect(data).to.be.ok
- expect(data?.streamUpdate).to.be.ok
-
- const streamData = await getStream({ streamId: updateableStream.id })
-
- expect(streamData).to.be.ok
- expect(streamData?.isDiscoverable).to.eq(val)
- expect(streamData?.isPublic).to.eq(val)
- }
-
- // Toggle on
- await testWithDiscoverable(true)
-
- // Toggle off
- await testWithDiscoverable(false)
- })
-
- cantMakeDiscoverableDataset.forEach(({ display, isDiscoverable, isPublic }) => {
- it(`cant be updated to be discoverable if ${display}`, async () => {
- const { errors, data } = await updateStream(apollo, {
- stream: {
- id: updateableStream.id,
- isPublic,
- isDiscoverable
- }
- })
-
- expect(errors).to.not.be.ok
- expect(data).to.be.ok
- expect(data?.streamUpdate).to.be.ok
-
- const streamData = await getStream({ streamId: updateableStream.id })
-
- expect(streamData).to.be.ok
- expect(streamData?.isDiscoverable).to.be.false
- expect(streamData?.isPublic).to.eq(isPublic)
- })
- })
- })
- })
-})
diff --git a/packages/server/modules/core/tests/integration/projectRepositories.spec.ts b/packages/server/modules/core/tests/integration/projectRepositories.spec.ts
index 90472155d..63becda62 100644
--- a/packages/server/modules/core/tests/integration/projectRepositories.spec.ts
+++ b/packages/server/modules/core/tests/integration/projectRepositories.spec.ts
@@ -1,5 +1,6 @@
import { db } from '@/db/knex'
import { Project } from '@/modules/core/domain/streams/types'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import {
deleteProjectFactory,
getProjectFactory,
@@ -22,11 +23,12 @@ const createTestProject = (overrides?: Partial): Project => {
createdAt: new Date(),
updatedAt: new Date(),
description: 'a test project',
- isDiscoverable: true,
- isPublic: true,
+ visibility: ProjectRecordVisibility.Public,
name: cryptoRandomString({ length: 10 }),
regionKey: null,
- workspaceId: null
+ workspaceId: null,
+ isPublic: true,
+ isDiscoverable: true
}
return assign(defaults, overrides || {})
}
diff --git a/packages/server/modules/core/tests/integration/projects.graph.spec.ts b/packages/server/modules/core/tests/integration/projects.graph.spec.ts
index f3c925275..33119bc20 100644
--- a/packages/server/modules/core/tests/integration/projects.graph.spec.ts
+++ b/packages/server/modules/core/tests/integration/projects.graph.spec.ts
@@ -1,246 +1,43 @@
-import { createTestWorkspace } from '@/modules/workspaces/tests/helpers/creation'
-import { BasicTestUser, createTestUser, login } from '@/test/authHelper'
+import { BasicTestUser, createTestUser } from '@/test/authHelper'
import {
- ActiveUserProjectsDocument,
CreateProjectDocument,
- CreateWorkspaceProjectDocument,
- GetWorkspaceDocument
+ ProjectVisibility
} from '@/test/graphql/generated/graphql'
import { Roles } from '@/modules/core/helpers/mainConstants'
import { expect } from 'chai'
-import cryptoRandomString from 'crypto-random-string'
-import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
-import { createRandomEmail } from '@/modules/core/helpers/testHelpers'
-import { db } from '@/db/knex'
-import { StreamAcl } from '@/modules/core/dbSchema'
+import { beforeEachContext } from '@/test/hooks'
+import { TestApolloServer, testApolloServer } from '@/test/graphqlHelper'
-const { FF_WORKSPACES_MODULE_ENABLED } = getFeatureFlags()
+describe('Projects GraphQL @core (outside of workspaces)', () => {
+ let apollo: TestApolloServer
+ const me: BasicTestUser = {
+ id: '',
+ name: 'me',
+ email: '',
+ role: Roles.Server.Admin
+ }
-describe('Projects GraphQL @core', () => {
- describe('query user.projects', () => {
- ;(FF_WORKSPACES_MODULE_ENABLED ? it : it.skip)(
- 'should return projects not in a workspace',
- async () => {
- const testAdminUser: BasicTestUser = {
- id: '',
- name: 'test',
- email: createRandomEmail(),
- role: Roles.Server.Admin,
- verified: true
- }
- await createTestUser(testAdminUser)
- const workspace = {
- id: '',
- name: 'test ws',
- slug: cryptoRandomString({ length: 10 }),
- ownerId: ''
- }
- await createTestWorkspace(workspace, testAdminUser)
+ before(async () => {
+ await beforeEachContext()
+ await createTestUser(me)
+ apollo = await testApolloServer({ authUserId: me.id })
+ })
- const session = await login(testAdminUser)
- const getWorkspaceRes = await session.execute(GetWorkspaceDocument, {
- workspaceId: workspace.id
- })
+ describe('when being created', () => {
+ it('should use private visibility by default ', async () => {
+ const res = await apollo.execute(
+ CreateProjectDocument,
+ {
+ input: {
+ name: 'Test Default Visibility Project'
+ }
+ },
+ { assertNoErrors: true }
+ )
- expect(getWorkspaceRes).to.not.haveGraphQLErrors()
- const workspaceId = getWorkspaceRes.data!.workspace.id
-
- const createProjectInWorkspaceRes = await session.execute(
- CreateWorkspaceProjectDocument,
- { input: { name: 'project', workspaceId } }
- )
- expect(createProjectInWorkspaceRes).to.not.haveGraphQLErrors()
-
- const createProjectNonInWorkspaceRes = await session.execute(
- CreateProjectDocument,
- { input: { name: 'project' } }
- )
- expect(createProjectNonInWorkspaceRes).to.not.haveGraphQLErrors()
- const projectNonInWorkspace =
- createProjectNonInWorkspaceRes.data!.projectMutations.create
-
- const userProjectsRes = await session.execute(ActiveUserProjectsDocument, {
- filter: { personalOnly: true }
- })
- expect(userProjectsRes).to.not.haveGraphQLErrors()
-
- const projects = userProjectsRes.data!.activeUser!.projects.items
-
- expect(projects).to.have.length(1)
- expect(projects[0].id).to.eq(projectNonInWorkspace.id)
- }
- )
- ;(FF_WORKSPACES_MODULE_ENABLED ? it : it.skip)(
- 'should return projects in workspace',
- async () => {
- const testAdminUser: BasicTestUser = {
- id: '',
- name: 'test',
- email: createRandomEmail(),
- role: Roles.Server.Admin,
- verified: true
- }
- await createTestUser(testAdminUser)
- const workspace = {
- id: '',
- name: 'test ws',
- slug: cryptoRandomString({ length: 10 }),
- ownerId: ''
- }
- await createTestWorkspace(workspace, testAdminUser)
-
- const session = await login(testAdminUser)
- const getWorkspaceRes = await session.execute(GetWorkspaceDocument, {
- workspaceId: workspace.id
- })
-
- expect(getWorkspaceRes).to.not.haveGraphQLErrors()
- const workspaceId = getWorkspaceRes.data!.workspace.id
-
- const createProjectInWorkspaceRes = await session.execute(
- CreateWorkspaceProjectDocument,
- { input: { name: 'project', workspaceId } }
- )
- expect(createProjectInWorkspaceRes).to.not.haveGraphQLErrors()
- const projectInWorkspace =
- createProjectInWorkspaceRes.data!.workspaceMutations.projects.create
-
- const createProjectNonInWorkspaceRes = await session.execute(
- CreateProjectDocument,
- { input: { name: 'project' } }
- )
- expect(createProjectNonInWorkspaceRes).to.not.haveGraphQLErrors()
-
- const userProjectsRes = await session.execute(ActiveUserProjectsDocument, {
- filter: { workspaceId }
- })
- expect(userProjectsRes).to.not.haveGraphQLErrors()
-
- const projects = userProjectsRes.data!.activeUser!.projects.items
-
- expect(projects).to.have.length(1)
- expect(projects[0].id).to.eq(projectInWorkspace.id)
- }
- )
- ;(FF_WORKSPACES_MODULE_ENABLED ? it : it.skip)(
- 'should return all user projects',
- async () => {
- const testAdminUser: BasicTestUser = {
- id: '',
- name: 'test',
- email: createRandomEmail(),
- role: Roles.Server.Admin,
- verified: true
- }
- await createTestUser(testAdminUser)
- const workspace = {
- id: '',
- name: 'test ws',
- slug: cryptoRandomString({ length: 10 }),
- ownerId: ''
- }
- await createTestWorkspace(workspace, testAdminUser)
-
- const session = await login(testAdminUser)
- const getWorkspaceRes = await session.execute(GetWorkspaceDocument, {
- workspaceId: workspace.id
- })
-
- expect(getWorkspaceRes).to.not.haveGraphQLErrors()
- const workspaceId = getWorkspaceRes.data!.workspace.id
-
- const createProjectInWorkspaceRes = await session.execute(
- CreateWorkspaceProjectDocument,
- { input: { name: 'project', workspaceId } }
- )
- expect(createProjectInWorkspaceRes).to.not.haveGraphQLErrors()
-
- const createProjectNonInWorkspaceRes = await session.execute(
- CreateProjectDocument,
- { input: { name: 'project' } }
- )
- expect(createProjectNonInWorkspaceRes).to.not.haveGraphQLErrors()
-
- const userProjectsRes = await session.execute(ActiveUserProjectsDocument, {
- filter: {}
- })
- expect(userProjectsRes).to.not.haveGraphQLErrors()
-
- const projects = userProjectsRes.data!.activeUser!.projects.items
-
- expect(projects).to.have.length(2)
- }
- )
- ;(FF_WORKSPACES_MODULE_ENABLED ? it : it.skip)(
- 'should return all user projects sorted by user role',
- async () => {
- const testAdminUser: BasicTestUser = {
- id: '',
- name: 'test',
- email: createRandomEmail(),
- role: Roles.Server.Admin,
- verified: true
- }
- await createTestUser(testAdminUser)
- const workspace = {
- id: '',
- name: 'test ws',
- slug: cryptoRandomString({ length: 10 }),
- ownerId: ''
- }
- await createTestWorkspace(workspace, testAdminUser)
-
- const session = await login(testAdminUser)
- const getWorkspaceRes = await session.execute(GetWorkspaceDocument, {
- workspaceId: workspace.id
- })
-
- expect(getWorkspaceRes).to.not.haveGraphQLErrors()
- const workspaceId = getWorkspaceRes.data!.workspace.id
-
- const createProjectInWorkspaceAsOwnerRes = await session.execute(
- CreateWorkspaceProjectDocument,
- { input: { name: 'project', workspaceId } }
- )
- expect(createProjectInWorkspaceAsOwnerRes).to.not.haveGraphQLErrors()
- const createProjectInWorkspaceAsContributorRes = await session.execute(
- CreateWorkspaceProjectDocument,
- { input: { name: 'project 2', workspaceId } }
- )
- expect(createProjectInWorkspaceAsContributorRes).to.not.haveGraphQLErrors()
- const projectContributorId =
- createProjectInWorkspaceAsContributorRes.data?.workspaceMutations.projects
- .create.id
- await db(StreamAcl.name)
- .update({ role: Roles.Stream.Contributor })
- .where({ userId: testAdminUser.id, resourceId: projectContributorId })
- const createProjectInWorkspaceAsReviewerRes = await session.execute(
- CreateWorkspaceProjectDocument,
- { input: { name: 'project 3', workspaceId } }
- )
- expect(createProjectInWorkspaceAsReviewerRes).to.not.haveGraphQLErrors()
- const projectReviewerId =
- createProjectInWorkspaceAsReviewerRes.data?.workspaceMutations.projects.create
- .id
- await db(StreamAcl.name)
- .update({ role: Roles.Stream.Reviewer })
- .where({ userId: testAdminUser.id, resourceId: projectReviewerId })
-
- const userProjectsRes = await session.execute(ActiveUserProjectsDocument, {
- filter: {},
- sortBy: ['role']
- })
- expect(userProjectsRes).to.not.haveGraphQLErrors()
-
- const projects = userProjectsRes.data!.activeUser!.projects.items
-
- expect(projects).to.have.length(3)
- expect(projects[0].id).to.eq(
- createProjectInWorkspaceAsOwnerRes.data?.workspaceMutations.projects.create.id
- )
- expect(projects[1].id).to.eq(projectContributorId)
- expect(projects[2].id).to.eq(projectReviewerId)
- }
- )
+ const project = res.data?.projectMutations.create
+ expect(project).to.be.ok
+ expect(project?.visibility).to.eq(ProjectVisibility.Private)
+ })
})
})
diff --git a/packages/server/modules/core/tests/integration/users.graph.spec.ts b/packages/server/modules/core/tests/integration/users.graph.spec.ts
index 2a271385c..ea2711ffd 100644
--- a/packages/server/modules/core/tests/integration/users.graph.spec.ts
+++ b/packages/server/modules/core/tests/integration/users.graph.spec.ts
@@ -1,3 +1,4 @@
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
import {
assignToWorkspaces,
@@ -19,7 +20,8 @@ import { waitForRegionUsers } from '@/test/speckle-helpers/regions'
import {
addAllToStream,
BasicTestStream,
- createTestStream
+ createTestStream,
+ createTestStreams
} from '@/test/speckle-helpers/streamHelper'
import { Roles } from '@speckle/shared'
import { expect } from 'chai'
@@ -68,11 +70,26 @@ describe('Users @graphql', () => {
id: '',
slug: ''
}
+
const myWorkspaceCollaboratorProject: BasicTestStream = {
name: 'My Workspace Collaborator Project #1',
ownerId: '',
id: '',
- isPublic: true
+ visibility: ProjectRecordVisibility.Workspace
+ }
+
+ const myPrivateWorkspaceCollaboratorProject: BasicTestStream = {
+ name: 'My Private Workspace Collaborator Project #1',
+ ownerId: '',
+ id: '',
+ visibility: ProjectRecordVisibility.Private
+ }
+
+ const myNoCollaboratorProject: BasicTestStream = {
+ name: 'My No Collaborator Project #1',
+ ownerId: '',
+ id: '',
+ visibility: ProjectRecordVisibility.Private
}
const myBasicCollaboratorProject: BasicTestStream = {
@@ -95,11 +112,18 @@ describe('Users @graphql', () => {
before(async () => {
await Promise.all([
createTestStream(myBasicCollaboratorProject, me),
+ createTestStream(myNoCollaboratorProject, me),
createTestWorkspace(myWorkspace, me, {
regionKey: getMainTestRegionKeyIfMultiRegion()
- }).then(() => (myWorkspaceCollaboratorProject.workspaceId = myWorkspace.id))
+ })
+ ])
+
+ myWorkspaceCollaboratorProject.workspaceId = myWorkspace.id
+ myPrivateWorkspaceCollaboratorProject.workspaceId = myWorkspace.id
+ await createTestStreams([
+ [myWorkspaceCollaboratorProject, me],
+ [myPrivateWorkspaceCollaboratorProject, me]
])
- await createTestStream(myWorkspaceCollaboratorProject, me)
// Seed in users
let remainingBasicProjectCollaborators = BASIC_COLLABORATOR_PROJECT_USER_COUNT
@@ -164,6 +188,15 @@ describe('Users @graphql', () => {
}
)
}
+
+ // Add specific user to myPrivateWorkspaceCollaboratorProject
+ await addAllToStream(
+ myPrivateWorkspaceCollaboratorProject,
+ [{ user: secondSpecificUser, role: Roles.Stream.Reviewer }],
+ {
+ owner: me
+ }
+ )
})
it('works with basic query', async () => {
@@ -235,7 +268,7 @@ describe('Users @graphql', () => {
])
})
- it('works with a projectId from a workspace', async () => {
+ it('works with a workspace visibility projectId from a workspace', async () => {
const res = await search(
{
query: 'user',
@@ -245,6 +278,7 @@ describe('Users @graphql', () => {
{ assertNoErrors: true }
)
+ // workspace visibility, so: find all members (implicit access) - guests cause none have explicit access + 1 explicit access user
expect(res.data?.users.items || []).to.have.lengthOf(
WORKSPACE_COLLABORATOR_USER_COUNT - WORKSPACE_GUEST_USER_COUNT + 1 // +1 for the secondSpecificUser
)
@@ -254,6 +288,37 @@ describe('Users @graphql', () => {
])
})
+ it('works with a private visibility projectId from a workspace', async () => {
+ const res = await search(
+ {
+ query: 'user',
+ projectId: myPrivateWorkspaceCollaboratorProject.id,
+ limit: 100
+ },
+ { assertNoErrors: true }
+ )
+
+ // private visibility, so: only 1 explicit access user
+ expect(res.data?.users.items || []).to.have.lengthOf(1)
+ expect((res.data?.users.items || []).map((u) => u.id)).to.deep.equal([
+ secondSpecificUser.id
+ ])
+ })
+
+ it('doesnt work if user doesnt have access to the project specified', async () => {
+ const res = await search(
+ {
+ query: 'user',
+ projectId: myNoCollaboratorProject.id,
+ limit: 100
+ },
+ { authUserId: firstSpecificUser.id }
+ )
+
+ expect(res).to.haveGraphQLErrors('You do not have access to the project')
+ expect(res.data?.users).to.not.be.ok
+ })
+
it('works with pagination', async () => {
const totalUserCount = RANDOMIZED_USER_COUNT + 2 // +2 for the specific users
const firstLimit = Math.floor(totalUserCount / 2)
diff --git a/packages/server/modules/core/tests/projects.spec.ts b/packages/server/modules/core/tests/projects.spec.ts
index df0bb6bb6..1ff648711 100644
--- a/packages/server/modules/core/tests/projects.spec.ts
+++ b/packages/server/modules/core/tests/projects.spec.ts
@@ -8,7 +8,8 @@ import {
BatchDeleteProjectsDocument,
CreateProjectDocument,
GetProjectObjectDocument,
- ProjectCreateInput
+ ProjectCreateInput,
+ ProjectVisibility
} from '@/test/graphql/generated/graphql'
import { createTestObject } from '@/test/speckle-helpers/commitHelper'
import { times } from 'lodash'
@@ -54,6 +55,9 @@ describe('Projects', () => {
expect(res.data?.projectMutations.create.id).to.be.ok
expect(res.data?.projectMutations.create.name).to.equal(input.name)
expect(res.data?.projectMutations.create.description).to.equal(input.description)
+ expect(res.data?.projectMutations.create.visibility).to.equal(
+ ProjectVisibility.Private // private by default
+ )
})
describe('after creation', () => {
diff --git a/packages/server/modules/core/tests/streams.spec.ts b/packages/server/modules/core/tests/streams.spec.ts
index b482495fb..aa89562d7 100644
--- a/packages/server/modules/core/tests/streams.spec.ts
+++ b/packages/server/modules/core/tests/streams.spec.ts
@@ -602,7 +602,7 @@ describe('Streams @core-streams', () => {
const TOTAL_OWN_STREAM_COUNT = OWNED_STREAM_COUNT + SHARED_STREAM_COUNT
const PUBLIC_STREAM_COUNT = 15
- const DISCOVERABLE_STREAM_COUNT = PUBLIC_STREAM_COUNT - 5
+ const DISCOVERABLE_STREAM_COUNT = PUBLIC_STREAM_COUNT
let userOneStreams: BasicTestStream[]
let userTwoStreams: BasicTestStream[]
@@ -613,7 +613,6 @@ describe('Streams @core-streams', () => {
async function setupStreams(user: BasicTestUser): Promise {
let remainingPublicStreams = PUBLIC_STREAM_COUNT
- let remainingDiscoverableStreams = DISCOVERABLE_STREAM_COUNT
// creating test streams
const streamDefinitions = times(
@@ -621,7 +620,6 @@ describe('Streams @core-streams', () => {
(i): BasicTestStream => ({
name: `${user.name} test stream #${i}`,
isPublic: remainingPublicStreams-- > 0,
- isDiscoverable: remainingDiscoverableStreams-- > 0,
id: '',
ownerId: ''
})
@@ -683,7 +681,7 @@ describe('Streams @core-streams', () => {
) => {
const { limitedUserQuery } = options
const expectedTotalCount = isOtherUser
- ? SHARED_STREAM_COUNT + DISCOVERABLE_STREAM_COUNT // only shared streams + discoverable ones
+ ? SHARED_STREAM_COUNT + DISCOVERABLE_STREAM_COUNT // only public
: TOTAL_OWN_STREAM_COUNT // all owned & shared streams
const requestPage = async (cursor?: Nullable) => {
diff --git a/packages/server/modules/core/tests/unit/projects.spec.ts b/packages/server/modules/core/tests/unit/projects.spec.ts
index 0a53c6f58..4d87705e2 100644
--- a/packages/server/modules/core/tests/unit/projects.spec.ts
+++ b/packages/server/modules/core/tests/unit/projects.spec.ts
@@ -2,6 +2,7 @@ import { ProjectEvents } from '@/modules/core/domain/projects/events'
import { Project } from '@/modules/core/domain/streams/types'
import { RegionalProjectCreationError } from '@/modules/core/errors/projects'
import { StreamNotFoundError } from '@/modules/core/errors/stream'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import { createNewProjectFactory } from '@/modules/core/services/projects'
import { isSpecificEventPayload } from '@/modules/shared/services/eventBus'
import { expectToThrow } from '@/test/assertionHelper'
@@ -31,13 +32,11 @@ describe('project services @core', () => {
const project = await createNewProject({ ownerId })
expect(project).deep.equal(storedProject)
- expect(storedProject!.isPublic).to.be.true
- expect(storedProject!.isDiscoverable).to.be.false
+ expect(storedProject!.visibility).to.eq(ProjectRecordVisibility.Private)
expect(storedProject!.allowPublicComments).to.be.false
})
- // Discoverability currently disabled
- it.skip(`makes PUBLIC projects public and discoverable`, async () => {
+ it(`makes PUBLIC projects public`, async () => {
const visibility = 'PUBLIC'
const ownerId = cryptoRandomString({ length: 10 })
@@ -60,12 +59,11 @@ describe('project services @core', () => {
const project = await createNewProject({ ownerId, visibility })
expect(project).deep.equal(storedProject)
- expect(storedProject!.isPublic).to.be.true
- expect(storedProject!.isDiscoverable).to.be.true
+ expect(storedProject!.visibility).to.eq(ProjectRecordVisibility.Public)
expect(storedProject!.allowPublicComments).to.be.false
})
- it(`makes UNLISTED projects public but not discoverable`, async () => {
+ it(`makes UNLISTED projects public`, async () => {
const visibility = 'UNLISTED'
const ownerId = cryptoRandomString({ length: 10 })
@@ -88,11 +86,10 @@ describe('project services @core', () => {
const project = await createNewProject({ ownerId, visibility })
expect(project).deep.equal(storedProject)
- expect(storedProject!.isPublic).to.be.true
- expect(storedProject!.isDiscoverable).to.be.false
+ expect(storedProject!.visibility).to.eq(ProjectRecordVisibility.Public)
expect(storedProject!.allowPublicComments).to.be.false
})
- // )
+
it('creates a private project', async () => {
const ownerId = cryptoRandomString({ length: 10 })
let storedProject: Project | undefined = undefined
@@ -113,8 +110,7 @@ describe('project services @core', () => {
const project = await createNewProject({ ownerId, visibility: 'PRIVATE' })
expect(project).deep.equal(storedProject)
- expect(storedProject!.isPublic).to.be.false
- expect(storedProject!.isDiscoverable).to.be.false
+ expect(storedProject!.visibility).to.eq(ProjectRecordVisibility.Private)
expect(storedProject!.allowPublicComments).to.be.false
})
it('deletes the created project if getProject throws StreamNotFoundError', async () => {
@@ -253,7 +249,7 @@ describe('project services @core', () => {
expect(eventPayload).deep.equal({
ownerId,
project,
- input: { description: '', name: project.name, visibility: 'PUBLIC' }
+ input: { description: '', name: project.name, visibility: 'PRIVATE' }
})
})
it('successfully creates a project', async () => {
@@ -317,7 +313,7 @@ describe('project services @core', () => {
expect(eventPayload).deep.equal({
ownerId,
project,
- input: { description: '', name: project.name, visibility: 'PUBLIC' }
+ input: { description: '', name: project.name, visibility: 'PRIVATE' }
})
})
})
diff --git a/packages/server/modules/cross-server-sync/graph/generated/graphql.ts b/packages/server/modules/cross-server-sync/graph/generated/graphql.ts
index 0a51ac5fa..240f9ce66 100644
--- a/packages/server/modules/cross-server-sync/graph/generated/graphql.ts
+++ b/packages/server/modules/cross-server-sync/graph/generated/graphql.ts
@@ -2070,7 +2070,7 @@ export type Project = {
versions: VersionCollection;
/** Return metadata about resources being requested in the viewer */
viewerResources: Array;
- visibility: SimpleProjectVisibility;
+ visibility: ProjectVisibility;
webhooks: WebhookCollection;
workspace?: Maybe;
workspaceId?: Maybe;
@@ -2691,9 +2691,14 @@ export const ProjectVersionsUpdatedMessageType = {
export type ProjectVersionsUpdatedMessageType = typeof ProjectVersionsUpdatedMessageType[keyof typeof ProjectVersionsUpdatedMessageType];
export const ProjectVisibility = {
+ /** Only accessible to explicit collaborators */
Private: 'PRIVATE',
+ /** Accessible to everyone (even non-logged in users) */
Public: 'PUBLIC',
- Unlisted: 'UNLISTED'
+ /** Legacy - same as public */
+ Unlisted: 'UNLISTED',
+ /** Accessible to everyone in the project's workspace */
+ Workspace: 'WORKSPACE'
} as const;
export type ProjectVisibility = typeof ProjectVisibility[keyof typeof ProjectVisibility];
@@ -3243,13 +3248,6 @@ export type SetPrimaryUserEmailInput = {
id: Scalars['ID']['input'];
};
-/** Visibility without the "discoverable" option */
-export const SimpleProjectVisibility = {
- Private: 'PRIVATE',
- Unlisted: 'UNLISTED'
-} as const;
-
-export type SimpleProjectVisibility = typeof SimpleProjectVisibility[keyof typeof SimpleProjectVisibility];
export type SmartTextEditorValue = {
__typename?: 'SmartTextEditorValue';
/** File attachments, if any */
@@ -3326,6 +3324,7 @@ export type Stream = {
/**
* Whether the stream (if public) can be found on public stream exploration pages
* and searches
+ * @deprecated Discoverability as a feature has been removed.
*/
isDiscoverable: Scalars['Boolean']['output'];
/** Whether the stream can be viewed by non-contributors */
@@ -5168,7 +5167,7 @@ export type CrossSyncProjectMetadataQueryVariables = Exact<{
}>;
-export type CrossSyncProjectMetadataQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, versions: { __typename?: 'VersionCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Version', id: string, createdAt: string, model: { __typename?: 'Model', id: string, name: string } }> } } };
+export type CrossSyncProjectMetadataQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, versions: { __typename?: 'VersionCollection', totalCount: number, cursor?: string | null, items: Array<{ __typename?: 'Version', id: string, createdAt: string, model: { __typename?: 'Model', id: string, name: string } }> } } };
export type CrossSyncClientTestQueryVariables = Exact<{ [key: string]: never; }>;
diff --git a/packages/server/modules/notifications/tests/activityDigest.spec.ts b/packages/server/modules/notifications/tests/activityDigest.spec.ts
index 1a3d31fa9..083cc2860 100644
--- a/packages/server/modules/notifications/tests/activityDigest.spec.ts
+++ b/packages/server/modules/notifications/tests/activityDigest.spec.ts
@@ -8,7 +8,11 @@ import {
StreamScopeActivity,
AllActivityTypes
} from '@/modules/activitystream/helpers/types'
-import { ServerInfo, UserRecord } from '@/modules/core/helpers/types'
+import {
+ ProjectRecordVisibility,
+ ServerInfo,
+ UserRecord
+} from '@/modules/core/helpers/types'
import { renderEmail } from '@/modules/emails/services/emailRendering'
import {
digestMostActiveStream,
@@ -116,14 +120,15 @@ describe('Activity digest notifications @notifications', () => {
id: streamName,
description: 'tester',
name: streamName,
- isPublic: true,
+ visibility: ProjectRecordVisibility.Public,
clonedFrom: null,
createdAt: new Date(),
updatedAt: new Date(),
allowPublicComments: true,
- isDiscoverable: true,
workspaceId: null,
- regionKey: null
+ regionKey: null,
+ isPublic: true,
+ isDiscoverable: true
},
activity: activities ?? [createActivity()]
})
diff --git a/packages/server/modules/previews/services/management.ts b/packages/server/modules/previews/services/management.ts
index cf6b8eb4f..2fa94a958 100644
--- a/packages/server/modules/previews/services/management.ts
+++ b/packages/server/modules/previews/services/management.ts
@@ -14,6 +14,7 @@ import { disablePreviews } from '@/modules/shared/helpers/envHelper'
import { Roles, Scopes } from '@speckle/shared'
import type { Logger } from 'pino'
import { PreviewPriority, PreviewStatus } from '@/modules/previews/domain/consts'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
const noPreviewImage = require.resolve('#/assets/previews/images/no_preview.png')
const previewErrorImage = require.resolve('#/assets/previews/images/preview_error.png')
@@ -164,11 +165,14 @@ export const checkStreamPermissionsFactory =
return { hasPermissions: false, httpErrorCode: 404 }
}
- if (!stream.isPublic && req.context.auth === false) {
+ if (
+ stream.visibility !== ProjectRecordVisibility.Public &&
+ req.context.auth === false
+ ) {
return { hasPermissions: false, httpErrorCode: 401 }
}
- if (!stream.isPublic) {
+ if (stream.visibility !== ProjectRecordVisibility.Public) {
try {
await deps.validateScopes(req.context.scopes, Scopes.Streams.Read)
} catch {
diff --git a/packages/server/modules/shared/authz.ts b/packages/server/modules/shared/authz.ts
index ce0ef3d7f..145f5d548 100644
--- a/packages/server/modules/shared/authz.ts
+++ b/packages/server/modules/shared/authz.ts
@@ -32,6 +32,7 @@ import {
} from '@/modules/shared/domain/authz/operations'
import { GetRoles } from '@/modules/shared/domain/rolesAndScopes/operations'
import { ValidateUserServerRole } from '@/modules/shared/domain/operations'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import { moduleAuthLoaders } from '@/modules/index'
export { AuthContext, AuthParams }
@@ -267,20 +268,25 @@ export const allowForServerAdmins: AuthPipelineFunction = async ({
export const allowForRegisteredUsersOnPublicStreamsEvenWithoutRole: AuthPipelineFunction =
async ({ context, authResult }) =>
- context.auth && context.stream?.isPublic
+ context.auth && context.stream?.visibility === ProjectRecordVisibility.Public
? authSuccess(context)
: { context, authResult }
export const allowForAllRegisteredUsersOnPublicStreamsWithPublicComments: AuthPipelineFunction =
async ({ context, authResult }) =>
- context.auth && context.stream?.isPublic && context.stream?.allowPublicComments
+ context.auth &&
+ context.stream?.visibility === ProjectRecordVisibility.Public &&
+ context.stream?.allowPublicComments
? authSuccess(context)
: { context, authResult }
export const allowAnonymousUsersOnPublicStreams: AuthPipelineFunction = async ({
context,
authResult
-}) => (context.stream?.isPublic ? authSuccess(context) : { context, authResult })
+}) =>
+ context.stream?.visibility === ProjectRecordVisibility.Public
+ ? authSuccess(context)
+ : { context, authResult }
export const authPipelineCreator = (
steps: AuthPipelineFunction[]
diff --git a/packages/server/modules/shared/services/auth.ts b/packages/server/modules/shared/services/auth.ts
index 4b5d17946..d19cd063b 100644
--- a/packages/server/modules/shared/services/auth.ts
+++ b/packages/server/modules/shared/services/auth.ts
@@ -4,6 +4,7 @@ import {
RoleResourceTargets,
roleResourceTypeToTokenResourceType
} from '@/modules/core/helpers/token'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import {
AuthorizeResolver,
GetUserAclRole,
@@ -32,10 +33,16 @@ export const validateScopesFactory = (): ValidateScopes => async (scopes, scope)
throw new ForbiddenError(errMsg, { info: { scope } })
}
-const workspaceRoleImplicitProjectRoleMap = {
- [Roles.Workspace.Admin]: Roles.Stream.Owner,
- [Roles.Workspace.Member]: Roles.Stream.Reviewer,
- [Roles.Workspace.Guest]: null
+const workspaceRoleImplicitProjectRoleMap = (
+ projectVisibility: ProjectRecordVisibility | null
+) => {
+ const isFullyPrivate = projectVisibility === ProjectRecordVisibility.Private
+
+ return {
+ [Roles.Workspace.Admin]: Roles.Stream.Owner,
+ [Roles.Workspace.Member]: isFullyPrivate ? null : Roles.Stream.Reviewer,
+ [Roles.Workspace.Guest]: null
+ }
}
/**
@@ -82,6 +89,7 @@ export const authorizeResolverFactory =
}
let targetWorkspaceId: string | null = null
+ let streamVisibility: ProjectRecordVisibility | null = null
if (role.resourceTarget === RoleResourceTargets.Streams) {
const stream = await deps.getStream({
@@ -96,8 +104,9 @@ export const authorizeResolverFactory =
}
targetWorkspaceId = stream.workspaceId
+ streamVisibility = stream.visibility
- const isPublic = !!stream?.isPublic
+ const isPublic = streamVisibility === ProjectRecordVisibility.Public
if (isPublic && role.weight < 200) return
}
@@ -114,9 +123,7 @@ export const authorizeResolverFactory =
: null
if (!userAclRole) {
- // TODO: Could be more optimized (caching?) but we're moving away from this towards
- // auth policies anyway
- // Check if workspace role allows for stream actions
+ // Implicit workspace project access
if (
role.resourceTarget === RoleResourceTargets.Streams &&
targetWorkspaceId &&
@@ -128,7 +135,9 @@ export const authorizeResolverFactory =
})
const implicitStreamRole =
workspaceRoleAndSeat?.role.role &&
- workspaceRoleImplicitProjectRoleMap[workspaceRoleAndSeat.role.role]
+ workspaceRoleImplicitProjectRoleMap(streamVisibility)[
+ workspaceRoleAndSeat.role.role
+ ]
userAclRole = implicitStreamRole
}
diff --git a/packages/server/modules/shared/test/authz.spec.js b/packages/server/modules/shared/test/authz.spec.js
index 376ddbd5d..c8ac64622 100644
--- a/packages/server/modules/shared/test/authz.spec.js
+++ b/packages/server/modules/shared/test/authz.spec.js
@@ -22,6 +22,7 @@ const { Roles } = require('@speckle/shared')
const {
TokenResourceIdentifierType
} = require('@/modules/core/graph/generated/graphql')
+const { ProjectRecordVisibility } = require('@/modules/core/helpers/types')
describe('AuthZ @shared', () => {
describe('Auth pipeline', () => {
@@ -411,7 +412,10 @@ describe('AuthZ @shared', () => {
expect(result).to.deep.equal(input)
})
it('public stream, no auth returns same context ', async () => {
- const input = { context: { stream: { isPublic: true } }, authResult: 'fake' }
+ const input = {
+ context: { stream: { visibility: ProjectRecordVisibility.Public } },
+ authResult: 'fake'
+ }
const result = await allowForRegisteredUsersOnPublicStreamsEvenWithoutRole(
input
)
@@ -419,7 +423,10 @@ describe('AuthZ @shared', () => {
})
it('not public stream, with auth returns same context ', async () => {
const input = {
- context: { auth: true, stream: { isPublic: false } },
+ context: {
+ auth: true,
+ stream: { visibility: ProjectRecordVisibility.Private }
+ },
authResult: 'fake'
}
const result = await allowForRegisteredUsersOnPublicStreamsEvenWithoutRole(
@@ -429,7 +436,10 @@ describe('AuthZ @shared', () => {
})
it('public stream, with auth returns authSuccess', async () => {
const input = {
- context: { auth: true, stream: { isPublic: true } },
+ context: {
+ auth: true,
+ stream: { visibility: ProjectRecordVisibility.Public }
+ },
authResult: 'fake'
}
const result = await allowForRegisteredUsersOnPublicStreamsEvenWithoutRole(
@@ -447,7 +457,10 @@ describe('AuthZ @shared', () => {
{
context: {
auth: true,
- stream: { isPublic: false, allowPublicComments: false }
+ stream: {
+ visibility: ProjectRecordVisibility.Private,
+ allowPublicComments: false
+ }
},
authResult: 'fake'
}
@@ -457,7 +470,10 @@ describe('AuthZ @shared', () => {
{
context: {
auth: true,
- stream: { isPublic: false, allowPublicComments: true }
+ stream: {
+ visibility: ProjectRecordVisibility.Private,
+ allowPublicComments: true
+ }
},
authResult: 'fake'
}
@@ -467,7 +483,10 @@ describe('AuthZ @shared', () => {
{
context: {
auth: true,
- stream: { isPublic: false, allowPublicComments: true }
+ stream: {
+ visibility: ProjectRecordVisibility.Private,
+ allowPublicComments: true
+ }
},
authResult: 'fake'
}
@@ -477,7 +496,10 @@ describe('AuthZ @shared', () => {
{
context: {
auth: false,
- stream: { isPublic: false, allowPublicComments: false }
+ stream: {
+ visibility: ProjectRecordVisibility.Private,
+ allowPublicComments: false
+ }
},
authResult: 'fake'
}
@@ -487,7 +509,10 @@ describe('AuthZ @shared', () => {
{
context: {
auth: false,
- stream: { isPublic: true, allowPublicComments: false }
+ stream: {
+ visibility: ProjectRecordVisibility.Public,
+ allowPublicComments: false
+ }
},
authResult: 'fake'
}
@@ -497,7 +522,10 @@ describe('AuthZ @shared', () => {
{
context: {
auth: false,
- stream: { isPublic: true, allowPublicComments: true }
+ stream: {
+ visibility: ProjectRecordVisibility.Public,
+ allowPublicComments: true
+ }
},
authResult: 'fake'
}
@@ -507,7 +535,10 @@ describe('AuthZ @shared', () => {
{
context: {
auth: false,
- stream: { isPublic: true, allowPublicComments: false }
+ stream: {
+ visibility: ProjectRecordVisibility.Public,
+ allowPublicComments: false
+ }
},
authResult: 'fake'
}
@@ -517,7 +548,10 @@ describe('AuthZ @shared', () => {
{
context: {
auth: false,
- stream: { isPublic: true, allowPublicComments: false }
+ stream: {
+ visibility: ProjectRecordVisibility.Public,
+ allowPublicComments: false
+ }
},
authResult: 'fake'
}
@@ -534,7 +568,10 @@ describe('AuthZ @shared', () => {
const input = {
context: {
auth: true,
- stream: { isPublic: true, allowPublicComments: true }
+ stream: {
+ visibility: ProjectRecordVisibility.Public,
+ allowPublicComments: true
+ }
},
authResult: 'fake'
}
diff --git a/packages/server/modules/workspaces/repositories/workspaces.ts b/packages/server/modules/workspaces/repositories/workspaces.ts
index c5c36b151..fa9065b57 100644
--- a/packages/server/modules/workspaces/repositories/workspaces.ts
+++ b/packages/server/modules/workspaces/repositories/workspaces.ts
@@ -44,7 +44,8 @@ import {
ServerAclRecord,
BranchRecord,
StreamAclRecord,
- StreamRecord
+ StreamRecord,
+ ProjectRecordVisibility
} from '@/modules/core/helpers/types'
import { WorkspaceInvalidRoleError } from '@/modules/workspaces/errors/workspace'
import {
@@ -564,8 +565,11 @@ const getPaginatedWorkspaceProjectsBaseQueryFactory =
/**
* If userId is set:
* - If no workspace role, user should be server admin w/ admin override enabled
- * - If workspace role is guest, user should have explicit stream roles
- * - If workspace role other than guest, just get all workspace streams
+ * - If workspace role is admin: user can get all workspace streams
+ * - If workspace role is guest: user should have explicit stream roles
+ * - If workspace role is member:
+ * - Public/Workspace visibility: get stream
+ * - Private visibility: user should have explicit stream roles
*
* If withProjectRoleOnly is set: Require project role always
*/
@@ -590,10 +594,21 @@ const getPaginatedWorkspaceProjectsBaseQueryFactory =
}
w.orWhere((w2) => {
- // Ensure workspace role exists and its not guest or the user has explicit stream roles
+ // Ensure workspace role exists and:
+ // user has explicit stream role or is admin or is a non-guest in a non-private project
w2.whereNotNull(DbWorkspaceAcl.col.role).andWhere((w3) => {
if (!withProjectRoleOnly) {
- w3.whereNot(DbWorkspaceAcl.col.role, Roles.Workspace.Guest)
+ w3.where(DbWorkspaceAcl.col.role, Roles.Workspace.Admin).orWhere(
+ (w4) => {
+ w4.whereNot(
+ DbWorkspaceAcl.col.role,
+ Roles.Workspace.Guest
+ ).andWhereNot(
+ Streams.col.visibility,
+ ProjectRecordVisibility.Private
+ )
+ }
+ )
}
w3.orWhereExists(
diff --git a/packages/server/modules/workspaces/services/projects.ts b/packages/server/modules/workspaces/services/projects.ts
index 06b4a225a..27517dcc7 100644
--- a/packages/server/modules/workspaces/services/projects.ts
+++ b/packages/server/modules/workspaces/services/projects.ts
@@ -1,4 +1,4 @@
-import { StreamRecord } from '@/modules/core/helpers/types'
+import { ProjectRecordVisibility, StreamRecord } from '@/modules/core/helpers/types'
import {
GetDefaultRegion,
GetWorkspaceDomains,
@@ -211,7 +211,17 @@ export const moveProjectToWorkspaceFactory =
}
// Assign project to workspace
- return await updateProject({ projectUpdate: { id: projectId, workspaceId } })
+ return await updateProject({
+ projectUpdate: {
+ id: projectId,
+ workspaceId,
+ visibility:
+ // Migrate from Private -> Workspace visibility
+ project.visibility === ProjectRecordVisibility.Private
+ ? ProjectRecordVisibility.Workspace
+ : project.visibility
+ }
+ })
}
export const getWorkspaceRoleToDefaultProjectRoleMappingFactory =
diff --git a/packages/server/modules/workspaces/tests/helpers/invites.ts b/packages/server/modules/workspaces/tests/helpers/invites.ts
index 20427aa1c..ccd5ae5de 100644
--- a/packages/server/modules/workspaces/tests/helpers/invites.ts
+++ b/packages/server/modules/workspaces/tests/helpers/invites.ts
@@ -32,6 +32,7 @@ import { expect } from 'chai'
import { MaybeAsync, StreamRoles, WorkspaceRoles } from '@speckle/shared'
import { expectToThrow } from '@/test/assertionHelper'
import { ForbiddenError } from '@/modules/shared/errors'
+import { isBoolean } from 'lodash'
export const buildInvitesGraphqlOperations = (deps: { apollo: TestApolloServer }) => {
const { apollo } = deps
@@ -80,7 +81,7 @@ export const buildInvitesGraphqlOperations = (deps: { apollo: TestApolloServer }
) => apollo.execute(UseWorkspaceProjectInviteDocument, args, options)
const validateResourceAccess = async (params: {
- shouldHaveAccess: boolean
+ shouldHaveAccess: boolean | { workspace: boolean; project: boolean }
userId: string
workspaceId: string
streamId?: string
@@ -88,8 +89,17 @@ export const buildInvitesGraphqlOperations = (deps: { apollo: TestApolloServer }
expectedProjectRole?: StreamRoles
}) => {
const { shouldHaveAccess, userId, workspaceId, streamId } = params
+ const shouldHaveWorkspaceAccess = isBoolean(shouldHaveAccess)
+ ? shouldHaveAccess
+ : shouldHaveAccess.workspace
+ const shouldHaveProjectAccess = isBoolean(shouldHaveAccess)
+ ? shouldHaveAccess
+ : shouldHaveAccess.project
- const wrapAccessCheck = async (fn: () => MaybeAsync) => {
+ const wrapAccessCheck = async (
+ fn: () => MaybeAsync,
+ shouldHaveAccess: boolean
+ ) => {
if (shouldHaveAccess) {
await fn()
} else {
@@ -113,7 +123,7 @@ export const buildInvitesGraphqlOperations = (deps: { apollo: TestApolloServer }
`Unexpected workspace role! Expected: ${params.expectedWorkspaceRole}, real: ${workspace.role}`
)
}
- })
+ }, shouldHaveWorkspaceAccess)
if (streamId?.length) {
await wrapAccessCheck(async () => {
@@ -133,7 +143,7 @@ export const buildInvitesGraphqlOperations = (deps: { apollo: TestApolloServer }
`Unexpected project role! Expected: ${params.expectedProjectRole}, real: ${project?.role}`
)
}
- })
+ }, shouldHaveProjectAccess)
}
}
diff --git a/packages/server/modules/workspaces/tests/integration/invites.graph.spec.ts b/packages/server/modules/workspaces/tests/integration/invites.graph.spec.ts
index 62570699c..9d8280704 100644
--- a/packages/server/modules/workspaces/tests/integration/invites.graph.spec.ts
+++ b/packages/server/modules/workspaces/tests/integration/invites.graph.spec.ts
@@ -67,6 +67,7 @@ import {
} from '@/modules/workspaces/tests/helpers/invites'
import { getEventBus } from '@/modules/shared/services/eventBus'
import { WorkspaceSeatType } from '@/modules/workspacesCore/domain/types'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
enum InviteByTarget {
Email = 'email',
@@ -1017,7 +1018,14 @@ describe('Workspaces Invites GQL', () => {
name: 'My Invite Target Workspace Stream 1',
id: '',
ownerId: '',
- isPublic: false
+ visibility: ProjectRecordVisibility.Workspace
+ }
+
+ const myInviteTargetPrivateWorkspaceStream1: BasicTestStream = {
+ name: 'My Invite Target Private Workspace Stream 1',
+ id: '',
+ ownerId: '',
+ visibility: ProjectRecordVisibility.Private
}
const processableWorkspaceInvite = {
@@ -1050,15 +1058,16 @@ describe('Workspaces Invites GQL', () => {
}
const validateResourceAccess = async (params: {
- shouldHaveAccess: boolean
+ shouldHaveAccess: boolean | { workspace: boolean; project: boolean }
expectedWorkspaceRole?: WorkspaceRoles
expectedProjectRole?: StreamRoles
+ streamId: string
}) => {
return gqlHelpers.validateResourceAccess({
...params,
userId: otherGuy.id,
workspaceId: myInviteTargetWorkspace.id,
- streamId: myInviteTargetWorkspaceStream1.id
+ streamId: params.streamId
})
}
@@ -1067,7 +1076,11 @@ describe('Workspaces Invites GQL', () => {
await createTestWorkspaces([[myInviteTargetWorkspace, me]])
myInviteTargetWorkspaceStream1.workspaceId = myInviteTargetWorkspace.id
- await createTestStreams([[myInviteTargetWorkspaceStream1, me]])
+ myInviteTargetPrivateWorkspaceStream1.workspaceId = myInviteTargetWorkspace.id
+ await createTestStreams([
+ [myInviteTargetWorkspaceStream1, me],
+ [myInviteTargetPrivateWorkspaceStream1, me]
+ ])
})
beforeEach(async () => {
@@ -1392,7 +1405,15 @@ describe('Workspaces Invites GQL', () => {
})
expect(invite).to.be.not.ok
- await validateResourceAccess({ shouldHaveAccess: accept })
+ // Should have access to workspace visibility stream, not the other one
+ await validateResourceAccess({
+ shouldHaveAccess: accept,
+ streamId: myInviteTargetWorkspaceStream1.id
+ })
+ await validateResourceAccess({
+ shouldHaveAccess: { workspace: accept, project: false },
+ streamId: myInviteTargetPrivateWorkspaceStream1.id
+ })
}
)
@@ -1440,7 +1461,10 @@ describe('Workspaces Invites GQL', () => {
expect(res).to.not.haveGraphQLErrors()
expect(res.data?.workspaceMutations.invites.use).to.be.ok
- await validateResourceAccess({ shouldHaveAccess: accept })
+ await validateResourceAccess({
+ shouldHaveAccess: accept,
+ streamId: myInviteTargetWorkspaceStream1.id
+ })
const verifiedEmails = await findVerifiedEmailsByUserIdFactory({
db
@@ -1487,7 +1511,8 @@ describe('Workspaces Invites GQL', () => {
await validateResourceAccess({
shouldHaveAccess: true,
- expectedWorkspaceRole: Roles.Workspace.Member
+ expectedWorkspaceRole: Roles.Workspace.Member,
+ streamId: myInviteTargetWorkspaceStream1.id
})
const targetInvite = roleChanged
@@ -1516,7 +1541,8 @@ describe('Workspaces Invites GQL', () => {
shouldHaveAccess: true,
expectedWorkspaceRole: roleChanged
? Roles.Workspace.Admin
- : Roles.Workspace.Member
+ : Roles.Workspace.Member,
+ streamId: myInviteTargetWorkspaceStream1.id
})
const email = targetInvite.email
@@ -1610,7 +1636,8 @@ describe('Workspaces Invites GQL', () => {
await validateResourceAccess({
shouldHaveAccess: true,
expectedWorkspaceRole: Roles.Workspace.Guest,
- expectedProjectRole: Roles.Stream.Reviewer
+ expectedProjectRole: Roles.Stream.Reviewer,
+ streamId: myInviteTargetWorkspaceStream1.id
})
})
@@ -1666,7 +1693,14 @@ describe('Workspaces Invites GQL', () => {
expectedWorkspaceRole: withRole
? Roles.Workspace.Admin
: Roles.Workspace.Guest,
- expectedProjectRole: withRole ? Roles.Stream.Owner : Roles.Stream.Reviewer
+ expectedProjectRole: withRole ? Roles.Stream.Owner : Roles.Stream.Reviewer,
+ streamId: myInviteTargetWorkspaceStream1.id
+ })
+
+ // ws admin will have access to everything
+ await validateResourceAccess({
+ shouldHaveAccess: { workspace: true, project: withRole ? true : false },
+ streamId: myInviteTargetPrivateWorkspaceStream1.id
})
}
)
diff --git a/packages/server/modules/workspaces/tests/integration/projects.graph.spec.ts b/packages/server/modules/workspaces/tests/integration/projects.graph.spec.ts
index 8efcfa527..ecee3df98 100644
--- a/packages/server/modules/workspaces/tests/integration/projects.graph.spec.ts
+++ b/packages/server/modules/workspaces/tests/integration/projects.graph.spec.ts
@@ -1,4 +1,6 @@
import { db } from '@/db/knex'
+import { StreamAcl } from '@/modules/core/dbSchema'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import { grantStreamPermissionsFactory } from '@/modules/core/repositories/streams'
import { WorkspaceSeatType } from '@/modules/gatekeeper/domain/billing'
import { getWorkspaceUserSeatsFactory } from '@/modules/gatekeeper/repositories/workspaceSeat'
@@ -10,16 +12,25 @@ import {
createTestWorkspace
} from '@/modules/workspaces/tests/helpers/creation'
import { describeEach, itEach } from '@/test/assertionHelper'
-import { BasicTestUser, createTestUser, createTestUsers } from '@/test/authHelper'
import {
+ BasicTestUser,
+ createTestUser,
+ createTestUsers,
+ login
+} from '@/test/authHelper'
+import {
+ ActiveUserProjectsDocument,
ActiveUserProjectsWorkspaceDocument,
+ CreateProjectDocument,
CreateWorkspaceProjectDocument,
GetProjectDocument,
+ GetWorkspaceDocument,
GetWorkspaceProjectsDocument,
GetWorkspaceProjectsQuery,
GetWorkspaceTeamDocument,
MoveProjectToWorkspaceDocument,
ProjectUpdateRoleInput,
+ ProjectVisibility,
UpdateProjectRoleDocument,
UpdateWorkspaceProjectRoleDocument
} from '@/test/graphql/generated/graphql'
@@ -41,7 +52,8 @@ import {
Nullable,
Optional,
PaidWorkspacePlans,
- Roles
+ Roles,
+ WorkspacePlans
} from '@speckle/shared'
import { expect } from 'chai'
import cryptoRandomString from 'crypto-random-string'
@@ -97,6 +109,48 @@ describe('Workspace project GQL CRUD', () => {
)
})
+ describe('when creating project', () => {
+ it('should have workspace visibility by default', async () => {
+ const res = await apollo.execute(
+ CreateWorkspaceProjectDocument,
+ {
+ input: {
+ name: 'Test Default Project',
+ workspaceId: workspace.id
+ }
+ },
+ { assertNoErrors: true }
+ )
+
+ const project = res.data?.workspaceMutations?.projects.create
+ expect(project).to.be.ok
+ expect(project?.visibility).to.equal(ProjectVisibility.Workspace)
+ })
+
+ it('should create the project in that workspace', async () => {
+ const projectName = cryptoRandomString({ length: 6 })
+
+ const createRes = await apollo.execute(CreateWorkspaceProjectDocument, {
+ input: {
+ name: projectName,
+ workspaceId: workspace.id
+ }
+ })
+
+ const getRes = await apollo.execute(GetWorkspaceProjectsDocument, {
+ id: workspace.id
+ })
+
+ const workspaceProject = getRes.data?.workspace.projects.items.find(
+ (project) => project.name === projectName
+ )
+
+ expect(createRes).to.not.haveGraphQLErrors()
+ expect(getRes).to.not.haveGraphQLErrors()
+ expect(workspaceProject).to.exist
+ })
+ })
+
describe('when changing workspace project roles', () => {
const workspaceGuest: BasicTestUser = {
id: '',
@@ -240,31 +294,6 @@ describe('Workspace project GQL CRUD', () => {
})
})
- describe('when specifying a workspace id during project creation', () => {
- it('should create the project in that workspace', async () => {
- const projectName = cryptoRandomString({ length: 6 })
-
- const createRes = await apollo.execute(CreateWorkspaceProjectDocument, {
- input: {
- name: projectName,
- workspaceId: workspace.id
- }
- })
-
- const getRes = await apollo.execute(GetWorkspaceProjectsDocument, {
- id: workspace.id
- })
-
- const workspaceProject = getRes.data?.workspace.projects.items.find(
- (project) => project.name === projectName
- )
-
- expect(createRes).to.not.haveGraphQLErrors()
- expect(getRes).to.not.haveGraphQLErrors()
- expect(workspaceProject).to.exist
- })
- })
-
describe('when querying projects', () => {
const PAGE_SIZE = 5
const PAGE_COUNT = 3
@@ -285,18 +314,36 @@ describe('Workspace project GQL CRUD', () => {
email: '',
name: 'Query Workspace Guest'
}
+
const workspaceAdmin = serverMemberUser
+ const workspaceAdmin2: BasicTestUser = {
+ id: '',
+ email: '',
+ name: 'Query Workspace Admin 2'
+ }
+
const workspaceMember: BasicTestUser = {
id: '',
email: '',
name: 'Query Workspace Member'
}
+ const workspaceMemberNoExplicitRoles: BasicTestUser = {
+ id: '',
+ email: '',
+ name: 'Query Workspace Member w/ No Explicit Project Roles'
+ }
+
let wsProjects: BasicTestStream[]
let nonWorkspaceProjects: BasicTestStream[]
let apollo: TestApolloServer
before(async () => {
- await createTestUsers([workspaceGuest, workspaceMember])
+ await createTestUsers([
+ workspaceGuest,
+ workspaceMember,
+ workspaceAdmin2,
+ workspaceMemberNoExplicitRoles
+ ])
await createTestWorkspace(queryWorkspace, workspaceAdmin, {
addPlan: { name: 'team', status: 'valid' }
})
@@ -312,6 +359,18 @@ describe('Workspace project GQL CRUD', () => {
workspaceMember,
Roles.Workspace.Member,
WorkspaceSeatType.Editor
+ ],
+ [
+ queryWorkspace,
+ workspaceAdmin2,
+ Roles.Workspace.Admin,
+ WorkspaceSeatType.Editor
+ ],
+ [
+ queryWorkspace,
+ workspaceMemberNoExplicitRoles,
+ Roles.Workspace.Member,
+ WorkspaceSeatType.Editor
]
])
wsProjects = times(
@@ -320,7 +379,11 @@ describe('Workspace project GQL CRUD', () => {
id: '',
ownerId: '',
name: `Query Workspace Project - #${i}`,
- isPublic: false, // have to be private for tests below
+ // Make all except the very last one workspace visibility
+ visibility:
+ i === TOTAL_WS_PROJECT_COUNT - 1
+ ? ProjectRecordVisibility.Private
+ : ProjectRecordVisibility.Workspace,
workspaceId: queryWorkspace.id
})
)
@@ -330,7 +393,7 @@ describe('Workspace project GQL CRUD', () => {
id: '',
ownerId: '',
name: `Non Workspace Project - #${i}`,
- isPublic: false
+ visibility: ProjectRecordVisibility.Private
})
)
@@ -351,8 +414,9 @@ describe('Workspace project GQL CRUD', () => {
)
await Promise.all([
- // Add explicit single assignment to workspaceMember to 1st non-workspace project
+ // Add explicit single assignment to workspaceMember & workspaceAdmin to 1st non-workspace project
addToStream(nonWorkspaceProjects[0], workspaceMember, Roles.Stream.Contributor),
+ addToStream(nonWorkspaceProjects[0], workspaceAdmin, Roles.Stream.Contributor),
// Add explicit single assignment to workspaceMember to 1st workspace project
addToStream(wsProjects[0], workspaceMember, Roles.Stream.Contributor)
])
@@ -362,12 +426,18 @@ describe('Workspace project GQL CRUD', () => {
})
})
+ // projects at the end have no explicit project assignments (and very last one is fully private),
+ // and first X ones are explicitly assigned to guest user
+ const implicitPrivateProject = () => wsProjects.at(-1)!
+ const implicitWorkspaceVisibilityProject = () => wsProjects.at(-2)!
+ const explicitGuestProject = () => wsProjects.at(0)!
+
afterEach(async () => {
adminOverrideMock.disable()
})
describe('through Workspace.projects', () => {
- it('should return all projects for workspace members', async () => {
+ it('should return all projects for workspace admin', async () => {
const res = await apollo.execute(GetWorkspaceProjectsDocument, {
id: queryWorkspace.id,
limit: 999 // get everything
@@ -443,6 +513,24 @@ describe('Workspace project GQL CRUD', () => {
expect(collection?.totalCount).to.equal(GUEST_PROJECT_COUNT)
})
+ it('should return all non-private for members who may not even have any explicit project roles', async () => {
+ const apollo = await testApolloServer({
+ authUserId: workspaceMemberNoExplicitRoles.id
+ })
+ const res = await apollo.execute(GetWorkspaceProjectsDocument, {
+ id: queryWorkspace.id,
+ limit: 999 // get everything
+ })
+
+ const nonPrivateCount = TOTAL_WS_PROJECT_COUNT - 1 // -1 for the fully private one
+
+ expect(res).to.not.haveGraphQLErrors()
+ const collection = res.data?.workspace.projects
+ expect(collection?.items.length).to.equal(nonPrivateCount)
+ expect(collection?.cursor).to.be.ok
+ expect(collection?.totalCount).to.equal(nonPrivateCount)
+ })
+
it('should respect limits', async () => {
const res = await apollo.execute(GetWorkspaceProjectsDocument, {
id: queryWorkspace.id,
@@ -542,17 +630,36 @@ describe('Workspace project GQL CRUD', () => {
await createTestUser(randomServerGuy)
})
- // projects at the end have no explicit project assignments,
- // and first X ones are explicitly assigned to guest user
- const implicitProject = () => wsProjects.at(-1)!
- const explicitGuestProject = () => wsProjects.at(0)!
-
- it('it should be accessible to workspace member', async () => {
+ it('workspace visibility should be accessible to workspace member', async () => {
const apollo = await testApolloServer({
authUserId: workspaceMember.id
})
const res = await apollo.execute(GetProjectDocument, {
- id: implicitProject().id
+ id: implicitWorkspaceVisibilityProject().id
+ })
+
+ expect(res).to.not.haveGraphQLErrors()
+ expect(res.data?.project.id).to.be.ok
+ })
+
+ it('private visibility should not be accessible to workspace member w/o explicit role', async () => {
+ const apollo = await testApolloServer({
+ authUserId: workspaceMember.id
+ })
+ const res = await apollo.execute(GetProjectDocument, {
+ id: implicitPrivateProject().id
+ })
+
+ expect(res).to.haveGraphQLErrors()
+ expect(res.data?.project).to.not.be.ok
+ })
+
+ it('private visibility should be accessible to workspace admin w/o explicit role', async () => {
+ const apollo = await testApolloServer({
+ authUserId: workspaceAdmin2.id
+ })
+ const res = await apollo.execute(GetProjectDocument, {
+ id: implicitPrivateProject().id
})
expect(res).to.not.haveGraphQLErrors()
@@ -564,7 +671,7 @@ describe('Workspace project GQL CRUD', () => {
authUserId: randomServerGuy.id
})
const res = await apollo.execute(GetProjectDocument, {
- id: implicitProject().id
+ id: implicitWorkspaceVisibilityProject().id
})
expect(res).to.haveGraphQLErrors()
@@ -582,7 +689,9 @@ describe('Workspace project GQL CRUD', () => {
authUserId: workspaceGuest.id
})
const res = await apollo.execute(GetProjectDocument, {
- id: explicit ? explicitGuestProject().id : implicitProject().id
+ id: explicit
+ ? explicitGuestProject().id
+ : implicitWorkspaceVisibilityProject().id
})
if (explicit) {
@@ -599,8 +708,8 @@ describe('Workspace project GQL CRUD', () => {
[{ adminOverrideEnabled: true }, { adminOverrideEnabled: false }],
({ adminOverrideEnabled }) =>
adminOverrideEnabled
- ? 'it should return project for server admins if override enabled'
- : 'it should not return project for server admins if override disabled',
+ ? 'it should return fully private project for server admins if override enabled'
+ : 'it should not return fully private project for server admins if override disabled',
async ({ adminOverrideEnabled }) => {
const apollo = await testApolloServer({
authUserId: serverAdminUser.id
@@ -608,7 +717,7 @@ describe('Workspace project GQL CRUD', () => {
adminOverrideMock.enable(adminOverrideEnabled)
const res = await apollo.execute(GetProjectDocument, {
- id: implicitProject().id
+ id: implicitPrivateProject().id
})
if (adminOverrideEnabled) {
@@ -671,28 +780,41 @@ describe('Workspace project GQL CRUD', () => {
]).to.deep.equalInAnyOrder([nonWorkspaceProjects[0].id, wsProjects[0].id])
})
- it('should return all projects user is explicitly or implicitly assigned to, if flag set', async () => {
- const apolloMember = await testApolloServer({
- authUserId: workspaceMember.id
- })
- const memberRes = await apolloMember.execute(
- ActiveUserProjectsWorkspaceDocument,
- { limit: 999, filter: { includeImplicitAccess: true } },
- { assertNoErrors: true }
- )
- const memberCollection = memberRes.data?.activeUser?.projects
+ itEach(
+ [{ admin: true }, { admin: false }],
+ ({ admin }) =>
+ `should return all projects ${
+ admin ? 'ws admin' : 'ws member'
+ } is explicitly or implicitly assigned to, if flag set`,
+ async ({ admin }) => {
+ const apollo = await testApolloServer({
+ authUserId: admin ? workspaceAdmin.id : workspaceMember.id
+ })
+ const res = await apollo.execute(
+ ActiveUserProjectsWorkspaceDocument,
+ { limit: 999, filter: { includeImplicitAccess: true } },
+ { assertNoErrors: true }
+ )
+ const projects = res.data?.activeUser?.projects
- // 1 non-workspace assignment + all workspace projects
- const expectedMemberCount = TOTAL_WS_PROJECT_COUNT + 1
+ // 1 non-workspace assignment + all workspace projects
+ // (except the last one thats fully private, if not admin)
+ let expectedCount = TOTAL_WS_PROJECT_COUNT + 1
+ if (!admin) {
+ expectedCount -= 1
+ }
- expect(memberCollection).to.be.ok
- expect(memberCollection!.totalCount).to.equal(expectedMemberCount)
- expect(memberCollection!.items.length).to.equal(expectedMemberCount)
- expect(memberCollection!.items.map((i) => i.id)).to.deep.equalInAnyOrder([
- nonWorkspaceProjects[0].id,
- ...wsProjects.map((p) => p.id)
- ])
- })
+ expect(projects).to.be.ok
+ expect(projects!.totalCount).to.equal(expectedCount)
+ expect(projects!.items.length).to.equal(expectedCount)
+ expect(projects!.items.map((i) => i.id)).to.deep.equalInAnyOrder([
+ nonWorkspaceProjects[0].id,
+ ...wsProjects
+ .filter((p) => (admin ? true : p.id !== implicitPrivateProject().id))
+ .map((p) => p.id)
+ ])
+ }
+ )
it('should only return workspace projects if filter set', async () => {
const res = await apollo.execute(ActiveUserProjectsWorkspaceDocument, {
@@ -739,7 +861,7 @@ describe('Workspace project GQL CRUD', () => {
id: '',
ownerId: '',
name: 'Test Project',
- isPublic: false
+ visibility: ProjectRecordVisibility.Private
}
const targetWorkspace: BasicTestWorkspace = {
@@ -750,7 +872,9 @@ describe('Workspace project GQL CRUD', () => {
}
before(async () => {
- await createTestWorkspace(targetWorkspace, serverAdminUser)
+ await createTestWorkspace(targetWorkspace, serverAdminUser, {
+ addPlan: WorkspacePlans.Unlimited
+ })
})
beforeEach(async () => {
@@ -762,17 +886,38 @@ describe('Workspace project GQL CRUD', () => {
})
})
- it('should move the project to the target workspace', async () => {
+ it('should move the project to the target workspace and update visibility', async () => {
const res = await apollo.execute(MoveProjectToWorkspaceDocument, {
projectId: testProject.id,
workspaceId: targetWorkspace.id
})
- const { workspaceId } =
- res.data?.workspaceMutations.projects.moveToWorkspace ?? {}
+ const project = res.data?.workspaceMutations.projects.moveToWorkspace
expect(res).to.not.haveGraphQLErrors()
- expect(workspaceId).to.equal(targetWorkspace.id)
+ expect(project?.workspaceId).to.equal(targetWorkspace.id)
+ expect(project?.visibility).to.equal(ProjectVisibility.Workspace)
+ })
+
+ it('should move a public project to the target workspace and keep same visibility', async () => {
+ const publicProject: BasicTestStream = {
+ id: '',
+ ownerId: '',
+ name: 'Test Public Project',
+ visibility: ProjectRecordVisibility.Public
+ }
+ await createTestStream(publicProject, serverAdminUser)
+
+ const res = await apollo.execute(MoveProjectToWorkspaceDocument, {
+ projectId: publicProject.id,
+ workspaceId: targetWorkspace.id
+ })
+
+ const project = res.data?.workspaceMutations.projects.moveToWorkspace
+
+ expect(res).to.not.haveGraphQLErrors()
+ expect(project?.workspaceId).to.equal(targetWorkspace.id)
+ expect(project?.visibility).to.equal(ProjectVisibility.Public)
})
it('should preserve project roles for project members with editor seats', async () => {
@@ -839,4 +984,224 @@ describe('Workspace project GQL CRUD', () => {
expect(adminWorkspaceRole?.role).to.equal(Roles.Workspace.Admin)
})
})
+
+ // moved over Alessandro's tests from core to here, since they are all related to workspaces
+ // they're kind of a mess and need to be cleaned up
+ describe('query user.projects', () => {
+ it('should return projects not in a workspace', async () => {
+ const testAdminUser: BasicTestUser = {
+ id: '',
+ name: 'test',
+ email: '',
+ role: Roles.Server.Admin,
+ verified: true
+ }
+ await createTestUser(testAdminUser)
+ const workspace = {
+ id: '',
+ name: 'test ws',
+ slug: cryptoRandomString({ length: 10 }),
+ ownerId: ''
+ }
+ await createTestWorkspace(workspace, testAdminUser)
+
+ const session = await login(testAdminUser)
+ const getWorkspaceRes = await session.execute(GetWorkspaceDocument, {
+ workspaceId: workspace.id
+ })
+
+ expect(getWorkspaceRes).to.not.haveGraphQLErrors()
+ const workspaceId = getWorkspaceRes.data!.workspace.id
+
+ const createProjectInWorkspaceRes = await session.execute(
+ CreateWorkspaceProjectDocument,
+ { input: { name: 'project', workspaceId } }
+ )
+ expect(createProjectInWorkspaceRes).to.not.haveGraphQLErrors()
+
+ const createProjectNonInWorkspaceRes = await session.execute(
+ CreateProjectDocument,
+ { input: { name: 'project' } }
+ )
+ expect(createProjectNonInWorkspaceRes).to.not.haveGraphQLErrors()
+ const projectNonInWorkspace =
+ createProjectNonInWorkspaceRes.data!.projectMutations.create
+
+ const userProjectsRes = await session.execute(ActiveUserProjectsDocument, {
+ filter: { personalOnly: true }
+ })
+ expect(userProjectsRes).to.not.haveGraphQLErrors()
+
+ const projects = userProjectsRes.data!.activeUser!.projects.items
+
+ expect(projects).to.have.length(1)
+ expect(projects[0].id).to.eq(projectNonInWorkspace.id)
+ })
+
+ it('should return projects in workspace', async () => {
+ const testAdminUser: BasicTestUser = {
+ id: '',
+ name: 'test',
+ email: '',
+ role: Roles.Server.Admin,
+ verified: true
+ }
+ await createTestUser(testAdminUser)
+ const workspace = {
+ id: '',
+ name: 'test ws',
+ slug: cryptoRandomString({ length: 10 }),
+ ownerId: ''
+ }
+ await createTestWorkspace(workspace, testAdminUser)
+
+ const session = await login(testAdminUser)
+ const getWorkspaceRes = await session.execute(GetWorkspaceDocument, {
+ workspaceId: workspace.id
+ })
+
+ expect(getWorkspaceRes).to.not.haveGraphQLErrors()
+ const workspaceId = getWorkspaceRes.data!.workspace.id
+
+ const createProjectInWorkspaceRes = await session.execute(
+ CreateWorkspaceProjectDocument,
+ { input: { name: 'project', workspaceId } }
+ )
+ expect(createProjectInWorkspaceRes).to.not.haveGraphQLErrors()
+ const projectInWorkspace =
+ createProjectInWorkspaceRes.data!.workspaceMutations.projects.create
+
+ const createProjectNonInWorkspaceRes = await session.execute(
+ CreateProjectDocument,
+ { input: { name: 'project' } }
+ )
+ expect(createProjectNonInWorkspaceRes).to.not.haveGraphQLErrors()
+
+ const userProjectsRes = await session.execute(ActiveUserProjectsDocument, {
+ filter: { workspaceId }
+ })
+ expect(userProjectsRes).to.not.haveGraphQLErrors()
+
+ const projects = userProjectsRes.data!.activeUser!.projects.items
+
+ expect(projects).to.have.length(1)
+ expect(projects[0].id).to.eq(projectInWorkspace.id)
+ })
+
+ it('should return all user projects', async () => {
+ const testAdminUser: BasicTestUser = {
+ id: '',
+ name: 'test',
+ email: '',
+ role: Roles.Server.Admin,
+ verified: true
+ }
+ await createTestUser(testAdminUser)
+ const workspace = {
+ id: '',
+ name: 'test ws',
+ slug: cryptoRandomString({ length: 10 }),
+ ownerId: ''
+ }
+ await createTestWorkspace(workspace, testAdminUser)
+
+ const session = await login(testAdminUser)
+ const getWorkspaceRes = await session.execute(GetWorkspaceDocument, {
+ workspaceId: workspace.id
+ })
+
+ expect(getWorkspaceRes).to.not.haveGraphQLErrors()
+ const workspaceId = getWorkspaceRes.data!.workspace.id
+
+ const createProjectInWorkspaceRes = await session.execute(
+ CreateWorkspaceProjectDocument,
+ { input: { name: 'project', workspaceId } }
+ )
+ expect(createProjectInWorkspaceRes).to.not.haveGraphQLErrors()
+
+ const createProjectNonInWorkspaceRes = await session.execute(
+ CreateProjectDocument,
+ { input: { name: 'project' } }
+ )
+ expect(createProjectNonInWorkspaceRes).to.not.haveGraphQLErrors()
+
+ const userProjectsRes = await session.execute(ActiveUserProjectsDocument, {
+ filter: {}
+ })
+ expect(userProjectsRes).to.not.haveGraphQLErrors()
+
+ const projects = userProjectsRes.data!.activeUser!.projects.items
+
+ expect(projects).to.have.length(2)
+ })
+
+ it('should return all user projects sorted by user role', async () => {
+ const testAdminUser: BasicTestUser = {
+ id: '',
+ name: 'test',
+ email: '',
+ role: Roles.Server.Admin,
+ verified: true
+ }
+ await createTestUser(testAdminUser)
+ const workspace = {
+ id: '',
+ name: 'test ws',
+ slug: cryptoRandomString({ length: 10 }),
+ ownerId: ''
+ }
+ await createTestWorkspace(workspace, testAdminUser)
+
+ const session = await login(testAdminUser)
+ const getWorkspaceRes = await session.execute(GetWorkspaceDocument, {
+ workspaceId: workspace.id
+ })
+
+ expect(getWorkspaceRes).to.not.haveGraphQLErrors()
+ const workspaceId = getWorkspaceRes.data!.workspace.id
+
+ const createProjectInWorkspaceAsOwnerRes = await session.execute(
+ CreateWorkspaceProjectDocument,
+ { input: { name: 'project', workspaceId } }
+ )
+ expect(createProjectInWorkspaceAsOwnerRes).to.not.haveGraphQLErrors()
+ const createProjectInWorkspaceAsContributorRes = await session.execute(
+ CreateWorkspaceProjectDocument,
+ { input: { name: 'project 2', workspaceId } }
+ )
+ expect(createProjectInWorkspaceAsContributorRes).to.not.haveGraphQLErrors()
+ const projectContributorId =
+ createProjectInWorkspaceAsContributorRes.data?.workspaceMutations.projects
+ .create.id
+ await db(StreamAcl.name)
+ .update({ role: Roles.Stream.Contributor })
+ .where({ userId: testAdminUser.id, resourceId: projectContributorId })
+ const createProjectInWorkspaceAsReviewerRes = await session.execute(
+ CreateWorkspaceProjectDocument,
+ { input: { name: 'project 3', workspaceId } }
+ )
+ expect(createProjectInWorkspaceAsReviewerRes).to.not.haveGraphQLErrors()
+ const projectReviewerId =
+ createProjectInWorkspaceAsReviewerRes.data?.workspaceMutations.projects.create
+ .id
+ await db(StreamAcl.name)
+ .update({ role: Roles.Stream.Reviewer })
+ .where({ userId: testAdminUser.id, resourceId: projectReviewerId })
+
+ const userProjectsRes = await session.execute(ActiveUserProjectsDocument, {
+ filter: {},
+ sortBy: ['role']
+ })
+ expect(userProjectsRes).to.not.haveGraphQLErrors()
+
+ const projects = userProjectsRes.data!.activeUser!.projects.items
+
+ expect(projects).to.have.length(3)
+ expect(projects[0].id).to.eq(
+ createProjectInWorkspaceAsOwnerRes.data?.workspaceMutations.projects.create.id
+ )
+ expect(projects[1].id).to.eq(projectContributorId)
+ expect(projects[2].id).to.eq(projectReviewerId)
+ })
+ })
})
diff --git a/packages/server/modules/workspaces/tests/integration/roles.graph.spec.ts b/packages/server/modules/workspaces/tests/integration/roles.graph.spec.ts
index e929a6183..ec8434f92 100644
--- a/packages/server/modules/workspaces/tests/integration/roles.graph.spec.ts
+++ b/packages/server/modules/workspaces/tests/integration/roles.graph.spec.ts
@@ -1,5 +1,6 @@
import { Streams } from '@/modules/core/dbSchema'
import { AllScopes } from '@/modules/core/helpers/mainConstants'
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import {
assignToWorkspace,
BasicTestWorkspace,
@@ -283,7 +284,6 @@ describe('Workspaces Roles/Seats GQL', () => {
})
})
- // TODO: Viewer vs Editor
describe('in a workspace with projects', () => {
const workspace: BasicTestWorkspace = {
id: '',
@@ -326,35 +326,43 @@ describe('Workspaces Roles/Seats GQL', () => {
id: '',
ownerId: '',
name: 'Project A',
- isPublic: false
+ visibility: ProjectRecordVisibility.Workspace
}
const workspaceProjectB: BasicTestStream = {
id: '',
ownerId: '',
name: 'Project B',
- isPublic: false
+ visibility: ProjectRecordVisibility.Workspace
}
const workspaceProjectC: BasicTestStream = {
id: '',
ownerId: '',
name: 'Project C',
- isPublic: false
+ visibility: ProjectRecordVisibility.Workspace
}
const workspaceProjectD: BasicTestStream = {
id: '',
ownerId: '',
name: 'Project D',
- isPublic: false
+ visibility: ProjectRecordVisibility.Workspace
+ }
+
+ const workspaceProjectE: BasicTestStream = {
+ id: '',
+ ownerId: '',
+ name: 'Project E (Fully private)',
+ visibility: ProjectRecordVisibility.Private
}
const workspaceProjects = [
workspaceProjectA,
workspaceProjectB,
workspaceProjectC,
- workspaceProjectD
+ workspaceProjectD,
+ workspaceProjectE
]
before(async () => {
@@ -424,13 +432,13 @@ describe('Workspaces Roles/Seats GQL', () => {
*
* Initial explicit workspace project roles:
*
- * | | Project A | Project B | Project C | Project D |
- * |---------------------------|-------------|-------------|-----------|-----------|
- * | workspaceAdminUser | Owner | None | None | None |
- * | workspaceMemberUser | Owner | Contributor | Reviewer | None |
- * | workspaceGuestUser | Contributor | Reviewer | None | None |
- * | workspaceMemberViewerUser | Reviewer | None | None | None |
- * | workspaceGuestViewerUser | None | Reviewer | None | None |
+ * | | Project A | Project B | Project C | Project D | Project E (private) |
+ * |---------------------------|-------------|-------------|-----------|-----------|---------------------|
+ * | workspaceAdminUser | Owner | None | None | None | None
+ * | workspaceMemberUser | Owner | Contributor | Reviewer | None | None
+ * | workspaceGuestUser | Contributor | Reviewer | None | None | Reviewer
+ * | workspaceMemberViewerUser | Reviewer | None | None | None | Reviewer
+ * | workspaceGuestViewerUser | None | Reviewer | None | None | Reviewer
*/
await Promise.all([
@@ -448,7 +456,15 @@ describe('Workspaces Roles/Seats GQL', () => {
addToStream(workspaceProjectB, workspaceGuestUser, Roles.Stream.Reviewer),
addToStream(workspaceProjectB, workspaceGuestViewerUser, Roles.Stream.Reviewer),
// C
- addToStream(workspaceProjectC, workspaceMemberUser, Roles.Stream.Reviewer)
+ addToStream(workspaceProjectC, workspaceMemberUser, Roles.Stream.Reviewer),
+ // E
+ addToStream(workspaceProjectE, workspaceGuestUser, Roles.Stream.Reviewer),
+ addToStream(
+ workspaceProjectE,
+ workspaceMemberViewerUser,
+ Roles.Stream.Reviewer
+ ),
+ addToStream(workspaceProjectE, workspaceGuestViewerUser, Roles.Stream.Reviewer)
])
})
@@ -470,15 +486,16 @@ describe('Workspaces Roles/Seats GQL', () => {
user: workspaceAdminUser
})
- expect(projects.length).to.eq(4)
+ expect(projects.length).to.eq(5)
expect(checkAllProjects((p) => p.isOwner)).to.be.ok
expect(checkProject(workspaceProjectA).isExplicitOwner).to.be.ok
expect(checkProject(workspaceProjectB).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectC).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectE).hasExplicitRole).to.be.not.ok
})
- it('workspaceMemberUser is implicit reviewer in all of them, and also has explicit roles in some', async () => {
+ it('workspaceMemberUser is implicit reviewer in all of them, except E, and also has explicit roles in some', async () => {
const { projects, checkAllProjects, checkProject } = await getProjects({
user: workspaceMemberUser
})
@@ -489,42 +506,46 @@ describe('Workspaces Roles/Seats GQL', () => {
expect(checkProject(workspaceProjectB).isExplicitContributor).to.be.ok
expect(checkProject(workspaceProjectC).isExplicitReviewer).to.be.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectE).hasAccess).to.be.not.ok
})
- it('workspaceGuestUser only has explicit roles in 2 projects', async () => {
+ it('workspaceGuestUser only has explicit roles in 3 projects', async () => {
const { projects, checkProject } = await getProjects({
user: workspaceGuestUser
})
- expect(projects.length).to.eq(2)
+ expect(projects.length).to.eq(3)
expect(checkProject(workspaceProjectA).isExplicitContributor).to.be.ok
expect(checkProject(workspaceProjectB).isExplicitReviewer).to.be.ok
- expect(checkProject(workspaceProjectC).hasExplicitRole).to.be.not.ok
- expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectC).hasAccess).to.be.not.ok
+ expect(checkProject(workspaceProjectD).hasAccess).to.be.not.ok
+ expect(checkProject(workspaceProjectE).isExplicitReviewer).to.be.ok
})
- it('workspaceMemberViewerUser is only explicit reviewer in 1 project, and has implicit roles elsewhere', async () => {
+ it('workspaceMemberViewerUser is only explicit reviewer in 2 projects, and has implicit roles elsewhere', async () => {
const { projects, checkAllProjects, checkProject } = await getProjects({
user: workspaceMemberViewerUser
})
- expect(projects.length).to.eq(4)
+ expect(projects.length).to.eq(5)
expect(checkAllProjects((p) => p.isReviewer)).to.be.ok
expect(checkProject(workspaceProjectA).isExplicitReviewer).to.be.ok
expect(checkProject(workspaceProjectB).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectC).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectE).isExplicitReviewer).to.be.ok
})
- it('workspaceGuestViewerUser is only explicit reviewer in 1 project', async () => {
+ it('workspaceGuestViewerUser is only explicit reviewer in 2 projects', async () => {
const { projects, checkProject } = await getProjects({
user: workspaceGuestViewerUser
})
- expect(projects.length).to.eq(1)
+ expect(projects.length).to.eq(2)
expect(checkProject(workspaceProjectB).isExplicitReviewer).to.be.ok
expect(checkProject(workspaceProjectA).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectC).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectE).isExplicitReviewer).to.be.ok
})
})
@@ -582,9 +603,10 @@ describe('Workspaces Roles/Seats GQL', () => {
user: workspaceGuestUser
})
- expect(projects.length).to.eq(2)
+ expect(projects.length).to.eq(3)
expect(checkProject(workspaceProjectA).isExplicitReviewer).to.be.ok
expect(checkProject(workspaceProjectB).isExplicitReviewer).to.be.ok
+ expect(checkProject(workspaceProjectE).isExplicitReviewer).to.be.ok
})
})
@@ -605,17 +627,18 @@ describe('Workspaces Roles/Seats GQL', () => {
)
})
- it('should still remain explicit owner and be implicit reviewer elsewhere', async () => {
+ it('should still remain explicit owner and be implicit reviewer elsewhere, except private E', async () => {
const { projects, checkAllProjects, checkProject } = await getProjects({
user: workspaceAdminUser
})
expect(projects.length).to.eq(4)
+ expect(checkAllProjects((p) => p.isReviewer)).to.be.ok
expect(checkProject(workspaceProjectA).isExplicitOwner).to.be.ok
expect(checkProject(workspaceProjectB).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectC).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
- expect(checkAllProjects((p) => p.isReviewer)).to.be.ok
+ expect(checkProject(workspaceProjectE).hasAccess).to.be.not.ok
})
})
@@ -670,12 +693,13 @@ describe('Workspaces Roles/Seats GQL', () => {
user: workspaceMemberUser
})
- expect(projects.length).to.eq(4)
+ expect(projects.length).to.eq(5)
expect(checkAllProjects((p) => p.isOwner)).to.be.ok
expect(checkProject(workspaceProjectA).isExplicitOwner).to.be.ok
expect(checkProject(workspaceProjectB).isExplicitOwner).to.be.ok
expect(checkProject(workspaceProjectC).isExplicitOwner).to.be.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.not.be.ok
+ expect(checkProject(workspaceProjectE).hasExplicitRole).to.not.be.ok
})
})
@@ -704,6 +728,7 @@ describe('Workspaces Roles/Seats GQL', () => {
expect(checkProject(workspaceProjectB).isExplicitContributor).to.be.ok
expect(checkProject(workspaceProjectC).isExplicitReviewer).to.be.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectE).hasExplicitRole).to.be.not.ok
})
})
})
@@ -729,12 +754,13 @@ describe('Workspaces Roles/Seats GQL', () => {
user: workspaceGuestUser
})
- expect(projects.length).to.eq(4)
+ expect(projects.length).to.eq(5)
expect(checkAllProjects((p) => p.isOwner)).to.be.ok
expect(checkProject(workspaceProjectA).isExplicitOwner).to.be.ok
expect(checkProject(workspaceProjectB).isExplicitOwner).to.be.ok
expect(checkProject(workspaceProjectC).hasExplicitRole).to.not.be.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectE).isExplicitOwner).to.be.ok
})
})
@@ -758,12 +784,13 @@ describe('Workspaces Roles/Seats GQL', () => {
user: workspaceGuestUser
})
- expect(projects.length).to.eq(4)
+ expect(projects.length).to.eq(5)
expect(checkAllProjects((p) => p.isReviewer)).to.be.ok
expect(checkProject(workspaceProjectA).isExplicitContributor).to.be.ok
expect(checkProject(workspaceProjectB).isExplicitReviewer).to.be.ok
expect(checkProject(workspaceProjectC).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectE).isExplicitReviewer).to.be.ok
})
})
})
@@ -791,12 +818,13 @@ describe('Workspaces Roles/Seats GQL', () => {
})
expect(workspace.seatType).to.eq(WorkspaceSeatType.Editor)
- expect(projects.length).to.eq(4)
+ expect(projects.length).to.eq(5)
expect(checkAllProjects((p) => p.isOwner)).to.be.ok
expect(checkProject(workspaceProjectA).isExplicitOwner).to.be.ok
expect(checkProject(workspaceProjectB).hasExplicitRole).to.not.be.ok
expect(checkProject(workspaceProjectC).hasExplicitRole).to.not.be.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.not.be.ok
+ expect(checkProject(workspaceProjectE).isExplicitOwner).to.be.ok
})
})
@@ -821,8 +849,9 @@ describe('Workspaces Roles/Seats GQL', () => {
})
expect(workspace.seatType).to.eq(WorkspaceSeatType.Viewer)
- expect(projects.length).to.eq(1)
+ expect(projects.length).to.eq(2)
expect(checkProject(workspaceProjectA).isExplicitReviewer).to.be.ok
+ expect(checkProject(workspaceProjectE).isExplicitReviewer).to.be.ok
})
})
})
@@ -850,12 +879,13 @@ describe('Workspaces Roles/Seats GQL', () => {
})
expect(workspace.seatType).to.eq(WorkspaceSeatType.Editor)
- expect(projects.length).to.eq(4)
+ expect(projects.length).to.eq(5)
expect(checkAllProjects((p) => p.isOwner)).to.be.ok
expect(checkProject(workspaceProjectA).hasExplicitRole).to.not.be.ok
expect(checkProject(workspaceProjectB).isExplicitOwner).to.be.ok
expect(checkProject(workspaceProjectC).hasExplicitRole).to.not.be.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectE).isExplicitOwner).to.be.ok
})
})
@@ -874,19 +904,20 @@ describe('Workspaces Roles/Seats GQL', () => {
)
})
- it('should retain viewer seat, same explicit access and get full implicit acccess', async () => {
+ it('should retain viewer seat, same explicit access and get full workspace visibility implicit acccess', async () => {
const { workspace, projects, checkProject, checkAllProjects } =
await getProjects({
user: workspaceGuestViewerUser
})
expect(workspace.seatType).to.eq(WorkspaceSeatType.Viewer)
- expect(projects.length).to.eq(4)
+ expect(projects.length).to.eq(5)
expect(checkAllProjects((p) => p.isReviewer)).to.be.ok
expect(checkProject(workspaceProjectA).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectB).isExplicitReviewer).to.be.ok
expect(checkProject(workspaceProjectC).hasExplicitRole).to.be.not.ok
expect(checkProject(workspaceProjectD).hasExplicitRole).to.be.not.ok
+ expect(checkProject(workspaceProjectE).isExplicitReviewer).to.be.ok
})
})
})
diff --git a/packages/server/modules/workspaces/tests/integration/sso.graph.spec.ts b/packages/server/modules/workspaces/tests/integration/sso.graph.spec.ts
index 79846e8f8..c7be7516f 100644
--- a/packages/server/modules/workspaces/tests/integration/sso.graph.spec.ts
+++ b/packages/server/modules/workspaces/tests/integration/sso.graph.spec.ts
@@ -1,3 +1,4 @@
+import { ProjectRecordVisibility } from '@/modules/core/helpers/types'
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
import {
assignToWorkspaces,
@@ -110,9 +111,9 @@ const { FF_WORKSPACES_SSO_ENABLED } = getFeatureFlags()
const testProject: BasicTestStream = {
id: '',
ownerId: '',
- isPublic: false,
name: 'Workspace Project',
- workspaceId: testWorkspaceWithSso.id
+ workspaceId: testWorkspaceWithSso.id,
+ visibility: ProjectRecordVisibility.Workspace
}
await createTestStream(testProject, workspaceAdmin)
diff --git a/packages/server/test/authHelper.ts b/packages/server/test/authHelper.ts
index e70209891..c4ae62e90 100644
--- a/packages/server/test/authHelper.ts
+++ b/packages/server/test/authHelper.ts
@@ -1,5 +1,6 @@
import { db } from '@/db/knex'
import { AllScopes, ServerRoles } from '@/modules/core/helpers/mainConstants'
+import { createRandomEmail } from '@/modules/core/helpers/testHelpers'
import { UserRecord } from '@/modules/core/helpers/types'
import { getServerInfoFactory } from '@/modules/core/repositories/server'
import {
@@ -36,7 +37,7 @@ import { createTestContext, testApolloServer } from '@/test/graphqlHelper'
import { faker } from '@faker-js/faker'
import { ServerScope, wait } from '@speckle/shared'
import cryptoRandomString from 'crypto-random-string'
-import { isArray, isNumber, kebabCase, omit, times } from 'lodash'
+import { isArray, isNumber, omit, times } from 'lodash'
const getServerInfo = getServerInfoFactory({ db })
const findEmail = findEmailFactory({ db })
@@ -120,7 +121,7 @@ export async function createTestUser(userObj?: Partial) {
}
if (!baseUser.email) {
- setVal('email', `${kebabCase(baseUser.name)}@example.org`)
+ setVal('email', createRandomEmail().toLowerCase())
}
const id = await createUser(omit(baseUser, ['id', 'allowPersonalEmail']), {
diff --git a/packages/server/test/graphql/generated/graphql.ts b/packages/server/test/graphql/generated/graphql.ts
index 96742d948..ffbbc689e 100644
--- a/packages/server/test/graphql/generated/graphql.ts
+++ b/packages/server/test/graphql/generated/graphql.ts
@@ -2071,7 +2071,7 @@ export type Project = {
versions: VersionCollection;
/** Return metadata about resources being requested in the viewer */
viewerResources: Array;
- visibility: SimpleProjectVisibility;
+ visibility: ProjectVisibility;
webhooks: WebhookCollection;
workspace?: Maybe;
workspaceId?: Maybe;
@@ -2692,9 +2692,14 @@ export const ProjectVersionsUpdatedMessageType = {
export type ProjectVersionsUpdatedMessageType = typeof ProjectVersionsUpdatedMessageType[keyof typeof ProjectVersionsUpdatedMessageType];
export const ProjectVisibility = {
+ /** Only accessible to explicit collaborators */
Private: 'PRIVATE',
+ /** Accessible to everyone (even non-logged in users) */
Public: 'PUBLIC',
- Unlisted: 'UNLISTED'
+ /** Legacy - same as public */
+ Unlisted: 'UNLISTED',
+ /** Accessible to everyone in the project's workspace */
+ Workspace: 'WORKSPACE'
} as const;
export type ProjectVisibility = typeof ProjectVisibility[keyof typeof ProjectVisibility];
@@ -3244,13 +3249,6 @@ export type SetPrimaryUserEmailInput = {
id: Scalars['ID']['input'];
};
-/** Visibility without the "discoverable" option */
-export const SimpleProjectVisibility = {
- Private: 'PRIVATE',
- Unlisted: 'UNLISTED'
-} as const;
-
-export type SimpleProjectVisibility = typeof SimpleProjectVisibility[keyof typeof SimpleProjectVisibility];
export type SmartTextEditorValue = {
__typename?: 'SmartTextEditorValue';
/** File attachments, if any */
@@ -3327,6 +3325,7 @@ export type Stream = {
/**
* Whether the stream (if public) can be found on public stream exploration pages
* and searches
+ * @deprecated Discoverability as a feature has been removed.
*/
isDiscoverable: Scalars['Boolean']['output'];
/** Whether the stream can be viewed by non-contributors */
@@ -5466,7 +5465,7 @@ export type UpdateWorkspaceProjectRoleMutationVariables = Exact<{
}>;
-export type UpdateWorkspaceProjectRoleMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', projects: { __typename?: 'WorkspaceProjectMutations', updateRole: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string } } } };
+export type UpdateWorkspaceProjectRoleMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', projects: { __typename?: 'WorkspaceProjectMutations', updateRole: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string } } } };
export type UpdateWorkspaceSeatTypeMutationVariables = Exact<{
input: WorkspaceUpdateSeatTypeInput;
@@ -5854,7 +5853,7 @@ export type EditProjectCommentMutationVariables = Exact<{
export type EditProjectCommentMutation = { __typename?: 'Mutation', commentMutations: { __typename?: 'CommentMutations', edit: { __typename?: 'Comment', id: string, rawText?: string | null, authorId: string, text?: { __typename?: 'SmartTextEditorValue', doc?: Record | null } | null } } };
-export type BasicProjectFieldsFragment = { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string };
+export type BasicProjectFieldsFragment = { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string };
export type AdminProjectListQueryVariables = Exact<{
query?: InputMaybe;
@@ -5865,7 +5864,7 @@ export type AdminProjectListQueryVariables = Exact<{
}>;
-export type AdminProjectListQuery = { __typename?: 'Query', admin: { __typename?: 'AdminQueries', projectList: { __typename?: 'ProjectCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string }> } } };
+export type AdminProjectListQuery = { __typename?: 'Query', admin: { __typename?: 'AdminQueries', projectList: { __typename?: 'ProjectCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string }> } } };
export type GetProjectObjectQueryVariables = Exact<{
projectId: Scalars['String']['input'];
@@ -5880,14 +5879,14 @@ export type GetProjectQueryVariables = Exact<{
}>;
-export type GetProjectQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, workspaceId?: string | null, role?: string | null, description?: string | null, visibility: SimpleProjectVisibility, allowPublicComments: boolean, createdAt: string, updatedAt: string } };
+export type GetProjectQuery = { __typename?: 'Query', project: { __typename?: 'Project', id: string, name: string, workspaceId?: string | null, role?: string | null, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, createdAt: string, updatedAt: string } };
export type CreateProjectMutationVariables = Exact<{
input: ProjectCreateInput;
}>;
-export type CreateProjectMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', create: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string } } };
+export type CreateProjectMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', create: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string } } };
export type BatchDeleteProjectsMutationVariables = Exact<{
ids: Array | Scalars['String']['input'];
@@ -5901,7 +5900,7 @@ export type UpdateProjectRoleMutationVariables = Exact<{
}>;
-export type UpdateProjectRoleMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', updateRole: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: SimpleProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string } } };
+export type UpdateProjectRoleMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', updateRole: { __typename?: 'Project', id: string, name: string, description?: string | null, visibility: ProjectVisibility, allowPublicComments: boolean, role?: string | null, createdAt: string, updatedAt: string } } };
export type GetProjectCollaboratorsQueryVariables = Exact<{
projectId: Scalars['String']['input'];
@@ -6167,7 +6166,7 @@ export type TestWorkspaceFragment = { __typename?: 'Workspace', id: string, name
export type TestWorkspaceCollaboratorFragment = { __typename?: 'WorkspaceCollaborator', id: string, role: string, user: { __typename?: 'LimitedUser', name: string }, projectRoles: Array<{ __typename?: 'ProjectRole', role: string, project: { __typename?: 'Project', id: string, name: string } }> };
-export type TestWorkspaceProjectFragment = { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string }> };
+export type TestWorkspaceProjectFragment = { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, visibility: ProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string }> };
export type CreateWorkspaceMutationVariables = Exact<{
input: WorkspaceCreateInput;
@@ -6226,7 +6225,7 @@ export type CreateWorkspaceProjectMutationVariables = Exact<{
}>;
-export type CreateWorkspaceProjectMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', projects: { __typename?: 'WorkspaceProjectMutations', create: { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string }> } } } };
+export type CreateWorkspaceProjectMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', projects: { __typename?: 'WorkspaceProjectMutations', create: { __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, visibility: ProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string }> } } } };
export type GetWorkspaceProjectsQueryVariables = Exact<{
id: Scalars['String']['input'];
@@ -6236,7 +6235,7 @@ export type GetWorkspaceProjectsQueryVariables = Exact<{
}>;
-export type GetWorkspaceProjectsQuery = { __typename?: 'Query', workspace: { __typename?: 'Workspace', projects: { __typename?: 'ProjectCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string }> }> } } };
+export type GetWorkspaceProjectsQuery = { __typename?: 'Query', workspace: { __typename?: 'Workspace', projects: { __typename?: 'ProjectCollection', cursor?: string | null, totalCount: number, items: Array<{ __typename?: 'Project', id: string, name: string, createdAt: string, updatedAt: string, visibility: ProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string }> }> } } };
export type GetWorkspaceSsoQueryVariables = Exact<{
id: Scalars['String']['input'];
@@ -6282,7 +6281,7 @@ export type MoveProjectToWorkspaceMutationVariables = Exact<{
}>;
-export type MoveProjectToWorkspaceMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', projects: { __typename?: 'WorkspaceProjectMutations', moveToWorkspace: { __typename?: 'Project', id: string, workspaceId?: string | null, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string }> } } } };
+export type MoveProjectToWorkspaceMutation = { __typename?: 'Mutation', workspaceMutations: { __typename?: 'WorkspaceMutations', projects: { __typename?: 'WorkspaceProjectMutations', moveToWorkspace: { __typename?: 'Project', id: string, workspaceId?: string | null, visibility: ProjectVisibility, team: Array<{ __typename?: 'ProjectCollaborator', id: string, role: string }> } } } };
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"}},{"kind":"Field","name":{"kind":"Name","value":"readOnly"}}]}}]} as unknown as DocumentNode;
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;
@@ -6305,7 +6304,7 @@ export const BaseUserFieldsFragmentDoc = {"kind":"Document","definitions":[{"kin
export const BaseLimitedUserFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"BaseLimitedUserFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LimitedUser"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}},{"kind":"Field","name":{"kind":"Name","value":"company"}},{"kind":"Field","name":{"kind":"Name","value":"avatar"}},{"kind":"Field","name":{"kind":"Name","value":"verified"}}]}}]} as unknown as DocumentNode;
export const TestWorkspaceFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspace"},"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":"description"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"readOnly"}},{"kind":"Field","name":{"kind":"Name","value":"discoverabilityEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]} as unknown as DocumentNode;
export const TestWorkspaceCollaboratorFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"projectRoles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"project"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode;
-export const TestWorkspaceProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspaceProject"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]} as unknown as DocumentNode;
+export const TestWorkspaceProjectFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspaceProject"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]} as unknown as DocumentNode;
export const CreateObjectDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateObject"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ObjectCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"objectCreate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"objectInput"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode;
export const PingPongDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"PingPong"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"ping"}}]}}]} as unknown as DocumentNode;
export const OnUserProjectsUpdatedDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"subscription","name":{"kind":"Name","value":"OnUserProjectsUpdated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userProjectsUpdated"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"project"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode;
@@ -6454,11 +6453,11 @@ export const GetActiveUserDiscoverableWorkspacesDocument = {"kind":"Document","d
export const UpdateWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceUpdateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"update"},"arguments":[{"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":"TestWorkspace"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspace"},"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":"description"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"readOnly"}},{"kind":"Field","name":{"kind":"Name","value":"discoverabilityEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]} as unknown as DocumentNode;
export const GetActiveUserWorkspacesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetActiveUserWorkspaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaces"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"TestWorkspace"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspace"},"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":"description"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"readOnly"}},{"kind":"Field","name":{"kind":"Name","value":"discoverabilityEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]} as unknown as DocumentNode;
export const UpdateWorkspaceRoleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateWorkspaceRole"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceRoleUpdateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateRole"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"TestWorkspaceCollaborator"}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"projectRoles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"project"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode;
-export const CreateWorkspaceProjectDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateWorkspaceProject"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceProjectCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"create"},"arguments":[{"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":"TestWorkspaceProject"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspaceProject"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]} as unknown as DocumentNode;
-export const GetWorkspaceProjectsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceProjects"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceProjectsFilter"}}}],"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":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"TestWorkspaceProject"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspaceProject"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]} as unknown as DocumentNode;
+export const CreateWorkspaceProjectDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateWorkspaceProject"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceProjectCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"create"},"arguments":[{"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":"TestWorkspaceProject"}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspaceProject"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]} as unknown as DocumentNode;
+export const GetWorkspaceProjectsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceProjects"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceProjectsFilter"}}}],"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":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"TestWorkspaceProject"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspaceProject"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Project"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]} as unknown as DocumentNode;
export const GetWorkspaceSsoDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceSso"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"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":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sso"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"provider"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"session"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"validUntil"}}]}}]}}]}}]}}]} as unknown as DocumentNode;
export const GetWorkspaceTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceTeam"},"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":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceTeamFilter"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"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":"Field","name":{"kind":"Name","value":"team"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"TestWorkspaceCollaborator"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"TestWorkspaceCollaborator"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkspaceCollaborator"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"projectRoles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"project"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode;
export const ActiveUserLeaveWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ActiveUserLeaveWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"leave"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}]}}]}}]} as unknown as DocumentNode;
export const ActiveUserProjectsWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ActiveUserProjectsWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UserProjectsFilter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"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":"workspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode;
export const ActiveUserExpiredSsoSessionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ActiveUserExpiredSsoSessions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expiredSsoSessions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]}}]} as unknown as DocumentNode;
-export const MoveProjectToWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"MoveProjectToWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"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":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"moveToWorkspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"projectId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}},{"kind":"Argument","name":{"kind":"Name","value":"workspaceId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode;
\ No newline at end of file
+export const MoveProjectToWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"MoveProjectToWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"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":"workspaceMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projects"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"moveToWorkspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"projectId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}},{"kind":"Argument","name":{"kind":"Name","value":"workspaceId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workspaceId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"workspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"team"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode;
\ No newline at end of file
diff --git a/packages/server/test/graphql/workspaces.ts b/packages/server/test/graphql/workspaces.ts
index 7fdd080dd..26105796c 100644
--- a/packages/server/test/graphql/workspaces.ts
+++ b/packages/server/test/graphql/workspaces.ts
@@ -38,6 +38,7 @@ export const workspaceProjectFragment = gql`
name
createdAt
updatedAt
+ visibility
team {
id
role
@@ -271,6 +272,7 @@ export const moveProjectToWorkspaceMutation = gql`
moveToWorkspace(projectId: $projectId, workspaceId: $workspaceId) {
id
workspaceId
+ visibility
team {
id
role
diff --git a/packages/server/test/speckle-helpers/streamHelper.ts b/packages/server/test/speckle-helpers/streamHelper.ts
index 2af82afe4..3891570ed 100644
--- a/packages/server/test/speckle-helpers/streamHelper.ts
+++ b/packages/server/test/speckle-helpers/streamHelper.ts
@@ -1,5 +1,6 @@
import { db } from '@/db/knex'
import { StreamAcl } from '@/modules/core/dbSchema'
+import { mapDbToGqlProjectVisibility } from '@/modules/core/helpers/project'
import { StreamAclRecord, StreamRecord } from '@/modules/core/helpers/types'
import { createBranchFactory } from '@/modules/core/repositories/branches'
import { getServerInfoFactory } from '@/modules/core/repositories/server'
@@ -161,7 +162,10 @@ const addOrUpdateStreamCollaborator = addOrUpdateStreamCollaboratorFactory({
export type BasicTestStream = {
name: string
- isPublic: boolean
+ /**
+ * @deprecated Use visibility instead
+ */
+ isPublic?: boolean
/**
* The ID of the owner user. Will be filled in by createTestStream().
*/
@@ -189,6 +193,13 @@ export async function createTestStream(
owner: BasicTestUser
) {
let id: string
+
+ const visibility = streamObj.isPublic
+ ? ProjectVisibility.Public
+ : (streamObj.visibility
+ ? mapDbToGqlProjectVisibility(streamObj.visibility)
+ : undefined) || ProjectVisibility.Private
+
if (streamObj.workspaceId) {
const createWorkspaceProject = createWorkspaceProjectFactory({
getDefaultRegion: getDefaultRegionFactory({ db })
@@ -197,9 +208,7 @@ export async function createTestStream(
input: {
name: streamObj.name || faker.commerce.productName(),
description: streamObj.description,
- visibility: streamObj.isPublic
- ? ProjectVisibility.Public
- : ProjectVisibility.Private,
+ visibility,
workspaceId: streamObj.workspaceId
},
ownerId: owner.id
@@ -207,7 +216,8 @@ export async function createTestStream(
id = newProject.id
} else {
id = await createStream({
- ...omit(streamObj, ['id', 'ownerId']),
+ ...omit(streamObj, ['id', 'ownerId', 'visibility']),
+ isPublic: visibility === ProjectVisibility.Public,
ownerId: owner.id
})
}
diff --git a/packages/shared/src/authz/checks/projects.spec.ts b/packages/shared/src/authz/checks/projects.spec.ts
index 4e4e56dab..87e99b58f 100644
--- a/packages/shared/src/authz/checks/projects.spec.ts
+++ b/packages/shared/src/authz/checks/projects.spec.ts
@@ -3,6 +3,7 @@ import { isPubliclyReadableProject, hasMinimumProjectRole } from './projects.js'
import cryptoRandomString from 'crypto-random-string'
import { Roles } from '../../core/index.js'
import { getProjectFake } from '../../tests/fakes.js'
+import { ProjectVisibility } from '../domain/projects/types.js'
describe('project checks', () => {
describe('isPubliclyReadableProject returns a function, that', () => {
@@ -14,13 +15,7 @@ describe('project checks', () => {
})
it('returns true for public projects', async () => {
const result = await isPubliclyReadableProject({
- getProject: getProjectFake({ isPublic: true })
- })({ projectId: cryptoRandomString({ length: 10 }) })
- expect(result).toEqual(true)
- })
- it('returns true for discoverable projects', async () => {
- const result = await isPubliclyReadableProject({
- getProject: getProjectFake({ isDiscoverable: true })
+ getProject: getProjectFake({ visibility: ProjectVisibility.Public })
})({ projectId: cryptoRandomString({ length: 10 }) })
expect(result).toEqual(true)
})
diff --git a/packages/shared/src/authz/checks/projects.ts b/packages/shared/src/authz/checks/projects.ts
index 4708fc97f..9c9fd73b2 100644
--- a/packages/shared/src/authz/checks/projects.ts
+++ b/packages/shared/src/authz/checks/projects.ts
@@ -2,6 +2,7 @@ import { StreamRoles } from '../../core/index.js'
import { AuthPolicyCheck } from '../domain/policies.js'
import { isMinimumProjectRole } from '../domain/logic/roles.js'
import { ProjectContext, UserContext } from '../domain/context.js'
+import { ProjectVisibility } from '../domain/projects/types.js'
export const hasMinimumProjectRole: AuthPolicyCheck<
'getProjectRole',
@@ -19,5 +20,5 @@ export const isPubliclyReadableProject: AuthPolicyCheck<'getProject', ProjectCon
async ({ projectId }) => {
const project = await loaders.getProject({ projectId })
if (!project) return false
- return project.isPublic || project.isDiscoverable
+ return project.visibility === ProjectVisibility.Public
}
diff --git a/packages/shared/src/authz/domain/projects/types.ts b/packages/shared/src/authz/domain/projects/types.ts
index 9e0be219d..6a464ce7c 100644
--- a/packages/shared/src/authz/domain/projects/types.ts
+++ b/packages/shared/src/authz/domain/projects/types.ts
@@ -1,12 +1,15 @@
+export const ProjectVisibility = {
+ Public: 'public',
+ Private: 'private',
+ Workspace: 'workspace'
+}
+
+export type ProjectVisibility =
+ (typeof ProjectVisibility)[keyof typeof ProjectVisibility]
+
export type Project = {
id: string
- /**
- * @deprecated
- */
- isDiscoverable: boolean
- isPublic: boolean
+ visibility: ProjectVisibility
workspaceId: string | null
allowPublicComments: boolean
}
-
-export type ProjectVisibility = 'public' | 'linkShareable' | 'private'
diff --git a/packages/shared/src/authz/fragments/projects.spec.ts b/packages/shared/src/authz/fragments/projects.spec.ts
index bab3503f2..1928637e7 100644
--- a/packages/shared/src/authz/fragments/projects.spec.ts
+++ b/packages/shared/src/authz/fragments/projects.spec.ts
@@ -21,15 +21,14 @@ import {
import { OverridesOf } from '../../tests/helpers/types.js'
import { getProjectFake } from '../../tests/fakes.js'
import { TIME_MS } from '../../core/index.js'
+import { ProjectVisibility } from '../domain/projects/types.js'
describe('ensureMinimumProjectRoleFragment', () => {
const buildSUT = (overrides?: OverridesOf) =>
ensureMinimumProjectRoleFragment({
getProject: getProjectFake({
id: 'projectId',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getWorkspace: async () => null,
getWorkspaceSsoProvider: async () => null,
@@ -48,8 +47,7 @@ describe('ensureMinimumProjectRoleFragment', () => {
getProject: getProjectFake({
id: 'projectId',
workspaceId: 'workspaceId',
- isDiscoverable: false,
- isPublic: false
+ visibility: ProjectVisibility.Workspace
}),
getWorkspace: async () => ({
id: 'workspaceId',
@@ -143,6 +141,44 @@ describe('ensureMinimumProjectRoleFragment', () => {
expect(result).toBeAuthOKResult()
})
+ it('succeeds if user has implicit owner role even in private project', async () => {
+ const result = await buildWorkspaceSUT({
+ getWorkspaceRole: async () => Roles.Workspace.Admin,
+ getProjectRole: async () => null,
+ getProject: getProjectFake({
+ id: 'projectId',
+ workspaceId: 'workspaceId',
+ visibility: ProjectVisibility.Private
+ })
+ })({
+ userId: 'userId',
+ projectId: 'projectId',
+ role: Roles.Stream.Reviewer
+ })
+
+ expect(result).toBeAuthOKResult()
+ })
+
+ it('fails if user doesnt have explicit project role and project is private', async () => {
+ const result = await buildWorkspaceSUT({
+ getWorkspaceRole: async () => Roles.Workspace.Member,
+ getProjectRole: async () => null,
+ getProject: getProjectFake({
+ id: 'projectId',
+ workspaceId: 'workspaceId',
+ visibility: ProjectVisibility.Private
+ })
+ })({
+ userId: 'userId',
+ projectId: 'projectId',
+ role: Roles.Stream.Reviewer
+ })
+
+ expect(result).toBeAuthErrorResult({
+ code: ProjectNoAccessError.code
+ })
+ })
+
it('fails if implicit role is not enough', async () => {
const result = await buildWorkspaceSUT({
getWorkspaceRole: async () => Roles.Workspace.Member,
@@ -167,9 +203,7 @@ describe('checkIfPubliclyReadableProjectFragment', () => {
checkIfPubliclyReadableProjectFragment({
getProject: getProjectFake({
id: 'projectId',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getEnv: async () => parseFeatureFlags({}),
...overrides
@@ -200,8 +234,7 @@ describe('checkIfPubliclyReadableProjectFragment', () => {
getProject: getProjectFake({
id: 'projectId',
workspaceId: null,
- isDiscoverable: false,
- isPublic: true
+ visibility: ProjectVisibility.Public
})
})
@@ -216,9 +249,7 @@ describe('checkIfPubliclyReadableProjectFragment', () => {
const sut = buildSUT({
getProject: getProjectFake({
id: 'projectId',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
})
})
const result = await sut({
@@ -235,9 +266,7 @@ describe('ensureProjectWorkspaceAccessFragment', () => {
ensureProjectWorkspaceAccessFragment({
getProject: getProjectFake({
id: 'projectId',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getEnv: async () => parseFeatureFlags({}),
getWorkspace: async () => null,
@@ -253,9 +282,7 @@ describe('ensureProjectWorkspaceAccessFragment', () => {
buildSUT({
getProject: getProjectFake({
id: 'projectId',
- workspaceId: 'workspaceId',
- isDiscoverable: false,
- isPublic: false
+ workspaceId: 'workspaceId'
}),
getWorkspace: async () => ({
id: 'workspaceId',
@@ -391,9 +418,7 @@ describe('ensureImplicitProjectMemberWithReadAccessFragment', async () => {
ensureImplicitProjectMemberWithReadAccessFragment({
getProject: getProjectFake({
id: 'projectId',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getAdminOverrideEnabled: async () => false,
getServerRole: async () => Roles.Server.User,
@@ -413,8 +438,7 @@ describe('ensureImplicitProjectMemberWithReadAccessFragment', async () => {
getProject: getProjectFake({
id: 'projectId',
workspaceId: 'workspaceId',
- isDiscoverable: false,
- isPublic: false
+ visibility: ProjectVisibility.Workspace
}),
getProjectRole: async () => null,
getWorkspace: async () => ({
@@ -537,6 +561,27 @@ describe('ensureImplicitProjectMemberWithReadAccessFragment', async () => {
expect(result).toBeAuthOKResult()
})
+ it('fails w/o explicit project role if private project', async () => {
+ const sut = buildWorkspaceSUT({
+ getProjectRole: async () => null,
+ getProject: getProjectFake({
+ id: 'projectId',
+ workspaceId: 'workspaceId',
+ visibility: ProjectVisibility.Private
+ })
+ })
+
+ const result = await sut({
+ userId: 'userId',
+ projectId: 'projectId',
+ role: Roles.Stream.Reviewer
+ })
+
+ expect(result).toBeAuthErrorResult({
+ code: ProjectNoAccessError.code
+ })
+ })
+
it('succeeds w/o sso session, if workspace guest w/ explicit project role', async () => {
const sut = buildWorkspaceSUT({
getWorkspaceRole: async () => Roles.Workspace.Guest,
@@ -612,9 +657,7 @@ describe('ensureImplicitProjectMemberWithWriteAccessFragment', () => {
ensureImplicitProjectMemberWithWriteAccessFragment({
getProject: getProjectFake({
id: 'projectId',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getServerRole: async () => Roles.Server.User,
getProjectRole: async () => Roles.Stream.Contributor,
@@ -633,8 +676,7 @@ describe('ensureImplicitProjectMemberWithWriteAccessFragment', () => {
getProject: getProjectFake({
id: 'projectId',
workspaceId: 'workspaceId',
- isDiscoverable: false,
- isPublic: false
+ visibility: ProjectVisibility.Workspace
}),
getProjectRole: async () => null,
getWorkspace: async () => ({
diff --git a/packages/shared/src/authz/fragments/projects.ts b/packages/shared/src/authz/fragments/projects.ts
index c2c8bb7d2..d35b166d1 100644
--- a/packages/shared/src/authz/fragments/projects.ts
+++ b/packages/shared/src/authz/fragments/projects.ts
@@ -24,11 +24,16 @@ import {
checkIfAdminOverrideEnabledFragment,
ensureMinimumServerRoleFragment
} from './server.js'
+import { ProjectVisibility } from '../domain/projects/types.js'
-const workspaceRoleImplicitProjectRoleMap = {
- [Roles.Workspace.Admin]: Roles.Stream.Owner,
- [Roles.Workspace.Member]: Roles.Stream.Reviewer,
- [Roles.Workspace.Guest]: null
+const workspaceRoleImplicitProjectRoleMap = (projectVisibility: ProjectVisibility) => {
+ const isFullyPrivate = projectVisibility === ProjectVisibility.Private
+
+ return {
+ [Roles.Workspace.Admin]: Roles.Stream.Owner,
+ [Roles.Workspace.Member]: isFullyPrivate ? null : Roles.Stream.Reviewer,
+ [Roles.Workspace.Guest]: null
+ }
}
/**
@@ -79,13 +84,14 @@ export const ensureMinimumProjectRoleFragment: AuthPolicyEnsureFragment<
// Now check if there's an implicit one
const { workspaceId } = project
+
if (env.FF_WORKSPACES_MODULE_ENABLED && !!workspaceId) {
// Check for implicit workspace project role
const userWorkspaceRole = await loaders.getWorkspaceRole({ userId, workspaceId })
if (userWorkspaceRole) {
const implicitProjectRole = explicit
? null
- : workspaceRoleImplicitProjectRoleMap[userWorkspaceRole]
+ : workspaceRoleImplicitProjectRoleMap(project.visibility)[userWorkspaceRole]
if (implicitProjectRole) {
// Does it fit minimum?
if (isMinimumProjectRole(implicitProjectRole, requiredProjectRole)) {
diff --git a/packages/shared/src/authz/policies/project/automation/canCreate.spec.ts b/packages/shared/src/authz/policies/project/automation/canCreate.spec.ts
index f56654991..e77c3a2cc 100644
--- a/packages/shared/src/authz/policies/project/automation/canCreate.spec.ts
+++ b/packages/shared/src/authz/policies/project/automation/canCreate.spec.ts
@@ -13,6 +13,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../../domain/authErrors.js'
import { TIME_MS } from '../../../../core/index.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
const buildCanCreatePolicy = (
overrides?: Partial[0]>
@@ -22,8 +23,7 @@ const buildCanCreatePolicy = (
getProject: async () => ({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: false,
+ visibility: ProjectVisibility.Private,
allowPublicComments: false
}),
getProjectRole: async () => Roles.Stream.Owner,
@@ -131,8 +131,7 @@ describe('canCreateAutomation', () => {
getProject: async () => ({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false,
+ visibility: ProjectVisibility.Private,
allowPublicComments: false
}),
getWorkspace: async () => ({
@@ -176,6 +175,21 @@ describe('canCreateAutomation', () => {
expect(result).toBeAuthOKResult()
})
+ it('returns error with implicit member role', async () => {
+ const canCreateAutomation = buildCanCreatePolicy({
+ ...overrides,
+ getWorkspaceRole: async () => Roles.Workspace.Member,
+ getProjectRole: async () => null
+ })
+ const result = await canCreateAutomation({
+ userId: 'user-id',
+ projectId: 'project-id'
+ })
+ expect(result).toBeAuthErrorResult({
+ code: ProjectNoAccessError.code
+ })
+ })
+
it('returns error if no workspace role, even w/ valid project role', async () => {
const canCreateAutomation = buildCanCreatePolicy({
...overrides,
diff --git a/packages/shared/src/authz/policies/project/automation/canDelete.spec.ts b/packages/shared/src/authz/policies/project/automation/canDelete.spec.ts
index 26809e00e..887c254b9 100644
--- a/packages/shared/src/authz/policies/project/automation/canDelete.spec.ts
+++ b/packages/shared/src/authz/policies/project/automation/canDelete.spec.ts
@@ -13,6 +13,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../../domain/authErrors.js'
import { TIME_MS } from '../../../../core/index.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
const buildCanDeletePolicy = (
overrides?: Partial[0]>
@@ -22,9 +23,8 @@ const buildCanDeletePolicy = (
getProject: async () => ({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: false,
- allowPublicComments: false
+ allowPublicComments: false,
+ visibility: ProjectVisibility.Private
}),
getProjectRole: async () => Roles.Stream.Owner,
getServerRole: async () => Roles.Server.User,
@@ -131,8 +131,7 @@ describe('canDeleteAutomation', () => {
getProject: async () => ({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false,
+ visibility: ProjectVisibility.Private,
allowPublicComments: false
}),
getWorkspace: async () => ({
diff --git a/packages/shared/src/authz/policies/project/automation/canRead.spec.ts b/packages/shared/src/authz/policies/project/automation/canRead.spec.ts
index a9bf88283..a3fa55eae 100644
--- a/packages/shared/src/authz/policies/project/automation/canRead.spec.ts
+++ b/packages/shared/src/authz/policies/project/automation/canRead.spec.ts
@@ -13,6 +13,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../../domain/authErrors.js'
import { TIME_MS } from '../../../../core/index.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
const buildCanReadAutomationPolicy = (
overrides?: OverridesOf
@@ -20,9 +21,7 @@ const buildCanReadAutomationPolicy = (
canReadAutomationPolicy({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isPublic: false,
- isDiscoverable: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Reviewer,
getAdminOverrideEnabled: async () => false,
@@ -125,8 +124,7 @@ describe('canReadAutomationPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isPublic: false,
- isDiscoverable: false
+ visibility: ProjectVisibility.Workspace
}),
getWorkspace: getWorkspaceFake({
id: 'workspace-id'
diff --git a/packages/shared/src/authz/policies/project/automation/canUpdate.spec.ts b/packages/shared/src/authz/policies/project/automation/canUpdate.spec.ts
index 1e29ed311..1441fd981 100644
--- a/packages/shared/src/authz/policies/project/automation/canUpdate.spec.ts
+++ b/packages/shared/src/authz/policies/project/automation/canUpdate.spec.ts
@@ -13,6 +13,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../../domain/authErrors.js'
import { TIME_MS } from '../../../../core/index.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
const buildCanUpdatePolicy = (
overrides?: Partial[0]>
@@ -22,8 +23,7 @@ const buildCanUpdatePolicy = (
getProject: async () => ({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: false,
+ visibility: ProjectVisibility.Private,
allowPublicComments: false
}),
getProjectRole: async () => Roles.Stream.Owner,
@@ -131,8 +131,7 @@ describe('canUpdateAutomation', () => {
getProject: async () => ({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false,
+ visibility: ProjectVisibility.Private,
allowPublicComments: false
}),
getWorkspace: async () => ({
diff --git a/packages/shared/src/authz/policies/project/canBroadcastActivity.spec.ts b/packages/shared/src/authz/policies/project/canBroadcastActivity.spec.ts
index d2842b351..a633f8a04 100644
--- a/packages/shared/src/authz/policies/project/canBroadcastActivity.spec.ts
+++ b/packages/shared/src/authz/policies/project/canBroadcastActivity.spec.ts
@@ -13,6 +13,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../domain/authErrors.js'
import { TIME_MS } from '../../../core/helpers/timeConstants.js'
+import { ProjectVisibility } from '../../domain/projects/types.js'
describe('canBroadcastProjectActivityPolicy', () => {
const buildSUT = (
@@ -22,9 +23,7 @@ describe('canBroadcastProjectActivityPolicy', () => {
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getAdminOverrideEnabled: async () => false,
getProjectRole: async () => Roles.Stream.Reviewer,
@@ -43,8 +42,7 @@ describe('canBroadcastProjectActivityPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false
+ visibility: ProjectVisibility.Workspace
}),
getProjectRole: async () => null,
getWorkspace: async () => ({
@@ -79,8 +77,7 @@ describe('canBroadcastProjectActivityPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: true
+ visibility: ProjectVisibility.Public
}),
getProjectRole: async () => null
})
@@ -187,8 +184,7 @@ describe('canBroadcastProjectActivityPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: true
+ visibility: ProjectVisibility.Public
})
})
diff --git a/packages/shared/src/authz/policies/project/canDelete.spec.ts b/packages/shared/src/authz/policies/project/canDelete.spec.ts
index 12fc2198a..4a49af9e7 100644
--- a/packages/shared/src/authz/policies/project/canDelete.spec.ts
+++ b/packages/shared/src/authz/policies/project/canDelete.spec.ts
@@ -13,9 +13,7 @@ describe('canDeleteProjectPolicy', () => {
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Owner,
getServerRole: async () => Roles.Server.User,
@@ -32,9 +30,7 @@ describe('canDeleteProjectPolicy', () => {
buildSUT({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false
+ workspaceId: 'workspace-id'
}),
getWorkspace: async () => ({
id: 'workspace-id',
diff --git a/packages/shared/src/authz/policies/project/canLeave.spec.ts b/packages/shared/src/authz/policies/project/canLeave.spec.ts
index ff46b135e..f0b35bc4f 100644
--- a/packages/shared/src/authz/policies/project/canLeave.spec.ts
+++ b/packages/shared/src/authz/policies/project/canLeave.spec.ts
@@ -20,9 +20,7 @@ describe('canLeaveProjectPolicy', () => {
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Reviewer,
getServerRole: async () => Roles.Server.Guest,
@@ -38,9 +36,7 @@ describe('canLeaveProjectPolicy', () => {
buildSUT({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false
+ workspaceId: 'workspace-id'
}),
getProjectRole: async () => Roles.Stream.Reviewer,
getWorkspace: async () => ({
diff --git a/packages/shared/src/authz/policies/project/canLoad.spec.ts b/packages/shared/src/authz/policies/project/canLoad.spec.ts
index 250ab7b00..930a32d0a 100644
--- a/packages/shared/src/authz/policies/project/canLoad.spec.ts
+++ b/packages/shared/src/authz/policies/project/canLoad.spec.ts
@@ -12,6 +12,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../domain/authErrors.js'
import { TIME_MS } from '../../../core/index.js'
+import { ProjectVisibility } from '../../domain/projects/types.js'
const buildCanLoadPolicy = (overrides?: Partial[0]>) =>
canLoadPolicy({
@@ -19,8 +20,7 @@ const buildCanLoadPolicy = (overrides?: Partial
getProject: async () => ({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: false,
+ visibility: ProjectVisibility.Private,
allowPublicComments: false
}),
getProjectRole: async () => Roles.Stream.Owner,
@@ -114,8 +114,7 @@ describe('canLoad', () => {
getProject: async () => ({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false,
+ visibility: ProjectVisibility.Workspace,
allowPublicComments: false
}),
getWorkspace: async () => ({
diff --git a/packages/shared/src/authz/policies/project/canPublish.spec.ts b/packages/shared/src/authz/policies/project/canPublish.spec.ts
index cfd4c31fa..7b73aff80 100644
--- a/packages/shared/src/authz/policies/project/canPublish.spec.ts
+++ b/packages/shared/src/authz/policies/project/canPublish.spec.ts
@@ -12,6 +12,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../domain/authErrors.js'
import { TIME_MS } from '../../../core/index.js'
+import { ProjectVisibility } from '../../domain/projects/types.js'
const buildCanPublishPolicy = (
overrides?: Partial[0]>
@@ -21,8 +22,7 @@ const buildCanPublishPolicy = (
getProject: async () => ({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: false,
+ visibility: ProjectVisibility.Private,
allowPublicComments: false
}),
getProjectRole: async () => Roles.Stream.Owner,
@@ -116,8 +116,7 @@ describe('canPublish', () => {
getProject: async () => ({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false,
+ visibility: ProjectVisibility.Workspace,
allowPublicComments: false
}),
getWorkspace: async () => ({
diff --git a/packages/shared/src/authz/policies/project/canRead.spec.ts b/packages/shared/src/authz/policies/project/canRead.spec.ts
index 209c2f962..2060eef80 100644
--- a/packages/shared/src/authz/policies/project/canRead.spec.ts
+++ b/packages/shared/src/authz/policies/project/canRead.spec.ts
@@ -14,6 +14,7 @@ import {
import { getProjectFake } from '../../../tests/fakes.js'
import cryptoRandomString from 'crypto-random-string'
import { AuthCheckContextLoaders } from '../../domain/loaders.js'
+import { ProjectVisibility } from '../../domain/projects/types.js'
const canReadProjectArgs = () => {
const projectId = crs({ length: 10 })
@@ -61,7 +62,7 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
const canReadProject = canReadProjectPolicy({
getAdminOverrideEnabled: async () => false,
getEnv: async () => parseFeatureFlags({}),
- getProject: getProjectFake({ isPublic: true }),
+ getProject: getProjectFake({ visibility: ProjectVisibility.Public }),
getProjectRole: () => {
assert.fail()
},
@@ -83,31 +84,6 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
const canQuery = await canReadProject(canReadProjectArgs())
expect(canQuery).toBeAuthOKResult()
})
- it('allows anyone on a linkShareable project', async () => {
- const canReadProject = canReadProjectPolicy({
- getAdminOverrideEnabled: async () => false,
- getEnv: async () => parseFeatureFlags({}),
- getProject: getProjectFake({ isDiscoverable: true }),
- getProjectRole: () => {
- assert.fail()
- },
- getServerRole: () => {
- assert.fail()
- },
- getWorkspace,
- getWorkspaceRole: () => {
- assert.fail()
- },
- getWorkspaceSsoSession: () => {
- assert.fail()
- },
- getWorkspaceSsoProvider: () => {
- assert.fail()
- }
- })
- const canQuery = await canReadProject(canReadProjectArgs())
- expect(canQuery).toBeAuthOKResult()
- })
})
describe('server roles', () => {
@@ -116,7 +92,7 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
getAdminOverrideEnabled: async () => false,
getEnv: async () =>
parseFeatureFlags({ FF_WORKSPACES_MODULE_ENABLED: 'false' }),
- getProject: getProjectFake({ isDiscoverable: false, isPublic: true }),
+ getProject: getProjectFake({ visibility: ProjectVisibility.Public }),
getProjectRole: async () => Roles.Stream.Owner,
getServerRole: async () => Roles.Server.ArchivedUser,
getWorkspace,
@@ -138,7 +114,7 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
getAdminOverrideEnabled: async () => false,
getEnv: async () =>
parseFeatureFlags({ FF_WORKSPACES_MODULE_ENABLED: 'false' }),
- getProject: getProjectFake({ isDiscoverable: false, isPublic: false }),
+ getProject: getProjectFake({}),
getProjectRole: async () => Roles.Stream.Owner,
getServerRole: async () => Roles.Server.ArchivedUser,
getWorkspace,
@@ -162,7 +138,7 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
getAdminOverrideEnabled: async () => false,
getEnv: async () =>
parseFeatureFlags({ FF_WORKSPACES_MODULE_ENABLED: 'false' }),
- getProject: getProjectFake({ isDiscoverable: false, isPublic: false }),
+ getProject: getProjectFake({}),
getProjectRole: async () => Roles.Stream.Owner,
getServerRole: async () => null,
getWorkspace,
@@ -192,7 +168,7 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
getAdminOverrideEnabled: async () => false,
getEnv: async () =>
parseFeatureFlags({ FF_WORKSPACES_MODULE_ENABLED: 'false' }),
- getProject: getProjectFake({ isDiscoverable: false, isPublic: false }),
+ getProject: getProjectFake({}),
getProjectRole: async () => role,
getServerRole: async () => Roles.Server.User,
getWorkspace,
@@ -216,7 +192,7 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
getAdminOverrideEnabled: async () => false,
getEnv: async () =>
parseFeatureFlags({ FF_WORKSPACES_MODULE_ENABLED: 'false' }),
- getProject: getProjectFake({ isDiscoverable: false, isPublic: false }),
+ getProject: getProjectFake({}),
getProjectRole: async () => null,
getWorkspace,
getServerRole: async () => Roles.Server.Admin,
@@ -241,7 +217,7 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
const result = canReadProjectPolicy({
getAdminOverrideEnabled: async () => true,
getEnv: async () => parseFeatureFlags({}),
- getProject: getProjectFake({ isDiscoverable: false, isPublic: false }),
+ getProject: getProjectFake({}),
getServerRole: async () => Roles.Server.Admin,
getProjectRole: () => {
assert.fail()
@@ -268,7 +244,7 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
parseFeatureFlags({
FF_WORKSPACES_MODULE_ENABLED: 'false'
}),
- getProject: getProjectFake({ isDiscoverable: false, isPublic: false }),
+ getProject: getProjectFake({}),
getServerRole: async () => Roles.Server.Admin,
getProjectRole: async () => null,
getWorkspace,
@@ -296,8 +272,6 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
getEnv: async () =>
parseFeatureFlags({ FF_WORKSPACES_MODULE_ENABLED: 'false' }),
getProject: getProjectFake({
- isDiscoverable: false,
- isPublic: false,
workspaceId: crs({ length: 10 })
}),
getProjectRole: async () => Roles.Stream.Contributor,
@@ -325,8 +299,6 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
FF_WORKSPACES_MODULE_ENABLED: 'true'
}),
getProject: getProjectFake({
- isDiscoverable: false,
- isPublic: false,
workspaceId: crs({ length: 10 })
}),
getProjectRole: async () => Roles.Stream.Contributor,
@@ -347,7 +319,7 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
})
})
- it('allows project access via workspace role if user does not have project role', async () => {
+ it('allows project access via workspace admin role if user does not have project role, even if private project', async () => {
const result = canReadProjectPolicy({
getAdminOverrideEnabled: async () => false,
getEnv: async () =>
@@ -355,9 +327,8 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
FF_WORKSPACES_MODULE_ENABLED: 'true'
}),
getProject: getProjectFake({
- isDiscoverable: false,
- isPublic: false,
- workspaceId: crs({ length: 10 })
+ workspaceId: crs({ length: 10 }),
+ visibility: ProjectVisibility.Private
}),
getProjectRole: async () => null,
getServerRole: async () => Roles.Server.User,
@@ -371,6 +342,31 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
await expect(result).resolves.toBeAuthOKResult()
})
+
+ it('allows project access via workspace role if user does not have project role on workspace visibility', async () => {
+ const result = canReadProjectPolicy({
+ getAdminOverrideEnabled: async () => false,
+ getEnv: async () =>
+ parseFeatureFlags({
+ FF_WORKSPACES_MODULE_ENABLED: 'true'
+ }),
+ getProject: getProjectFake({
+ workspaceId: crs({ length: 10 }),
+ visibility: ProjectVisibility.Workspace
+ }),
+ getProjectRole: async () => null,
+ getServerRole: async () => Roles.Server.User,
+ getWorkspaceRole: async () => Roles.Workspace.Member,
+ getWorkspaceSsoSession: () => {
+ assert.fail()
+ },
+ getWorkspace,
+ getWorkspaceSsoProvider: async () => null
+ })(canReadProjectArgs())
+
+ await expect(result).resolves.toBeAuthOKResult()
+ })
+
it('does not check SSO sessions if user is workspace guest', async () => {
const result = canReadProjectPolicy({
getAdminOverrideEnabled: async () => false,
@@ -379,8 +375,6 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
FF_WORKSPACES_MODULE_ENABLED: 'true'
}),
getProject: getProjectFake({
- isDiscoverable: false,
- isPublic: false,
workspaceId: crs({ length: 10 })
}),
getProjectRole: async () => Roles.Stream.Contributor,
@@ -405,8 +399,6 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
FF_WORKSPACES_MODULE_ENABLED: 'true'
}),
getProject: getProjectFake({
- isDiscoverable: false,
- isPublic: false,
workspaceId: crs({ length: 10 })
}),
getProjectRole: async () => Roles.Stream.Contributor,
@@ -429,8 +421,6 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
FF_WORKSPACES_MODULE_ENABLED: 'true'
}),
getProject: getProjectFake({
- isDiscoverable: false,
- isPublic: false,
workspaceId: crs({ length: 10 })
}),
getProjectRole: async () => Roles.Stream.Contributor,
@@ -457,8 +447,6 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
FF_WORKSPACES_MODULE_ENABLED: 'true'
}),
getProject: getProjectFake({
- isDiscoverable: false,
- isPublic: false,
workspaceId: crs({ length: 10 })
}),
getProjectRole: async () => Roles.Stream.Contributor,
@@ -485,8 +473,6 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
FF_WORKSPACES_MODULE_ENABLED: 'true'
}),
getProject: getProjectFake({
- isDiscoverable: false,
- isPublic: false,
workspaceId: crs({ length: 10 })
}),
getProjectRole: async () => Roles.Stream.Contributor,
@@ -517,8 +503,6 @@ describe('canReadProjectPolicy creates a function, that handles ', () => {
FF_WORKSPACES_MODULE_ENABLED: 'true'
}),
getProject: getProjectFake({
- isDiscoverable: false,
- isPublic: false,
workspaceId: crs({ length: 10 })
}),
getProjectRole: async () => Roles.Stream.Contributor,
diff --git a/packages/shared/src/authz/policies/project/canReadSettings.spec.ts b/packages/shared/src/authz/policies/project/canReadSettings.spec.ts
index 48805184f..9775da2b9 100644
--- a/packages/shared/src/authz/policies/project/canReadSettings.spec.ts
+++ b/packages/shared/src/authz/policies/project/canReadSettings.spec.ts
@@ -12,6 +12,7 @@ import {
} from '../../domain/authErrors.js'
import { getProjectFake } from '../../../tests/fakes.js'
import { TIME_MS } from '../../../core/helpers/timeConstants.js'
+import { ProjectVisibility } from '../../domain/projects/types.js'
describe('canReadProjectSettingsPolicy', () => {
const buildSUT = (overrides?: OverridesOf) =>
@@ -19,9 +20,7 @@ describe('canReadProjectSettingsPolicy', () => {
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getAdminOverrideEnabled: async () => false,
getProjectRole: async () => Roles.Stream.Reviewer,
@@ -40,8 +39,7 @@ describe('canReadProjectSettingsPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false
+ visibility: ProjectVisibility.Workspace
}),
getProjectRole: async () => null,
getWorkspace: async () => ({
diff --git a/packages/shared/src/authz/policies/project/canReadWebhooks.spec.ts b/packages/shared/src/authz/policies/project/canReadWebhooks.spec.ts
index af70bdbd5..71d335e63 100644
--- a/packages/shared/src/authz/policies/project/canReadWebhooks.spec.ts
+++ b/packages/shared/src/authz/policies/project/canReadWebhooks.spec.ts
@@ -13,6 +13,7 @@ import {
import { canReadProjectWebhooksPolicy } from './canReadWebhooks.js'
import { getProjectFake } from '../../../tests/fakes.js'
import { TIME_MS } from '../../../core/helpers/timeConstants.js'
+import { ProjectVisibility } from '../../domain/projects/types.js'
describe('canReadProjectWebhooksPolicy', () => {
const buildSUT = (overrides?: OverridesOf) =>
@@ -20,9 +21,7 @@ describe('canReadProjectWebhooksPolicy', () => {
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getAdminOverrideEnabled: async () => false,
getProjectRole: async () => Roles.Stream.Owner,
@@ -41,8 +40,7 @@ describe('canReadProjectWebhooksPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false
+ visibility: ProjectVisibility.Workspace
}),
getProjectRole: async () => null,
getWorkspace: async () => ({
diff --git a/packages/shared/src/authz/policies/project/canUpdate.spec.ts b/packages/shared/src/authz/policies/project/canUpdate.spec.ts
index 5bcae5760..24bb96318 100644
--- a/packages/shared/src/authz/policies/project/canUpdate.spec.ts
+++ b/packages/shared/src/authz/policies/project/canUpdate.spec.ts
@@ -21,9 +21,7 @@ const buildSUT = (overrides?: Partial[
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Owner,
getServerRole: async () => Roles.Server.User,
@@ -40,9 +38,7 @@ const buildWorkspaceSUT = (
buildSUT({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false
+ workspaceId: 'workspace-id'
}),
getWorkspace: async () => ({
id: 'workspace-id',
diff --git a/packages/shared/src/authz/policies/project/canUpdateAllowPublicComments.spec.ts b/packages/shared/src/authz/policies/project/canUpdateAllowPublicComments.spec.ts
index 9d0b6d57b..eb4a465e0 100644
--- a/packages/shared/src/authz/policies/project/canUpdateAllowPublicComments.spec.ts
+++ b/packages/shared/src/authz/policies/project/canUpdateAllowPublicComments.spec.ts
@@ -5,6 +5,7 @@ import { parseFeatureFlags } from '../../../environment/index.js'
import { Roles } from '../../../core/constants.js'
import { ProjectNoAccessError } from '../../domain/authErrors.js'
import { getProjectFake } from '../../../tests/fakes.js'
+import { ProjectVisibility } from '../../domain/projects/types.js'
describe('canUpdateProjectAllowPublicCommentsPolicy', () => {
const buildSUT = (
@@ -15,8 +16,7 @@ describe('canUpdateProjectAllowPublicCommentsPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: true
+ visibility: ProjectVisibility.Public
}),
getProjectRole: async () => Roles.Stream.Owner,
getServerRole: async () => Roles.Server.User,
@@ -38,24 +38,6 @@ describe('canUpdateProjectAllowPublicCommentsPolicy', () => {
expect(result).toBeOKResult()
})
- it('succeeds if discoverable project', async () => {
- const sut = buildSUT({
- getProject: getProjectFake({
- id: 'project-id',
- workspaceId: null,
- isDiscoverable: true,
- isPublic: false
- })
- })
-
- const result = await sut({
- userId: 'user-id',
- projectId: 'project-id'
- })
-
- expect(result).toBeOKResult()
- })
-
it("fails if can't update at all", async () => {
const sut = buildSUT({
getProjectRole: async () => null
@@ -71,13 +53,12 @@ describe('canUpdateProjectAllowPublicCommentsPolicy', () => {
})
})
- it('fails if project is neither public nor discoverable', async () => {
+ it('fails if project is not public', async () => {
const sut = buildSUT({
getProject: getProjectFake({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ visibility: ProjectVisibility.Private
})
})
diff --git a/packages/shared/src/authz/policies/project/canUpdateAllowPublicComments.ts b/packages/shared/src/authz/policies/project/canUpdateAllowPublicComments.ts
index 74a94399a..d9ca32838 100644
--- a/packages/shared/src/authz/policies/project/canUpdateAllowPublicComments.ts
+++ b/packages/shared/src/authz/policies/project/canUpdateAllowPublicComments.ts
@@ -14,6 +14,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../domain/authErrors.js'
import { canUpdateProjectPolicy } from './canUpdate.js'
+import { ProjectVisibility } from '../../domain/projects/types.js'
export const canUpdateProjectAllowPublicCommentsPolicy: AuthPolicy<
| typeof Loaders.getProject
@@ -54,7 +55,7 @@ export const canUpdateProjectAllowPublicCommentsPolicy: AuthPolicy<
return err(new ProjectNotFoundError())
}
- const isPublic = project.isPublic || project.isDiscoverable
+ const isPublic = project.visibility === ProjectVisibility.Public
return isPublic
? ok()
: err(
diff --git a/packages/shared/src/authz/policies/project/comment/canArchive.spec.ts b/packages/shared/src/authz/policies/project/comment/canArchive.spec.ts
index df27e2f10..6a6fe00e1 100644
--- a/packages/shared/src/authz/policies/project/comment/canArchive.spec.ts
+++ b/packages/shared/src/authz/policies/project/comment/canArchive.spec.ts
@@ -13,6 +13,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../../domain/authErrors.js'
import { TIME_MS } from '../../../../core/helpers/timeConstants.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
describe('canArchiveProjectCommentPolicy', () => {
const buildSUT = (overrides?: OverridesOf) =>
@@ -20,9 +21,7 @@ describe('canArchiveProjectCommentPolicy', () => {
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Reviewer,
getServerRole: async () => Roles.Server.User,
@@ -45,9 +44,8 @@ describe('canArchiveProjectCommentPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false,
- allowPublicComments: false
+ allowPublicComments: false,
+ visibility: ProjectVisibility.Workspace
}),
getProjectRole: async () => null,
getWorkspace: async () => ({
diff --git a/packages/shared/src/authz/policies/project/comment/canCreate.spec.ts b/packages/shared/src/authz/policies/project/comment/canCreate.spec.ts
index 9c09bc4c9..4a72ae657 100644
--- a/packages/shared/src/authz/policies/project/comment/canCreate.spec.ts
+++ b/packages/shared/src/authz/policies/project/comment/canCreate.spec.ts
@@ -12,6 +12,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../../domain/authErrors.js'
import { TIME_MS } from '../../../../core/helpers/timeConstants.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
describe('canCreateProjectCommentPolicy', () => {
const buildSUT = (overrides?: OverridesOf) =>
@@ -19,9 +20,7 @@ describe('canCreateProjectCommentPolicy', () => {
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Reviewer,
getServerRole: async () => Roles.Server.User,
@@ -39,9 +38,8 @@ describe('canCreateProjectCommentPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false,
- allowPublicComments: false
+ allowPublicComments: false,
+ visibility: ProjectVisibility.Workspace
}),
getProjectRole: async () => null,
getWorkspace: async () => ({
@@ -76,8 +74,7 @@ describe('canCreateProjectCommentPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: true,
+ visibility: ProjectVisibility.Public,
allowPublicComments: true
}),
getProjectRole: async () => null
@@ -112,8 +109,7 @@ describe('canCreateProjectCommentPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: true,
+ visibility: ProjectVisibility.Public,
allowPublicComments: false
})
})
diff --git a/packages/shared/src/authz/policies/project/comment/canCreate.ts b/packages/shared/src/authz/policies/project/comment/canCreate.ts
index c8b3e4469..aabb90a05 100644
--- a/packages/shared/src/authz/policies/project/comment/canCreate.ts
+++ b/packages/shared/src/authz/policies/project/comment/canCreate.ts
@@ -16,6 +16,7 @@ import {
} from '../../../domain/authErrors.js'
import { ensureImplicitProjectMemberWithWriteAccessFragment } from '../../../fragments/projects.js'
import { Roles } from '../../../../core/constants.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
export const canCreateProjectCommentPolicy: AuthPolicy<
| typeof Loaders.getProject
@@ -53,7 +54,7 @@ export const canCreateProjectCommentPolicy: AuthPolicy<
const project = await loaders.getProject({ projectId })
if (!project) return err(new ProjectNotFoundError())
const allowPublicCommenting =
- (project.isPublic || project.isDiscoverable) && project.allowPublicComments
+ project.visibility === ProjectVisibility.Public && project.allowPublicComments
if (allowPublicCommenting) return ok()
// Not public, ensure proper project write access
diff --git a/packages/shared/src/authz/policies/project/comment/canEdit.spec.ts b/packages/shared/src/authz/policies/project/comment/canEdit.spec.ts
index 068ac2100..102f3b9bc 100644
--- a/packages/shared/src/authz/policies/project/comment/canEdit.spec.ts
+++ b/packages/shared/src/authz/policies/project/comment/canEdit.spec.ts
@@ -14,6 +14,7 @@ import {
} from '../../../domain/authErrors.js'
import { canEditProjectCommentPolicy } from './canEdit.js'
import { TIME_MS } from '../../../../core/helpers/timeConstants.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
describe('canEditProjectCommentPolicy', () => {
const buildSUT = (overrides?: OverridesOf) =>
@@ -21,9 +22,7 @@ describe('canEditProjectCommentPolicy', () => {
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Reviewer,
getServerRole: async () => Roles.Server.User,
@@ -46,9 +45,8 @@ describe('canEditProjectCommentPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false,
- allowPublicComments: false
+ allowPublicComments: false,
+ visibility: ProjectVisibility.Workspace
}),
getProjectRole: async () => null,
getWorkspace: async () => ({
@@ -84,8 +82,7 @@ describe('canEditProjectCommentPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: true,
+ visibility: ProjectVisibility.Public,
allowPublicComments: true
}),
getProjectRole: async () => null
@@ -160,8 +157,7 @@ describe('canEditProjectCommentPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: null,
- isDiscoverable: false,
- isPublic: true,
+ visibility: ProjectVisibility.Public,
allowPublicComments: false
})
})
diff --git a/packages/shared/src/authz/policies/project/model/canCreate.spec.ts b/packages/shared/src/authz/policies/project/model/canCreate.spec.ts
index 3727f436a..882c7773e 100644
--- a/packages/shared/src/authz/policies/project/model/canCreate.spec.ts
+++ b/packages/shared/src/authz/policies/project/model/canCreate.spec.ts
@@ -23,8 +23,6 @@ const buildCanCreateModelPolicy = (
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: cryptoRandomString({ length: 9 }),
- isPublic: false,
- isDiscoverable: false,
workspaceId: cryptoRandomString({ length: 9 })
}),
getProjectRole: async () => {
diff --git a/packages/shared/src/authz/policies/project/model/canDelete.spec.ts b/packages/shared/src/authz/policies/project/model/canDelete.spec.ts
index b07789a94..3bd1c94f1 100644
--- a/packages/shared/src/authz/policies/project/model/canDelete.spec.ts
+++ b/packages/shared/src/authz/policies/project/model/canDelete.spec.ts
@@ -20,9 +20,7 @@ const buildSUT = (overrides?: Partial[0]
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getModel: getModelFake({
id: 'model-id',
@@ -45,9 +43,7 @@ const buildWorkspaceSUT = (
buildSUT({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false
+ workspaceId: 'workspace-id'
}),
getWorkspace: async () => ({
id: 'workspace-id',
diff --git a/packages/shared/src/authz/policies/project/model/canUpdate.spec.ts b/packages/shared/src/authz/policies/project/model/canUpdate.spec.ts
index c1d7d6ec6..56387f3bc 100644
--- a/packages/shared/src/authz/policies/project/model/canUpdate.spec.ts
+++ b/packages/shared/src/authz/policies/project/model/canUpdate.spec.ts
@@ -18,9 +18,7 @@ const buildSUT = (overrides?: Partial[0]
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Contributor,
getServerRole: async () => Roles.Server.User,
@@ -37,9 +35,7 @@ const buildWorkspaceSUT = (
buildSUT({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false
+ workspaceId: 'workspace-id'
}),
getWorkspace: async () => ({
id: 'workspace-id',
diff --git a/packages/shared/src/authz/policies/project/version/canCreate.spec.ts b/packages/shared/src/authz/policies/project/version/canCreate.spec.ts
index 68c74f997..60246166d 100644
--- a/packages/shared/src/authz/policies/project/version/canCreate.spec.ts
+++ b/packages/shared/src/authz/policies/project/version/canCreate.spec.ts
@@ -14,15 +14,14 @@ import {
} from '../../../domain/authErrors.js'
import { canCreateProjectVersionPolicy } from './canCreate.js'
import { TIME_MS } from '../../../../core/index.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
-describe('canReceiveProjectVersionPolicy', () => {
+describe('canCreateProjectVersionPolicy', () => {
const buildSUT = (overrides?: OverridesOf) =>
canCreateProjectVersionPolicy({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isPublic: false,
- isDiscoverable: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Contributor,
getEnv: async () => parseFeatureFlags({}),
@@ -41,8 +40,7 @@ describe('canReceiveProjectVersionPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isPublic: false,
- isDiscoverable: false
+ visibility: ProjectVisibility.Workspace
}),
getWorkspace: getWorkspaceFake({
id: 'workspace-id'
diff --git a/packages/shared/src/authz/policies/project/version/canReceive.spec.ts b/packages/shared/src/authz/policies/project/version/canReceive.spec.ts
index b69a392ae..bb469ec28 100644
--- a/packages/shared/src/authz/policies/project/version/canReceive.spec.ts
+++ b/packages/shared/src/authz/policies/project/version/canReceive.spec.ts
@@ -13,15 +13,14 @@ import {
} from '../../../domain/authErrors.js'
import { canReceiveProjectVersionPolicy } from './canReceive.js'
import { TIME_MS } from '../../../../core/index.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
describe('canReceiveProjectVersionPolicy', () => {
const buildSUT = (overrides?: OverridesOf) =>
canReceiveProjectVersionPolicy({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isPublic: false,
- isDiscoverable: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Reviewer,
getEnv: async () => parseFeatureFlags({}),
@@ -40,8 +39,7 @@ describe('canReceiveProjectVersionPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isPublic: false,
- isDiscoverable: false
+ visibility: ProjectVisibility.Workspace
}),
getWorkspace: getWorkspaceFake({
id: 'workspace-id'
diff --git a/packages/shared/src/authz/policies/project/version/canRequestRender.spec.ts b/packages/shared/src/authz/policies/project/version/canRequestRender.spec.ts
index 47e0d4a31..c11357cc0 100644
--- a/packages/shared/src/authz/policies/project/version/canRequestRender.spec.ts
+++ b/packages/shared/src/authz/policies/project/version/canRequestRender.spec.ts
@@ -13,6 +13,7 @@ import {
WorkspaceSsoSessionNoAccessError
} from '../../../domain/authErrors.js'
import { TIME_MS } from '../../../../core/index.js'
+import { ProjectVisibility } from '../../../domain/projects/types.js'
describe('canRequestProjectVersionRenderPolicy', () => {
const buildSUT = (
@@ -21,9 +22,7 @@ describe('canRequestProjectVersionRenderPolicy', () => {
canRequestProjectVersionRenderPolicy({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isPublic: false,
- isDiscoverable: false
+ workspaceId: null
}),
getProjectRole: async () => Roles.Stream.Reviewer,
getAdminOverrideEnabled: async () => false,
@@ -43,8 +42,7 @@ describe('canRequestProjectVersionRenderPolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isPublic: false,
- isDiscoverable: false
+ visibility: ProjectVisibility.Workspace
}),
getWorkspace: getWorkspaceFake({
id: 'workspace-id'
diff --git a/packages/shared/src/authz/policies/project/version/canUpdate.spec.ts b/packages/shared/src/authz/policies/project/version/canUpdate.spec.ts
index a8aa405b0..9d4ec59d1 100644
--- a/packages/shared/src/authz/policies/project/version/canUpdate.spec.ts
+++ b/packages/shared/src/authz/policies/project/version/canUpdate.spec.ts
@@ -22,9 +22,7 @@ const buildSUT = (overrides?: OverridesOf)
getEnv: async () => parseFeatureFlags({}),
getProject: getProjectFake({
id: 'project-id',
- workspaceId: null,
- isDiscoverable: false,
- isPublic: false
+ workspaceId: null
}),
getVersion: getVersionFake({
id: 'version-id',
@@ -46,9 +44,7 @@ const buildWorkspaceSUT = (
buildSUT({
getProject: getProjectFake({
id: 'project-id',
- workspaceId: 'workspace-id',
- isDiscoverable: false,
- isPublic: false
+ workspaceId: 'workspace-id'
}),
getWorkspace: async () => ({
id: 'workspace-id',
diff --git a/packages/shared/src/authz/policies/workspace/canReceiveProjectsUpdatedMessage.spec.ts b/packages/shared/src/authz/policies/workspace/canReceiveProjectsUpdatedMessage.spec.ts
index 05f321f89..c9388dfe5 100644
--- a/packages/shared/src/authz/policies/workspace/canReceiveProjectsUpdatedMessage.spec.ts
+++ b/packages/shared/src/authz/policies/workspace/canReceiveProjectsUpdatedMessage.spec.ts
@@ -10,6 +10,7 @@ import {
ServerNoSessionError,
WorkspaceNoAccessError
} from '../../domain/authErrors.js'
+import { ProjectVisibility } from '../../domain/projects/types.js'
describe('canReceiveWorkspaceProjectsUpdatedMessagePolicy', () => {
const buildSUT = (
@@ -20,8 +21,7 @@ describe('canReceiveWorkspaceProjectsUpdatedMessagePolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: 'workspace-id',
- isDiscoverable: true,
- isPublic: true
+ visibility: ProjectVisibility.Public
}),
getProjectRole: async () => Roles.Stream.Reviewer,
getServerRole: async () => Roles.Server.Guest,
@@ -73,8 +73,7 @@ describe('canReceiveWorkspaceProjectsUpdatedMessagePolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: null,
- isDiscoverable: true,
- isPublic: true
+ visibility: ProjectVisibility.Public
}),
getProjectRole: async () => null
})
@@ -95,8 +94,7 @@ describe('canReceiveWorkspaceProjectsUpdatedMessagePolicy', () => {
getProject: getProjectFake({
id: 'project-id',
workspaceId: null,
- isDiscoverable: true,
- isPublic: true
+ visibility: ProjectVisibility.Public
}),
getServerRole: async () => null
})
diff --git a/packages/shared/src/tests/fakes.ts b/packages/shared/src/tests/fakes.ts
index 6bf2dcf47..2d5d86b32 100644
--- a/packages/shared/src/tests/fakes.ts
+++ b/packages/shared/src/tests/fakes.ts
@@ -1,5 +1,5 @@
import { merge } from '#lodash'
-import { Project } from '../authz/domain/projects/types.js'
+import { Project, ProjectVisibility } from '../authz/domain/projects/types.js'
import { Comment } from '../authz/domain/comments/types.js'
import { nanoid } from 'nanoid'
import { Model } from '../authz/domain/models/types.js'
@@ -19,8 +19,7 @@ export const fakeGetFactory =
export const getProjectFake = fakeGetFactory(() => ({
id: nanoid(10),
- isPublic: false,
- isDiscoverable: false,
+ visibility: ProjectVisibility.Private,
workspaceId: null,
allowPublicComments: false
}))