UNPKG

@speckle/shared

Version:

Shared code between various Speckle JS packages

263 lines 11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isPlanFeature = exports.workspacePlanHasAccessToFeature = exports.workspaceReachedPlanLimit = exports.workspaceExceedsPlanLimit = exports.WorkspacePlanConfigs = exports.WorkspaceUnpaidPlanConfigs = exports.WorkspacePaidPlanConfigs = exports.WorkspacePlanFeaturesMetadata = exports.isWorkspaceFeatureFlagOn = exports.WorkspaceFeatureFlags = exports.WorkspacePlanFeatures = void 0; const plans_js_1 = require("./plans.js"); /** * WORKSPACE FEATURES */ exports.WorkspacePlanFeatures = { // Core features pretty much available to everyone AutomateBeta: 'automateBeta', DomainDiscoverability: 'domainDiscoverability', // Optional/plan specific DomainSecurity: 'domainBasedSecurityPolicies', SSO: 'oidcSso', CustomDataRegion: 'workspaceDataRegionSpecificity', HideSpeckleBranding: 'hideSpeckleBranding', ExclusiveMembership: 'exclusiveMembership', EmbedPrivateProjects: 'embedPrivateProjects', SavedViews: 'savedViews' }; // this const will be used as a bitwise flag for a per workspace feature access controller // IMPORTANT: always use powers of 2 as the value of the object // read more https://www.hendrik-erz.de/post/bitwise-flags-are-beautiful-and-heres-why // this will make its way to the pricing plan and info setup at some point // but for now its an internal only control exports.WorkspaceFeatureFlags = { none: 0, dashboards: 1, accIntegration: 2, // High numbers for internal features presentations: 64 }; const isWorkspaceFeatureFlagOn = ({ workspaceFeatureFlags, feature }) => (workspaceFeatureFlags & feature) === feature; exports.isWorkspaceFeatureFlagOn = isWorkspaceFeatureFlagOn; exports.WorkspacePlanFeaturesMetadata = { [exports.WorkspacePlanFeatures.AutomateBeta]: { displayName: 'Automate beta access', description: 'Run custom automations on every new model version' }, [exports.WorkspacePlanFeatures.DomainDiscoverability]: { displayName: 'Domain discoverability', description: 'Allow people to discover your workspace if they use a verified company email' }, [exports.WorkspacePlanFeatures.DomainSecurity]: { displayName: 'Domain protection', description: 'Require workspace members to use a verified company email' }, [exports.WorkspacePlanFeatures.SSO]: { displayName: 'Single Sign-On (SSO)', description: 'Require workspace members to authenticate with your SSO provider' }, [exports.WorkspacePlanFeatures.CustomDataRegion]: { displayName: 'Custom data residency', description: 'Store your data in EU, UK, North America, or Asia Pacific' }, [exports.WorkspacePlanFeatures.HideSpeckleBranding]: { displayName: 'Customised viewer', description: 'Hide the Speckle branding in embedded viewer' }, [exports.WorkspacePlanFeatures.ExclusiveMembership]: { displayName: 'Exclusive workspace membership', description: 'Members of exclusive workspaces cannot join or create other workspaces' }, [exports.WorkspacePlanFeatures.EmbedPrivateProjects]: { displayName: 'Embed private projects', description: 'Embed projects with visibility set to private or workspace' }, [exports.WorkspacePlanFeatures.SavedViews]: { displayName: 'Saved views', description: 'Create and share saved views of your models' } }; const unlimited = { projectCount: null, modelCount: null, versionsHistory: null, commentHistory: null }; const baseFeatures = [ exports.WorkspacePlanFeatures.AutomateBeta, exports.WorkspacePlanFeatures.DomainDiscoverability, exports.WorkspacePlanFeatures.EmbedPrivateProjects ]; const WorkspacePaidPlanConfigs = (params) => { const finalBaseFeatures = [ ...baseFeatures, ...(params.featureFlags?.FF_SAVED_VIEWS_ENABLED ? [exports.WorkspacePlanFeatures.SavedViews] : []) ]; return { [plans_js_1.PaidWorkspacePlans.Team]: { plan: plans_js_1.PaidWorkspacePlans.Team, features: [...finalBaseFeatures], limits: { projectCount: 5, modelCount: 25, versionsHistory: { value: 30, unit: 'day' }, commentHistory: { value: 30, unit: 'day' } } }, [plans_js_1.PaidWorkspacePlans.TeamUnlimited]: { plan: plans_js_1.PaidWorkspacePlans.TeamUnlimited, features: [...finalBaseFeatures], limits: { projectCount: null, modelCount: null, versionsHistory: { value: 30, unit: 'day' }, commentHistory: { value: 30, unit: 'day' } } }, [plans_js_1.PaidWorkspacePlans.Pro]: { plan: plans_js_1.PaidWorkspacePlans.Pro, features: [ ...finalBaseFeatures, exports.WorkspacePlanFeatures.DomainSecurity, exports.WorkspacePlanFeatures.SSO, exports.WorkspacePlanFeatures.CustomDataRegion, exports.WorkspacePlanFeatures.HideSpeckleBranding ], limits: { projectCount: 10, modelCount: 50, versionsHistory: null, commentHistory: null } }, [plans_js_1.PaidWorkspacePlans.ProUnlimited]: { plan: plans_js_1.PaidWorkspacePlans.ProUnlimited, features: [ ...finalBaseFeatures, exports.WorkspacePlanFeatures.DomainSecurity, exports.WorkspacePlanFeatures.SSO, exports.WorkspacePlanFeatures.CustomDataRegion, exports.WorkspacePlanFeatures.HideSpeckleBranding ], limits: { projectCount: null, modelCount: null, versionsHistory: null, commentHistory: null } } }; }; exports.WorkspacePaidPlanConfigs = WorkspacePaidPlanConfigs; const WorkspaceUnpaidPlanConfigs = (params) => { const finalBaseFeatures = [ ...baseFeatures, ...(params.featureFlags?.FF_SAVED_VIEWS_ENABLED ? [exports.WorkspacePlanFeatures.SavedViews] : []) ]; return { [plans_js_1.UnpaidWorkspacePlans.Enterprise]: { plan: plans_js_1.UnpaidWorkspacePlans.Enterprise, features: [ ...finalBaseFeatures, exports.WorkspacePlanFeatures.DomainSecurity, exports.WorkspacePlanFeatures.SSO, exports.WorkspacePlanFeatures.CustomDataRegion, exports.WorkspacePlanFeatures.HideSpeckleBranding, exports.WorkspacePlanFeatures.ExclusiveMembership ], limits: unlimited }, [plans_js_1.UnpaidWorkspacePlans.Unlimited]: { plan: plans_js_1.UnpaidWorkspacePlans.Unlimited, features: [ ...finalBaseFeatures, exports.WorkspacePlanFeatures.DomainSecurity, exports.WorkspacePlanFeatures.SSO, exports.WorkspacePlanFeatures.CustomDataRegion, exports.WorkspacePlanFeatures.HideSpeckleBranding, exports.WorkspacePlanFeatures.ExclusiveMembership ], limits: unlimited }, [plans_js_1.UnpaidWorkspacePlans.Academia]: { plan: plans_js_1.UnpaidWorkspacePlans.Academia, features: [ ...finalBaseFeatures, exports.WorkspacePlanFeatures.DomainSecurity, exports.WorkspacePlanFeatures.SSO, exports.WorkspacePlanFeatures.CustomDataRegion, exports.WorkspacePlanFeatures.HideSpeckleBranding ], limits: unlimited }, [plans_js_1.UnpaidWorkspacePlans.TeamUnlimitedInvoiced]: { ...(0, exports.WorkspacePaidPlanConfigs)(params).teamUnlimited, plan: plans_js_1.UnpaidWorkspacePlans.TeamUnlimitedInvoiced }, [plans_js_1.UnpaidWorkspacePlans.ProUnlimitedInvoiced]: { ...(0, exports.WorkspacePaidPlanConfigs)(params).proUnlimited, plan: plans_js_1.UnpaidWorkspacePlans.ProUnlimitedInvoiced }, [plans_js_1.UnpaidWorkspacePlans.Free]: { plan: plans_js_1.UnpaidWorkspacePlans.Free, features: finalBaseFeatures, limits: { projectCount: 1, modelCount: 5, versionsHistory: { value: 7, unit: 'day' }, commentHistory: { value: 7, unit: 'day' } } } }; }; exports.WorkspaceUnpaidPlanConfigs = WorkspaceUnpaidPlanConfigs; const WorkspacePlanConfigs = (params) => ({ ...(0, exports.WorkspacePaidPlanConfigs)(params), ...(0, exports.WorkspaceUnpaidPlanConfigs)(params) }); exports.WorkspacePlanConfigs = WorkspacePlanConfigs; /** * Checks if a workspace exceeds its plan limits for projects and models */ const workspaceExceedsPlanLimit = (params) => { const { plan, projectCount, modelCount, featureFlags } = params; if (!plan) return false; const planConfig = (0, exports.WorkspacePlanConfigs)({ featureFlags })[plan]; if (!planConfig) return false; const limits = planConfig.limits; if (!limits.projectCount || !limits.modelCount) return false; if (!projectCount || !modelCount) return false; return projectCount > limits.projectCount || modelCount > limits.modelCount; }; exports.workspaceExceedsPlanLimit = workspaceExceedsPlanLimit; /** * Checks if a workspace reached its plan limits for projects and models */ const workspaceReachedPlanLimit = (params) => { const { plan, projectCount, modelCount, featureFlags } = params; if (!plan) return false; const planConfig = (0, exports.WorkspacePlanConfigs)({ featureFlags })[plan]; if (!planConfig) return false; const limits = planConfig.limits; if (!limits.projectCount || !limits.modelCount) return false; return projectCount === limits.projectCount || modelCount === limits.modelCount; }; exports.workspaceReachedPlanLimit = workspaceReachedPlanLimit; const workspacePlanHasAccessToFeature = ({ plan, feature, featureFlags }) => { const planConfig = (0, exports.WorkspacePlanConfigs)({ featureFlags })[plan]; const hasAccess = planConfig.features.includes(feature); return hasAccess; }; exports.workspacePlanHasAccessToFeature = workspacePlanHasAccessToFeature; const isPlanFeature = (feature) => { if (typeof feature === 'number') { return false; } return Object.values(exports.WorkspacePlanFeatures).includes(feature); }; exports.isPlanFeature = isPlanFeature; //# sourceMappingURL=features.js.map